Skip to content

Commit 80fd3eb

Browse files
Copilotm7medVision
andcommitted
Implement environment variable support for API keys
Co-authored-by: m7medVision <88824957+m7medVision@users.noreply.github.com>
1 parent b0e1fd2 commit 80fd3eb

2 files changed

Lines changed: 119 additions & 1 deletion

File tree

internal/config/config.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,19 @@ func GetAPIKey() (string, error) {
100100
return "", fmt.Errorf("API key for provider '%s' is not set", cfg.ActiveProvider)
101101
}
102102

103-
return providerConfig.APIKey, nil
103+
apiKey := providerConfig.APIKey
104+
105+
// Check if the API key is an environment variable reference
106+
if strings.HasPrefix(apiKey, "$") {
107+
envVarName := strings.TrimPrefix(apiKey, "$")
108+
envValue := os.Getenv(envVarName)
109+
if envValue == "" {
110+
return "", fmt.Errorf("environment variable '%s' for provider '%s' is not set or empty", envVarName, cfg.ActiveProvider)
111+
}
112+
return envValue, nil
113+
}
114+
115+
return apiKey, nil
104116
}
105117

106118
// GetModel returns the model for the active provider.

internal/config/config_test.go

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package config
2+
3+
import (
4+
"os"
5+
"testing"
6+
7+
"github.com/spf13/viper"
8+
)
9+
10+
func TestGetAPIKey_EnvironmentVariable(t *testing.T) {
11+
// Reset configuration for clean test
12+
cfg = nil
13+
viper.Reset()
14+
15+
// Set up test environment variable
16+
testEnvVar := "TEST_API_KEY"
17+
testAPIKey := "test-api-key-value-123"
18+
os.Setenv(testEnvVar, testAPIKey)
19+
defer os.Unsetenv(testEnvVar)
20+
21+
// Initialize config
22+
InitConfig()
23+
24+
// Set up test provider with environment variable reference
25+
testProvider := "openrouter"
26+
cfg.ActiveProvider = testProvider
27+
if cfg.Providers == nil {
28+
cfg.Providers = make(map[string]ProviderConfig)
29+
}
30+
cfg.Providers[testProvider] = ProviderConfig{
31+
APIKey: "$" + testEnvVar,
32+
Model: "test-model",
33+
}
34+
35+
// Test that environment variable is resolved
36+
resolvedKey, err := GetAPIKey()
37+
if err != nil {
38+
t.Fatalf("Expected no error, got: %v", err)
39+
}
40+
41+
if resolvedKey != testAPIKey {
42+
t.Errorf("Expected resolved API key to be %s, got %s", testAPIKey, resolvedKey)
43+
}
44+
}
45+
46+
func TestGetAPIKey_EnvironmentVariableNotSet(t *testing.T) {
47+
// Reset configuration for clean test
48+
cfg = nil
49+
viper.Reset()
50+
51+
// Initialize config
52+
InitConfig()
53+
54+
// Set up test provider with environment variable reference that doesn't exist
55+
testProvider := "openrouter"
56+
cfg.ActiveProvider = testProvider
57+
if cfg.Providers == nil {
58+
cfg.Providers = make(map[string]ProviderConfig)
59+
}
60+
cfg.Providers[testProvider] = ProviderConfig{
61+
APIKey: "$NONEXISTENT_API_KEY",
62+
Model: "test-model",
63+
}
64+
65+
// Test that missing environment variable returns error
66+
_, err := GetAPIKey()
67+
if err == nil {
68+
t.Fatal("Expected error for missing environment variable, got nil")
69+
}
70+
71+
expectedError := "environment variable 'NONEXISTENT_API_KEY' for provider 'openrouter' is not set or empty"
72+
if err.Error() != expectedError {
73+
t.Errorf("Expected error message '%s', got '%s'", expectedError, err.Error())
74+
}
75+
}
76+
77+
func TestGetAPIKey_RegularAPIKey(t *testing.T) {
78+
// Reset configuration for clean test
79+
cfg = nil
80+
viper.Reset()
81+
82+
// Initialize config
83+
InitConfig()
84+
85+
// Set up test provider with regular API key (not environment variable)
86+
testProvider := "openrouter"
87+
testAPIKey := "regular-api-key-123"
88+
cfg.ActiveProvider = testProvider
89+
if cfg.Providers == nil {
90+
cfg.Providers = make(map[string]ProviderConfig)
91+
}
92+
cfg.Providers[testProvider] = ProviderConfig{
93+
APIKey: testAPIKey,
94+
Model: "test-model",
95+
}
96+
97+
// Test that regular API key is returned as-is
98+
resolvedKey, err := GetAPIKey()
99+
if err != nil {
100+
t.Fatalf("Expected no error, got: %v", err)
101+
}
102+
103+
if resolvedKey != testAPIKey {
104+
t.Errorf("Expected API key to be %s, got %s", testAPIKey, resolvedKey)
105+
}
106+
}

0 commit comments

Comments
 (0)