132 lines
7.7 KiB
Markdown
132 lines
7.7 KiB
Markdown
# Shared validation mechanics
|
|
|
|
`internal/validation` owns reusable checks for one captured candidate.
|
|
`internal/candidate` captures the clean source revision and keeps the
|
|
validation sequence shared by local checking and publication. It calls the
|
|
shared executor, runs product-specific `AdditionalChecks` once, and owns the
|
|
post-validation build callback and local-state recheck. `internal/publish`
|
|
adds its endpoint guards, tag creation, push, and recovery around that same
|
|
candidate path.
|
|
|
|
The executor runs one offline Go suite, optionally with the race detector when
|
|
selected. When full vet is selected, it disables test-time vet for that suite
|
|
and runs native `go vet -mod=readonly ./...` after the suite succeeds. It then
|
|
runs `go build -mod=readonly -o <os.DevNull> ./...` in static mode for each
|
|
selected package-compilation target, preserving target order and stopping on
|
|
the first failure. This compiles source without producing an artifact or
|
|
executing a target binary. Test, vet, and package-compilation failures retain
|
|
their `go-test`, `go-vet`, and `package-compile` identities, selected target
|
|
where applicable, and underlying causes. Its
|
|
request carries the captured repository directory and commit, output writer,
|
|
and internal settings. When selected, the Go-format check loads the candidate
|
|
tree once, reads regular Go blobs from the captured commit, and compares them
|
|
with go/format output. It includes vendor and nested-module files, skips
|
|
symlink blobs, reports all unformatted paths, and stops with a contextual cause
|
|
on parse or inspection errors. It runs before product checks and build callbacks.
|
|
`Request.ReadCandidateTree` lets selected file checks request candidate
|
|
contents; the Go-only path does not enumerate the tree.
|
|
|
|
The workspace-file check uses that same candidate inventory and reports blob
|
|
entries named go.work or go.work.sum, including nested paths and symlink blobs.
|
|
It does not read workspace contents or depend on the workspace selected for Go
|
|
commands.
|
|
The local-replacement check parses every committed go.mod blob with
|
|
`golang.org/x/mod/modfile`, including nested modules and vendor declarations.
|
|
It follows committed symlink declarations through the captured tree and fails
|
|
with an inspection cause when their selected contents are unavailable. A
|
|
replacement with no parsed version is reported with its go.mod path, line,
|
|
directive, and target; versioned replacements are allowed. It runs after the
|
|
workspace-file check using the same candidate inventory.
|
|
The optional file-size check uses each blob's captured Git size, including
|
|
symlink link-text bytes, and skips entries without a blob size such as gitlinks.
|
|
It applies normalized literal file/directory exclusions with path-boundary
|
|
matching, then returns the first oversized path with `FileSizeMeasurement`.
|
|
`CandidateTree` gets metadata and bytes from Git objects, reads blob bytes
|
|
lazily, and resolves destinations without consulting the worktree or
|
|
neighboring files.
|
|
|
|
The internal Markdown parser uses Goldmark to record inline, reference, and
|
|
autolinks, images, titles, and their source use sites, and to build heading
|
|
anchors from visible AST text. It supports ATX and Setext headings, decodes
|
|
Markdown text through the parser, and assigns collision-free numeric suffixes
|
|
to repeated anchors. Link locations use one-based line and byte-column values.
|
|
A per-path cache retains the parsed records and anchors for each candidate
|
|
document. The parser remains internal; destination resolution and check selection
|
|
are tracked in the [implementation plan](../roadmap/implementation.md).
|
|
|
|
Committed-tree metadata and blob reads disable lazy fetching and Git transports
|
|
for those child commands. Missing local objects produce inspection errors;
|
|
source preparation retains its separate network-capable operations. See Git's
|
|
[lazy-fetch controls](https://git-scm.com/docs/git) for the command mechanism.
|
|
|
|
Public validation errors convert their diagnostic fields to the internal
|
|
failure model for shared formatting. Converted failures retain their original
|
|
contextual cause and reuse its rendering when it already contains the same
|
|
diagnostics. The CLI presents the complete error chain, including candidate
|
|
context around callback-supplied diagnostics.
|
|
|
|
## Adding a shared check
|
|
|
|
When an optional check is accepted for implementation:
|
|
|
|
1. Define its typed Go setting in the root facade and its equivalent CLI-owned
|
|
JSON field. Specify zero-value and omitted-profile behavior in GoDoc and the
|
|
configuration reference. Keep future settings in the roadmap until their
|
|
check is implemented.
|
|
2. Add the corresponding internal setting and explicit conversions. Use the
|
|
same root request conversion for `Check` and `Publish`, and the shared CLI
|
|
request conversion for profile-based candidate commands.
|
|
3. Implement a plain check function owned by `internal/validation`. Keep its
|
|
rule semantics in the capability owner and pass only the captured candidate
|
|
inputs it needs. A file-oriented check can call `Request.ReadCandidateTree`
|
|
and read only the blobs it inspects.
|
|
4. Return an internal `*Failure` with the check identity, repository-relative
|
|
findings, useful locations where available, and the underlying cause. Let
|
|
the root facade convert those records to its own diagnostic types. Preserve
|
|
cancellation and process errors through `Unwrap`.
|
|
5. Add the check to the shared executor at the ordering point selected by its
|
|
capability. Stop on failure. Keep product assertions in `AdditionalChecks`
|
|
and profile `checks`; keep artifact building in `internal/build`.
|
|
6. Cover observable behavior through both the Go facade and profile path when
|
|
both are supported. Check default behavior, useful findings, cause
|
|
preservation, cancellation where relevant, and failure stopping. Reuse the
|
|
existing local Git and CLI fixtures.
|
|
7. Update only the canonical owners for behavior that has landed: GoDoc for the
|
|
API, configuration and CLI references for profile behavior, and this
|
|
inventory for internal ownership. Keep later feature contracts in the
|
|
product roadmap.
|
|
|
|
Do not add a public validator registration interface. The public specification
|
|
selects ReleaseKit-owned checks; `AdditionalChecks` remains the extension point
|
|
for product behavior.
|
|
|
|
## Go command environment reuse
|
|
|
|
The current executor uses the [shared Go command environment](gotool.md) for
|
|
its offline suite, vet pass, and selected-target package compilation. The
|
|
[implementation roadmap](../roadmap/implementation.md#execution-and-ownership)
|
|
records the shared ordering across validation and later file checks.
|
|
|
|
Reuse `internal/gotool` for native and static environments and target handling.
|
|
Keep toolchain and module-cache discovery in `gotool`; do not reproduce its
|
|
environment logic in a checker. Artifact output names, version injection,
|
|
native smoke checks, and artifact digests remain owned by `internal/build`.
|
|
|
|
## File-check coordination
|
|
|
|
File checks consume the captured tree and return findings to the shared error
|
|
model. They do not read sibling worktrees or follow live symlink targets.
|
|
`CandidateTree.ResolveDestination` returns data describing entries,
|
|
directories, missing paths, checkout boundaries, submodule paths, and symlink
|
|
cycles; the caller selects which observations fail validation or are reported
|
|
as out of scope.
|
|
|
|
Resolution walks committed components and symlink targets in order. Active
|
|
symlink expansion detects cycles, and traversal honors cancellation. Absolute
|
|
destinations and symlink targets within the repository directory map back to
|
|
candidate-relative paths; existence still comes from committed entries.
|
|
|
|
The [implementation plan](../roadmap/implementation.md) owns Markdown
|
|
destination checking, diagnostics, and boundary policy. The committed-file and
|
|
destination-resolution primitives are available for that later integration.
|