世界を動かす技術を、日本語で。

macOSのドットファイルは–/Library/Application Supportに入れるべきではない

概要

  • macOSのCLIツールが ~/Library/Application Support に設定ファイルを置く問題提起
  • 本来は XDG Base Directory Specification (~/.config)を使うべきという主張
  • 多くの人気ライブラリが誤ったデフォルトパスを採用
  • dotfileマネージャ も~/Library/Application Supportを無視
  • Apple自身のCLIツールも ~/.config を利用

macOS CLIツールの設定ファイル配置問題

  • macOSでCLIツールが ~/Library/Application Support に設定ファイルを置く事例増加
  • この挙動は ユーザー体験が悪い だけでなく、公式ドキュメントの意図とも異なる
  • 本来、CLIツールは XDG Base Directory Specification に従い、 $XDG_CONFIG_HOME (デフォルトは~/.config)を使うべき
  • ~/Library/Application Support に設定ファイルを置くのは、設計というより ライブラリのデフォルト挙動 に依存した結果
    • Pythonの platformdirs、JavaScriptの env-paths、Rustの dirs crate、Goの adrg/xdg などが該当
  • GUIアプリには適切だが、CLIツールの大半は ~/.config に置くべき

予想外の挙動とユーザー体験

  • 設定ファイルが ~/Library/Application Support にあるのは予期しない挙動
  • 多くのユーザーが XDG仕様 に慣れており、CLIツールにもそれを期待
  • Git, Emacs, Neovim, Tmux など多くのツールがXDG仕様を採用
  • 一貫性があることで システム探索性・予測性向上
  • 例外的な挙動はユーザーの 混乱と不満 を招く

dotfileマネージャの実態

  • 有名なdotfileマネージャ( chezmoi, dotbot, yadm, rcm, GNU Stow)も ~/Library/Application Support を無視
    • 明示的に指定すれば可能だが、デフォルトでは対応しない
  • dotfile管理の目的は 複数環境間での設定ファイルの一元管理
  • ほとんどのユーザーは ~/.config に設定ファイルを期待

macOS標準ディレクトリガイドラインの誤解

  • 一部開発者が「macOS標準ディレクトリガイドライン」に従うべきと主張
  • しかし、ガイドラインは アプリ(/ApplicationsにインストールされるGUIアプリ) 向け
  • CLIツール はアプリとは定義が異なる
    • バンドルIDやアイコン、サンドボックス要件等が必要
  • ガイドライン内でも /bin はCLIバイナリ用と明記
  • ~/Library/Application Support はアプリ専用ディレクトリ
    • サブディレクトリ名もバンドルID準拠
  • CLIツールは バンドルIDを持たない ため該当しない
  • Apple自身のCLIツール( bash, zsh, git, vim)も ~/.config を利用

~/Library/Application Supportを使うべきケース

  • 以下の2条件を満たす場合のみ ~/Library/Application Support を利用
    • /Applicationsまたは~/ApplicationsにインストールされたGUIアプリ
    • 設定ファイルを自動管理し、ユーザーが手動で編集しない場合

まとめ(TL;DR)

  • CLIツールが ~/Library/Application Support で設定ファイルを探すのは ユーザーの期待外れ
  • dotfileマネージャもこのディレクトリを デフォルトで無視
  • よくある正当化理由も CLIツールには当てはまらない
  • Apple純正CLIツールも ~/.config を利用
  • XDG Base Directory Specification の採用を強く推奨

Hackerたちの意見

私や他の人たちがdirs Rustクレートのメンテナーにこのことを指摘したけど、彼らはそうは考えてくれないんだよね。ほんとイライラする。今はxdgとknown-foldersを手動で組み合わせて使ってるよ。設定ディレクトリを取得するために、こんな感じで書いてる:[target.'cfg(windows)'.dependencies] known-folders = "1.2.0" [target.'cfg(not(windows))'.dependencies] xdg = "2.5.2" use anyhow::{Context, Result}; #[cfg(windows)] fn get_config_base_dir() -> Result { use known_folders::{KnownFolder, get_known_folder_path}; get_known_folder_path(KnownFolder::RoamingAppData).context("設定ディレクトリを取得できませんでした") } #[cfg(not(windows))] fn get_config_base_dir() -> Result { let base_dirs = xdg::BaseDirectories::new().context("設定ディレクトリを取得できませんでした")?; Ok(base_dirs.get_config_home()) }

