Symptom
A group can be declared under a path an earlier rule generates as a file:
: |> echo hi > %o |> d
: |> echo a > %o |> a.txt d/<g>
$ putup -B .
[.] Build completed: 2 commands in 4ms
The graph now holds d twice: once as a generated file and once as a directory containing <g>. The pre-#497 binary behaves the same. Run against build/putup from PR #497 (0dc8b5352).
An output in the same position is already refused ("Unable to create 'd/x' because the generated file 'd' is not a directory"). So is a group under a source file.
Upstream
tup error: Unable to output to a different directory because 'd' is a generated file
tup error: Failed to find directory ID for dir 'd/<g>' relative to '.'
This is find_dir_tupid_dt_pg.
Cause
get_or_create_group_node interns the group's directory as a source-root path, but a rule output is a build-root path. In an in-tree build, ensure_file_node aliases a build path to its source twin (src/graph/dag.cpp:171) but never a source path to its build twin. So the group's ensure_file_node(source d, Directory) finds no node, and creates a fresh Directory beside the generated file. add_file_node's parent check never sees the generated d.
Fix direction
In an in-tree build, when a source path has no node, the lookup should also try its build-root twin, the reverse of the existing alias. Then the group lands under the generated file and #494's parent check refuses it. REQ-OUTPUT-UNDER-DIRECTORY (spec/requirements/output-paths.ears.md) records this gap in its reference and leaves "a generated file" out of the group clause; the fix should restore it.
Symptom
A group can be declared under a path an earlier rule generates as a file:
The graph now holds
dtwice: once as a generated file and once as a directory containing<g>. The pre-#497 binary behaves the same. Run againstbuild/putupfrom PR #497 (0dc8b5352).An output in the same position is already refused ("Unable to create 'd/x' because the generated file 'd' is not a directory"). So is a group under a source file.
Upstream
This is
find_dir_tupid_dt_pg.Cause
get_or_create_group_nodeinterns the group's directory as a source-root path, but a rule output is a build-root path. In an in-tree build,ensure_file_nodealiases a build path to its source twin (src/graph/dag.cpp:171) but never a source path to its build twin. So the group'sensure_file_node(source d, Directory)finds no node, and creates a fresh Directory beside the generated file.add_file_node's parent check never sees the generatedd.Fix direction
In an in-tree build, when a source path has no node, the lookup should also try its build-root twin, the reverse of the existing alias. Then the group lands under the generated file and #494's parent check refuses it.
REQ-OUTPUT-UNDER-DIRECTORY(spec/requirements/output-paths.ears.md) records this gap in its reference and leaves "a generated file" out of the group clause; the fix should restore it.