147 lines
3.9 KiB
Go
147 lines
3.9 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
|
|
"github.com/spf13/cobra"
|
|
"github.com/spf13/viper"
|
|
|
|
"github.com/wild-cloud/wild-cli/cmd/wild/app"
|
|
"github.com/wild-cloud/wild-cli/cmd/wild/cluster"
|
|
"github.com/wild-cloud/wild-cli/cmd/wild/config"
|
|
"github.com/wild-cloud/wild-cli/cmd/wild/secret"
|
|
"github.com/wild-cloud/wild-cli/cmd/wild/setup"
|
|
"github.com/wild-cloud/wild-cli/cmd/wild/util"
|
|
"github.com/wild-cloud/wild-cli/internal/environment"
|
|
"github.com/wild-cloud/wild-cli/internal/output"
|
|
)
|
|
|
|
var (
|
|
// Global flags
|
|
cfgDir string
|
|
verbose bool
|
|
dryRun bool
|
|
noColor bool
|
|
wcRoot string
|
|
wcHome string
|
|
)
|
|
|
|
func newRootCommand() *cobra.Command {
|
|
cmd := &cobra.Command{
|
|
Use: "wild",
|
|
Short: "Wild Cloud - Personal cloud infrastructure management",
|
|
Long: `Wild Cloud CLI provides comprehensive management of your personal cloud infrastructure
|
|
built on Talos Linux and Kubernetes.
|
|
|
|
This tool replaces the collection of wild-* bash scripts with a single, unified CLI
|
|
that provides better error handling, progress tracking, and cross-platform support.`,
|
|
Version: "0.1.0-dev",
|
|
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
|
return initializeConfig(cmd.Context())
|
|
},
|
|
SilenceUsage: true,
|
|
SilenceErrors: true,
|
|
}
|
|
|
|
// Add persistent flags
|
|
pflags := cmd.PersistentFlags()
|
|
pflags.StringVar(&cfgDir, "config-dir", "", "config directory (default: current directory)")
|
|
pflags.BoolVarP(&verbose, "verbose", "v", false, "enable verbose logging")
|
|
pflags.BoolVar(&dryRun, "dry-run", false, "show what would be done without making changes")
|
|
pflags.BoolVar(&noColor, "no-color", false, "disable colored output")
|
|
pflags.StringVar(&wcRoot, "wc-root", "", "Wild Cloud installation directory")
|
|
pflags.StringVar(&wcHome, "wc-home", "", "Wild Cloud project directory")
|
|
|
|
// Bind flags to viper
|
|
_ = viper.BindPFlag("verbose", pflags.Lookup("verbose"))
|
|
_ = viper.BindPFlag("dry-run", pflags.Lookup("dry-run"))
|
|
_ = viper.BindPFlag("no-color", pflags.Lookup("no-color"))
|
|
|
|
// Add subcommands
|
|
cmd.AddCommand(
|
|
setup.NewSetupCommand(),
|
|
app.NewAppCommand(),
|
|
cluster.NewClusterCommand(),
|
|
config.NewConfigCommand(),
|
|
secret.NewSecretCommand(),
|
|
util.NewBackupCommand(),
|
|
util.NewDashboardCommand(),
|
|
util.NewTemplateCommand(),
|
|
util.NewStatusCommand(),
|
|
util.NewVersionCommand(),
|
|
)
|
|
|
|
return cmd
|
|
}
|
|
|
|
func initializeConfig(ctx context.Context) error {
|
|
// Set up output formatting based on flags
|
|
if noColor {
|
|
output.DisableColor()
|
|
}
|
|
|
|
if verbose {
|
|
output.SetVerbose(true)
|
|
}
|
|
|
|
// Initialize environment
|
|
env := environment.New()
|
|
|
|
// Set WC_ROOT
|
|
if wcRoot != "" {
|
|
env.SetWCRoot(wcRoot)
|
|
} else if envRoot := os.Getenv("WC_ROOT"); envRoot != "" {
|
|
env.SetWCRoot(envRoot)
|
|
}
|
|
|
|
// Detect or set WC_HOME
|
|
if wcHome != "" {
|
|
env.SetWCHome(wcHome)
|
|
} else if cfgDir != "" {
|
|
env.SetWCHome(cfgDir)
|
|
} else {
|
|
// Try to auto-detect WC_HOME by looking for .wildcloud marker
|
|
detected, err := env.DetectWCHome()
|
|
if err != nil {
|
|
return fmt.Errorf("failed to detect Wild Cloud project directory: %w", err)
|
|
}
|
|
if detected == "" {
|
|
// Only require WC_HOME for commands that need it
|
|
// Some commands like "wild setup scaffold" don't need an existing project
|
|
return nil
|
|
}
|
|
env.SetWCHome(detected)
|
|
}
|
|
|
|
// Validate environment
|
|
if err := env.Validate(ctx); err != nil {
|
|
return fmt.Errorf("environment validation failed: %w", err)
|
|
}
|
|
|
|
// Set up viper configuration
|
|
if env.WCHome() != "" {
|
|
viper.AddConfigPath(env.WCHome())
|
|
viper.SetConfigName("config")
|
|
viper.SetConfigType("yaml")
|
|
|
|
// Try to read config file (not required)
|
|
if err := viper.ReadInConfig(); err != nil {
|
|
if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
|
|
return fmt.Errorf("error reading config file: %w", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Set environment variables for child processes and internal use
|
|
if env.WCRoot() != "" {
|
|
_ = os.Setenv("WC_ROOT", env.WCRoot())
|
|
}
|
|
if env.WCHome() != "" {
|
|
_ = os.Setenv("WC_HOME", env.WCHome())
|
|
}
|
|
|
|
return nil
|
|
}
|