diff --git a/README.md b/README.md index cb2e491..a6ffb52 100644 --- a/README.md +++ b/README.md @@ -16,16 +16,18 @@ Supports Caddy 2 and up. ## Library usage ```go -caddyVersion := "v2.0.0-beta.20" -plugins := []xcaddy.Dependency{ - xcaddy.Dependency{ - ModulePath: "github.com/caddyserver/nginx-adapter", - Version: "6c484552e630ccac384d2d9c43c9d14c4e8d2e56", - }, +builder := xcaddy.Builder{ + CaddyVersion: "v2.0.0-rc.1", + Plugins: []xcaddy.Dependency{ + { + { + ModulePath: "github.com/caddyserver/nginx-adapter", + Version: "bdbb6db7ff9ad6ceb0dcd93f89e396f6365aa5d4", + }, + } + } } -output := "./caddy" - -err := xcaddy.Build(caddyVersion, plugins, output) +err := builder.Build("./caddy") ``` Versions can be anything compatible with `go get`. @@ -60,8 +62,8 @@ Where: For example: ```bash -$ xcaddy build v2.0.0-beta.20 \ - --with github.com/caddyserver/nginx-adapter@6c484552e630ccac384d2d9c43c9d14c4e8d2e56 +$ xcaddy build v2.0.0-rc.1 \ + --with github.com/caddyserver/nginx-adapter@bdbb6db7ff9ad6ceb0dcd93f89e396f6365aa5d4 ``` ### For plugin development diff --git a/builder.go b/builder.go index af00f5b..7e826b3 100644 --- a/builder.go +++ b/builder.go @@ -30,11 +30,18 @@ import ( "github.com/Masterminds/semver/v3" ) -// Build builds Caddy at the given version with the given plugins and -// plops a binary down at outputFile. -func Build(caddyVersion string, deps []Dependency, outputFile string) error { - if caddyVersion == "" { - return fmt.Errorf("caddy version is required") +// Builder can produce a custom Caddy build with the +// configuration it represents. +type Builder struct { + CaddyVersion string `json:"caddy_version,omitempty"` + Plugins []Dependency `json:"plugins,omitempty"` +} + +// Build builds Caddy at the configured version with the +// configured plugins and plops down a binary at outputFile. +func (b Builder) Build(outputFile string) error { + if b.CaddyVersion == "" { + return fmt.Errorf("CaddyVersion must be set") } if outputFile == "" { return fmt.Errorf("output file path is required") @@ -48,7 +55,7 @@ func Build(caddyVersion string, deps []Dependency, outputFile string) error { return err } - env, err := newEnvironment(caddyVersion, deps) + env, err := b.newEnvironment() if err != nil { return err } @@ -74,9 +81,17 @@ func Build(caddyVersion string, deps []Dependency, outputFile string) error { // Dependency pairs a Go module path with a version. type Dependency struct { + // The name (path) of the Go module. If at a version > 1, it + // should contain semantic import version suffix (i.e. "/v2"). + // Used with `go get` ModulePath string - Version string - Replace string + + // The version of the Go module, like used with `go get`. + Version string + + // Optional path to a replacement module. Equivalent to + // a `replace` directive in go.mod. + Replace string } // newTempFolder creates a new folder in a temporary location. diff --git a/cmd/xcaddy/main.go b/cmd/xcaddy/main.go index 74f5d2e..442425d 100644 --- a/cmd/xcaddy/main.go +++ b/cmd/xcaddy/main.go @@ -36,7 +36,7 @@ func main() { } // TODO: the caddy version needs to be settable by the user... maybe an env var? - if err := runDev("v2.0.0-beta.20", os.Args[1:]); err != nil { + if err := runDev("v2.0.0-rc.1", os.Args[1:]); err != nil { log.Fatalf("[ERROR] %v", err) } } @@ -89,7 +89,11 @@ func runBuild(args []string) error { } // perform the build - err := xcaddy.Build(caddyVersion, plugins, output) + builder := xcaddy.Builder{ + CaddyVersion: caddyVersion, + Plugins: plugins, + } + err := builder.Build(output) if err != nil { log.Fatalf("[FATAL] %v", err) } @@ -131,12 +135,16 @@ func runDev(caddyVersion string, args []string) error { moduleDir := strings.TrimSpace(string(out)) // build caddy with this module plugged in - err = xcaddy.Build(caddyVersion, []xcaddy.Dependency{ - { - ModulePath: currentModule, - Replace: moduleDir, + builder := xcaddy.Builder{ + CaddyVersion: caddyVersion, + Plugins: []xcaddy.Dependency{ + { + ModulePath: currentModule, + Replace: moduleDir, + }, }, - }, binOutput) + } + err = builder.Build(binOutput) if err != nil { return err } diff --git a/environment.go b/environment.go index 9ee4752..92668e8 100644 --- a/environment.go +++ b/environment.go @@ -27,20 +27,20 @@ import ( "time" ) -func newEnvironment(caddyVersion string, plugins []Dependency) (*environment, error) { - // assume v2 if no semantic version is provided +func (b Builder) newEnvironment() (*environment, error) { + // assume Caddy v2 if no semantic version is provided caddyModulePath := defaultCaddyModulePath - if !strings.HasPrefix(caddyVersion, "v") || !strings.Contains(caddyVersion, ".") { + if !strings.HasPrefix(b.CaddyVersion, "v") || !strings.Contains(b.CaddyVersion, ".") { caddyModulePath += "/v2" } - caddyModulePath, err := versionedModulePath(caddyModulePath, caddyVersion) + caddyModulePath, err := versionedModulePath(caddyModulePath, b.CaddyVersion) if err != nil { return nil, err } // clean up any SIV-incompatible module paths real quick - for i, p := range plugins { - plugins[i].ModulePath, err = versionedModulePath(p.ModulePath, p.Version) + for i, p := range b.Plugins { + b.Plugins[i].ModulePath, err = versionedModulePath(p.ModulePath, p.Version) if err != nil { return nil, err } @@ -50,7 +50,7 @@ func newEnvironment(caddyVersion string, plugins []Dependency) (*environment, er ctx := moduleTemplateContext{ CaddyModule: caddyModulePath, } - for _, p := range plugins { + for _, p := range b.Plugins { ctx.Plugins = append(ctx.Plugins, p.ModulePath) } @@ -89,8 +89,8 @@ func newEnvironment(caddyVersion string, plugins []Dependency) (*environment, er } env := &environment{ - caddyVersion: caddyVersion, - plugins: plugins, + caddyVersion: b.CaddyVersion, + plugins: b.Plugins, caddyModulePath: caddyModulePath, tempFolder: tempFolder, } @@ -104,25 +104,26 @@ func newEnvironment(caddyVersion string, plugins []Dependency) (*environment, er } // specify module replacements before pinning versions - for _, p := range plugins { - if p.Replace != "" { - log.Printf("[INFO] Replace %s => %s", p.ModulePath, p.Replace) - cmd := env.newCommand("go", "mod", "edit", - "-replace", fmt.Sprintf("%s=%s", p.ModulePath, p.Replace)) - err := env.runCommand(cmd, 10*time.Second) - if err != nil { - return nil, err - } + for _, p := range b.Plugins { + if p.Replace == "" { + continue + } + log.Printf("[INFO] Replace %s => %s", p.ModulePath, p.Replace) + cmd := env.newCommand("go", "mod", "edit", + "-replace", fmt.Sprintf("%s=%s", p.ModulePath, p.Replace)) + err := env.runCommand(cmd, 10*time.Second) + if err != nil { + return nil, err } } // pin versions by populating go.mod, first for Caddy itself and then plugins log.Println("[INFO] Pinning versions") - err = env.execGoGet(caddyModulePath, caddyVersion) + err = env.execGoGet(caddyModulePath, b.CaddyVersion) if err != nil { return nil, err } - for _, p := range plugins { + for _, p := range b.Plugins { if p.Replace != "" { continue }