package config import ( "encoding/json" "flag" "fmt" "os" ) const Version = "v0.0.5" // Package-level variables for flags var ( baseConfigFile string projectConfigFile string pipelineFile string ) type BaseConfig struct { RetryDelaySenconds int `json:"retry_delay_seconds"` } // ParseFlags parses all command-line flags and handles help/version flags func ParseFlags() { helpFlag := flag.Bool("help", false, "show help") versionFlag := flag.Bool("version", false, "show version") vFlag := flag.Bool("v", false, "show version (shorthand)") flag.StringVar(&baseConfigFile, "base-config", "", "Path to base config file (optional)") flag.StringVar(&projectConfigFile, "project-config", "", "Path to project config file (optional)") flag.StringVar(&pipelineFile, "f", "", "Path to pipeline file") flag.StringVar(&pipelineFile, "deployment-file", "", "Path to pipeline file (long format)") flag.Parse() if *helpFlag { fmt.Println("Usage: infctl-cli --deployment-file=") fmt.Println("DEPLOYMENT_TYPE environment variable must be set to 'json' or 'api (api is not implemented yet)'") os.Exit(0) } if *versionFlag || *vFlag { fmt.Println("infctl-cli version:", Version) os.Exit(0) } } func ReadBaseConfig(path string) (BaseConfig, error) { config := BaseConfig{} // If base.json does not exist, create it with default value if _, err := os.Stat(path); os.IsNotExist(err) { if err := CreateDefaultBaseConfig(path); err != nil { return BaseConfig{}, fmt.Errorf("failed to create default base config: %w", err) } } data, err := os.ReadFile(path) if err != nil { return BaseConfig{}, fmt.Errorf("failed to read the config file: %w", err) } if err := json.Unmarshal(data, &config); err != nil { return config, fmt.Errorf("failed to unmarshal JSON: %w", err) } return config, nil } // CreateDefaultBaseConfig creates a default base.json with retry_delay_seconds: 3 func CreateDefaultBaseConfig(path string) error { defaultConfig := BaseConfig{ RetryDelaySenconds: 3, } data, err := json.MarshalIndent(defaultConfig, "", " ") if err != nil { return fmt.Errorf("failed to marshal default base config: %w", err) } if err := os.WriteFile(path, data, 0644); err != nil { return fmt.Errorf("failed to write default base config to file: %w", err) } return nil } // LoadConfigs resolves config paths and loads both configs func LoadConfigs() (BaseConfig, ProjectConfig, error) { wd, err := os.Getwd() if err != nil { return BaseConfig{}, ProjectConfig{}, fmt.Errorf("failed to get current directory: %w", err) } var baseConfigPath string if baseConfigFile == "" { baseConfigPath = wd + string(os.PathSeparator) + "base.json" } else { baseConfigPath = baseConfigFile } var projectConfigPath string if projectConfigFile == "" { projectConfigPath = wd + string(os.PathSeparator) + "config.json" } else { projectConfigPath = projectConfigFile } baseConfig, err := ReadBaseConfig(baseConfigPath) if err != nil { return BaseConfig{}, ProjectConfig{}, fmt.Errorf("error reading base config file: %w", err) } projectConfig, err := ReadProjectConfig(projectConfigPath, &pipelineFile) if err != nil { return BaseConfig{}, ProjectConfig{}, fmt.Errorf("error reading project config file: %w", err) } return baseConfig, projectConfig, nil }