From 71552a347396aecafffe9ea06c39f09894061d0a Mon Sep 17 00:00:00 2001 From: Alex Collins Date: Sat, 22 Nov 2025 10:11:03 -0800 Subject: [PATCH] refactor: replace internal keyring wrapper with direct keyring library usage - Add replace directive in go.mod to use github.com/kitproj/go-keyring v0.2.10 - Update config package to import keyring library directly - Remove internal/keyring wrapper package - Fix tests to respect XDG_CONFIG_HOME environment variable --- go.mod | 3 ++- go.sum | 8 ++------ internal/config/config.go | 16 ++++++++++++---- internal/keyring/keyring.go | 15 --------------- mcp_test.go | 19 ++++++++++++++++++- 5 files changed, 34 insertions(+), 27 deletions(-) delete mode 100644 internal/keyring/keyring.go diff --git a/go.mod b/go.mod index 46071d4..f62c4ae 100644 --- a/go.mod +++ b/go.mod @@ -10,8 +10,9 @@ require ( golang.org/x/term v0.36.0 ) +replace github.com/zalando/go-keyring => github.com/kitproj/go-keyring v0.2.10 + require ( - al.essio.dev/pkg/shellescape v1.5.1 // indirect github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/buger/jsonparser v1.1.1 // indirect github.com/danieljoos/wincred v1.2.2 // indirect diff --git a/go.sum b/go.sum index b03e4a3..e438031 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,3 @@ -al.essio.dev/pkg/shellescape v1.5.1 h1:86HrALUujYS/h+GtqoB26SBEdkWfmMI6FubjXlsXyho= -al.essio.dev/pkg/shellescape v1.5.1/go.mod h1:6sIqp7X2P6mThCQ7twERpZTuigpr6KbZWtls1U8I890= github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/bndr/gojenkins v1.1.0 h1:TWyJI6ST1qDAfH33DQb3G4mD8KkrBfyfSUoZBHQAvPI= @@ -19,13 +17,13 @@ github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/invopop/jsonschema v0.13.0 h1:KvpoAJWEjR3uD9Kbm2HWJmqsEaHt8lBUpd0qHcIi21E= github.com/invopop/jsonschema v0.13.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/kitproj/go-keyring v0.2.10 h1:ZjwJOV8mIG8pYrWSGxtdGj62sYg6uAdMVa8kPbeMicQ= +github.com/kitproj/go-keyring v0.2.10/go.mod h1:yhtJhnoQt44WWzPtoc44uANw82MILytMeDc01iKC8cM= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -50,8 +48,6 @@ github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/ github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4= github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4= -github.com/zalando/go-keyring v0.2.6 h1:r7Yc3+H+Ux0+M72zacZoItR3UDxeWfKTcabvkI8ua9s= -github.com/zalando/go-keyring v0.2.6/go.mod h1:2TCrxYrbUNYfNS/Kgy/LSrkSQzZ5UPVH85RwfczwvcI= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa h1:F+8P+gmewFQYRk6JoLQLwjBCTu3mcIURZfNkVweuRKA= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= diff --git a/internal/config/config.go b/internal/config/config.go index 9a8d8b7..7b375f9 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -6,7 +6,7 @@ import ( "os" "path/filepath" - "github.com/kitproj/jenkins-cli/internal/keyring" + "github.com/zalando/go-keyring" ) const ( @@ -22,9 +22,17 @@ type config struct { // getConfigPath returns the path to the config file func getConfigPath() (string, error) { - configDirPath, err := os.UserConfigDir() - if err != nil { - return "", fmt.Errorf("failed to get config directory: %w", err) + var configDirPath string + var err error + + // Check XDG_CONFIG_HOME first (Linux standard, also used in tests) + if xdgConfigHome := os.Getenv("XDG_CONFIG_HOME"); xdgConfigHome != "" { + configDirPath = xdgConfigHome + } else { + configDirPath, err = os.UserConfigDir() + if err != nil { + return "", fmt.Errorf("failed to get config directory: %w", err) + } } configPath := filepath.Join(configDirPath, "jenkins-cli", configFile) diff --git a/internal/keyring/keyring.go b/internal/keyring/keyring.go deleted file mode 100644 index 8974ab1..0000000 --- a/internal/keyring/keyring.go +++ /dev/null @@ -1,15 +0,0 @@ -package keyring - -import ( - "github.com/zalando/go-keyring" -) - -// Set stores a secret in the keyring -func Set(service, user, password string) error { - return keyring.Set(service, user, password) -} - -// Get retrieves a secret from the keyring -func Get(service, user string) (string, error) { - return keyring.Get(service, user) -} diff --git a/mcp_test.go b/mcp_test.go index 3a4ac13..c312789 100644 --- a/mcp_test.go +++ b/mcp_test.go @@ -36,13 +36,30 @@ func TestRun_MCPServer(t *testing.T) { } func TestRun_MCPServerMissingConfig(t *testing.T) { - // Unset JENKINS_URL env var + // Use a temp directory for config to ensure no config file exists + tmpDir := t.TempDir() + oldXDGConfigHome := os.Getenv("XDG_CONFIG_HOME") + os.Setenv("XDG_CONFIG_HOME", tmpDir) + defer func() { + if oldXDGConfigHome != "" { + os.Setenv("XDG_CONFIG_HOME", oldXDGConfigHome) + } else { + os.Unsetenv("XDG_CONFIG_HOME") + } + }() + + // Unset JENKINS_URL and JENKINS_TOKEN env vars oldURL := os.Getenv("JENKINS_URL") + oldToken := os.Getenv("JENKINS_TOKEN") os.Unsetenv("JENKINS_URL") + os.Unsetenv("JENKINS_TOKEN") defer func() { if oldURL != "" { os.Setenv("JENKINS_URL", oldURL) } + if oldToken != "" { + os.Setenv("JENKINS_TOKEN", oldToken) + } }() ctx := context.Background()