Skip to content

A PATH change that swaps a tool goes unnoticed unless CONFIG_TRACKED_TOOLS names it, which nothing does by default #482

Description

@typeless

Symptom

CONFIG_TRACKED_TOOLS is empty by default, so in a default configuration a PATH change that resolves a command's tool to a different binary produces a stale build with no diagnostic. putup reports the project up to date while the compiler it would run has changed.

Reproduced on main 8dd8a5a6b, with first/mytool printing v1 and second/mytool printing v2, on a project whose only rule is : |> mytool > %o |> out.txt:

$ PATH=$d/first:$PATH  putup -B .
[.] Build completed: 1 commands in 1ms          out.txt: v1
$ PATH=$d/second:$d/first:$PATH  putup -B .
[.] Nothing to do (up to date).                 out.txt: v1     # stale

With one line added to tup.config, the same PATH change is caught:

$ echo CONFIG_TRACKED_TOOLS=mytool >> tup.config
$ PATH=$d/second:$d/first:$PATH  putup -B .
[.] Build completed: 1 commands in 1ms          out.txt: v2

Why it is not just "tup does this too"

tup makes PATH a sticky env node of every command (environ_add_defaults in environ.c, tup_db_check_env/env_cb in db.c), so upstream catches this case — by re-running every command on any PATH change, which tup.1 documents as a known cost under export ("if PATH is changed, all commands will run again").

#480 decided putup would not follow that, because a PATH recorded as a string cannot tell a change that shadows a tool from one that does not, and a build system that re-runs everything whenever direnv, nvm, an IDE terminal or a CI job composes PATH differently is not incremental for a large class of real setups. REQ-ENV-FORWARDED-IDENTITY names CONFIG_TRACKED_TOOLS as the compensating route and REQ-ENV-TRACKED-TOOLS specifies it (append_tool_stat in builder.cpp folds the resolved path:size:mtime, so a shadowing prefix re-runs and an inert one does not).

That reasoning holds only where the route is switched on. The requirement records the residue as a stated limitation rather than hiding it; this issue is that residue.

Decisions to make

  • Whether putup should seed tracking automatically — for example from the first word of each rule's rendered command text — so the default configuration catches a shadowed tool without PATH entering identity. Cost: a stat per distinct tool per build, and a decision about what to do with a tool that resolves to nothing.
  • If tracking stays opt-in, whether a PATH whose value differs from the one the index was built under deserves a warning rather than silence, and whether docs/reference.md should say plainly that an unconfigured project does not notice a toolchain change made through PATH.
  • Either way, whether the chosen answer is pinned by a requirement in command-record.ears.md's env-values group, next to the three that process: forward HOME to build commands, and pin the forwarded set out of identity #481 added.

Found while settling #480 (PR #481); listed there as an open risk.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions