Support unvendored repositories: precise go.mod/go.sum dependency diffing (rebased on #73)#71
Open
bts-bastion wants to merge 12 commits into
Open
Support unvendored repositories: precise go.mod/go.sum dependency diffing (rebased on #73)#71bts-bastion wants to merge 12 commits into
bts-bastion wants to merge 12 commits into
Conversation
These methods enable distinguishing local (main module) packages from external dependencies and mapping changed dependency modules to the local packages that import them. Foundation for unvendored repo support. Co-authored by: Blue Thunder Somogyi
When packages.Load returns packages with errors (common for external dependencies in unvendored repos), skip them when building the forward/reverse dependency graphs. Module info is still recorded. Co-authored by: Blue Thunder Somogyi
When a package in the dependency graph cannot be resolved (e.g., an external dependency in an unvendored repo), skip it instead of returning an error from ChangedPackages(). This prevents GTA from crashing on unvendored repositories. Co-authored by: Blue Thunder Somogyi
When traversing the dependency graph in markedPackages(), skip edges to external (non-local) packages. Uses a type assertion so custom Packager implementations retain the existing traversal behavior. In GOPATH mode (no modules), all packages are treated as local. Co-authored by: Blue Thunder Somogyi
New file gomod.go provides diffGoMod() and diffGoSum() for precise dependency change detection. diffGoMod compares Require and Replace directives using modfile.Parse with ParseLax fallback. diffGoSum does line-level comparison to catch transitive dependency changes. Co-authored by: Blue Thunder Somogyi
BaseFileReader enables reading file content at the git merge-base, used to retrieve old go.mod/go.sum for dependency diff analysis. SetBaseGoMod and SetBaseGoSum options provide the same capability for file-differ mode (no git access). Co-authored by: Blue Thunder Somogyi
When go.mod or go.sum changes in an unvendored repo, GTA now parses the diff to identify exactly which dependency modules changed, then marks only the local packages that import those modules. This replaces the previous "mark all packages" approach which negated GTA's value. Falls back to mark-all when base file content is unavailable (e.g., custom Differ without BaseFileReader, no SetBaseGoMod option). go.work changes continue to use mark-all since workspace structural changes warrant full re-evaluation. Co-authored by: Blue Thunder Somogyi
…aces
Originally written against the fork's multi-root workspace implementation,
where it demonstrated a false negative: relativeModFilePath() computed
module-relative paths ("go.mod") while BaseFileReader.ReadBaseFile resolves
git-repo-root-relative paths, silently diffing the repo-root go.mod against
the module's new go.mod and marking nothing for a dependency bump.
On this branch (upstream single workspace root = directory containing
go.work) the computed path is correct and the test passes. It remains as a
regression guard for the path-resolution contract, which Task 6 hardens by
moving path resolution into the differ itself.
BaseFileReader.ReadBaseFile now takes an absolute path and the git differ resolves it against the repo toplevel it already discovers during diff(). This removes relativeModFilePath(), whose g.roots-based computation was only correct when the workspace/module root coincided with the git toplevel, and rejects paths outside the repository.
Ported from the fork's go.work support work: verifies that in a Go workspace, a change in one module marks dependent packages in sibling modules, an isolated module reports only itself, and a go.work change marks all workspace packages. These pass against upstream's single-root workspace handling (PR digitalocean#73) without any multi-root machinery; gta relies on packages.Load workspace awareness for cross-module resolution.
5cb0172 to
0b40ad6
Compare
Author
|
Revised to build on #73 |
Wrap the toplevel() error with %w so an inconsistent-vendoring error (from `go list -m`) surfaces to the caller instead of being replaced with a generic "could not get top level directory" message.
packages.Load reports Module.Dir with symlinks resolved, but the git differ root, GOWORK-derived roots, and caller-supplied differ paths may be un-resolved. On systems where the repo path differs from its resolved form (macOS /tmp -> /private/tmp, container bind mounts, automounts) the equality/prefix comparisons in resolveLocal and isIgnoredByGo never match, so a changed package silently resolves to nothing. Add canonicalDir (EvalSymlinks with a deepest-existing-ancestor fallback for deleted dirs) and normalize incoming paths in resolveLocal, the git differ root, and roots before comparison.
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.
Summary
Detect
go.mod/go.sumchanges precisely and mark only the dependent packagesthat actually changed, rather than falling back to marking every package when
no
vendor/tree is present.Rebased onto current
master, which includes the single-rootgo.worksupportfrom #73. The fork's multi-root
go.workcommit is dropped — #73 supersedes it,and the cross-module tests added here confirm workspace detection works on the
single-root base without multi-root code. The companion go.work PR is closed.
Changes
Graph construction under module/workspace loads:
isLocalPackage/LocalImportersOfon the package context.PackageFromImporterrors for unresolvable dependents.Precise go.mod/go.sum diffing:
gomod.go: diffgo.modrequire directives andgo.sumentries.BaseFileReaderinterface plusSetBaseGoMod/SetBaseGoSum, sourcing oldmodule-file content from the git differ or from explicitly supplied files.
markedPackages()diffs changedgo.mod/go.sum, resolves the affectedmodule paths to their local importers, and marks those. The mark-all path
remains as fallback when no base is available;
go.workchanges still forcefull re-evaluation.
Path resolution:
BaseFileReader.ReadBaseFiletakes an absolute path; the git differ resolvesit against the repository toplevel from
diff()and rejects paths outside therepo. Removes the
roots-based computation, which was correct only when themodule root coincided with the git toplevel.
Tests:
sibling modules; an isolated module reports only itself; a
go.workchangemarks all workspace packages.
Notes
GOWORK=off; there is no gta flag.BaseFileReaderis new in this PR, so its absolute-path signature is not abreaking change.
Testing
go test -count=1 -race ./...andgo vet ./...pass.