You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
A PATH change that swaps a tool goes unnoticed unless CONFIG_TRACKED_TOOLS names it, which nothing does by default #482
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:
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 anyPATH 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.
Symptom
CONFIG_TRACKED_TOOLSis empty by default, so in a default configuration aPATHchange 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, withfirst/mytoolprintingv1andsecond/mytoolprintingv2, on a project whose only rule is: |> mytool > %o |> out.txt:With one line added to
tup.config, the same PATH change is caught:Why it is not just "tup does this too"
tup makes
PATHa sticky env node of every command (environ_add_defaultsin environ.c,tup_db_check_env/env_cbin db.c), so upstream catches this case — by re-running every command on anyPATHchange, which tup.1 documents as a known cost underexport("if PATH is changed, all commands will run again").#480 decided putup would not follow that, because a
PATHrecorded 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 composesPATHdifferently is not incremental for a large class of real setups.REQ-ENV-FORWARDED-IDENTITYnamesCONFIG_TRACKED_TOOLSas the compensating route andREQ-ENV-TRACKED-TOOLSspecifies it (append_tool_statin builder.cpp folds the resolvedpath: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
PATHentering identity. Cost: a stat per distinct tool per build, and a decision about what to do with a tool that resolves to nothing.PATHwhose value differs from the one the index was built under deserves a warning rather than silence, and whetherdocs/reference.mdshould say plainly that an unconfigured project does not notice a toolchain change made throughPATH.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.