Skip to content

An output onto a source directory or a group's directory is not refused at parse time, where tup refuses it #498

Description

@typeless

Symptom

An output may name a directory that exists in the source tree, or the directory a group lives in. putup does not refuse it at parse time. tup does.

Output onto a source directory, in-tree. srcdir/ holds f.c:

: |> echo hi > %o |> srcdir
$ putup -B .
[.] Error: Attempting to create files the build does not own:
  srcdir
You can do one of two things to fix this:
  1) If a file is really supposed to be created from the command, delete it from the filesystem and try again.

putup does refuse this, but later in the build and as an ownership conflict. That message tells the user to delete a directory of sources.

The same, in a variant build. putup -B build prints Build completed: 1 commands and writes a regular file build/srcdir.

Output onto a group's directory. d does not exist on disk:

: |> echo a > %o |> a.txt d/<g>
: |> echo hi > %o |> d
$ putup -B .
[.] Build completed: 2 commands in 1ms

This writes a regular file d, while the graph still holds d as the directory of <g>.

All three were run against build/putup from PR #497 (0dc8b5352).

Upstream

tup parse refuses all three:

tup error: Attempting to insert 'srcdir' as a generated node when it already exists as a different type (directory). ...
tup error: Attempting to insert 'd' as a generated node when it already exists as a different type (generated directory). ...

In a variant build, do_rule_outputs checks the output against its source-tree counterpart ("... in the source directory").

Cause

PR #497 refuses an output whose bound node is not a file (REQ-OUTPUT-NOT-A-DIRECTORY, the switch after ensure_file_node in expand_rule, src/graph/builder.cpp:2254). That catches only a Directory node under the build root.

  • An output is a build-root path. In an in-tree build, ensure_file_node's alias branch (src/graph/dag.cpp:171) aliases it to its source-root twin only when the twin is a Ghost or a File. A Directory twin, whether it was read from disk or created for a group, is skipped. So the output gets a second, Generated node beside it, and the check accepts that node.
  • In a variant build, nothing compares an output against the source tree.

Fix direction

At the output check, also look up the output's source-root twin, in-tree and in a variant build, and refuse when it is a Directory. That would conform to validate_output and do_rule_outputs. REQ-OUTPUT-NOT-A-DIRECTORY (spec/requirements/output-paths.ears.md) records this gap as its third divergence; the fix removes it.

Activity

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

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions