fix: ignore hidden named source operands

This commit is contained in:
2026-08-22 19:28:54 +09:00
parent 6279d46652
commit 3922f1c34e
6 changed files with 627 additions and 0 deletions

View File

@@ -9955,6 +9955,131 @@ artifact-layout, harness-protocol, cache, database, or publication field.
Build workdir format remains `18`, test workdir format remains `19`, semantic
storage format remains `3`, and no test-result cache is introduced.
### 11.50 Implemented named-source leading-dot/underscore eligibility
An explicitly named raw `.ww` source now observes the same unconditional
basename exclusion as a named `.go` source in Go 1.26.5. This closes the gap in
WW's existing single-source command route: a final requested basename beginning
`.` or `_` is not a package source, even though named sources otherwise bypass
directory-only target-suffix selection. Directory selection already enforced
this rule and remains unchanged.
#### Pinned Go evidence and applicability
The reference is official Go 1.26.5 at commit
`c19862e5f8415b4f24b189d065ed739517c548ba`:
- `PackagesAndErrors` recognizes an existing `.go` operand and routes the
complete named list to `GoFilesPackage`
([`cmd/go/internal/load/pkg.go`, lines 29032918](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/load/pkg.go#L2903-L2918)).
`GoFilesPackage` enables `UseAllFiles`, presents only the named `FileInfo`
entries through a synthetic directory, and loads one command-line package
([lines 32443315](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/load/pkg.go#L3244-L3315)).
- `go/build.Import` passes each synthetic entry through `Context.matchFile`
([`go/build/build.go`, lines 886914](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/go/build/build.go#L886-L914)).
`matchFile` rejects a name beginning `_` or `.` before extension, target
suffix, open, imports, or build constraints; that branch precedes the
`UseAllFiles` condition
([lines 14381509](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/go/build/build.go#L1438-L1509)).
A package with no remaining source category returns `NoGoError`
([lines 10761082](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/go/build/build.go#L1076-L1082));
the command loader presents the case as `no Go files`
([`cmd/go/internal/load/pkg.go`, lines 250270](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/load/pkg.go#L250-L270)).
- Build reports load errors before installation/action construction
([`cmd/go/internal/work/build.go`, lines 697728](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/work/build.go#L697-L728)).
Test uses the same loader
([`cmd/go/internal/test/test.go`, lines 703719](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/test/test.go#L703-L719))
and turns its error into package setup failure before constructing a runnable
([lines 10151050](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/test/test.go#L1015-L1050)).
- Official command testdata explicitly records that `_cgo_yy.go` named on the
command line is ignored and permits the exact `no Go files` result
([`cgo_bad_directives.txt`, lines 1123](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/testdata/script/cgo_bad_directives.txt#L11-L23)).
`import_ignore.txt` independently proves a dot file contributes no import
([lines 111](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/testdata/script/import_ignore.txt#L1-L11)).
The rule honestly applies to WW's local literal `.ww` operand. It adds no
module, manifest, registry, network, generalized import, or build-expression
surface. This section is deliberately bounded to the existing single raw
source target. Multiple named sources as one package and visible
`*_test.ww` exclusion from `ww build` remain separate open semantics; when a
future source-set loader admits multiple names, it must apply this same rule to
each requested basename.
#### Source, package, and import ownership
The twin public drivers own one allocation-free operand predicate after
existing CLI-shape checks and a successful requested-path `Stat`, but before
logical resolution or graph entry. It requires an original spelling ending
exactly `.ww`, then examines only the final requested basename. A hidden parent
containing visible `main.ww` does not
exclude the named source. A requested hidden symlink spelling is excluded even
when its target is visible or non-regular, while a visible requested spelling
remains eligible even when its target basename is hidden. This follows the
`FileInfo.Name` seen
by Go's synthetic named-file directory: Unix `Stat` follows the target but
fills `Name` from the requested path
([`os/stat_unix.go`, lines 2838](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/os/stat_unix.go#L28-L38),
[`os/stat_linux.go`, lines 1330](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/os/stat_linux.go#L13-L30)).
Physical target paths do not become identity.
Prefix exclusion precedes every later classifier. `_main_test.ww` and
`.main_test.ww` are absent before production/test partitioning. A hidden
`_main_windows.ww` is absent, but a visible `main_windows.ww` named directly
remains eligible because the named-file analogue uses `UseAllFiles`; directory
platform filtering is unchanged. Logical operands without a `.ww` suffix,
directory and recursive requests, imports, and `ww run` retain their existing
routes.
An excluded operand creates no package clause, declaration, production/test
variant, or top-level state. Its bytes are not decoded or parsed: malformed
UTF-8, NUL, BOM, missing/invalid package clauses, late imports, missing imports,
unused imports, cycles, `internal`/vendor rules, and checker diagnostics cannot
resurrect it or outrank selection. It contributes no qualifier, import-use
obligation, edge, canonical dotted identity, initializer, or link closure. The
lexical parent printed by the diagnostic is presentation metadata only and is
never package, import, graph, action, symbol, `.wwi`, artifact, publication, or
persistence identity.
#### Observable command and lifecycle behavior
`ww build HIDDEN.ww` exits 1 with empty standard output and
`ww: PARENT: directory contains no WW package sources` on standard error.
An ordinary explicit running `ww test HIDDEN.ww` adds its established exact
command-owned `FAIL` line on standard output; compile-only and assembly-only
test requests do not. With no slash, `PARENT` is `.`, a root child uses `/`,
and otherwise it is the requested lexical bytes before the final slash. CLI
flag/path-length errors and the existing raw-test directory-only package-option
shape keep their precedence. A failed requested-path `Stat` retains ordinary
target/logical resolution; for an existing non-directory raw operand,
no-source selection precedes logical resolution, output-destination preflight,
and all source, producer, publication, and runtime diagnostics. Exact
`/dev/null` does not suppress the load failure.
No root/dependency action, test support, generated main, compiler, assembler,
archiver, linker, harness, test child, or program process starts. Cold rejection
creates no default or explicit output, workdir, adjacent `.sepwork`, unit,
`.wwi`, assembly, object, archive, init artifact, binary, status, stage, capture,
result, transaction, or private temporary directory. Warm rejection starts no
transaction and preserves every prior work-artifact and public/retained byte.
It leaves no `.new`, `.install`, `.wwtxn.*`, or recovery residue. Producer,
runtime, publication-only, cleanup-only, signal, timeout, and descendant
semantics for visible inputs are unchanged.
The predicate is request-local and creates no shared state, process group,
lock, or interruption owner, so overlapping hidden and visible requests remain
isolated. Cstage and WWstage must agree byte-for-byte on status, stdout, stderr,
and complete artifact absence; representative visible named sources retain
binary and semantic-artifact identity. The focused native
`named_source_prefixes_are_ignored` observer owns both prefixes, build/test and
compile-only paths, prefix-before-test/platform precedence, requested symlink
spelling, hidden-parent/visible-basename and wrong-platform controls, unread
malformed/import bytes, cold cleanup, warm preservation/restoration, residue,
and stage parity.
No serialized format changes. Build workdir format remains `18`, test workdir
format remains `19`, semantic storage format remains `3`, and there is no test
result cache.
## 12. Candidate architectures and hard-gate decision
Five candidates were developed as coherent systems, not as feature bins.