Skip to content

Commit 4c147e8

Browse files
committed
fix: unify config precedence for base URL and API key across all command paths
Extract resolveBaseURL() and resolveAPIKey() helpers in cmdutil.go so that exec, cp, and push WebSocket/auth paths use the same CLI flag > env var > config file > default precedence as the SDK client created by getDefaultRequestOptions(). Previously, getDefaultRequestOptions read base_url and api_key from cli.yaml, but exec/cp/push resolved these from env vars only, causing split configuration sources within a single command run.
1 parent 672a55a commit 4c147e8

File tree

4 files changed

+41
-42
lines changed

4 files changed

+41
-42
lines changed

pkg/cmd/cmdutil.go

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,29 +22,46 @@ import (
2222
"golang.org/x/term"
2323
)
2424

25+
// resolveBaseURL returns the effective base URL using precedence:
26+
// CLI flag > env var > config file > default.
27+
func resolveBaseURL(cmd *cli.Command) string {
28+
if baseURL := cmd.Root().String("base-url"); baseURL != "" {
29+
return baseURL
30+
}
31+
if baseURL := os.Getenv("HYPEMAN_BASE_URL"); baseURL != "" {
32+
return baseURL
33+
}
34+
cfg := loadCLIConfig()
35+
if cfg.BaseURL != "" {
36+
return cfg.BaseURL
37+
}
38+
return "http://localhost:8080"
39+
}
40+
41+
// resolveAPIKey returns the effective API key using precedence:
42+
// env var > config file. Returns an error if no key is found.
43+
func resolveAPIKey() (string, error) {
44+
if apiKey := os.Getenv("HYPEMAN_API_KEY"); apiKey != "" {
45+
return apiKey, nil
46+
}
47+
cfg := loadCLIConfig()
48+
if cfg.APIKey != "" {
49+
return cfg.APIKey, nil
50+
}
51+
return "", fmt.Errorf("HYPEMAN_API_KEY environment variable or api_key in config file required")
52+
}
53+
2554
func getDefaultRequestOptions(cmd *cli.Command) []option.RequestOption {
2655
opts := []option.RequestOption{
2756
option.WithHeader("User-Agent", fmt.Sprintf("Hypeman/CLI %s", Version)),
2857
}
2958

30-
// Load config file for fallback values
31-
cfg := loadCLIConfig()
32-
33-
// Precedence for base URL: CLI flag > env var > config file
34-
if baseURL := cmd.String("base-url"); baseURL != "" {
59+
if baseURL := resolveBaseURL(cmd); baseURL != "http://localhost:8080" {
3560
opts = append(opts, option.WithBaseURL(baseURL))
36-
} else if baseURL := os.Getenv("HYPEMAN_BASE_URL"); baseURL != "" {
37-
opts = append(opts, option.WithBaseURL(baseURL))
38-
} else if cfg.BaseURL != "" {
39-
opts = append(opts, option.WithBaseURL(cfg.BaseURL))
4061
}
4162

42-
// Precedence for API key: env var > config file
43-
// (no CLI flag for API key for security reasons)
44-
if apiKey := os.Getenv("HYPEMAN_API_KEY"); apiKey != "" {
63+
if apiKey, err := resolveAPIKey(); err == nil {
4564
opts = append(opts, option.WithAPIKey(apiKey))
46-
} else if cfg.APIKey != "" {
47-
opts = append(opts, option.WithAPIKey(cfg.APIKey))
4865
}
4966

5067
return opts

pkg/cmd/cp.go

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -146,17 +146,11 @@ func handleCp(ctx context.Context, cmd *cli.Command) error {
146146
}
147147

148148
// Get base URL and API key
149-
baseURL := cmd.Root().String("base-url")
150-
if baseURL == "" {
151-
baseURL = os.Getenv("HYPEMAN_BASE_URL")
152-
}
153-
if baseURL == "" {
154-
baseURL = "http://localhost:8080"
155-
}
149+
baseURL := resolveBaseURL(cmd)
156150

157-
apiKey := os.Getenv("HYPEMAN_API_KEY")
158-
if apiKey == "" {
159-
return fmt.Errorf("HYPEMAN_API_KEY environment variable required")
151+
apiKey, err := resolveAPIKey()
152+
if err != nil {
153+
return err
160154
}
161155

162156
archive := cmd.Bool("archive")

pkg/cmd/exec.go

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -146,17 +146,11 @@ func handleExec(ctx context.Context, cmd *cli.Command) error {
146146
}
147147

148148
// Get base URL and API key
149-
baseURL := cmd.Root().String("base-url")
150-
if baseURL == "" {
151-
baseURL = os.Getenv("HYPEMAN_BASE_URL")
152-
}
153-
if baseURL == "" {
154-
baseURL = "http://localhost:8080"
155-
}
149+
baseURL := resolveBaseURL(cmd)
156150

157-
apiKey := os.Getenv("HYPEMAN_API_KEY")
158-
if apiKey == "" {
159-
return fmt.Errorf("HYPEMAN_API_KEY environment variable required")
151+
apiKey, err := resolveAPIKey()
152+
if err != nil {
153+
return err
160154
}
161155

162156
// Build WebSocket URL

pkg/cmd/push.go

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,7 @@ func handlePush(ctx context.Context, cmd *cli.Command) error {
3535
targetName = args[1]
3636
}
3737

38-
baseURL := cmd.String("base-url")
39-
if baseURL == "" {
40-
baseURL = os.Getenv("HYPEMAN_BASE_URL")
41-
}
42-
if baseURL == "" {
43-
baseURL = "http://localhost:8080"
44-
}
38+
baseURL := resolveBaseURL(cmd)
4539

4640
parsedURL, err := url.Parse(baseURL)
4741
if err != nil {
@@ -73,7 +67,7 @@ func handlePush(ctx context.Context, cmd *cli.Command) error {
7367

7468
token := os.Getenv("HYPEMAN_BEARER_TOKEN")
7569
if token == "" {
76-
token = os.Getenv("HYPEMAN_API_KEY")
70+
token, _ = resolveAPIKey()
7771
}
7872

7973
// Use custom transport that always sends Basic auth header

0 commit comments

Comments
 (0)