- Feature Name: link-override
- Start Date: 2022-04-07
Summary
When the static folder is hard linked, the hard links override any existing files.
Motivation
The entire public directory is erased and copied over every time the project is built.
The theme static files are copied over before the project static files.
If hard linking is disabled, then the project static files simply override the theme static files.
At least one theme encourages the use of this feature as a method for theme customisation.
However, if hard linking is enabled, trying to override a theme static file with a hard link will inevitably fail with the following error:
Failed to build the site
Error: Was not able to copy file /home/user/web/static/js/zola.386.js to /home/user/web/public
Reason: File exists (os error 17)
This makes hard linking incompatible with those themes that are customisable by way of static overrides.
By having the copy function check if file exists, and if so delete it before creating the hard link, this brings hard link behaviour in line with file copy behaviour.
Guide-level explanation
When hard_link_static is set to “true”, files in the static
directory are hard-linked.
Useful for large static files.
Note that for this to work, both static
and the output directory need to be on the same filesystem.
Note that the theme’s static
files are always copied, regardless of this setting, but these files will be removed and replaced with the project’s static
files or hard links.
Reference-level explanation
When hard_link_static is true, the copy_file_if_needed function will check whether the destination path is a file, and if so, remove the file at the destination path and then attempt to create the hard link.
Drawbacks
This might allow for copy_file_if_needed to override some file that it’s not supposed to somewhere else down the line.
Rationale and alternatives
This design brings the hard link true behaviour in line with the file copy behaviour.
By not doing this, trying to override theme configurations in a hard linked static folder will cause the builds to fail.
Unresolved questions
I have not yet checked exhaustively for all the use cases of copy_file_if_needed, nor if allowing it to remove a file to replace it with a hard link can break some other behaviour.
Future possibilities
My current attempt at implementing this simply deletes the destination file and creates the hard link.
A future version might replicate the behaviour of the file copy override mechanism, checking the modification time of both source and destination.
Ideally this would be done in an idiomatic way with minimal code duplication.