Files
pcli/cmd/root.go
T
Steve Cliff b07572fed5 Released v1
2026-02-12 10:37:19 +00:00

107 lines
2.5 KiB
Go

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
}