Rust界隈には二つのクレートが必要だと思う。@socの回答はアプリに関しては納得できるけど、記事が言ってる通り、多くの(ほとんどの?)Rustプログラムを作ってる人たちはアプリを作ってるわけじゃないから、このクレートを使うべきじゃないと思う。これは明らかにMacOSの「アプリ」だけをサポートしてるからね。

彼らはそうは考えてくれないんだよね だから、アプリ開発の長期的な未来はコンテナなんだ。人間的なレベルで、共通の利益のために人々を動かすのは無理だよ。https://specifications.freedesktop.org/basedir-spec/latest/ を考えてみて。XDG仕様は22年前からある。ユーザーにとって本当にメリットがあるし、実装も簡単なのに、2025年になってもTypeScriptの開発者たちが「これが『クソ』に従うのは難しすぎる」って文句言って、$HOMEにファイルを置くのを続けてるのを見ると、もう技術的な調整問題を人間の善意に訴えて解決するのは諦めたよ。唯一効果的なのは、アプリケーションをできるだけ厳しくサンドボックス化して、外部世界へのアクセスを狭いインターフェースを通じて制限することなんだ。

前の記憶からすると、これに関してはほとんどすべてのRustクレートで問題があると思う。これを解決する正しい方法は、仕様を修正して、ライブラリがその仕様に従うようにすることだよ。

なんであのsocってやつはそんなに怒ってて失礼なの?

アプリを作ってるわけじゃなくて、CLIツールだけど、CLIツールもアプリケーションだよね。

そろそろ、ルールにちゃんと従ったdirs-rsのフォークを作る時期かな。dirs-rsを使ってるライブラリは、そういうことを考えたくないから使ってるんだろうし。もし正しくやってるライブラリがあれば、シンプルなクレートの置き換えなら、きっと良い採用がされると思うよ。

etceteraのデフォルト設定の方が良さそうだね。https://docs.rs/etcetera/latest/etcetera/#native-strategy > choose_base_strategy()choose_app_strategy()は、LinuxとmacOSではXDG戦略を、WindowsではWindows戦略を使うんだ。これって、ほとんどのCLIツールや一部のGUIツールで使われてるよ。

Goの標準ライブラリも~/Library/Application Supportを使ってるよね[1]。Golangのトップの人たちのUnixの経歴を考えると、この決定には良い理由があると思うんだけど?[1] https://pkg.go.dev/os#UserConfigDir

UNIX、Plan 9、Infernoは、macOSと全く同じではないよ。たとえmacOSが認定されたUNIXでもね。POSIXが存在するのは、UNIX System Vから、すべてのクローンがそれぞれの道を進んだからなんだ。

あなたのバイナリが/Applicationsに置くべきなら、設定は~/Application Supportに置いてもいいよ。もし/binとかその辺にあるなら、またはデフォルトやシステム全体の設定が/etcに行くなら、設定は~/.configに置くべきだね。

同意!でも、ほとんど無意味だね。一般的に、単一のバイナリのCLIユーティリティは/Applicationsに置くべきじゃない。あのフォルダは.app拡張子のアプリバンドル用で、Info.plistファイルとかが入ってる。シェルで使われるPATHにも含まれてないし(デフォルトではね)。例外は、アプリバンドルに補助的なCLIユーティリティが含まれていて、それが/ApplicationsのアプリバンドルからPATHにシンボリックリンクされる場合かな。例えば、VSCodeのcode CLIツールみたいに。基本的に、純粋なCLIバイナリは/Applicationsには絶対に入らないと思うよ。

https://uapi-group.org/specifications/specs/configuration_fi... が好きだな。デフォルトは/usr/に置くべきだよ。これはパッケージ開発者やメンテナの領域だ。システム全体のオーバーライドは/etc/に置くべきで、これはシステム管理者の権限だ。重要なのは、> プログラムは/etc/に設定ファイルが見つからない場合でも正しく動作しなければならない。ユーザー特有のオーバーライドはXDG_CONFIG_HOMEに置くべきで、~/.config/にフォールバックするべきだ。

