Skip to content
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

cmd: Allow add-package to select version of package #6665

Merged
merged 2 commits into from
Oct 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions cmd/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -409,12 +409,13 @@ latest versions. EXPERIMENTAL: May be changed or removed.

RegisterCommand(Command{
Name: "add-package",
Usage: "<packages...>",
Usage: "<package[@version]...>",
Short: "Adds Caddy packages (EXPERIMENTAL)",
Long: `
Downloads an updated Caddy binary with the specified packages (module/plugin)
added. Retains existing packages. Returns an error if the any of packages are
already included. EXPERIMENTAL: May be changed or removed.
added, with an optional version specified (e.g., "package@version"). Retains
existing packages. Returns an error if any of the specified packages are already
included. EXPERIMENTAL: May be changed or removed.
`,
CobraFunc: func(cmd *cobra.Command) {
cmd.Flags().BoolP("keep-backup", "k", false, "Keep the backed up binary, instead of deleting it")
Expand Down
58 changes: 49 additions & 9 deletions cmd/packagesfuncs.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,25 @@ func cmdUpgrade(fl Flags) (int, error) {
return upgradeBuild(pluginPkgs, fl)
}

func splitModule(arg string) (module, version string, err error) {
const versionSplit = "@"

// accommodate module paths that have @ in them, but we can only tolerate that if there's also
// a version, otherwise we don't know if it's a version separator or part of the file path
lastVersionSplit := strings.LastIndex(arg, versionSplit)
if lastVersionSplit < 0 {
module = arg
} else {
module, version = arg[:lastVersionSplit], arg[lastVersionSplit+1:]
}

if module == "" {
err = fmt.Errorf("module name is required")
}

return
}

func cmdAddPackage(fl Flags) (int, error) {
if len(fl.Args()) == 0 {
return caddy.ExitCodeFailedStartup, fmt.Errorf("at least one package name must be specified")
Expand All @@ -60,10 +79,15 @@ func cmdAddPackage(fl Flags) (int, error) {
}

for _, arg := range fl.Args() {
if _, ok := pluginPkgs[arg]; ok {
module, version, err := splitModule(arg)
if err != nil {
return caddy.ExitCodeFailedStartup, fmt.Errorf("invalid module name: %v", err)
}
// only allow a version to be specified if it's different from the existing version
if _, ok := pluginPkgs[module]; ok && !(version != "" && pluginPkgs[module].Version != version) {
return caddy.ExitCodeFailedStartup, fmt.Errorf("package is already added")
}
pluginPkgs[arg] = struct{}{}
pluginPkgs[module] = pluginPackage{Version: version, Path: module}
}

return upgradeBuild(pluginPkgs, fl)
Expand All @@ -83,7 +107,11 @@ func cmdRemovePackage(fl Flags) (int, error) {
}

for _, arg := range fl.Args() {
if _, ok := pluginPkgs[arg]; !ok {
module, _, err := splitModule(arg)
if err != nil {
return caddy.ExitCodeFailedStartup, fmt.Errorf("invalid module name: %v", err)
}
if _, ok := pluginPkgs[module]; !ok {
// package does not exist
return caddy.ExitCodeFailedStartup, fmt.Errorf("package is not added")
}
Expand All @@ -93,7 +121,7 @@ func cmdRemovePackage(fl Flags) (int, error) {
return upgradeBuild(pluginPkgs, fl)
}

func upgradeBuild(pluginPkgs map[string]struct{}, fl Flags) (int, error) {
func upgradeBuild(pluginPkgs map[string]pluginPackage, fl Flags) (int, error) {
l := caddy.Log()

thisExecPath, err := os.Executable()
Expand All @@ -120,8 +148,8 @@ func upgradeBuild(pluginPkgs map[string]struct{}, fl Flags) (int, error) {
"os": {runtime.GOOS},
"arch": {runtime.GOARCH},
}
for pkg := range pluginPkgs {
qs.Add("p", pkg)
for _, pkgInfo := range pluginPkgs {
qs.Add("p", pkgInfo.String())
}

// initiate the build
Expand Down Expand Up @@ -276,14 +304,14 @@ func downloadBuild(qs url.Values) (*http.Response, error) {
return resp, nil
}

func getPluginPackages(modules []moduleInfo) (map[string]struct{}, error) {
pluginPkgs := make(map[string]struct{})
func getPluginPackages(modules []moduleInfo) (map[string]pluginPackage, error) {
pluginPkgs := make(map[string]pluginPackage)
for _, mod := range modules {
if mod.goModule.Replace != nil {
return nil, fmt.Errorf("cannot auto-upgrade when Go module has been replaced: %s => %s",
mod.goModule.Path, mod.goModule.Replace.Path)
}
pluginPkgs[mod.goModule.Path] = struct{}{}
pluginPkgs[mod.goModule.Path] = pluginPackage{Version: mod.goModule.Version, Path: mod.goModule.Path}
}
return pluginPkgs, nil
}
Expand Down Expand Up @@ -312,3 +340,15 @@ func writeCaddyBinary(path string, body *io.ReadCloser, fileInfo os.FileInfo) er
}

const downloadPath = "https://caddyserver.com/api/download"

type pluginPackage struct {
Version string
Path string
}

func (p pluginPackage) String() string {
if p.Version == "" {
return p.Path
}
return p.Path + "@" + p.Version
}
Loading