Skip to content

cabal-install: v2-install should touch symlink target #8536

@frasertweedale

Description

@frasertweedale

Describe the bug
When running v2-install using symlink method (the default), cabal will not rebuild if the package+hash is already in the cabal store, it does not rebuild the package. Instead it just (re)writes the symlink to point to the exist binary. This is what we want.

The problem is that programs in the environment may use stat to query program modification time, for audit or other behavioural reasons. For example, if the modification timestamp of the symlink target did not move forward in time, programs that use dyre or similar techniques will not be able to notice that the executable changed.

To better support such use cases, v2-install should touch (update modification timestamp) the target executable, ensuring that observers will always see it as changed/newer.

Please use version-prefixed commands (e.g. v2-build or v1-build) to avoid ambiguity.

Additional context

In some cases it is possible for tools to work around this issue by:

  • inquiring whether the file in question is symlink
  • if so, check the modification time of both the symlink (lstat) and its target (stat).

But if doing this from within the Haskell process (e.g. when using dyre or similar techniques),
getExecutablePath gives you the actual executable file, not the symlink that was resolved to it (if any).
Using getProgName is less reliable and imposes yet more burden on the application. It can all
be avoided by simply touching the target executable when writing the symlink.

Alternatively, we can change nothing and expect the user who runs v2-install to also touch the symlink
target themselves. If we are concerned that touching the executable could have unintended consequences
for other use cases, then we could at least add something to the documentation to explain that cabal intentionally
leaves the executable as-is, and use cases that need the modification timestamp to be bumped must deal
with that manually.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions