package cmd import ( "context" "fmt" "log/slog" "net/url" "os" "git.franklin.lab/steve.cliff/pcli/client" "git.franklin.lab/steve.cliff/pcli/logging" "git.franklin.lab/steve.cliff/pcli/output" "github.com/spf13/cobra" ) var ( flagFormat string flagURL string flagAPIKey string flagLogLevel string apiClient *client.Client logger *slog.Logger ) var rootCmd = &cobra.Command{ Use: "pcli", Short: "CLI for Planka API", Long: "A command-line interface for interacting with the Planka project management API", PersistentPreRunE: func(cmd *cobra.Command, args []string) error { url := flagURL if url == "" { url = os.Getenv("PLANKA_URL") } if url == "" { return fmt.Errorf("PLANKA_URL must be set via --url flag or PLANKA_URL environment variable") } // Validate URL format if err := validateURL(url); err != nil { return fmt.Errorf("invalid PLANKA_URL: %w", err) } apiKey := flagAPIKey if apiKey == "" { apiKey = os.Getenv("PLANKA_API_KEY") } if apiKey == "" { return fmt.Errorf("PLANKA_API_KEY must be set via --api-key flag or PLANKA_API_KEY environment variable") } logger = logging.NewLogger(flagLogLevel) logger.Debug("Initializing client", slog.String("url", url), slog.String("log_level", flagLogLevel), ) apiClient = client.NewClient(url, apiKey, logger) return nil }, } func init() { rootCmd.PersistentFlags().StringVar(&flagFormat, "format", "json", "Output format (json or table)") rootCmd.PersistentFlags().StringVar(&flagURL, "url", "", "Planka API URL (overrides PLANKA_URL env var)") rootCmd.PersistentFlags().StringVar(&flagAPIKey, "api-key", "", "Planka API key (overrides PLANKA_API_KEY env var)") rootCmd.PersistentFlags().StringVar(&flagLogLevel, "log-level", "warn", "Log level (debug, info, warn, error)") } func Execute() { if err := rootCmd.Execute(); err != nil { output.PrintError(err, flagFormat, os.Stdout) os.Exit(1) } } func getClient() *client.Client { return apiClient } func getContext() context.Context { return context.Background() } func getFormat() string { return flagFormat } func validateURL(urlStr string) error { parsedURL, err := url.Parse(urlStr) if err != nil { return fmt.Errorf("failed to parse URL: %w", err) } if parsedURL.Scheme != "http" && parsedURL.Scheme != "https" { return fmt.Errorf("URL must use http or https scheme, got: %s", parsedURL.Scheme) } if parsedURL.Host == "" { return fmt.Errorf("URL must have a valid host") } return nil }