diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 15b6d31..a46ffc2 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -41,6 +41,10 @@ archives: format_overrides: - goos: windows format: zip + files: + - config.yml + - README.md + - LICENSE checksum: name_template: 'checksums.txt' @@ -73,6 +77,7 @@ brews: install: | bin.install "amqcli" + (etc/"amqcli").install "config.yml" test: | system "#{bin}/amqcli", "--version" diff --git a/cmd/main.go b/cmd/main.go index 7e1b1e2..a207730 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -21,6 +21,7 @@ var ( func main() { env := flag.String("env", "dev", "Environment profile to use (e.g. dev, prod)") showVersion := flag.Bool("version", false, "Print application version") + configPath := flag.String("config", "config.yml", "Path to configuration file") flag.Parse() if *showVersion { @@ -29,7 +30,7 @@ func main() { } // 1. Load config - cfg, err := config.LoadConfig("config.yml") + cfg, err := config.LoadConfig(*configPath) if err != nil { log.Fatalf("Failed to load config: %v", err) } diff --git a/config/config.go b/config/config.go index 9e5345c..f1ab679 100644 --- a/config/config.go +++ b/config/config.go @@ -31,9 +31,31 @@ type ActiveMQConfig struct { } func LoadConfig(path string) (*Config, error) { - data, err := os.ReadFile(path) // #nosec G304 -- path is a fixed config file path from CLI args, not user-controlled input + var data []byte + var err error + + // 1. Try reading the specified path (or "config.yml" from current directory) + // #nosec G304 -- config path is fixed or loaded from user's CLI argument + data, err = os.ReadFile(path) if err != nil { - return nil, fmt.Errorf("failed to read config file: %w", err) + // 2. Fallback to home directory config (~/.amqcli.yml) + homeDir, homeErr := os.UserHomeDir() + if homeErr == nil { + homeConfigPath := homeDir + "/.amqcli.yml" + // #nosec G304 -- config path is safe + data, err = os.ReadFile(homeConfigPath) + if err != nil { + // 3. Create default template if it doesn't exist anywhere + fmt.Printf("Config file not found. Creating default template at: %s\n", homeConfigPath) + createDefaultConfig(homeConfigPath) + // #nosec G304 -- config path is safe + data, err = os.ReadFile(homeConfigPath) + } + } + } + + if err != nil { + return nil, fmt.Errorf("failed to read config file (try creating ~/.amqcli.yml): %w", err) } // Expand environment variables (e.g. ${VAR} or ${VAR:-default}) @@ -101,3 +123,28 @@ func expandEnvFunc(k string) string { } return val } + +func createDefaultConfig(path string) { + defaultTemplate := `refresh_interval: 3s +encoding: "utf-8" + +environments: + dev: + protocol: stomp + host: 127.0.0.1 + stomp_port: 61613 + amqp_port: 5672 + web_port: 8161 + username: admin + password: admin + prod: + protocol: amqp + host: 192.168.0.100 + stomp_port: 61613 + amqp_port: 5672 + web_port: 8161 + username: myuser + password: mypassword +` + _ = os.WriteFile(path, []byte(defaultTemplate), 0600) +}