Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions templates/cli/internal/app/install.go.twig
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"runtime"
"strings"

"github.com/{{ sdk.gitUserName }}/{{ sdk.gitRepoName | caseDash }}/internal/config"
"github.com/{{ sdk.gitUserName }}/{{ sdk.gitRepoName | caseDash }}/internal/update"
)

Expand Down Expand Up @@ -165,7 +166,7 @@ func UpdateChecker() *update.Checker {
return nil
}

home, err := os.UserHomeDir()
directory, err := config.GlobalDirectory(ExecutableName)
if err != nil {
return nil
}
Expand All @@ -174,7 +175,7 @@ func UpdateChecker() *update.Checker {
RegistryURL: NPMRegistryURL,
PrereleaseRegistryURL: NPMPrereleaseRegistryURL,
// Beside the preferences, which is already the directory this CLI owns.
CachePath: filepath.Join(home, "."+ExecutableName, "update-check.json"),
CachePath: filepath.Join(directory, "update-check.json"),
Current: Version,
}
}
1 change: 1 addition & 0 deletions templates/cli/internal/cmd/completion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ func setHome(t *testing.T) string {
home := t.TempDir()
t.Setenv("HOME", home)
t.Setenv("USERPROFILE", home)
t.Setenv("XDG_CONFIG_HOME", "")

return home
}
Expand Down
1 change: 1 addition & 0 deletions templates/cli/internal/cmd/fanout_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ func TestAllSubcommandsNeverPrompt(t *testing.T) {
home := t.TempDir()
t.Setenv("HOME", home)
t.Setenv("USERPROFILE", home)
t.Setenv("XDG_CONFIG_HOME", "")
inDirectory(t, t.TempDir())

root := NewRootCommand()
Expand Down
1 change: 1 addition & 0 deletions templates/cli/internal/cmd/generate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ func TestGenerateEndpointFallsBackToTheDefault(t *testing.T) {
home := t.TempDir()
t.Setenv("HOME", home)
t.Setenv("USERPROFILE", home)
t.Setenv("XDG_CONFIG_HOME", "")

if got := resolveGenerateEndpoint(""); got != config.DefaultEndpoint {
t.Errorf("endpoint = %q, want %q", got, config.DefaultEndpoint)
Expand Down
90 changes: 90 additions & 0 deletions templates/cli/internal/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -394,3 +394,93 @@ func TestMigrateLegacySessionIgnoresAPartialOrModernFile(t *testing.T) {
})
}
}

func TestGlobalPathFollowsXDGConfigHome(t *testing.T) {
cases := []struct {
name string
legacy bool
missing bool
xdg func(home string) string
want func(home, xdg string) string
}{
{
name: "existing home directory wins over XDG",
legacy: true,
xdg: func(home string) string { return filepath.Join(home, "xdg") },
want: func(home, _ string) string { return filepath.Join(home, ".appwrite", "prefs.json") },
},
{
name: "absolute XDG_CONFIG_HOME",
xdg: func(home string) string { return filepath.Join(home, "xdg") },
want: func(_, xdg string) string { return filepath.Join(xdg, "appwrite", "prefs.json") },
},
{
name: "missing XDG_CONFIG_HOME directory",
missing: true,
xdg: func(home string) string { return filepath.Join(home, "xdg") },
want: func(_, xdg string) string { return filepath.Join(xdg, "appwrite", "prefs.json") },
},
{
name: "unset XDG_CONFIG_HOME",
xdg: func(string) string { return "" },
want: func(home, _ string) string { return filepath.Join(home, ".appwrite", "prefs.json") },
},
{
name: "relative XDG_CONFIG_HOME",
xdg: func(string) string { return filepath.Join("relative", "config") },
want: func(home, _ string) string { return filepath.Join(home, ".appwrite", "prefs.json") },
},
}

for _, test := range cases {
t.Run(test.name, func(t *testing.T) {
home := t.TempDir()
t.Setenv("HOME", home)
t.Setenv("USERPROFILE", home)
xdg := test.xdg(home)
t.Setenv("XDG_CONFIG_HOME", xdg)

if filepath.IsAbs(xdg) && !test.missing {
if err := os.MkdirAll(xdg, 0o700); err != nil {
t.Fatal(err)
}
}
if test.legacy {
if err := os.MkdirAll(filepath.Join(home, ".appwrite"), 0o700); err != nil {
t.Fatal(err)
}
}

got, err := GlobalPath("appwrite")
if err != nil {
t.Fatal(err)
}
if want := test.want(home, xdg); got != want {
t.Errorf("GlobalPath = %q, want %q", got, want)
}
})
}
}

func TestGlobalWriteCreatesTheXDGDirectory(t *testing.T) {
home := t.TempDir()
xdg := filepath.Join(t.TempDir(), "config")
t.Setenv("HOME", home)
t.Setenv("USERPROFILE", home)
t.Setenv("XDG_CONFIG_HOME", xdg)

path, err := GlobalPath("appwrite")
if err != nil {
t.Fatal(err)
}
if err := LoadGlobal(path).Write(); err != nil {
t.Fatal(err)
}

if _, err := os.Stat(filepath.Join(xdg, "appwrite", "prefs.json")); err != nil {
t.Errorf("prefs.json was not written under XDG_CONFIG_HOME: %v", err)
}
if _, err := os.Stat(filepath.Join(home, ".appwrite")); !os.IsNotExist(err) {
t.Errorf("the home directory was created alongside XDG_CONFIG_HOME: %v", err)
}
}
22 changes: 20 additions & 2 deletions templates/cli/internal/config/global.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ var ignoredAttributes = map[string]bool{
PreferenceClientID: true,
}

// Global is the user-level preferences file, `~/.appwrite/prefs.json`.
// Global is the user-level preferences file, `prefs.json` in GlobalDirectory.
type Global struct {
path string
data *Object
Expand All @@ -67,12 +67,30 @@ type Session struct {

// GlobalPath returns the default preferences path for the current user.
func GlobalPath(executableName string) (string, error) {
directory, err := GlobalDirectory(executableName)
if err != nil {
return "", err
}

return filepath.Join(directory, "prefs.json"), nil
}

func GlobalDirectory(executableName string) (string, error) {
home, err := homeDir()
if err != nil {
return "", err
}

return filepath.Join(home, "."+executableName, "prefs.json"), nil
legacy := filepath.Join(home, "."+executableName)
if info, err := os.Stat(legacy); err == nil && info.IsDir() {
return legacy, nil
}

if xdg := os.Getenv("XDG_CONFIG_HOME"); filepath.IsAbs(xdg) {
return filepath.Join(xdg, executableName), nil
}

return legacy, nil
}

// LoadGlobal reads the preferences file. A missing or unparseable file yields
Expand Down
1 change: 1 addition & 0 deletions tests/e2e/languages/cli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ func (h *harness) command(args ...string) *exec.Cmd {
command.Env = append(os.Environ(),
"HOME="+h.home,
"USERPROFILE="+h.home,
"XDG_CONFIG_HOME="+filepath.Join(h.home, ".config"),
)

return command
Expand Down
Loading