@@ -46,6 +46,25 @@ func cmdUpgrade(fl Flags) (int, error) {
46
46
return upgradeBuild (pluginPkgs , fl )
47
47
}
48
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
+
49
68
func cmdAddPackage (fl Flags ) (int , error ) {
50
69
if len (fl .Args ()) == 0 {
51
70
return caddy .ExitCodeFailedStartup , fmt .Errorf ("at least one package name must be specified" )
@@ -60,10 +79,15 @@ func cmdAddPackage(fl Flags) (int, error) {
60
79
}
61
80
62
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 ) {
64
88
return caddy .ExitCodeFailedStartup , fmt .Errorf ("package is already added" )
65
89
}
66
- pluginPkgs [arg ] = struct {}{ }
90
+ pluginPkgs [module ] = pluginPackage { Version : version , Path : module }
67
91
}
68
92
69
93
return upgradeBuild (pluginPkgs , fl )
@@ -83,7 +107,11 @@ func cmdRemovePackage(fl Flags) (int, error) {
83
107
}
84
108
85
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 {
87
115
// package does not exist
88
116
return caddy .ExitCodeFailedStartup , fmt .Errorf ("package is not added" )
89
117
}
@@ -93,7 +121,7 @@ func cmdRemovePackage(fl Flags) (int, error) {
93
121
return upgradeBuild (pluginPkgs , fl )
94
122
}
95
123
96
- func upgradeBuild (pluginPkgs map [string ]struct {} , fl Flags ) (int , error ) {
124
+ func upgradeBuild (pluginPkgs map [string ]pluginPackage , fl Flags ) (int , error ) {
97
125
l := caddy .Log ()
98
126
99
127
thisExecPath , err := os .Executable ()
@@ -120,8 +148,8 @@ func upgradeBuild(pluginPkgs map[string]struct{}, fl Flags) (int, error) {
120
148
"os" : {runtime .GOOS },
121
149
"arch" : {runtime .GOARCH },
122
150
}
123
- for pkg := range pluginPkgs {
124
- qs .Add ("p" , pkg )
151
+ for _ , pkgInfo := range pluginPkgs {
152
+ qs .Add ("p" , pkgInfo . String () )
125
153
}
126
154
127
155
// initiate the build
@@ -276,14 +304,14 @@ func downloadBuild(qs url.Values) (*http.Response, error) {
276
304
return resp , nil
277
305
}
278
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 )
281
309
for _ , mod := range modules {
282
310
if mod .goModule .Replace != nil {
283
311
return nil , fmt .Errorf ("cannot auto-upgrade when Go module has been replaced: %s => %s" ,
284
312
mod .goModule .Path , mod .goModule .Replace .Path )
285
313
}
286
- pluginPkgs [mod .goModule .Path ] = struct {}{ }
314
+ pluginPkgs [mod .goModule .Path ] = pluginPackage { Version : mod . goModule . Version , Path : mod . goModule . Path }
287
315
}
288
316
return pluginPkgs , nil
289
317
}
@@ -312,3 +340,15 @@ func writeCaddyBinary(path string, body *io.ReadCloser, fileInfo os.FileInfo) er
312
340
}
313
341
314
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
+ }
0 commit comments