Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add XDG_CONFIG_HOME/.config to search of pixi global manifest path #2547

Merged
merged 12 commits into from
Nov 27, 2024
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ crossbeam-channel = { workspace = true }
csv = { workspace = true }
deno_task_shell = { workspace = true }
dialoguer = { workspace = true }
dirs = { workspace = true }
dunce = { workspace = true }
fancy_display = { workspace = true }
flate2 = { workspace = true }
Expand Down Expand Up @@ -255,7 +256,6 @@ uv-pep440 = { workspace = true }
uv-pep508 = { workspace = true }
uv-pypi-types = { workspace = true }

dirs = "5.0.1"
fs-err = { workspace = true, features = ["tokio"] }
pixi_build_frontend = { workspace = true }
pixi_build_types = { workspace = true }
Expand Down
10 changes: 2 additions & 8 deletions crates/pixi_config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ pub fn get_default_author() -> Option<(String, String)> {
/// # Returns
///
/// The pixi home directory
pub fn home_path() -> Option<PathBuf> {
pub fn pixi_home() -> Option<PathBuf> {
if let Some(path) = std::env::var_os("PIXI_HOME") {
Some(PathBuf::from(path))
} else {
Expand Down Expand Up @@ -1103,15 +1103,9 @@ pub fn config_path_system() -> PathBuf {

/// Returns the path(s) to the global pixi config file.
pub fn config_path_global() -> Vec<PathBuf> {
let xdg_config_home = std::env::var_os("XDG_CONFIG_HOME").map_or_else(
|| dirs::home_dir().map(|d| d.join(".config")),
|p| Some(PathBuf::from(p)),
);

vec![
xdg_config_home.map(|d| d.join("pixi").join(consts::CONFIG_FILE)),
dirs::config_dir().map(|d| d.join("pixi").join(consts::CONFIG_FILE)),
home_path().map(|d| d.join(consts::CONFIG_FILE)),
pixi_home().map(|d| d.join(consts::CONFIG_FILE)),
]
.into_iter()
.flatten()
Expand Down
31 changes: 19 additions & 12 deletions docs/features/global_tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,27 +88,34 @@ exposed = { py3 = "python" } # (2)!
### Manifest locations

The manifest can be found at the following locations depending on your operating system.
Run `pixi info`, to find the currently used manifest on your system.

=== "Linux"

| **Priority** | **Location** | **Comments** |
|--------------|------------------------------------------------------------------------|------------------------------------------------------------------------------------|
| 2 | `$PIXI_HOME/manifests/pixi-global.toml` | Global manifest in the user home directory. `PIXI_HOME` defaults to `~/.pixi` |
| 1 | `$HOME/.pixi/manifests/pixi-global.toml` | User-specific manifest |
| **Priority** | **Location** | **Comments** |
|--------------|----------------------------------------------------------|-----------------------------------------------|
| 4 | `$PIXI_HOME/manifests/pixi-global.toml` | Global manifest in `PIXI_HOME`. |
| 3 | `$HOME/.pixi/manifests/pixi-global.toml` | Global manifest in user home directory. |
| 2 | `$XDG_CONFIG_HOME/pixi/manifests/pixi-global.toml` | XDG compliant config directory. |
| 1 | `$HOME/.config/pixi/manifests/pixi-global.toml` | Config directory. |

=== "macOS"

| **Priority** | **Location** | **Comments** |
|--------------|------------------------------------------------------------------------|------------------------------------------------------------------------------------|
| 2 | `$PIXI_HOME/manifests/pixi-global.toml` | Global manifest in the user home directory. `PIXI_HOME` defaults to `~/.pixi` |
| 1 | `$HOME/.pixi/manifests/pixi-global.toml` | User-specific manifest |
| **Priority** | **Location** | **Comments** |
|--------------|----------------------------------------------------------|-----------------------------------------------|
| 3 | `$PIXI_HOME/manifests/pixi-global.toml` | Global manifest in `PIXI_HOME`. |
| 2 | `$HOME/.pixi/manifests/pixi-global.toml` | Global manifest in user home directory. |
| 1 | `$HOME/Library/Application Support/pixi/pixi-global.toml`| Config directory. |
Hofer-Julian marked this conversation as resolved.
Show resolved Hide resolved


=== "Windows"

| **Priority** | **Location** | **Comments** |
|--------------|------------------------------------------------------------------------|------------------------------------------------------------------------------------------------|
| 2 | `$PIXI_HOME\manifests/pixi-global.toml` | Global manifest in the user home directory. `PIXI_HOME` defaults to `%USERPROFILE%/.pixi` |
| 1 | `%USERPROFILE%\.pixi\manifests\pixi-global.toml` | User-specific manifest |
| **Priority** | **Location** | **Comments** |
|--------------|----------------------------------------------------------|-----------------------------------------------|
| 3 | `$PIXI_HOME\manifests/pixi-global.toml` | Global manifest in `PIXI_HOME`. |
| 2 | `%USERPROFILE%\.pixi\manifests\pixi-global.toml` | Global manifest in user home directory. |
| 1 | `%APPDATA%\pixi\pixi-global.toml` | Config directory. |
Hofer-Julian marked this conversation as resolved.
Show resolved Hide resolved


!!! note
If multiple locations exist, the manifest with the highest priority will be used.
Expand Down
48 changes: 25 additions & 23 deletions docs/reference/pixi_configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,37 @@ The configuration is loaded in the following order:

=== "Linux"

| **Priority** | **Location** | **Comments** |
|--------------|------------------------------------------------------------------------|------------------------------------------------------------------------------------|
| 6 | Command line arguments (`--tls-no-verify`, `--change-ps1=false`, etc.) | Configuration via command line arguments |
| 5 | `your_project/.pixi/config.toml` | Project-specific configuration |
| 4 | `$PIXI_HOME/config.toml` | Global configuration in the user home directory. `PIXI_HOME` defaults to `~/.pixi` |
| 3 | `$HOME/.config/pixi/config.toml` | User-specific configuration |
| 2 | `$XDG_CONFIG_HOME/pixi/config.toml` | XDG compliant user-specific configuration |
| 1 | `/etc/pixi/config.toml` | System-wide configuration |
| **Priority** | **Location** | **Comments** |
|--------------|------------------------------------------------------------------------|-------------------------------------------------------|
| 7 | Command line arguments (`--tls-no-verify`, `--change-ps1=false`, etc.) | Configuration via command line arguments |
| 6 | `your_project/.pixi/config.toml` | Project-specific configuration |
| 5 | `$PIXI_HOME/config.toml` | Global configuration in `PIXI_HOME`. |
| 4 | `$HOME/.pixi/config.toml` | Global configuration in the user home directory. |
| 3 | `$XDG_CONFIG_HOME/pixi/config.toml` | XDG compliant user-specific configuration |
| 2 | `$HOME/.config/pixi/config.toml` | User-specific configuration |
| 1 | `/etc/pixi/config.toml` | System-wide configuration |

=== "macOS"

| **Priority** | **Location** | **Comments** |
|--------------|------------------------------------------------------------------------|------------------------------------------------------------------------------------|
| 6 | Command line arguments (`--tls-no-verify`, `--change-ps1=false`, etc.) | Configuration via command line arguments |
| 5 | `your_project/.pixi/config.toml` | Project-specific configuration |
| 4 | `$PIXI_HOME/config.toml` | Global configuration in the user home directory. `PIXI_HOME` defaults to `~/.pixi` |
| 3 | `$HOME/Library/Application Support/pixi/config.toml` | User-specific configuration |
| 2 | `$XDG_CONFIG_HOME/pixi/config.toml` | XDG compliant user-specific configuration |
| 1 | `/etc/pixi/config.toml` | System-wide configuration |
| **Priority** | **Location** | **Comments** |
|--------------|------------------------------------------------------------------------|-------------------------------------------------------|
| 6 | Command line arguments (`--tls-no-verify`, `--change-ps1=false`, etc.) | Configuration via command line arguments |
| 5 | `your_project/.pixi/config.toml` | Project-specific configuration |
| 4 | `$PIXI_HOME/config.toml` | Global configuration in `PIXI_HOME`. |
| 3 | `$HOME/.pixi/config.toml` | Global configuration in the user home directory. |
| 2 | `$HOME/Library/Application Support/pixi/config.toml` | User-specific configuration |
| 1 | `/etc/pixi/config.toml` | System-wide configuration |

=== "Windows"

| **Priority** | **Location** | **Comments** |
|--------------|------------------------------------------------------------------------|------------------------------------------------------------------------------------------------|
| 5 | Command line arguments (`--tls-no-verify`, `--change-ps1=false`, etc.) | Configuration via command line arguments |
| 4 | `your_project\.pixi\config.toml` | Project-specific configuration |
| 3 | `$PIXI_HOME\config.toml` | Global configuration in the user home directory. `PIXI_HOME` defaults to `%USERPROFILE%/.pixi` |
| 2 | `%APPDATA%\pixi\config.toml` | User-specific configuration |
| 1 | `C:\ProgramData\pixi\config.toml` | System-wide configuration |
| **Priority** | **Location** | **Comments** |
|--------------|------------------------------------------------------------------------|-------------------------------------------------------|
| 6 | Command line arguments (`--tls-no-verify`, `--change-ps1=false`, etc.) | Configuration via command line arguments |
| 5 | `your_project\.pixi\config.toml` | Project-specific configuration |
| 4 | `%PIXI_HOME%\config.toml` | Global configuration in `PIXI_HOME`. |
| 3 | `%USERPROFILE%\.pixi\config.toml` | Global configuration in the user home directory. |
| 2 | `%APPDATA%\pixi\config.toml` | User-specific configuration |
| 1 | `C:\ProgramData\pixi\config.toml` | System-wide configuration |

!!! note
The highest priority wins. If a configuration file is found in a higher priority location, the values from the configuration read from lower priority locations are overwritten.
Expand Down
2 changes: 1 addition & 1 deletion mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ nav:
- Production Deployment: advanced/production_deployment.md
- Pyproject.toml: advanced/pyproject_toml.md
- Reference:
- Project Configuration: reference/project_configuration.md
- Pixi Manifest: reference/project_configuration.md
- Pixi Configuration: reference/pixi_configuration.md
- CLI: reference/cli.md
- Misc:
Expand Down
6 changes: 3 additions & 3 deletions src/global/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use indexmap::{IndexMap, IndexSet};
use is_executable::IsExecutable;
use itertools::Itertools;
use miette::{Context, IntoDiagnostic};
use pixi_config::home_path;
use pixi_config::pixi_home;
use pixi_manifest::PrioritizedChannel;
use pixi_utils::executable_from_path;
use rattler::install::{Transaction, TransactionOperation};
Expand Down Expand Up @@ -44,7 +44,7 @@ impl BinDir {

/// Create the binary executable directory from environment variables
pub async fn from_env() -> miette::Result<Self> {
let bin_dir = home_path()
let bin_dir = pixi_home()
.map(|path| path.join("bin"))
.ok_or(miette::miette!(
"Couldn't determine global binary executable directory"
Expand Down Expand Up @@ -113,7 +113,7 @@ impl EnvRoot {

/// Create the environment root directory from environment variables
pub(crate) async fn from_env() -> miette::Result<Self> {
let path = home_path()
let path = pixi_home()
.map(|path| path.join("envs"))
.ok_or_else(|| miette::miette!("Couldn't get home path"))?;
tokio_fs::create_dir_all(&path).await.into_diagnostic()?;
Expand Down
22 changes: 19 additions & 3 deletions src/global/project/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub(crate) use manifest::{ExposedType, Manifest, Mapping};
use miette::{miette, Context, IntoDiagnostic};
use parsed_manifest::ParsedManifest;
pub(crate) use parsed_manifest::{ExposedName, ParsedEnvironment};
use pixi_config::{default_channel_config, home_path, Config};
use pixi_config::{default_channel_config, pixi_home, Config};
use pixi_consts::consts;
use pixi_manifest::PrioritizedChannel;
use pixi_progress::{await_in_progress, global_multi_progress, wrap_in_progress};
Expand Down Expand Up @@ -369,9 +369,25 @@ impl Project {

/// Get default dir for the pixi global manifest
pub(crate) fn manifest_dir() -> miette::Result<PathBuf> {
home_path()
// Potential directories, with the highest priority coming first
let potential_dirs = [pixi_home(), dirs::config_dir().map(|dir| dir.join("pixi"))]
.into_iter()
.flatten()
.map(|dir| dir.join(MANIFESTS_DIR))
.ok_or_else(|| miette::miette!("Couldn't get home directory"))
.collect_vec();

// First, check if a `pixi-global.toml` already exists
for dir in &potential_dirs {
if dir.join(MANIFEST_DEFAULT_NAME).is_file() {
return Ok(dir.clone());
}
}

// If not, return the first option
potential_dirs
.first()
.cloned()
.ok_or_else(|| miette::miette!("Couldn't obtain global manifest directory"))
}

/// Get the default path to the global manifest file
Expand Down
Loading