From fa48cadc9ab2b439137a66e1e51ba27c2e3d280f Mon Sep 17 00:00:00 2001 From: Amaan Qureshi Date: Sun, 25 Jan 2026 15:49:48 -0500 Subject: [PATCH 1/2] test: fix environment pollution in tests Tests were inheriting environment variables from the host environment (GH_TOKEN, GH_CONFIG_DIR, etc.), causing failures when these were set. Explicitly clear these variables in each test to ensure isolation. --- pkg/api/client_options_test.go | 3 +++ pkg/api/graphql_client_test.go | 12 ++++++++++++ pkg/api/http_client_test.go | 3 +++ pkg/api/rest_client_test.go | 3 +++ pkg/auth/auth_test.go | 3 +++ pkg/config/config_test.go | 9 ++++++++- 6 files changed, 32 insertions(+), 1 deletion(-) diff --git a/pkg/api/client_options_test.go b/pkg/api/client_options_test.go index 35cfb34..e2f1055 100644 --- a/pkg/api/client_options_test.go +++ b/pkg/api/client_options_test.go @@ -9,6 +9,9 @@ import ( ) func TestResolveOptions(t *testing.T) { + t.Setenv("GH_CONFIG_DIR", "") + t.Setenv("GH_TOKEN", "") + t.Setenv("GITHUB_TOKEN", "") testutils.StubConfig(t, testConfigWithSocket()) tests := []struct { diff --git a/pkg/api/graphql_client_test.go b/pkg/api/graphql_client_test.go index 15cdc7a..d7f484b 100644 --- a/pkg/api/graphql_client_test.go +++ b/pkg/api/graphql_client_test.go @@ -13,6 +13,9 @@ import ( ) func TestGraphQLClient(t *testing.T) { + t.Setenv("GH_CONFIG_DIR", "") + t.Setenv("GH_TOKEN", "") + t.Setenv("GITHUB_TOKEN", "") testutils.StubConfig(t, testConfig()) t.Cleanup(gock.Off) @@ -35,6 +38,9 @@ func TestGraphQLClient(t *testing.T) { } func TestGraphQLClientDoError(t *testing.T) { + t.Setenv("GH_CONFIG_DIR", "") + t.Setenv("GH_TOKEN", "") + t.Setenv("GITHUB_TOKEN", "") testutils.StubConfig(t, testConfig()) t.Cleanup(gock.Off) @@ -57,6 +63,9 @@ func TestGraphQLClientDoError(t *testing.T) { } func TestGraphQLClientQueryError(t *testing.T) { + t.Setenv("GH_CONFIG_DIR", "") + t.Setenv("GH_TOKEN", "") + t.Setenv("GITHUB_TOKEN", "") testutils.StubConfig(t, testConfig()) t.Cleanup(gock.Off) @@ -79,6 +88,9 @@ func TestGraphQLClientQueryError(t *testing.T) { } func TestGraphQLClientMutateError(t *testing.T) { + t.Setenv("GH_CONFIG_DIR", "") + t.Setenv("GH_TOKEN", "") + t.Setenv("GITHUB_TOKEN", "") testutils.StubConfig(t, testConfig()) t.Cleanup(gock.Off) diff --git a/pkg/api/http_client_test.go b/pkg/api/http_client_test.go index 19c911d..d765800 100644 --- a/pkg/api/http_client_test.go +++ b/pkg/api/http_client_test.go @@ -14,6 +14,9 @@ import ( ) func TestHTTPClient(t *testing.T) { + t.Setenv("GH_CONFIG_DIR", "") + t.Setenv("GH_TOKEN", "") + t.Setenv("GITHUB_TOKEN", "") testutils.StubConfig(t, testConfig()) t.Cleanup(gock.Off) diff --git a/pkg/api/rest_client_test.go b/pkg/api/rest_client_test.go index 905888e..8249219 100644 --- a/pkg/api/rest_client_test.go +++ b/pkg/api/rest_client_test.go @@ -14,6 +14,9 @@ import ( ) func TestRESTClient(t *testing.T) { + t.Setenv("GH_CONFIG_DIR", "") + t.Setenv("GH_TOKEN", "") + t.Setenv("GITHUB_TOKEN", "") testutils.StubConfig(t, testConfig()) t.Cleanup(gock.Off) diff --git a/pkg/auth/auth_test.go b/pkg/auth/auth_test.go index f149c36..228b2b6 100644 --- a/pkg/auth/auth_test.go +++ b/pkg/auth/auth_test.go @@ -238,6 +238,9 @@ func TestKnownHosts(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + t.Setenv("GH_CONFIG_DIR", "") + t.Setenv("GH_HOST", "") + t.Setenv("GH_TOKEN", "") if tt.ghHost != "" { t.Setenv("GH_HOST", tt.ghHost) } diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index 01cb61b..5d1ef95 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -41,6 +41,7 @@ func TestConfigDir(t *testing.T) { { name: "XDG_CONFIG_HOME specified", env: map[string]string{ + "GH_CONFIG_DIR": "", "XDG_CONFIG_HOME": tempDir, }, output: filepath.Join(tempDir, "gh"), @@ -57,7 +58,8 @@ func TestConfigDir(t *testing.T) { name: "AppData specified", onlyWindows: true, env: map[string]string{ - "AppData": tempDir, + "GH_CONFIG_DIR": "", + "AppData": tempDir, }, output: filepath.Join(tempDir, "GitHub CLI"), }, @@ -74,6 +76,7 @@ func TestConfigDir(t *testing.T) { name: "XDG_CONFIG_HOME and AppData specified", onlyWindows: true, env: map[string]string{ + "GH_CONFIG_DIR": "", "XDG_CONFIG_HOME": tempDir, "AppData": tempDir, }, @@ -170,6 +173,7 @@ func TestDataDir(t *testing.T) { { name: "HOME/USERPROFILE specified", env: map[string]string{ + "GH_DATA_DIR": "", "XDG_DATA_HOME": "", "GH_CONFIG_DIR": "", "XDG_CONFIG_HOME": "", @@ -182,6 +186,7 @@ func TestDataDir(t *testing.T) { { name: "XDG_DATA_HOME specified", env: map[string]string{ + "GH_DATA_DIR": "", "XDG_DATA_HOME": tempDir, }, output: filepath.Join(tempDir, "gh"), @@ -190,6 +195,7 @@ func TestDataDir(t *testing.T) { name: "LocalAppData specified", onlyWindows: true, env: map[string]string{ + "GH_DATA_DIR": "", "LocalAppData": tempDir, }, output: filepath.Join(tempDir, "GitHub CLI"), @@ -198,6 +204,7 @@ func TestDataDir(t *testing.T) { name: "XDG_DATA_HOME and LocalAppData specified", onlyWindows: true, env: map[string]string{ + "GH_DATA_DIR": "", "XDG_DATA_HOME": tempDir, "LocalAppData": tempDir, }, From dabd0d4674edd1c7db063661a8feac9a3d923804 Mon Sep 17 00:00:00 2001 From: Amaan Qureshi Date: Sun, 25 Jan 2026 15:49:54 -0500 Subject: [PATCH 2/2] config: allow overriding data directory via GH_DATA_DIR MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for GH_DATA_DIR environment variable to customize the data directory location, mirroring GH_CONFIG_DIR for config. Data path precedence: GH_DATA_DIR → XDG_DATA_HOME → LocalAppData → HOME This enables system-wide configuration on NixOS and other declarative systems where config may be read-only in /etc/gh but data (extensions, etc.) needs a separate writable location. --- pkg/config/config.go | 17 ++++++++++------- pkg/config/config_test.go | 15 +++++++++++++++ 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/pkg/config/config.go b/pkg/config/config.go index 9789a06..a4ec2af 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -17,6 +17,7 @@ import ( const ( appData = "AppData" ghConfigDir = "GH_CONFIG_DIR" + ghDataDir = "GH_DATA_DIR" localAppData = "LocalAppData" xdgConfigHome = "XDG_CONFIG_HOME" xdgDataHome = "XDG_DATA_HOME" @@ -280,16 +281,18 @@ func StateDir() string { // DataDir returns the path to the data directory. // -// Data path precedence: XDG_DATA_HOME, LocalAppData (windows only), HOME. +// Data path precedence: GH_DATA_DIR, XDG_DATA_HOME, LocalAppData (windows only), HOME. func DataDir() string { var path string - if a := os.Getenv(xdgDataHome); a != "" { - path = filepath.Join(a, "gh") - } else if b := os.Getenv(localAppData); runtime.GOOS == "windows" && b != "" { - path = filepath.Join(b, "GitHub CLI") + if a := os.Getenv(ghDataDir); a != "" { + path = a + } else if b := os.Getenv(xdgDataHome); b != "" { + path = filepath.Join(b, "gh") + } else if c := os.Getenv(localAppData); runtime.GOOS == "windows" && c != "" { + path = filepath.Join(c, "GitHub CLI") } else { - c, _ := os.UserHomeDir() - path = filepath.Join(c, ".local", "share", "gh") + d, _ := os.UserHomeDir() + path = filepath.Join(d, ".local", "share", "gh") } return path } diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index 5d1ef95..f2d01b3 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -210,6 +210,21 @@ func TestDataDir(t *testing.T) { }, output: filepath.Join(tempDir, "gh"), }, + { + name: "GH_DATA_DIR specified", + env: map[string]string{ + "GH_DATA_DIR": filepath.Join(tempDir, "gh_data_dir"), + }, + output: filepath.Join(tempDir, "gh_data_dir"), + }, + { + name: "GH_DATA_DIR and XDG_DATA_HOME specified", + env: map[string]string{ + "GH_DATA_DIR": filepath.Join(tempDir, "gh_data_dir"), + "XDG_DATA_HOME": tempDir, + }, + output: filepath.Join(tempDir, "gh_data_dir"), + }, } for _, tt := range tests {