TFAの終わりの方で、Appleのバンドルされたコマンドラインユーティリティ、つまりzshやvimが、ドットファイルを~/.configに置くって言ってるけど、実際はそうじゃないんだよね。伝統的なBSDの場所、ユーザーのホームディレクトリ~/.に置かれるんだ。今自分の見てみたら、.bash_login、.emacs(おお!古いね)、.lldb、.lldbinit、.vimrc、.swiftpm、.z{profile,env,rc}とかいくつかあって、~/.configディレクトリは見当たらない。macOS用のコマンドラインユーティリティを書くときは、macOS APIを使って設定(昔は「preferences」と呼ばれてた)を~/Library/Preferencesに書くようにしてるんだ。そうすれば、GUI版とも連携できるし、ユーティリティ自体にも設定を制御するコマンドラインオプションを持たせられるからね。兄弟コメントが指摘してるように、名前空間の衝突を避ける必要があるよね。逆DNS名を使ったり、企業名をそのまま使ったりするのがいいかも。これらは.plistファイルとして現れるけど、実際にはデーモンによって管理されてるから、複数のプロセスが設定を更新する際のレース問題をうまく回避できるんだ。もしドキュメント化されたフォーマットのドットファイルを持つポータブルユーティリティを書くなら、ホームディレクトリの下にドットファイルを置くかな。~/Library/Application Supportは、ユーザーごとの静的データ、プリセットやテンプレートみたいなものにもっと適してると思う。GUIではダイアログの文字列で知られてるけど、ユーザーがファイルとして考えるわけではないものだね。

macOS用のコマンドラインユーティリティを書くときは、macOS APIを使って設定(昔は「preferences」と呼ばれてた)を~/Library/Preferencesに書くようにしてる。これは、基本的に設定の編集はCLIツール自体で行わなきゃならないってことになるのかな?macOSのpreferencesは、ユーザーが直接編集することを想定してないからね。それは、ここで話してる設定とは全然違うカテゴリのように感じる。でも、確かに便利な機能を提供してるよね。

XDGはLinux中心の仕様だよね。もし私たちがOSに依存しないものを望むなら、それを検証して設計しなきゃならない。今のところ、macOSのアプリがXDGを採用する理由が見当たらないな、たとえそれが私の好みでも。

記事から、> 他のところで、Reilly Woodが「Application Supportを使わないことにデメリットはあるのか?」と聞いてきたユーザーに対して、「[Nushellは] macOSの標準ディレクトリガイドラインに従わなくなる」と返してる。> そのガイドラインをすぐに見てみるけど、そもそもそれが関係あるのかはっきりしないな。XDGベースディレクトリ仕様書にはUnixが何度か言及されてるけど、macOSや他のOSに対する特例は書かれてない。もし~/.configがUnix系OSの設定ファイルの標準位置として受け入れられているなら、macOSもBSD経由でUnixだから、当然標準位置になるはずだよね。> でも、XDG仕様が一部のUnix系OSにしか適用されないと認めると仮定しよう。macOSの標準ディレクトリのドキュメントは「[システムが提供するか、アプリが作成するかに関わらず、すべてのファイルにはmacOSにおける場所がある]」と始まっていて、正直そこで読み終わってもいいくらいだ。だって、コマンドラインツールはシステムでもアプリでもないから。

反対派に入るかな。XDG仕様はXウィンドウシステム向けのもので、Macには合わないから、採用する理由にはならないと思う。著者はユーザーの期待を主張してるけど、証拠がない。ちなみに、私の期待とは違うよ。1995年から2005年くらいまでLinuxとSolarisを広く使ってて、Mac OS Xのパブリックベータ以来、ターミナルを使ってるMacユーザーだから。正直、CLIプログラムは好き勝手にやるもので、.configなんて聞いたこともない。一般的に、設定ファイルとアプリケーションデータはホームディレクトリのルートに置かれると思ってる。ファイルが複数ある場合は、サブディレクトリに入ってるのが理想かな。選べるなら、アプリケーションデータ(アプリが自分用に書いたファイル)は~/Library/Application Supportに置いてほしい。そこが期待する場所だから。手動で編集する設定については、あまり自信がないけど。多分、ホームディレクトリのルートがいいかな。そうすれば、調べなくても簡単に見つけられるし。

