Have hard links override static files

  • 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.