Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS
Mirrored from https://github.com/Slazee/caddy.git
Synced Nov 11, 17:15 UTC
cmd: Add --json flag to list-modules command (#7409)
Paulo Henrique committed
Dec 26, 2025 at 14:32 UTC
9eabd443cb170ed846a70a84acf87002683ad29b
2 files changed
+58
-13
cmd/commandfuncs.go
+56
-12
@@ -411,11 +411,65 @@ func cmdBuildInfo(_ Flags) (int, error) {
411
return caddy.ExitCodeSuccess, nil
412
}
413
414
+// jsonModuleInfo holds metadata about a Caddy module for JSON output.
415
+type jsonModuleInfo struct {
416
+ ModuleName string `json:"module_name"`
417
+ ModuleType string `json:"module_type"`
418
+ Version string `json:"version,omitempty"`
419
+ PackageURL string `json:"package_url,omitempty"`
420
+}
421
+
422
func cmdListModules(fl Flags) (int, error) {
423
packages := fl.Bool("packages")
424
versions := fl.Bool("versions")
425
skipStandard := fl.Bool("skip-standard")
426
+ jsonOutput := fl.Bool("json")
427
+
428
+ // Organize modules by whether they come with the standard distribution
429
+ standard, nonstandard, unknown, err := getModules()
430
+ if err != nil {
431
+ // If module info can't be fetched, just print the IDs and exit
432
+ for _, m := range caddy.Modules() {
433
+ fmt.Println(m)
434
+ }
435
+ return caddy.ExitCodeSuccess, nil
436
+ }
437
+
438
+ // Logic for JSON output
439
+ if jsonOutput {
440
+ output := []jsonModuleInfo{}
441
+
442
+ // addToOutput is a helper to convert internal module info to the JSON-serializable struct
443
+ addToOutput := func(list []moduleInfo, moduleType string) {
444
+ for _, mi := range list {
445
+ item := jsonModuleInfo{
446
+ ModuleName: mi.caddyModuleID,
447
+ ModuleType: moduleType, // Mapping the type here
448
+ }
449
+ if mi.goModule != nil {
450
+ item.Version = mi.goModule.Version
451
+ item.PackageURL = mi.goModule.Path
452
+ }
453
+ output = append(output, item)
454
+ }
455
+ }
456
457
+ // Pass the respective type for each category
458
+ if !skipStandard {
459
+ addToOutput(standard, "standard")
460
+ }
461
+ addToOutput(nonstandard, "non-standard")
462
+ addToOutput(unknown, "unknown")
463
+
464
+ jsonBytes, err := json.MarshalIndent(output, "", " ")
465
+ if err != nil {
466
+ return caddy.ExitCodeFailedQuit, err
467
+ }
468
+ fmt.Println(string(jsonBytes))
469
+ return caddy.ExitCodeSuccess, nil
470
+ }
471
+
472
+ // Logic for Text output (Fallback)
473
printModuleInfo := func(mi moduleInfo) {
474
fmt.Print(mi.caddyModuleID)
475
if versions && mi.goModule != nil {
@@ -433,16 +487,6 @@ func cmdListModules(fl Flags) (int, error) {
487
fmt.Println()
488
}
489
436
- // organize modules by whether they come with the standard distribution
437
- standard, nonstandard, unknown, err := getModules()
438
- if err != nil {
439
- // oh well, just print the module IDs and exit
440
- for _, m := range caddy.Modules() {
441
- fmt.Println(m)
442
- }
443
- return caddy.ExitCodeSuccess, nil
444
- }
445
-
490
// Standard modules (always shipped with Caddy)
491
if !skipStandard {
492
if len(standard) > 0 {
@@ -461,8 +505,8 @@ func cmdListModules(fl Flags) (int, error) {
505
for _, mod := range nonstandard {
506
printModuleInfo(mod)
507
}
508
+ fmt.Printf("\n Non-standard modules: %d\n", len(nonstandard))
509
}
465
- fmt.Printf("\n Non-standard modules: %d\n", len(nonstandard))
510
511
// Unknown modules (couldn't get Caddy module info)
512
if len(unknown) > 0 {
@@ -472,8 +516,8 @@ func cmdListModules(fl Flags) (int, error) {
516
for _, mod := range unknown {
517
printModuleInfo(mod)
518
}
519
+ fmt.Printf("\n Unknown modules: %d\n", len(unknown))
520
}
476
- fmt.Printf("\n Unknown modules: %d\n", len(unknown))
521
522
return caddy.ExitCodeSuccess, nil
523
}
cmd/commands.go
+2
-1
@@ -229,12 +229,13 @@ documentation: https://go.dev/doc/modules/version-numbers
229
230
RegisterCommand(Command{
231
Name: "list-modules",
232
- Usage: "[--packages] [--versions] [--skip-standard]",
232
+ Usage: "[--packages] [--versions] [--skip-standard] [--json]",
233
Short: "Lists the installed Caddy modules",
234
CobraFunc: func(cmd *cobra.Command) {
235
cmd.Flags().BoolP("packages", "", false, "Print package paths")
236
cmd.Flags().BoolP("versions", "", false, "Print version information")
237
cmd.Flags().BoolP("skip-standard", "s", false, "Skip printing standard modules")
238
+ cmd.Flags().BoolP("json", "", false, "Print modules in JSON format")
239
cmd.RunE = WrapCommandFuncForCobra(cmdListModules)
240
},
241
})