Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Write files using create_new option to avoid accidental overwrites #855

Closed
wants to merge 1 commit into from

Conversation

phil-opp
Copy link
Contributor

The previously used File::create silently overwrites existing files, which causes problems e.g. when two pages accidentally specify the same path. By opening all files with the create_new option, we can ensure that no files are overwritten.

Fixes #366

The previously used `File::create` silently overwrites existing files, which causes problems e.g. when two pages accidentally specify the same `path`. By opening all files with the `create_new` option, we can ensure that no files are overwritten.
@phil-opp
Copy link
Contributor Author

This approach is a bit more far-reaching than only checking for path collisions, but I think it is a good sanity check. The error message that occurs for duplicate files is still ok, e.g.:

Error: Failed to create "public/freestanding-rust-binary/index.html"
Reason: File exists (os error 17)

@Keats
Copy link
Collaborator

Keats commented Nov 26, 2019

That works but I would prefer having a full report on why it is failing, eg which files are conflicting.
It would basically take the permalinks of each page/section + their alias and associate it to a Set and if the len(set) > 1, we have some duplicates that we can report with the exact file info.

@phil-opp
Copy link
Contributor Author

I understand. However I still think that the create_new option should be set to catch future mistakes (e.g. in other features). If there is any reason for Zola to overwrite files in the future, we can still provide an explicit way to do this. But currently, an overwritten file indicates a (configuration) bug so we should error in this case.

@phil-opp
Copy link
Contributor Author

To clarify: I think there should be both: A nice error report and a sanity check that no files are overwritten.

@phil-opp
Copy link
Contributor Author

phil-opp commented Nov 26, 2019

Ok, from the CI tests it seems like there are a few cases where Zola does indeed overwrite files:

Err(Error { kind: Msg("Failed to create \"/tmp/.tmpvtbHLn/test_site_i18n/public/index.html\""), source: Some(Os { code: 17, kind: AlreadyExists, message: "File exists" }) })
thread 'can_rebuild_after_editing_in_colocated_asset_folder_with_language' panicked at 'assertion failed: res.is_ok()', components/rebuild/tests/rebuild.rs:269:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.

---- can_rebuild_after_deleting_file stdout ----
thread 'can_rebuild_after_deleting_file' panicked at 'called `Result::unwrap()` on an `Err` value: Error { kind: Msg("Failed to create \"/tmp/.tmpQjzN5k/test_site/public/posts/2018/transparent-page/index.html\""), source: Some(Os { code: 17, kind: AlreadyExists, message: "File exists" }) }', src/libcore/result.rs:1084:5

---- can_rebuild_after_renaming_colocated_asset_folder stdout ----
thread 'can_rebuild_after_renaming_colocated_asset_folder' panicked at 'called `Result::unwrap()` on an `Err` value: Error { kind: Msg("Failed to create \"/tmp/.tmpYAUV59/test_site/public/posts/2018/transparent-page/index.html\""), source: Some(Os { code: 17, kind: AlreadyExists, message: "File exists" }) }', src/libcore/result.rs:1084:5

---- can_rebuild_after_renaming_page stdout ----
thread 'can_rebuild_after_renaming_page' panicked at 'called `Result::unwrap()` on an `Err` value: Error { kind: Msg("Failed to create \"/tmp/.tmpI4nlAs/test_site/public/posts/2018/transparent-page/index.html\""), source: Some(Os { code: 17, kind: AlreadyExists, message: "File exists" }) }', src/libcore/result.rs:1084:5

---- can_rebuild_after_renaming_non_md_asset_in_colocated_folder stdout ----
thread 'can_rebuild_after_renaming_non_md_asset_in_colocated_folder' panicked at 'called `Result::unwrap()` on an `Err` value: Error { kind: Msg("Failed to create \"/tmp/.tmp6gybnn/test_site/public/posts/2018/transparent-page/index.html\""), source: Some(Os { code: 17, kind: AlreadyExists, message: "File exists" }) }', src/libcore/result.rs:1084:5

---- can_rebuild_after_renaming_section_and_deleting_file stdout ----
thread 'can_rebuild_after_renaming_section_and_deleting_file' panicked at 'called `Result::unwrap()` on an `Err` value: Error { kind: Msg("Failed to create \"/tmp/.tmp3vozll/test_site/public/posts/2018/transparent-page/index.html\""), source: Some(Os { code: 17, kind: AlreadyExists, message: "File exists" }) }', src/libcore/result.rs:1084:5

---- can_rebuild_after_renaming_section_folder stdout ----
thread 'can_rebuild_after_renaming_section_folder' panicked at 'called `Result::unwrap()` on an `Err` value: Error { kind: Msg("Failed to create \"/tmp/.tmpxWVPw2/test_site/public/posts/2018/transparent-page/index.html\""), source: Some(Os { code: 17, kind: AlreadyExists, message: "File exists" }) }', src/libcore/result.rs:1084:5

---- can_rebuild_after_simple_change_to_page_content stdout ----
thread 'can_rebuild_after_simple_change_to_page_content' panicked at 'called `Result::unwrap()` on an `Err` value: Error { kind: Msg("Failed to create \"/tmp/.tmpATtdAu/test_site/public/posts/2018/transparent-page/index.html\""), source: Some(Os { code: 17, kind: AlreadyExists, message: "File exists" }) }', src/libcore/result.rs:1084:5

---- can_rebuild_after_sort_change_in_section stdout ----
thread 'can_rebuild_after_sort_change_in_section' panicked at 'called `Result::unwrap()` on an `Err` value: Error { kind: Msg("Failed to create \"/tmp/.tmpwLg15l/test_site/public/posts/2018/transparent-page/index.html\""), source: Some(Os { code: 17, kind: AlreadyExists, message: "File exists" }) }', src/libcore/result.rs:1084:5

---- can_rebuild_after_transparent_change stdout ----
thread 'can_rebuild_after_transparent_change' panicked at 'called `Result::unwrap()` on an `Err` value: Error { kind: Msg("Failed to create \"/tmp/.tmpsfR6R1/test_site/public/posts/2018/transparent-page/index.html\""), source: Some(Os { code: 17, kind: AlreadyExists, message: "File exists" }) }', src/libcore/result.rs:1084:5

---- can_rebuild_after_title_change_page_global_func_usage stdout ----
thread 'can_rebuild_after_title_change_page_global_func_usage' panicked at 'called `Result::unwrap()` on an `Err` value: Error { kind: Msg("Failed to create \"/tmp/.tmphmHRgy/test_site/public/posts/2018/transparent-page/index.html\""), source: Some(Os { code: 17, kind: AlreadyExists, message: "File exists" }) }', src/libcore/result.rs:1084:5

I guess we could fix those by deleting the existing content before recreating it (i.e. once before zola starts writing files). This would also ensure that we have no stale files left over from previous runs. Let me know if I should try something like this or if you prefer to close this PR!

@Keats
Copy link
Collaborator

Keats commented Nov 26, 2019

However I still think that the create_new option should be set to catch future mistakes (e.g. in other features)

Very good point. But in that specific case of rebuilding, we do want to overwrite files otherwise zola serve doesn't work. We could use a different function in build and serve but that seems like a recipe for disaster.

@phil-opp
Copy link
Contributor Author

I see. Seems like this approach isn't the right on then.

@phil-opp phil-opp closed this Nov 27, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants