107 lines
2.5 KiB
Go
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
|
|
}
|