Add --replace for dependency replacement (#186)

* add --replace to change dependency version

* deduplicate codes

* update README.md
This commit is contained in:
WeidiDeng 2024-05-30 04:51:37 +08:00 committed by GitHub
parent 33a5925979
commit d7277dbc5d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 26 additions and 11 deletions

View file

@ -62,6 +62,7 @@ Syntax:
$ xcaddy build [<caddy_version>]
[--output <file>]
[--with <module[@version][=replacement]>...]
[--replace <module[@version]=replacement>...]
[--embed <[alias]:path/to/dir>...]
```
@ -73,6 +74,7 @@ $ xcaddy build [<caddy_version>]
- `--output` changes the output file.
- `--with` can be used multiple times to add plugins by specifying the Go module name and optionally its version, similar to `go get`. Module name is required, but specific version and/or local replacement are optional.
- `--replace` can be used multiple times to replace dependencies to specific forks or local replacements. Useful in development environment to fix bugs in dependencies.
- `--embed` can be used multiple times to embed directories into the built Caddy executable. The directory can be prefixed with a custom alias and a colon `:` to use it with the `root` directive and sub-directive.
Examples:
@ -97,14 +99,14 @@ $ xcaddy build \
--with github.com/caddyserver/ntlm-transport@v0.1.1=../../my-fork
```
You can even replace Caddy core using the `--with` flag:
You can even replace Caddy core using the `--replace` flag:
```
$ xcaddy build \
--with github.com/caddyserver/caddy/v2=../../my-caddy-fork
--replace github.com/caddyserver/caddy/v2=../../my-caddy-fork
$ xcaddy build \
--with github.com/caddyserver/caddy/v2=github.com/my-user/caddy/v2@some-branch
--replace github.com/caddyserver/caddy/v2=github.com/my-user/caddy/v2@some-branch
```
This allows you to hack on Caddy core (and optionally plug in extra modules at the same time!) with relative ease.

View file

@ -199,6 +199,13 @@ type Dependency struct {
Version string `json:"version,omitempty"`
}
func (d Dependency) String() string {
if d.Version != "" {
return d.PackagePath + "@" + d.Version
}
return d.PackagePath
}
// ReplacementPath represents an old or new path component
// within a Go module replacement directive.
type ReplacementPath string

View file

@ -74,9 +74,10 @@ func runBuild(ctx context.Context, args []string) error {
var embedDir []string
for i := 0; i < len(args); i++ {
switch args[i] {
case "--with":
case "--with", "--replace":
arg := args[i]
if i == len(args)-1 {
return fmt.Errorf("expected value after --with flag")
return fmt.Errorf("expected value after %s flag", arg)
}
i++
mod, ver, repl, err := splitWith(args[i])
@ -84,10 +85,16 @@ func runBuild(ctx context.Context, args []string) error {
return err
}
mod = strings.TrimSuffix(mod, "/") // easy to accidentally leave a trailing slash if pasting from a URL, but is invalid for Go modules
plugins = append(plugins, xcaddy.Dependency{
PackagePath: mod,
Version: ver,
})
if arg == "--with" {
plugins = append(plugins, xcaddy.Dependency{
PackagePath: mod,
Version: ver,
})
}
if arg != "--with" && repl == "" {
return fmt.Errorf("expected value after --replace flag")
}
if repl != "" {
// adjust relative replacements in current working directory since our temporary module is in a different directory
if strings.HasPrefix(repl, ".") {
@ -97,9 +104,8 @@ func runBuild(ctx context.Context, args []string) error {
}
log.Printf("[INFO] Resolved relative replacement %s to %s", args[i], repl)
}
replacements = append(replacements, xcaddy.NewReplace(mod, repl))
replacements = append(replacements, xcaddy.NewReplace(xcaddy.Dependency{PackagePath: mod, Version: ver}.String(), repl))
}
case "--output":
if i == len(args)-1 {
return fmt.Errorf("expected value after --output flag")