@marcel91200 / caddy Mirror · read-only / commits / d398898b
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 12, 07:00 UTC

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

* feat: allow versioning of packages * docs: remove xcaddy issue reference

Lucas VerÍssimo Botelho committed Oct 30, 2024 at 13:48 UTC d398898b352a6a7e8ac5c24da01dd948fc334d77
2 files changed +53 -12
cmd/commands.go
+4 -3
@@ -409,12 +409,13 @@ latest versions. EXPERIMENTAL: May be changed or removed.
409
410 RegisterCommand(Command{
411 Name: "add-package",
412 - Usage: "<packages...>",
412 + Usage: "<package[@version]...>",
413 Short: "Adds Caddy packages (EXPERIMENTAL)",
414 Long: `
415 Downloads an updated Caddy binary with the specified packages (module/plugin)
416 -added. Retains existing packages. Returns an error if the any of packages are
417 -already included. EXPERIMENTAL: May be changed or removed.
416 +added, with an optional version specified (e.g., "package@version"). Retains
417 +existing packages. Returns an error if any of the specified packages are already
418 +included. EXPERIMENTAL: May be changed or removed.
419 `,
420 CobraFunc: func(cmd *cobra.Command) {
421 cmd.Flags().BoolP("keep-backup", "k", false, "Keep the backed up binary, instead of deleting it")
cmd/packagesfuncs.go
+49 -9
@@ -46,6 +46,25 @@ func cmdUpgrade(fl Flags) (int, error) {
46 return upgradeBuild(pluginPkgs, fl)
47 }
48
49 +func splitModule(arg string) (module, version string, err error) {
50 + const versionSplit = "@"
51 +
52 + // accommodate module paths that have @ in them, but we can only tolerate that if there's also
53 + // a version, otherwise we don't know if it's a version separator or part of the file path
54 + lastVersionSplit := strings.LastIndex(arg, versionSplit)
55 + if lastVersionSplit < 0 {
56 + module = arg
57 + } else {
58 + module, version = arg[:lastVersionSplit], arg[lastVersionSplit+1:]
59 + }
60 +
61 + if module == "" {
62 + err = fmt.Errorf("module name is required")
63 + }
64 +
65 + return
66 +}
67 +
68 func cmdAddPackage(fl Flags) (int, error) {
69 if len(fl.Args()) == 0 {
70 return caddy.ExitCodeFailedStartup, fmt.Errorf("at least one package name must be specified")
@@ -60,10 +79,15 @@ func cmdAddPackage(fl Flags) (int, error) {
79 }
80
81 for _, arg := range fl.Args() {
63 - if _, ok := pluginPkgs[arg]; ok {
82 + module, version, err := splitModule(arg)
83 + if err != nil {
84 + return caddy.ExitCodeFailedStartup, fmt.Errorf("invalid module name: %v", err)
85 + }
86 + // only allow a version to be specified if it's different from the existing version
87 + if _, ok := pluginPkgs[module]; ok && !(version != "" && pluginPkgs[module].Version != version) {
88 return caddy.ExitCodeFailedStartup, fmt.Errorf("package is already added")
89 }
66 - pluginPkgs[arg] = struct{}{}
90 + pluginPkgs[module] = pluginPackage{Version: version, Path: module}
91 }
92
93 return upgradeBuild(pluginPkgs, fl)
@@ -83,7 +107,11 @@ func cmdRemovePackage(fl Flags) (int, error) {
107 }
108
109 for _, arg := range fl.Args() {
86 - if _, ok := pluginPkgs[arg]; !ok {
110 + module, _, err := splitModule(arg)
111 + if err != nil {
112 + return caddy.ExitCodeFailedStartup, fmt.Errorf("invalid module name: %v", err)
113 + }
114 + if _, ok := pluginPkgs[module]; !ok {
115 // package does not exist
116 return caddy.ExitCodeFailedStartup, fmt.Errorf("package is not added")
117 }
@@ -93,7 +121,7 @@ func cmdRemovePackage(fl Flags) (int, error) {
121 return upgradeBuild(pluginPkgs, fl)
122 }
123
96 -func upgradeBuild(pluginPkgs map[string]struct{}, fl Flags) (int, error) {
124 +func upgradeBuild(pluginPkgs map[string]pluginPackage, fl Flags) (int, error) {
125 l := caddy.Log()
126
127 thisExecPath, err := os.Executable()
@@ -120,8 +148,8 @@ func upgradeBuild(pluginPkgs map[string]struct{}, fl Flags) (int, error) {
148 "os": {runtime.GOOS},
149 "arch": {runtime.GOARCH},
150 }
123 - for pkg := range pluginPkgs {
124 - qs.Add("p", pkg)
151 + for _, pkgInfo := range pluginPkgs {
152 + qs.Add("p", pkgInfo.String())
153 }
154
155 // initiate the build
@@ -276,14 +304,14 @@ func downloadBuild(qs url.Values) (*http.Response, error) {
304 return resp, nil
305 }
306
279 -func getPluginPackages(modules []moduleInfo) (map[string]struct{}, error) {
280 - pluginPkgs := make(map[string]struct{})
307 +func getPluginPackages(modules []moduleInfo) (map[string]pluginPackage, error) {
308 + pluginPkgs := make(map[string]pluginPackage)
309 for _, mod := range modules {
310 if mod.goModule.Replace != nil {
311 return nil, fmt.Errorf("cannot auto-upgrade when Go module has been replaced: %s => %s",
312 mod.goModule.Path, mod.goModule.Replace.Path)
313 }
286 - pluginPkgs[mod.goModule.Path] = struct{}{}
314 + pluginPkgs[mod.goModule.Path] = pluginPackage{Version: mod.goModule.Version, Path: mod.goModule.Path}
315 }
316 return pluginPkgs, nil
317 }
@@ -312,3 +340,15 @@ func writeCaddyBinary(path string, body *io.ReadCloser, fileInfo os.FileInfo) er
340 }
341
342 const downloadPath = "https://caddyserver.com/api/download"
343 +
344 +type pluginPackage struct {
345 + Version string
346 + Path string
347 +}
348 +
349 +func (p pluginPackage) String() string {
350 + if p.Version == "" {
351 + return p.Path
352 + }
353 + return p.Path + "@" + p.Version
354 +}