build: omit named test source operands
This commit is contained in:
@@ -10080,6 +10080,170 @@ 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.
|
||||
|
||||
### 11.51 Implemented explicit named test-source build omission
|
||||
|
||||
A single existing raw `ww build` operand whose requested final basename ends
|
||||
exactly `_test.ww` is now a test-only named source. WW syntax-observes only the
|
||||
package clause and its initial contiguous import section, preserves any read/header
|
||||
diagnostic, then omits the valid test-only root before logical resolution or
|
||||
action construction. This is deliberately distinct from the leading-dot and
|
||||
underscore rule in 11.50: `_test.ww` reaches that earlier exclusion, whereas a
|
||||
visible `x_test.ww` reaches this test-only omission.
|
||||
|
||||
#### Pinned authority, tests, and applicability
|
||||
|
||||
- **behavior directly implemented or asserted by pinned Go** — official Go
|
||||
1.26.5 commit `c19862e5f8415b4f24b189d065ed739517c548ba` recognizes an
|
||||
existing non-directory named `.go` operand in `PackagesAndErrors`
|
||||
([`cmd/go/internal/load/pkg.go`, lines 2903–2918](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/load/pkg.go#L2903-L2918)),
|
||||
builds its synthetic command-line package with `UseAllFiles`
|
||||
([lines 3244–3315](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/load/pkg.go#L3244-L3315)),
|
||||
and classifies `_test.go` separately from `GoFiles`
|
||||
([`go/build/build.go`, lines 930–1036](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/go/build/build.go#L930-L1036)).
|
||||
`UseAllFiles` bypasses ordinary target and build-expression rejection, but
|
||||
not that test-file classification
|
||||
([lines 1438–1509](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/go/build/build.go#L1438-L1509)).
|
||||
- **behavior directly implemented or asserted by pinned Go** — on a
|
||||
successfully scanned header, `readGoInfo` reads the initial package/import
|
||||
header and one stop byte, then removes that byte before parsing; on header
|
||||
syntax recovery it deliberately drains the remaining source
|
||||
([`go/build/read.go`, lines 265–315](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/go/build/read.go#L265-L315)).
|
||||
Every raw NUL reached by its reader is a read error
|
||||
([lines 71–89](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/go/build/read.go#L71-L89));
|
||||
`parser.ImportsOnly` stops before ordinary declarations
|
||||
([`go/parser/parser.go`, lines 2887–2923](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/go/parser/parser.go#L2887-L2923)).
|
||||
Thus a package or initial-import header error precedes omission, while a
|
||||
later declaration/body error does not become an ordinary-build error.
|
||||
- **behavior directly implemented or asserted by pinned Go** — ordinary
|
||||
initial loading does not recursively resolve test imports
|
||||
([`cmd/go/internal/load/pkg.go`, lines 350–358](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/load/pkg.go#L350-L358));
|
||||
`go/build` records their metadata at `go/build/build.go:1037–1040`.
|
||||
Build checks loader errors first and then omits a test-only root before
|
||||
output/action construction
|
||||
([`cmd/go/internal/work/build.go`, lines 459–559 and 731–745](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/work/build.go#L459-L559)).
|
||||
- **behavior directly implemented or asserted by pinned Go** — related
|
||||
official anchors are `go/build/build_test.go:382–421` (`TestMatchFile`),
|
||||
`go/build/build_test.go:812–831` (`TestDirectives` and `XTestDirectives`),
|
||||
`go/build/read_test.go:17–73,120–159,165–249` (header boundary, NUL, and
|
||||
syntax recovery),
|
||||
`cmd/go/testdata/script/test_relative_cmdline.txt:1–49`, and
|
||||
`cmd/go/testdata/script/build_test_only.txt:1–18`. The pinned official
|
||||
repository has no script that directly invokes `go build NAME_test.go`; the
|
||||
exact named-build result below is derived from its pinned loader and action
|
||||
ordering, not presented as an unanchored direct script assertion.
|
||||
- **behavior derived from the pinned implementation** — one valid named test
|
||||
source produces no build action. No effective `-o` and exact `/dev/null`
|
||||
succeed silently; a non-directory output reports `ww: no packages to
|
||||
build\n`; an existing or trailing-slash output directory reports
|
||||
`ww: no main packages to build\n`. Header loading occurs before those
|
||||
empty-selection branches.
|
||||
- **behavior derived from the pinned implementation** — the pinned body
|
||||
boundary is byte-sensitive: an ordinary non-`i` stop byte, a first malformed
|
||||
UTF-8 byte, or a later BOM byte is excluded, while a reached NUL and an
|
||||
unterminated comment remain load errors; a following byte `i` is attempted as
|
||||
another import. WW applies the corresponding rule at its lexical `import`
|
||||
boundary: it never lexes the first ordinary body token, but preserves NUL and
|
||||
comment diagnostics encountered while skipping header trivia.
|
||||
|
||||
The rule honestly applies to WW's local, manifest-free literal `.ww` model:
|
||||
`*_test.ww` already means test source for directory selection and `ww test`.
|
||||
It introduces no module, manifest, registry, lock, network resolver, cache,
|
||||
generalized import grammar, source build expression, or test-result cache.
|
||||
|
||||
#### Source and identity ownership
|
||||
|
||||
- **behavior directly implemented or asserted by pinned Go** — named-source
|
||||
package construction presents `Stat`-derived file information through its
|
||||
synthetic directory. The operand spelling remains the file name presented
|
||||
to selection, even though `Stat` follows a symlink.
|
||||
- **behavior derived from the pinned implementation** — the twin true owners
|
||||
are `cmd/ww/main.c::do_build` and `selfhost/cmd/ww/main.ww::dobuild`, after
|
||||
the existing hidden-prefix check and before `resolve_module` / `resolvemodule`.
|
||||
A requested visible non-directory spelling ending `_test.ww` is classified
|
||||
from that spelling; a symlink to a directory remains a directory request.
|
||||
The finite-stream header reader is not a regular-file restriction: a supplied
|
||||
finite FIFO is read as a source, while an unreadable entry reports its header
|
||||
read failure. Physical parent directories and symlink targets remain loader
|
||||
metadata, never canonical package or import identity.
|
||||
- **behavior derived from the pinned implementation** — platform-looking
|
||||
visible names such as `x_windows_test.ww` remain test-only named sources.
|
||||
Multiple named sources, logical operands without `.ww`, directories,
|
||||
recursive requests, `ww run`, and all visible non-test raw operands retain
|
||||
their prior routes. In particular, this does not implement Go's multiple
|
||||
named-source package collection.
|
||||
- **behavior derived from the pinned implementation** — the header observation
|
||||
is discarded after classification. It creates no canonical package,
|
||||
command-line package representative, dotted import identity, qualifier,
|
||||
symbol namespace, `.wwi`, action, archive, publication, or persistence key.
|
||||
Initial import syntax is checked solely for load-error precedence; omitted
|
||||
test-source imports are not resolved and create no graph edge or action.
|
||||
|
||||
#### Build, test, package, and import effects
|
||||
|
||||
- **behavior directly measured WW behavior** — before this change, both stages
|
||||
compiled, linked, published, persisted, and ran a valid visible
|
||||
`only_test.ww`; `ww build -w WORK -o OUT only_test.ww` exited 0 with empty
|
||||
streams, a byte-identical mode-0755 executable, populated work state, and
|
||||
runtime status 19. A missing test-only import likewise reached ordinary
|
||||
import resolution.
|
||||
- **behavior derived from the pinned implementation** — post-contract build
|
||||
behavior is an empty production selection after a valid header: no compiler,
|
||||
assembler, archiver, linker, generated main, test harness, test child, or
|
||||
program process starts. `-S` follows the same no-action rule. No runtime
|
||||
result can occur.
|
||||
- **behavior derived from the pinned implementation** — package behavior is
|
||||
confined to the transient header check; no production/test variant or
|
||||
package action remains. Import behavior is likewise confined to syntax;
|
||||
missing test-only dotted imports, late imports, body syntax/type errors, and
|
||||
runtime faults cannot enter the production graph.
|
||||
- **behavior derived from the pinned implementation** — test behavior is an
|
||||
explicit non-effect. Raw `ww test`, `ww test -c`, and `ww test -S` continue
|
||||
to select named test files. Directory and recursive `ww build` already
|
||||
exclude selected test sources and remain unchanged.
|
||||
|
||||
#### Diagnostics, artifacts, and lifecycle
|
||||
|
||||
- **behavior derived from the pinned implementation** — CLI-shape and
|
||||
multiple-operand delegation retain their prior precedence; 11.50 prefix
|
||||
exclusion precedes this header reader. Header read/package/initial-import
|
||||
diagnostics precede output policy. A first ordinary malformed UTF-8/BOM body
|
||||
byte is excluded, while a reached NUL or unterminated header-trivia comment
|
||||
is a header diagnostic. Once the header is valid, no unresolved import,
|
||||
graph, producer, linker, or runtime diagnostic may surface. Both
|
||||
stages use the same header boundary and must produce byte-identical status,
|
||||
stdout, and stderr.
|
||||
- **behavior derived from the pinned implementation** — cold no-action success
|
||||
creates no default/explicit output, output directory, `.wwi`, unit, assembly,
|
||||
object, archive, init product, `.sepwork`, workdir, stamp, transaction,
|
||||
capture, result, or private build temporary. Output-policy diagnostics also
|
||||
create none of those products.
|
||||
- **behavior derived from the pinned implementation** — a warm request starts
|
||||
no transaction, mutation, invalidation, reuse check, timestamp refresh, or
|
||||
producer. Existing output, sidecar, workdir and artifacts remain
|
||||
byte-identical on success and failure; no `.new`, `.install`, `.wwtxn.*`,
|
||||
backup, or recovery residue remains. Restoring a visible non-test source
|
||||
reuses prior valid warm state by the unchanged ordinary route.
|
||||
- **behavior derived from the pinned implementation** — no action means no
|
||||
publication, rollback work, producer/runtime failure path, shared lock, or
|
||||
child process. Concurrent Cstage/WWstage no-action and header-diagnostic
|
||||
requests are isolated. Interruption during header reading leaves no owned
|
||||
persistent state; after a valid header there is no child or publication window
|
||||
to clean up. Every reader closes its descriptor and releases request-local
|
||||
storage before return.
|
||||
- **behavior derived from the pinned implementation** — focused proof covers
|
||||
valid, malformed-header, missing-test-import, wrong-platform, symlink and
|
||||
finite-stream operands; default/file/directory/null/assembly output modes;
|
||||
cold/warm preservation; trace-proven tool and runtime absence; rollback,
|
||||
interruption, concurrency, cleanup, complete per-stage work preservation, and
|
||||
Cstage/WWstage semantic-artifact parity. The complete per-stage snapshot
|
||||
includes `.wwtool.ww`; cross-stage comparison excludes only that intentionally
|
||||
different producer binary snapshot. Unaffected visible production controls
|
||||
retain byte-identical outputs.
|
||||
|
||||
No serialized format changes accompany this omission. Build workdir format
|
||||
remains `18`, test workdir format remains `19`, semantic storage format remains
|
||||
`3`, and the slice adds no cache or persistent record.
|
||||
|
||||
## 12. Candidate architectures and hard-gate decision
|
||||
|
||||
Five candidates were developed as coherent systems, not as feature bins.
|
||||
|
||||
Reference in New Issue
Block a user