“~/Library/Application Supportには入れるべきじゃない”には同意だけど、なんで誰もそこに置くの?Macのやり方は~/Library/Preferencesか、システム全体の/Library/Preferences、そしてNSDefaultsの使用だよ。https://developer.apple.com/library/archive/documentation/Fi...: 「このディレクトリにはアプリ特有の設定ファイルが含まれています。このディレクトリに自分でファイルを作成するべきではありません。代わりに、NSUserDefaultsクラスやCFPreferences APIを使って、アプリの設定値を取得したり設定したりしてください。iOSでは、このディレクトリの内容はiTunesやiCloudによってバックアップされます。」もしツールがNSDefaultsを使いたくないなら、~/.configを使う方が、ユーザーのホームディレクトリを汚すよりはずっと好ましいと思うよ。

macOSのドットファイル用のXDGディレクトリは、俺のこだわりなんだ。さらに面白くするために、俺の$HOMEディレクトリは不変なんだよ:chflags uchg "${HOME}"(単に読み取り専用に設定するだけでもいいけどね)。$HOMEに任意の書き込みを防ぐと色々と問題が起きるけど、実際にはかなり稀なんだ。これをドキュメントにまとめるべきかな。いや、むしろこの狂気は自分だけのものにしておいた方がいいかも…

いや、もっと書いた方がいいと思うよ。動機とか、$HOMEにファイルを書いたり修正したりする必要があるプログラムやスクリプトについてはどうするの?稀だって言うけど、本当にそうなの?それに、二つのプログラム間で通信したい時はどうするの?お前の好みのIPCの方法は?俺も同じことをLinuxでやったら、どれくらい動くかチェックしてみるよ。:D ちなみに、俺はfirejailを使ってるから、アプリは$HOME内で何も実行できないし、一時的に(へへ)tmpfsをマウントしてる(別々のオプションでね)。

正直、ホームディレクトリを使わなければなんとかなると思ってる。vscodeみたいなアプリがホームディレクトリの汚染に対する代替手段を提供しないのは辛い。これってvscodeに影響するのかな?時間があれば詳しく教えてほしいな。

何十年もMacを使ってるけど、~/.configに何かが現れると、なんか適応できてないポートって感じがする。Windowsで実際には隠れてない.dotfilesを見るのと似た感覚だね。ああ、彼らは全然気にしてないんだなって。macOSのデスクトップのどの部分もXDG標準を使ってないし、POSIX標準でもないし、OSが受け入れてる標準でもない。これに従うのは、他人のカスタムを適用してるだけだよ。でも、別のコメントでも言われてたけど、~/Library/PreferencesがmacOSではもっと正しい場所だと思う。

著者がXDGに従っていると言っているツールは、実際にはXDGに従ってないよ。macOSに付属しているデフォルトツールは、.configの下にファイルを置かないし、$HOMEにはドットファイルの山があるだけだ。 .configを使うツールは、すべて外部ソースから手動でインストールしたものだよ。XDG仕様はLinuxソフトウェアのユーザースペースを調整するためのもので、CLIアプリとウィンドウアプリの両方を含む。Linuxは標準と呼ばれるものが必要なんだ。なぜなら、Linusが自分でそれを書こうとしなかったからで、MicrosoftがデータはAppDataに入ると言ったり、AppleがデータはLibraryに入ると言ったりするようなことはないから。OS間でCLIツールの標準として認識するのは間違ってる。macOSでCLIツールがこれをやるのは、「これがmacOSの標準だ」と思ったからじゃなくて、「-target darwinでコンパイルエラーが出ないから、出荷しよう!」って思ったからで、Windowsでも全く意味がない場所を頻繁に使ってる。標準化された場所はLibraryだよ。それを期待しないのは自分の責任だし、期待すべきだよ。標準化された場所なんだから。今になってようやく、人々がそれに追いつき始めてるんだ。最低限のmacOS特有のコードで盲目的にポートするのではなく、dirsのようなライブラリのおかげで簡単になったから。