diff --git a/docs/cli.md b/docs/cli.md index c9d839281..8e03411f4 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -280,6 +280,11 @@ pixi auth logout anaconda.org Global is the main entry point for the part of pixi that executes on the global(system) level. +!!! tip + Binaries and environments installed globally are stored in `~/.pixi` + by default, this can be changed by setting the `PIXI_HOME` environment + variable. + ### `global install` This command installs a package into its own environment and adds the binary to `PATH`, allowing you to access it anywhere on your system without activating the environment. diff --git a/install/install.ps1 b/install/install.ps1 index e65c5acd0..a63cb0b95 100644 --- a/install/install.ps1 +++ b/install/install.ps1 @@ -1,29 +1,54 @@ +<# +.SYNOPSIS + Pixi install script. +.DESCRIPTION + This script is used to install Pixi on Windows from the command line. +.PARAMETER PixiVersion + Specifies the version of Pixi to install. + The default value is 'latest'. You can also specify it by setting the + environment variable 'PIXI_VERSION'. +.PARAMETER PixiHome + Specifies Pixi's home directory. + The default value is '$Env:USERPROFILE\.pixi'. You can also specify it by + setting the environment variable 'PIXI_HOME'. +.LINK + https://pixi.sh +.LINK + https://github.com/prefix-dev/pixi +#> param ( - [string]$PIXI_DIR = "$Env:USERPROFILE\.pixi\bin" + [string] $PixiVersion = 'latest', + [string] $PixiHome = "$Env:USERPROFILE\.pixi" ) +Set-StrictMode -Version Latest + if ($Env:PIXI_VERSION) { - $PIXI_VERSION = $Env:PIXI_VERSION -} else { - $PIXI_VERSION = "latest" + $PixiVersion = $Env:PIXI_VERSION +} + +if ($Env:PIXI_HOME) { + $PixiHome = $Env:PIXI_HOME } # Repository name -$REPO = "prefix-dev/pixi" -$ARCH = "x86_64" -$PLATFORM = "pc-windows-msvc" +$REPO = 'prefix-dev/pixi' +$ARCH = 'x86_64' +$PLATFORM = 'pc-windows-msvc' $BINARY = "pixi-$ARCH-$PLATFORM" -if ($PIXI_VERSION -eq "latest") { +if ($PixiVersion -eq 'latest') { $DOWNLOAD_URL = "https://github.com/$REPO/releases/latest/download/$BINARY.zip" } else { - $DOWNLOAD_URL = "https://github.com/$REPO/releases/download/$PIXI_VERSION/$BINARY.zip" + $DOWNLOAD_URL = "https://github.com/$REPO/releases/download/$PixiVersion/$BINARY.zip" } -Write-Host "This script will automatically download and install Pixi ($PIXI_VERSION) for you." +$BinDir = Join-Path $PixiHome 'bin' + +Write-Host "This script will automatically download and install Pixi ($PixiVersion) for you." Write-Host "Getting it from this url: $DOWNLOAD_URL" -Write-Host "The binary will be installed into '$PIXI_DIR'" +Write-Host "The binary will be installed into '$BinDir'" $TEMP_FILE = [System.IO.Path]::GetTempFileName() @@ -31,23 +56,23 @@ try { Invoke-WebRequest -Uri $DOWNLOAD_URL -OutFile $TEMP_FILE # Create the install dir if it doesn't exist - if (!(Test-Path -Path $PIXI_DIR )) { - New-Item -ItemType directory -Path $PIXI_DIR + if (!(Test-Path -Path $BinDir)) { + New-Item -ItemType directory -Path $BinDir } $ZIP_FILE = $TEMP_FILE + ".zip" Rename-Item -Path $TEMP_FILE -NewName $ZIP_FILE # Extract pixi from the downloaded zip file - Expand-Archive -Path $ZIP_FILE -DestinationPath $PIXI_DIR -Force + Expand-Archive -Path $ZIP_FILE -DestinationPath $BinDir -Force # Add pixi to PATH if the folder is not already in the PATH variable $PATH = [Environment]::GetEnvironmentVariable("Path", "User") - if ($PATH -notlike "*$PIXI_DIR*") { - Write-Output "Adding $PIXI_DIR to PATH`n" - [Environment]::SetEnvironmentVariable("Path", "$PIXI_DIR;" + [Environment]::GetEnvironmentVariable("Path", "User"), "User") + if ($PATH -notlike "*$BinDir*") { + Write-Output "Adding $BinDir to PATH`n" + [Environment]::SetEnvironmentVariable("Path", "$BinDir;" + [Environment]::GetEnvironmentVariable("Path", "User"), "User") } else { - Write-Output "$PIXI_DIR is already in PATH`n" + Write-Output "$BinDir is already in PATH`n" } } catch { Write-Host "Error: '$DOWNLOAD_URL' is not available or failed to download" diff --git a/install/install.sh b/install/install.sh index 03792a7b8..e1ac976dd 100644 --- a/install/install.sh +++ b/install/install.sh @@ -4,7 +4,8 @@ set -euo pipefail __wrap__() { VERSION=${PIXI_VERSION:-latest} -INSTALL_DIR=${PIXI_DIR:-"$HOME/.pixi/bin"} +PIXI_HOME=${PIXI_HOME:-"$HOME/.pixi"} +BIN_DIR="$PIXI_HOME/bin" REPO=prefix-dev/pixi PLATFORM=$(uname -s) @@ -30,7 +31,7 @@ else DOWNLOAD_URL=https://github.com/${REPO}/releases/download/${VERSION}/${BINARY}.tar.gz fi -printf "This script will automatically download and install Pixi (${VERSION}) for you.\nGetting it from this url: $DOWNLOAD_URL\nThe binary will be installed into '$INSTALL_DIR'\n" +printf "This script will automatically download and install Pixi (${VERSION}) for you.\nGetting it from this url: $DOWNLOAD_URL\nThe binary will be installed into '$BIN_DIR'\n" if ! hash curl 2> /dev/null; then echo "error: you do not have 'curl' installed which is required for this script." @@ -64,8 +65,8 @@ if [[ ! -s $TEMP_FILE ]]; then fi # Extract pixi from the downloaded tar file -mkdir -p "$INSTALL_DIR" -tar -xzf "$TEMP_FILE" -C "$INSTALL_DIR" +mkdir -p "$BIN_DIR" +tar -xzf "$TEMP_FILE" -C "$BIN_DIR" update_shell() { FILE=$1 @@ -91,17 +92,17 @@ case "$(basename "$SHELL")" in # Default to bashrc as that is used in non login shells instead of the profile. BASH_FILE=~/.bashrc fi - LINE="export PATH=\$PATH:${INSTALL_DIR}" + LINE="export PATH=\$PATH:${BIN_DIR}" update_shell $BASH_FILE "$LINE" ;; fish) - LINE="fish_add_path ${INSTALL_DIR}" + LINE="fish_add_path ${BIN_DIR}" update_shell ~/.config/fish/config.fish "$LINE" ;; zsh) - LINE="export PATH=\$PATH:${INSTALL_DIR}" + LINE="export PATH=\$PATH:${BIN_DIR}" update_shell ~/.zshrc "$LINE" ;; @@ -110,7 +111,7 @@ case "$(basename "$SHELL")" in ;; esac -chmod +x "$INSTALL_DIR/pixi" +chmod +x "$BIN_DIR/pixi" echo "Please restart or source your shell." diff --git a/src/cli/global/install.rs b/src/cli/global/install.rs index 2f790ef1f..b4d9d49f8 100644 --- a/src/cli/global/install.rs +++ b/src/cli/global/install.rs @@ -23,9 +23,6 @@ use std::{ str::FromStr, }; -const BIN_DIR: &str = ".pixi/bin"; -const BIN_ENVS_DIR: &str = ".pixi/envs"; - /// Installs the defined package in a global accessible location. #[derive(Parser, Debug)] #[clap(arg_required_else_help = true)] @@ -70,11 +67,20 @@ impl BinDir { } } -/// Binaries are installed in ~/.pixi/bin +/// Get pixi home directory, default to `$HOME/.pixi` +fn home_path() -> miette::Result { + if let Some(path) = std::env::var_os("PIXI_HOME") { + Ok(PathBuf::from(path)) + } else { + home_dir() + .map(|path| path.join(".pixi")) + .ok_or_else(|| miette::miette!("could not find home directory")) + } +} + +/// Global binaries directory, default to `$HOME/.pixi/bin` fn bin_dir() -> miette::Result { - Ok(home_dir() - .ok_or_else(|| miette::miette!("could not find home directory"))? - .join(BIN_DIR)) + home_path().map(|path| path.join("bin")) } pub(crate) struct BinEnvDir(pub PathBuf); @@ -111,11 +117,9 @@ impl BinEnvDir { } } -/// Binary environments are installed in ~/.pixi/envs +/// GLobal binary environments directory, default to `$HOME/.pixi/envs` pub(crate) fn bin_env_dir() -> miette::Result { - Ok(home_dir() - .ok_or_else(|| miette::miette!("could not find home directory"))? - .join(BIN_ENVS_DIR)) + home_path().map(|path| path.join("envs")) } /// Find the designated package in the prefix @@ -376,11 +380,10 @@ pub async fn execute(args: Args) -> miette::Result<()> { "{whitespace}These apps are now globally available:\n{whitespace} - {script_names}", ) } else { - let bin_dir = format!("~/{BIN_DIR}"); eprintln!("{whitespace}These apps have been added to {}\n{whitespace} - {script_names}\n\n{} To use them, make sure to add {} to your PATH", - console::style(&bin_dir).bold(), + console::style(&bin_dir.display()).bold(), console::style("!").yellow().bold(), - console::style(&bin_dir).bold() + console::style(&bin_dir.display()).bold() ) }