Refactored the command registration system to use a centralized cli.Commands() function that can be called with rootCmd.AddCommand(cli.Commands()...).
New file that exports all top-level commands from a single function:
package cli
func Commands() []*cobra.Command {
return []*cobra.Command{
// All commands listed here
}
}Key Features:
- Single source of truth for all commands
- Subcommands automatically registered via
init()functions - Well-documented with comments explaining command hierarchy
- Organized into logical groups (workflow, database, query, etc.)
import (
// 30+ individual command imports
"go.devnw.com/canary/cli/bug"
"go.devnw.com/canary/cli/create"
// ... etc
)
func init() {
rootCmd.AddCommand(scan.ScanCmd)
rootCmd.AddCommand(canaryinit.InitCmd)
rootCmd.AddCommand(create.CreateCmd)
// ... 30+ more AddCommand calls
}import (
"go.devnw.com/canary/cli"
"go.devnw.com/canary/cli/db"
canaryinit "go.devnw.com/canary/cli/init"
"go.devnw.com/canary/cli/legacy"
"go.devnw.com/canary/cli/next"
// Only 5 imports needed for flag configuration
)
func init() {
// Add all commands with subcommands automatically included
rootCmd.AddCommand(cli.Commands()...)
// Configure flags for specific commands that need it
canaryinit.InitCmd.Flags().Bool("local", false, "...")
// ... etc
}Benefits:
- Reduced imports from 30+ to 5
- Reduced code from 40+ lines to 1 line for command registration
- Cleaner, more maintainable structure
- Easy to add new commands (just add to
cli/cmds.go)
The system now properly handles command hierarchies:
- bug ? list, create, update, show
- gap ? mark, query, report, helpful, unhelpful, config, categories
- deps ? (dynamically created subcommands)
- project ? DbCmd, ProjectCmd
- db ? MigrateCmd, RollbackCmd
- doc ? (document management subcommands)
- legacy ? DetectCmd, MigrateFromCmd
- migrate ? OrphanCmd
All subcommands are registered in their respective package init() functions, so they're automatically available when the parent command is added.
cli/
??? cmds.go # NEW: Central command registry
??? bug/
? ??? bug.go # Parent + helpers
? ??? list.go # Subcommand
? ??? create.go # Subcommand
? ??? update.go # Subcommand
? ??? show.go # Subcommand
??? gap/
? ??? gap.go # Parent + all subcommands
??? create/
? ??? create.go # Standalone command
??? list/
? ??? list.go # Standalone command
??? ... (other commands)
cmd/canary/
??? main.go # SIMPLIFIED: Uses cli.Commands()
-
Create command in its package:
// cli/mycommand/mycommand.go package mycommand var MyCmd = &cobra.Command{ Use: "mycommand", // ... } func init() { MyCmd.Flags().String("prompt", "", "...") // ... other flags }
-
Add to
cli/cmds.go:import "go.devnw.com/canary/cli/mycommand" func Commands() []*cobra.Command { return []*cobra.Command{ // ... existing commands mycommand.MyCmd, } }
-
Done! No need to modify
cmd/canary/main.go
-
Create subcommand file:
// cli/parent/subcommand.go package parent var subCmd = &cobra.Command{ Use: "sub", // ... } func init() { ParentCmd.AddCommand(subCmd) subCmd.Flags().String("prompt", "", "...") }
-
Already works! Subcommand is automatically included when parent is added
All functionality verified:
- ? All commands available:
canary --help - ? Bug subcommands work:
canary bug --help - ? Gap subcommands work:
canary gap --help - ? All --prompt flags present
- ? Binary builds successfully
- ? No duplicate command registrations
-
Maintainability
- Single place to see all commands
- Easy to add/remove commands
- Clear command hierarchy
-
Cleaner Code
- Reduced imports in main.go (30+ ? 5)
- Reduced code lines (40+ ? 1 for registration)
- Better separation of concerns
-
Flexibility
- Easy to reorganize commands
- Easy to add command groups
- Subcommands automatically included
-
Documentation
- Self-documenting structure in
cli/cmds.go - Comments explain command relationships
- Easy to understand command hierarchy
- Self-documenting structure in
cmd/canary/main.go: Usescli.Commands()instead of individualAddCommandcallscli/cmds.go: NEW file with centralized command registry- Imports: Reduced to only what's needed for flag configuration
- All command functionality
- All flag definitions
- All subcommand relationships
- All tests and behavior
- ? 100% backward compatible
- No breaking changes
- All commands work identically
- All flags preserved
With this structure, it's easy to add:
- Command groups/categories
- Dynamic command loading
- Plugin system for external commands
- Command aliases
- Command deprecation warnings
// 1. Create cli/export/export.go
package export
import "github.com/spf13/cobra"
var ExportCmd = &cobra.Command{
Use: "export",
Short: "Export CANARY tokens",
RunE: func(cmd *cobra.Command, args []string) error {
// Implementation
return nil
},
}
func init() {
ExportCmd.Flags().String("prompt", "", "Custom prompt (future use)")
ExportCmd.Flags().String("format", "json", "Export format")
}
// 2. Update cli/cmds.go
import "go.devnw.com/canary/cli/export"
func Commands() []*cobra.Command {
return []*cobra.Command{
// ... existing commands
export.ExportCmd, // Add new command here
}
}
// 3. Done! Command is now availableThe refactored command system provides a clean, maintainable structure that:
- Centralizes command registration
- Simplifies the main entry point
- Properly handles command hierarchies
- Makes it easy to add new commands
- Maintains full backward compatibility