Skip to content

Commit 12e34bf

Browse files
authored
fix(mnq): fix XDG_CONFIG_HOME compliance in NATS context directory (#5206)
1 parent bed543b commit 12e34bf

File tree

4 files changed

+339
-36
lines changed

4 files changed

+339
-36
lines changed

internal/namespaces/mnq/v1beta1/custom_nats_helpers.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ func writeFile(
8585

8686
func getNATSContextDir(ctx context.Context) (string, error) {
8787
xdgConfigHome := core.ExtractEnv(ctx, "XDG_CONFIG_HOME")
88-
interactive.Println("xdgConfigHome:", xdgConfigHome)
8988
if xdgConfigHome == "" {
9089
homeDir := core.ExtractEnv(ctx, "HOME")
9190
if homeDir == "" {
@@ -95,7 +94,7 @@ func getNATSContextDir(ctx context.Context) (string, error) {
9594
return filepath.Join(homeDir, ".config", "nats", "context"), nil
9695
}
9796

98-
return xdgConfigHome, nil
97+
return filepath.Join(xdgConfigHome, "nats", "context"), nil
9998
}
10099

101100
func saveNATSCredentials(

internal/namespaces/mnq/v1beta1/custom_nats_test.go

Lines changed: 127 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package mnq_test
22

33
import (
44
"os"
5+
"path/filepath"
56
"reflect"
67
"regexp"
78
"testing"
@@ -31,43 +32,11 @@ func Test_CreateContext(t *testing.T) {
3132
Replacement: "Select context using `nats context select context-placeholder`",
3233
},
3334
),
34-
func(t *testing.T, ctx *core.CheckFuncCtx) {
35-
t.Helper()
36-
result, isSuccessResult := ctx.Result.(*core.SuccessResult)
37-
assert.True(
38-
t,
39-
isSuccessResult,
40-
"Expected result to be of type *core.SuccessResult, got %s",
41-
reflect.TypeOf(result).String(),
42-
)
43-
assert.NotNil(t, result)
44-
expectedContextFile := result.Resource
45-
if !mnq.FileExists(expectedContextFile) {
46-
t.Errorf(
47-
"Expected credentials file not found expected [%s] ",
48-
expectedContextFile,
49-
)
50-
} else {
51-
ctx.Meta["deleteFiles"] = []string{expectedContextFile}
52-
}
53-
},
35+
checkContextFile,
5436
),
5537
AfterFunc: core.AfterFuncCombine(
5638
deleteNATSAccount("NATS"),
57-
func(ctx *core.AfterFuncCtx) error {
58-
if ctx.Meta["deleteFiles"] == nil {
59-
return nil
60-
}
61-
filesToDelete := ctx.Meta["deleteFiles"].([]string)
62-
for _, file := range filesToDelete {
63-
err := os.Remove(file)
64-
if err != nil {
65-
t.Errorf("Failed to delete the file : %s", err)
66-
}
67-
}
68-
69-
return nil
70-
},
39+
afterFuncDeleteFiles,
7140
),
7241
}))
7342
}
@@ -106,3 +75,127 @@ func Test_CreateContextNoInteractiveTermAndMultiAccount(t *testing.T) {
10675
AfterFunc: core.AfterFuncCombine(deleteNATSAccount("NATS"), deleteNATSAccount("NATS2")),
10776
}))
10877
}
78+
79+
func beforeFuncCopyConfigToTmpHome() core.BeforeFunc {
80+
return core.BeforeFuncWhenUpdatingCassette(func(ctx *core.BeforeFuncCtx) error {
81+
realHomeDir, err := os.UserHomeDir()
82+
if err != nil {
83+
return err
84+
}
85+
86+
realConfigPath := filepath.Join(realHomeDir, ".config", "scw", "config.yaml")
87+
if _, err := os.Stat(realConfigPath); os.IsNotExist(err) {
88+
return nil
89+
}
90+
91+
tmpHomeDir := ctx.OverrideEnv["HOME"]
92+
tmpConfigDir := filepath.Join(tmpHomeDir, ".config", "scw")
93+
if err := os.MkdirAll(tmpConfigDir, 0o0755); err != nil {
94+
return err
95+
}
96+
97+
data, err := os.ReadFile(realConfigPath)
98+
if err != nil {
99+
return err
100+
}
101+
102+
return os.WriteFile(filepath.Join(tmpConfigDir, "config.yaml"), data, 0o644)
103+
})
104+
}
105+
106+
func checkContextFile(t *testing.T, ctx *core.CheckFuncCtx) {
107+
t.Helper()
108+
result, isSuccessResult := ctx.Result.(*core.SuccessResult)
109+
assert.True(
110+
t,
111+
isSuccessResult,
112+
"Expected result to be of type *core.SuccessResult, got %s",
113+
reflect.TypeOf(result).String(),
114+
)
115+
assert.NotNil(t, result)
116+
expectedContextFile := result.Resource
117+
if !mnq.FileExists(expectedContextFile) {
118+
t.Errorf("Expected credentials file not found expected [%s]", expectedContextFile)
119+
} else {
120+
ctx.Meta["deleteFiles"] = []string{expectedContextFile}
121+
}
122+
}
123+
124+
func checkContextFileInXDGConfigHome(t *testing.T, ctx *core.CheckFuncCtx) {
125+
t.Helper()
126+
checkContextFile(t, ctx)
127+
128+
result := ctx.Result.(*core.SuccessResult)
129+
expectedContextFile := result.Resource
130+
xdgConfigHome := ctx.OverrideEnv["XDG_CONFIG_HOME"]
131+
tmpHomeDir := ctx.OverrideEnv["HOME"]
132+
133+
expectedContextDir := filepath.Join(xdgConfigHome, "nats", "context")
134+
assert.Contains(
135+
t,
136+
expectedContextFile,
137+
expectedContextDir,
138+
"Context file should be in XDG_CONFIG_HOME/nats/context, got: %s",
139+
expectedContextFile,
140+
)
141+
142+
tmpHomeNatsDir := filepath.Join(tmpHomeDir, ".config", "nats", "context")
143+
_, err := os.Stat(tmpHomeNatsDir)
144+
assert.True(
145+
t,
146+
os.IsNotExist(err),
147+
"Files should not be created in HOME/.config/nats/context when XDG_CONFIG_HOME is set: %s",
148+
tmpHomeNatsDir,
149+
)
150+
}
151+
152+
func afterFuncDeleteFiles(ctx *core.AfterFuncCtx) error {
153+
if ctx.Meta["deleteFiles"] == nil {
154+
return nil
155+
}
156+
filesToDelete := ctx.Meta["deleteFiles"].([]string)
157+
for _, file := range filesToDelete {
158+
if err := os.Remove(file); err != nil {
159+
return err
160+
}
161+
}
162+
163+
return nil
164+
}
165+
166+
func Test_CreateContextWithXDGConfigHome(t *testing.T) {
167+
xdgConfigHomeDir := t.TempDir()
168+
169+
t.Run("XDG_CONFIG_HOME compliance", core.Test(&core.TestConfig{
170+
Commands: mnq.GetCommands(),
171+
BeforeFunc: core.BeforeFuncCombine(
172+
beforeFuncCopyConfigToTmpHome(),
173+
createNATSAccount("NATS"),
174+
),
175+
Cmd: "scw mnq nats create-context nats-account-id={{ .NATS.ID }}",
176+
TmpHomeDir: true,
177+
OverrideEnv: map[string]string{
178+
"XDG_CONFIG_HOME": xdgConfigHomeDir,
179+
},
180+
Check: core.TestCheckCombine(
181+
core.TestCheckExitCode(0),
182+
core.TestCheckGoldenAndReplacePatterns(
183+
core.GoldenReplacement{
184+
Pattern: regexp.MustCompile(`cli[\w-]*creds[\w-]*`),
185+
Replacement: "credential-placeholder",
186+
},
187+
core.GoldenReplacement{
188+
Pattern: regexp.MustCompile(
189+
"(Select context using `nats context select )cli[\\w-]*`",
190+
),
191+
Replacement: "Select context using `nats context select context-placeholder`",
192+
},
193+
),
194+
checkContextFileInXDGConfigHome,
195+
),
196+
AfterFunc: core.AfterFuncCombine(
197+
deleteNATSAccount("NATS"),
198+
afterFuncDeleteFiles,
199+
),
200+
}))
201+
}

0 commit comments

Comments
 (0)