Skip to content

Conversation

@rawkode
Copy link

@rawkode rawkode commented Dec 17, 2025

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:

  • 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.

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]>
@rawkode rawkode force-pushed the fix/modreplace-issues branch from 5034727 to bde1f96 Compare December 17, 2025 12:23
@rawkode rawkode marked this pull request as ready for review December 17, 2025 12:24
@rawkode rawkode requested a review from cueckoo as a code owner December 17, 2025 12:24
Copilot AI review requested due to automatic review settings December 17, 2025 12:24
Copy link

Copilot AI left a 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.

rawkode added a commit to rawkode/cue that referenced this pull request Dec 17, 2025
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]>
Copy link

Copilot AI left a 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]>
Copy link

Copilot AI left a 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant