cli/cmd: tt package add, remove, update - #1359
Open
bigbes wants to merge 5 commits into
Open
Conversation
Engine.Resolve always took the newest version a constraint allowed, so any command that rewrites the manifest - add, remove - would drag every unrelated dependency forward on the re-resolve the changed manifest_hash forces. That contradicts the rule IsStale states: only an explicit tt package update pulls fresh registry versions. Add ResolvePinned, which prefers a caller-supplied version per rock, and PinsFromLock, which builds that set from an existing lock minus the names the caller wants freed. Resolve is now ResolvePinned with an empty set, so its callers are unaffected. A pin is a preference, not a constraint: it rides as an extra "==" on the constraint expression handed to the adapter, and when it no longer fits - the constraints moved, a later edge in the walk demands more, or the registry stopped serving that version - it is dropped, the rock resolves normally and a warning says so. Putting it in the expression is also what keeps a pinned and an unpinned query for the same rock in distinct slots of the shared resolution cache. Part of TNTP-9958
Add an Editor that rewrites [dependencies]/[dev_dependencies] in the manifest's own TOML text instead of re-marshaling the model, so comments, key order and the formatting of every untouched line survive an edit. Locating is done with go-toml's unstable expression parser; splicing works on the byte ranges it reports. Short, inline-table, sub-table and root dotted-key declarations are all editable; anything else is refused by name rather than guessed at. Part of TNTP-9958
Add the package behind tt package add/remove/update: edit the declaration with the position-preserving TOML editor, write the manifest, re-parse it so manifest_hash matches what is on disk, re-resolve under a per-command pin set and rewrite the lock. The pin set is what separates the three commands. Add and remove hold every version the lock already chose; a bare update pins nothing, which is the only way newer registry versions are pulled; update NAME frees that one rock and holds the rest. depguard's allow list gains cli/manifest/resolve, which the strict ruleset refused even though cli/manifest/build already imports it. Part of TNTP-9958
Wire the three dependency commands onto cli/manifest/deps. add takes an optional constraint and a --dev flag choosing the table; remove and update take a name, and update takes none for a whole-closure refresh. Each prints what it changed and then the closure diff, one rock per line: a rock that arrived shows only its new version, one that left is marked dropped, one that moved shows both ends. Closes TNTP-9958
The strict `default: all` ruleset had a job in CI and never ran: that job is gated on a full-commit-check PR label. Two packages joined its declared scope in the meantime and accumulated 254 findings between them with nothing going red. Scope the config to the packages that are actually clean under it, naming them rather than claiming the whole cli/manifest subtree - build, build/backend, inventory and pack are the outstanding work and rejoin the rule once each lints clean. Then give the ruleset a job of its own with no label condition. It needs no build step, nothing in the adopted scope being generated, so it is cheap enough to run on every push. The linter itself is now resolved rather than assumed. Two configs live in the tree, one per major version, and neither major can read the other's format; both targets shelled out to whatever golangci-lint was on PATH, so a mismatch surfaced as a parser error naming neither the binary nor the config. Each target states the major it needs, prefers the version-suffixed name a side-by-side install provides, and verifies the major it actually got. GOLANGCI_LINT_V1 and GOLANGCI_LINT_V2 name an alternative binary and are honored exactly, so a wrong major is an error rather than a silent fallback. The strict ruleset gets its own lint:strict target, since it needs a v2 linter where lint:golang needs a v1 one. Part of TNTP-9958
bigbes
force-pushed
the
bigbes/tntp-9958-package-deps-cli
branch
from
September 1, 2026 06:26
c6191bf to
9edb8aa
Compare
| submodules: recursive | ||
|
|
||
| - name: Setup Go | ||
| uses: actions/setup-go@v4 |
Contributor
There was a problem hiding this comment.
Suggested change
| uses: actions/setup-go@v4 | |
| uses: actions/setup-go@v7 |
Up to you.
patapenka-alexey
approved these changes
Sep 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three commands that edit
[dependencies]inapp.manifest.tomland re-resolve the lock:addtakes*when no constraint is given, writes to[dev_dependencies]under--devand rewrites the constraint of a dependency already declared;removedrops it from both files;updatere-resolves one dependency or all of them.manifest_hash, which forces a re-resolve, so without pinsaddandremovewould drag every unrelated dependency forward, contradicting the rule that only an explicitupdatepulls fresh versions from a registry. A pin is a preference: one that no longer fits is dropped with a warning, never an error, and that has to be caught in two places because the greedy walk discovers the two failure modes at different times.tt package resolvecan reuse the same re-resolve step.default: allruleset had a CI job that never ran, because it is gated on afull-commit-checkPR label, and two packages had joined its declared scope and accumulated 254 findings unnoticed. The scope now names the packages that are actually clean, the ruleset gets a job with no label condition, and both lint targets resolve and version-check the linter they need instead of using whatever is on PATH.Closes TNTP-9958