aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/mozart/src/commands/config_helpers.rs
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-02-23 01:23:40 +0900
committernsfisis <nsfisis@gmail.com>2026-02-23 01:23:40 +0900
commitc7a5859e1770dbc7cbc7cb1785c34b880162dfac (patch)
tree58081330c415776c9020771f12227889abcffa12 /crates/mozart/src/commands/config_helpers.rs
parent7372dc668476cde4bcb789e586cb9a65af1afca0 (diff)
downloadphp-mozart-c7a5859e1770dbc7cbc7cb1785c34b880162dfac.tar.gz
php-mozart-c7a5859e1770dbc7cbc7cb1785c34b880162dfac.tar.zst
php-mozart-c7a5859e1770dbc7cbc7cb1785c34b880162dfac.zip
fix(global): add ~/.composer fallback, XDG auto-detection, and no-arg handling
Rewrite composer_home() with Composer-compatible resolution: detect XDG environment (any XDG_* var or /etc/xdg), prefer existing directories, and fall back to ~/.composer for legacy systems. Consolidate duplicate composer_home_dir() from global.rs into shared config_helpers. Accept no subcommand gracefully with a helpful error instead of a parse error. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'crates/mozart/src/commands/config_helpers.rs')
-rw-r--r--crates/mozart/src/commands/config_helpers.rs60
1 files changed, 46 insertions, 14 deletions
diff --git a/crates/mozart/src/commands/config_helpers.rs b/crates/mozart/src/commands/config_helpers.rs
index 31792f4..fe5deb8 100644
--- a/crates/mozart/src/commands/config_helpers.rs
+++ b/crates/mozart/src/commands/config_helpers.rs
@@ -2,32 +2,64 @@ use anyhow::anyhow;
use std::path::{Path, PathBuf};
/// Return the Composer home directory, respecting `COMPOSER_HOME` and
-/// falling back to the platform default (`~/.config/composer` on Unix,
-/// `%APPDATA%/Composer` on Windows).
-pub(crate) fn composer_home() -> String {
- if let Ok(home) = std::env::var("COMPOSER_HOME") {
- return home;
+/// falling back to the platform default using Composer-compatible logic.
+///
+/// On Unix:
+/// - If XDG is in use (any `XDG_*` env var exists, or `/etc/xdg` exists),
+/// prefer `$XDG_CONFIG_HOME/composer` (or `$HOME/.config/composer`).
+/// - Always include `$HOME/.composer` as a fallback candidate.
+/// - Return the first candidate directory that exists on disk;
+/// if none exist, return the first candidate.
+pub(crate) fn composer_home() -> PathBuf {
+ if let Ok(val) = std::env::var("COMPOSER_HOME")
+ && !val.is_empty()
+ {
+ return PathBuf::from(val);
}
#[cfg(target_os = "windows")]
{
- std::env::var("APPDATA")
- .map(|p| format!("{p}/Composer"))
- .unwrap_or_else(|_| "C:/ProgramData/ComposerSetup/bin".to_string())
+ if let Ok(appdata) = std::env::var("APPDATA")
+ && !appdata.is_empty()
+ {
+ return PathBuf::from(appdata).join("Composer");
+ }
+ return PathBuf::from("C:/ProgramData/ComposerSetup/bin");
}
#[cfg(not(target_os = "windows"))]
{
- if let Ok(xdg) = std::env::var("XDG_CONFIG_HOME") {
- format!("{xdg}/composer")
- } else {
- std::env::var("HOME")
- .map(|h| format!("{h}/.config/composer"))
- .unwrap_or_else(|_| "/tmp/composer".to_string())
+ let home_dir = std::env::var("HOME")
+ .map(PathBuf::from)
+ .unwrap_or_else(|_| PathBuf::from("/tmp"));
+
+ let mut candidates: Vec<PathBuf> = Vec::new();
+
+ if use_xdg() {
+ let xdg_config = std::env::var("XDG_CONFIG_HOME")
+ .map(PathBuf::from)
+ .unwrap_or_else(|_| home_dir.join(".config"));
+ candidates.push(xdg_config.join("composer"));
}
+
+ candidates.push(home_dir.join(".composer"));
+
+ // Return first candidate that exists; otherwise return the first
+ candidates
+ .iter()
+ .find(|p| p.is_dir())
+ .cloned()
+ .unwrap_or_else(|| candidates.into_iter().next().unwrap())
}
}
+/// Check whether XDG base directories are in use:
+/// any env var starting with `XDG_` exists, OR `/etc/xdg` directory exists.
+fn use_xdg() -> bool {
+ std::env::vars().any(|(k, _)| k.starts_with("XDG_"))
+ || std::path::Path::new("/etc/xdg").is_dir()
+}
+
/// Build the working directory path, preferring `--working-dir` over `cwd`.
pub(crate) fn working_dir(cli: &super::Cli) -> anyhow::Result<PathBuf> {
match &cli.working_dir {