-
Notifications
You must be signed in to change notification settings - Fork 346
mod: add local module replacement support with robust path resolution #4214
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Add support for local path replacements in module.cue files, similar to Go's replace directive. This allows replacing module dependencies with local directories using paths like "./local-dep" or "../sibling". Key changes: - Add modreplace package for handling local path replacements - Add localreg.go to wrap Registry with replacement support - Update schema.cue to allow empty version for replace-only deps - Compute absolute paths at creation time instead of using os.Getwd() - Add comprehensive tests including script tests for various scenarios The path resolution now requires either: - A filesystem implementing module.OSRootFS, or - An absolute directory path This eliminates fragile reliance on os.Getwd() which could fail in containers, tests, or when the working directory changes. Signed-off-by: David Flanagan <[email protected]>
5034727 to
bde1f96
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR adds support for local module path replacements similar to Go's replace directive, allowing CUE modules to replace dependencies with local directories using paths like "./local-dep" or "../sibling". The implementation includes robust path resolution that avoids reliance on os.Getwd() by computing absolute paths at creation time.
Key changes:
- Introduces the modreplace package to handle local path replacement resolution and validation
- Adds localReplacementRegistry wrapper to intercept module fetches and requirements for replaced modules
- Updates schema.cue to support the replace field in dependencies and allow empty versions for replace-only deps
- Threads replacement maps through all Requirements creation and tidy operations
Reviewed changes
Copilot reviewed 21 out of 21 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| mod/modfile/schema.cue | Adds replace field to #Dep, allows empty version strings, and restricts local path replacements in strict mode |
| internal/mod/modfiledata/modfile.go | Implements Replacement struct and parseReplacement function to parse both local and remote replacements |
| internal/mod/modreplace/local.go | Core logic for resolving local paths to absolute paths and fetching module info from local directories |
| internal/mod/modreplace/local_test.go | Comprehensive unit tests for local replacement path resolution and error handling |
| internal/mod/modload/localreg.go | Registry wrapper that intercepts fetch/requirements calls to handle replacements |
| internal/mod/modrequirements/requirements.go | Adds replacement tracking to Requirements struct and applies remote replacements in cueModSummary |
| internal/mod/modrequirements/requirements_test.go | Updates test calls to include nil replacement parameter |
| internal/mod/modload/tidy.go | Preserves replace directives during tidy, adds replacement equality checking |
| internal/mod/modload/update.go | Threads replacements through UpdateVersions operations |
| cue/load/instances.go | Updates package loading to use wrapped registry with replacement support |
| internal/mod/modpkgload/pkgload_test.go | Updates test to pass nil replacements |
| internal/mod/modpkgload/import.go | Adds comment about registry handling replacements |
| internal/lsp/cache/module.go | Updates LSP module loading to pass replacements to Requirements |
| cmd/cue/cmd/modtidy.go | Changes to use module.OSDirFS for OSRootFS support |
| cue/load/loader_test.go | Updates expected line number in error message due to schema changes |
| cmd/cue/cmd/testdata/script/modreplace_*.txtar | Six new script tests covering local, remote, sibling, nested, missing, and command scenarios |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Address feedback from PR cue-lang#4214 review: - Fix misleading comment in requirements.go about local path replacement handling (local replacements are handled by localReplacementRegistry wrapper, not in cueModSummary) - Clarify schema.cue documentation: use "version-independent replacement" instead of "version is unknown" - Use module.Version.Equal() method instead of != operator in tidy.go for idiomatic comparison - Add clarifying comment explaining intentional orphan replacement preservation (matches Go's go mod tidy behavior) - Add explicit validation rejecting absolute paths in parseReplacement() with clear error messages for both Unix and Windows paths - Add test for self-referencing local replacements to verify the system handles edge cases gracefully
Address feedback from PR cue-lang#4214 review: - Fix misleading comment in requirements.go about local path replacement handling (local replacements are handled by localReplacementRegistry wrapper, not in cueModSummary) - Clarify schema.cue documentation: use "version-independent replacement" instead of "version is unknown" - Use module.Version.Equal() method instead of != operator in tidy.go for idiomatic comparison - Add clarifying comment explaining intentional orphan replacement preservation (matches Go's go mod tidy behavior) - Add explicit validation rejecting absolute paths in parseReplacement() with clear error messages for both Unix and Windows paths - Add test for self-referencing local replacements to verify the system handles edge cases gracefully Signed-off-by: David Flanagan <[email protected]>
a34a599 to
d3af39b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 21 out of 21 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Address remaining PR cue-lang#4214 review feedback: - Improve Windows drive letter validation to verify the first character is actually a letter using unicode.IsLetter() (fixes false positives on paths like "9:\notpath") - Add UNC path rejection for \\server\share and //server/share paths - Add comprehensive unit tests for parseReplacement() covering valid local/remote paths, absolute path rejection, UNC paths, strict mode, and invalid module paths/versions - Add script test verifying replace directives are preserved when dependencies are removed during tidy Signed-off-by: David Flanagan <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 23 out of 23 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Add support for local path replacements in module.cue files, similar to Go's replace directive. This allows replacing module dependencies with local directories using paths like "./local-dep" or "../sibling".
First pass at #2956
Key changes:
The path resolution now requires either:
This eliminates fragile reliance on os.Getwd() which could fail in containers, tests, or when the working directory changes.