package main import ( "fmt" "log" "os" "strings" "github.com/go-playground/validator/v10" "github.com/spf13/viper" ) // Gradle configuration structure type Gradle struct { Caches []string `mapstructure:"caches" validate:"required,min=1"` } // Jenkins configuration structure type Jenkins struct { Schema string `mapstructure:"schema" validate:"required,oneof=http https"` URL string `mapstructure:"url" validate:"required"` User string `mapstructure:"user" validate:"required"` Token string `mapstructure:"token" validate:"required"` Number string `mapstructure:"number" validate:"required"` DefaultParameters []map[string]interface{} `mapstructure:"default_parameters"` SpecialParameters []map[string]interface{} `mapstructure:"special_parameters"` } // Config represents the application configuration type Config struct { Gradle Gradle Jenkins Jenkins Jobs []string `mapstructure:"jobs" validate:"required,min=1"` Retries int `mapstructure:"retries" validate:"min=0"` } // DefaultConfig returns a configuration with default values func DefaultConfig() *Config { return &Config{ Gradle: Gradle{ Caches: []string{"/home/caches"}, }, Jenkins: Jenkins{ Schema: "https", Number: "lastBuild", DefaultParameters: []map[string]interface{}{ {"only_build": true}, }, SpecialParameters: []map[string]interface{}{}, }, Retries: 2, } } // ValidateConfig validates the configuration func ValidateConfig(config *Config) error { validate := validator.New() if err := validate.Struct(config); err != nil { return err } // Additional validation logic if !strings.HasSuffix(config.Jenkins.URL, "/") { config.Jenkins.URL += "/" } return nil } // LoadConfig loads configuration from the specified path func LoadConfig(path string) (*Config, error) { v := viper.New() v.SetConfigName("config") v.SetConfigType("yaml") v.AddConfigPath(path) // Also check current directory and /etc as fallbacks v.AddConfigPath(".") v.AddConfigPath("/etc") // Set environment variables prefix v.SetEnvPrefix("JENKINS_CRON") v.AutomaticEnv() // Load default config config := DefaultConfig() // Read config file if err := v.ReadInConfig(); err != nil { log.Printf("[CONFIG] Warning: Error reading config file: %v", err) log.Printf("[CONFIG] Using default configuration with environment variable overrides") } // Unmarshal config if err := v.Unmarshal(config); err != nil { return nil, fmt.Errorf("unable to decode config into struct: %w", err) } // Validate config if err := ValidateConfig(config); err != nil { return nil, fmt.Errorf("invalid configuration: %w", err) } return config, nil } // GetConfigPath returns the configuration path, either from command line or default func GetConfigPath() string { // Check if path is provided as argument if len(os.Args) > 1 { return os.Args[1] } return "/app" }