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
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2025 beatinaniwa
Copyright (c) 2026 beatinaniwa

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
17 changes: 8 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,15 +189,14 @@ mf journals create --json '{"..."}' --dry-run

### 設定ファイル

設定ファイルの保存場所は OS の `UserConfigDir` に基づきます:

| OS | パス |
|----|------|
| macOS | `~/Library/Application Support/mf-cli/` |
| Linux | `~/.config/mf-cli/` |
| Windows | `%AppData%\mf-cli\` |

`MF_CONFIG_DIR` 環境変数でオーバーライドできます。
設定ファイルの保存場所は [XDG Base Directory](https://specifications.freedesktop.org/basedir-spec/latest/) に準拠します:

| 条件 | パス |
|------|------|
| `MF_CONFIG_DIR` 設定時 | `$MF_CONFIG_DIR/` |
| `XDG_CONFIG_HOME` 設定時 | `$XDG_CONFIG_HOME/mf-cli/` |
| デフォルト(macOS/Linux) | `~/.config/mf-cli/` |
| デフォルト(Windows) | `%AppData%\mf-cli\` |

#### config.json

Expand Down
15 changes: 13 additions & 2 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"os"
"path/filepath"
"runtime"
"strconv"
)

Expand Down Expand Up @@ -73,9 +74,19 @@ func resolveConfigDir() (string, error) {
if v := os.Getenv("MF_CONFIG_DIR"); v != "" {
return v, nil
}
base, err := os.UserConfigDir()
if runtime.GOOS == "windows" {
base, err := os.UserConfigDir()
if err != nil {
return "", err
}
return filepath.Join(base, "mf-cli"), nil
}
if v := os.Getenv("XDG_CONFIG_HOME"); v != "" && filepath.IsAbs(v) {
return filepath.Join(v, "mf-cli"), nil
}
home, err := os.UserHomeDir()
if err != nil {
return "", err
}
return filepath.Join(base, "mf-cli"), nil
return filepath.Join(home, ".config", "mf-cli"), nil
}
58 changes: 58 additions & 0 deletions internal/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"os"
"path/filepath"
"runtime"
"testing"
)

Expand Down Expand Up @@ -141,6 +142,63 @@ func TestLoad_InvalidJSON(t *testing.T) {
}
}

func TestResolveConfigDir_XDGConfigHome(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("Windows does not recognise /custom/xdg as absolute")
}
t.Setenv("MF_CONFIG_DIR", "")
t.Setenv("XDG_CONFIG_HOME", "/custom/xdg")

dir, err := resolveConfigDir()
if err != nil {
t.Fatalf("resolveConfigDir() returned error: %v", err)
}
want := filepath.Join("/custom/xdg", "mf-cli")
if dir != want {
t.Errorf("resolveConfigDir() = %q, want %q", dir, want)
}
}

func TestResolveConfigDir_DefaultFallback(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("default fallback on Windows uses AppData, not ~/.config")
}
tmpHome := t.TempDir()
t.Setenv("HOME", tmpHome)
t.Setenv("MF_CONFIG_DIR", "")
t.Setenv("XDG_CONFIG_HOME", "")

dir, err := resolveConfigDir()
if err != nil {
t.Fatalf("resolveConfigDir() returned error: %v", err)
}

want := filepath.Join(tmpHome, ".config", "mf-cli")
if dir != want {
t.Errorf("resolveConfigDir() = %q, want %q", dir, want)
}
}

func TestResolveConfigDir_RelativeXDGIgnored(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("XDG fallback test not applicable on Windows")
}
tmpHome := t.TempDir()
t.Setenv("HOME", tmpHome)
t.Setenv("MF_CONFIG_DIR", "")
t.Setenv("XDG_CONFIG_HOME", "relative/path")

dir, err := resolveConfigDir()
if err != nil {
t.Fatalf("resolveConfigDir() returned error: %v", err)
}

want := filepath.Join(tmpHome, ".config", "mf-cli")
if dir != want {
t.Errorf("resolveConfigDir() = %q, want %q (relative XDG_CONFIG_HOME should be ignored)", dir, want)
}
}

func TestRequireClientID_Empty(t *testing.T) {
cfg := &Config{ClientID: ""}
if err := cfg.RequireClientID(); err == nil {
Expand Down
Loading