From c6b4280b00dc10efd70e79e2e8e778186b3fded3 Mon Sep 17 00:00:00 2001 From: Ruben Arts Date: Fri, 14 Jun 2024 15:26:09 +0200 Subject: [PATCH 1/6] fix: too much shell variables in activation of `pixi shell` (#1507) Fixes #1503 The issue was that the work on the clean-env introduced a situation where all env vars of the current environment are added to the shell activation. This is not what we want, so this pr reverts that behavior. This pr adds - Cleanup of the activation code - Storage of both the clean and normal environment variables when used in the tasks. - Introduces Environment variable behavior to tell the activator what to do with the current environment - Removes windows non-sense, I added the possible code to the related issue : #289 for future reference. --- pixi.toml | 6 +- src/activation.rs | 119 ++++++++++++++++------------------ src/cli/run.rs | 25 +++++--- src/cli/shell.rs | 37 +++++++---- src/cli/shell_hook.rs | 10 +-- src/lib.rs | 3 +- src/lock_file/update.rs | 22 ++++--- src/project/environment.rs | 34 +++++----- src/project/mod.rs | 125 ++++++++++++++++++++++++------------ src/task/executable_task.rs | 2 +- tests/common/mod.rs | 2 +- tests/test_activation.rs | 71 ++++++++++++++++++++ 12 files changed, 293 insertions(+), 163 deletions(-) create mode 100644 tests/test_activation.rs diff --git a/pixi.toml b/pixi.toml index a75de123c..f5a7607e5 100644 --- a/pixi.toml +++ b/pixi.toml @@ -67,6 +67,6 @@ pyyaml = ">=6.0.1,<6.1" taplo = ">=0.9.1,<0.10" [environments] -default = { features = ["build", "dev", "docs", "schema"], solve-group = "one"} -docs = { features = ["docs"], no-default-feature = true, solve-group = "one"} -schema = { features = ["schema"], no-default-feature = true , solve-group = "one"} +default = { features = ["build", "dev", "docs", "schema"], solve-group = "default"} +docs = { features = ["docs"], no-default-feature = true, solve-group = "default"} +schema = { features = ["schema"], no-default-feature = true , solve-group = "default"} diff --git a/src/activation.rs b/src/activation.rs index 429d7fd9d..983bf4ebc 100644 --- a/src/activation.rs +++ b/src/activation.rs @@ -3,22 +3,32 @@ use std::collections::HashMap; use itertools::Itertools; use miette::IntoDiagnostic; use rattler_conda_types::Platform; -use rattler_shell::activation::ActivationError::FailedToRunActivationScript; use rattler_shell::{ - activation::{ActivationError, ActivationVariables, Activator, PathModificationBehavior}, + activation::{ + ActivationError, ActivationError::FailedToRunActivationScript, ActivationVariables, + Activator, PathModificationBehavior, + }, shell::ShellEnum, }; -use crate::project::has_features::HasFeatures; use crate::{ - environment::{get_up_to_date_prefix, LockFileUsage}, - project::{manifest::EnvironmentName, Environment}, + project::{has_features::HasFeatures, manifest::EnvironmentName, Environment}, Project, }; // Setting a base prefix for the pixi package const PROJECT_PREFIX: &str = "PIXI_PROJECT_"; +pub enum CurrentEnvVarBehavior { + /// Clean the environment variables of the current shell. + /// This will return the minimal set of environment variables that are required to run the command. + Clean, + /// Copy the environment variables of the current shell. + Include, + /// Do not take any environment variables from the current shell. + Exclude, +} + impl Project { /// Returns environment variables and their values that should be injected when running a command. pub fn get_metadata_env(&self) -> HashMap { @@ -124,7 +134,7 @@ pub fn get_activator<'p>( // Add the environment variables from the project. activator .env_vars - .extend(get_environment_variables(environment)); + .extend(get_static_environment_variables(environment)); Ok(activator) } @@ -132,7 +142,7 @@ pub fn get_activator<'p>( /// Runs and caches the activation script. pub async fn run_activation( environment: &Environment<'_>, - clean_env: bool, + env_var_behavior: &CurrentEnvVarBehavior, ) -> miette::Result> { let activator = get_activator(environment, ShellEnum::default()).map_err(|e| { miette::miette!(format!( @@ -142,10 +152,11 @@ pub async fn run_activation( )) })?; - let path_modification_behavior = if clean_env { - PathModificationBehavior::Replace - } else { - PathModificationBehavior::Prepend + let path_modification_behavior = match env_var_behavior { + // We need to replace the full environment path with the new one. + // So only the executables from the pixi environment are available. + CurrentEnvVarBehavior::Clean => PathModificationBehavior::Replace, + _ => PathModificationBehavior::Prepend, }; let activator_result = match tokio::task::spawn_blocking(move || { @@ -193,51 +204,13 @@ pub async fn run_activation( } }; - if clean_env && cfg!(windows) { - return Err(miette::miette!( - format!("It's not possible to run a `clean-env` on Windows as it requires so many non conda specific files that it is basically useless to use. \ - So pixi currently doesn't support this feature."))); - } else if clean_env { - let mut cleaned_environment_variables = get_clean_environment_variables(); - - // Extend with the original activation environment - cleaned_environment_variables.extend(activator_result); - - // Enable this when we found a better way to support windows. - // On Windows the path is not completely replace, but we need to strip some paths to keep it as clean as possible. - // if cfg!(target_os = "windows") { - // let path = env - // .get("Path") - // .map(|path| { - // // Keep some of the paths - // let win_path = std::env::split_paths(&path).filter(|p| { - // // Required for base functionalities - // p.to_string_lossy().contains(":\\Windows") - // // Required for compilers - // || p.to_string_lossy().contains("\\Program Files") - // // Required for pixi environments - // || p.starts_with(environment.dir()) - // }); - // // Join back up the paths - // std::env::join_paths(win_path).expect("Could not join paths") - // }) - // .expect("Could not find PATH in environment variables"); - // // Insert the path back into the env. - // env.insert( - // "Path".to_string(), - // path.to_str() - // .expect("Path contains non-utf8 paths") - // .to_string(), - // ); - // } - - return Ok(cleaned_environment_variables); - } - Ok(std::env::vars().chain(activator_result).collect()) + Ok(activator_result) } /// Get the environment variables that are statically generated from the project and the environment. -pub fn get_environment_variables<'p>(environment: &'p Environment<'p>) -> HashMap { +pub fn get_static_environment_variables<'p>( + environment: &'p Environment<'p>, +) -> HashMap { // Get environment variables from the project let project_env = environment.project().get_metadata_env(); @@ -260,6 +233,8 @@ pub fn get_environment_variables<'p>(environment: &'p Environment<'p>) -> HashMa .collect() } +/// Get the environment variables that are set in the current shell +/// and strip them down to the minimal set required to run a command. pub fn get_clean_environment_variables() -> HashMap { let env = std::env::vars().collect::>(); @@ -302,18 +277,32 @@ pub fn get_clean_environment_variables() -> HashMap { /// Determine the environment variables that need to be set in an interactive shell to make it /// function as if the environment has been activated. This method runs the activation scripts from /// the environment and stores the environment variables it added, finally it adds environment -/// variables from the project. -pub async fn get_activation_env<'p>( - environment: &'p Environment<'p>, - lock_file_usage: LockFileUsage, -) -> miette::Result<&HashMap> { - // Get the prefix which we can then activate. - get_up_to_date_prefix(environment, lock_file_usage, false).await?; - - environment - .project() - .get_env_variables(environment, false) - .await +/// variables from the project and based on the clean_env setting it will also add in the current +/// shell environment variables. +pub(crate) async fn initialize_env_variables( + environment: &Environment<'_>, + env_var_behavior: CurrentEnvVarBehavior, +) -> miette::Result> { + let activation_env = run_activation(environment, &env_var_behavior).await?; + + // Get environment variables from the currently activated shell. + let current_shell_env_vars = match env_var_behavior { + CurrentEnvVarBehavior::Clean if cfg!(windows) => { + return Err(miette::miette!( + "Currently it's not possible to run a `clean-env` option on Windows." + )); + } + CurrentEnvVarBehavior::Clean => get_clean_environment_variables(), + CurrentEnvVarBehavior::Include => std::env::vars().collect(), + CurrentEnvVarBehavior::Exclude => HashMap::new(), + }; + + let all_variables: HashMap = current_shell_env_vars + .into_iter() + .chain(activation_env) + .collect(); + + Ok(all_variables) } #[cfg(test)] diff --git a/src/cli/run.rs b/src/cli/run.rs index e04ad025a..188c0dbbf 100644 --- a/src/cli/run.rs +++ b/src/cli/run.rs @@ -9,19 +9,19 @@ use dialoguer::theme::ColorfulTheme; use itertools::Itertools; use miette::{miette, Context, Diagnostic, IntoDiagnostic}; +use crate::activation::CurrentEnvVarBehavior; use crate::environment::verify_prefix_location_unchanged; -use crate::project::errors::UnsupportedPlatformError; -use crate::task::{ - AmbiguousTask, CanSkip, ExecutableTask, FailedToParseShellScript, InvalidWorkingDirectory, - SearchEnvironments, TaskAndEnvironment, TaskGraph, TaskName, -}; -use crate::Project; - use crate::lock_file::LockFileDerivedData; use crate::lock_file::UpdateLockFileOptions; use crate::progress::await_in_progress; +use crate::project::errors::UnsupportedPlatformError; use crate::project::virtual_packages::verify_current_platform_has_required_virtual_packages; use crate::project::Environment; +use crate::task::{ + AmbiguousTask, CanSkip, ExecutableTask, FailedToParseShellScript, InvalidWorkingDirectory, + SearchEnvironments, TaskAndEnvironment, TaskGraph, TaskName, +}; +use crate::{HasFeatures, Project}; use thiserror::Error; use tracing::Level; @@ -253,14 +253,21 @@ pub async fn get_task_env<'p>( lock_file_derived_data.prefix(environment).await?; // Get environment variables from the activation + let env_var_behavior = if clean_env { + CurrentEnvVarBehavior::Clean + } else { + CurrentEnvVarBehavior::Include + }; let activation_env = await_in_progress("activating environment", |_| { - crate::activation::run_activation(environment, clean_env) + environment + .project() + .get_activated_environment_variables(environment, env_var_behavior) }) .await .wrap_err("failed to activate environment")?; // Concatenate with the system environment variables - Ok(activation_env) + Ok(activation_env.clone()) } #[derive(Debug, Error, Diagnostic)] diff --git a/src/cli/shell.rs b/src/cli/shell.rs index c975da1ce..430f92dfb 100644 --- a/src/cli/shell.rs +++ b/src/cli/shell.rs @@ -1,21 +1,26 @@ -use crate::activation::get_activation_env; -use crate::config::ConfigCliPrompt; -use crate::{prompt, Project}; +use std::{collections::HashMap, io::Write, path::PathBuf}; + use clap::Parser; use miette::IntoDiagnostic; use rattler_conda_types::Platform; -use rattler_shell::activation::PathModificationBehavior; -use rattler_shell::shell::{CmdExe, PowerShell, Shell, ShellEnum, ShellScript}; -use std::collections::HashMap; -use std::io::Write; -use std::path::PathBuf; +use rattler_shell::{ + activation::PathModificationBehavior, + shell::{CmdExe, PowerShell, Shell, ShellEnum, ShellScript}, +}; #[cfg(target_family = "unix")] use crate::unix::PtySession; - -use crate::cli::LockFileUsageArgs; -use crate::project::manifest::EnvironmentName; -use crate::project::virtual_packages::verify_current_platform_has_required_virtual_packages; +use crate::{ + activation::CurrentEnvVarBehavior, + cli::LockFileUsageArgs, + config::ConfigCliPrompt, + environment::get_up_to_date_prefix, + project::{ + manifest::EnvironmentName, + virtual_packages::verify_current_platform_has_required_virtual_packages, + }, + prompt, Project, +}; /// Start a shell in the pixi environment of the project #[derive(Parser, Debug)] @@ -213,8 +218,14 @@ pub async fn execute(args: Args) -> miette::Result<()> { EnvironmentName::Named(name) => format!("{}:{}", project.name(), name), }; + // Make sure environment is up-to-date, default to install, users can avoid this with frozen or locked. + get_up_to_date_prefix(&environment, args.lock_file_usage.into(), false).await?; + // Get the environment variables we need to set activate the environment in the shell. - let env = get_activation_env(&environment, args.lock_file_usage.into()).await?; + let env = project + .get_activated_environment_variables(&environment, CurrentEnvVarBehavior::Exclude) + .await?; + tracing::debug!("Pixi environment activation:\n{:?}", env); // Start the shell as the last part of the activation script based on the default shell. diff --git a/src/cli/shell_hook.rs b/src/cli/shell_hook.rs index 823c65a87..a50fe91bd 100644 --- a/src/cli/shell_hook.rs +++ b/src/cli/shell_hook.rs @@ -10,12 +10,12 @@ use serde::Serialize; use serde_json; use crate::{ - activation::get_activator, + activation::{get_activator, CurrentEnvVarBehavior}, cli::LockFileUsageArgs, config::ConfigCliPrompt, environment::get_up_to_date_prefix, - project::{has_features::HasFeatures, Environment}, - Project, + project::Environment, + HasFeatures, Project, }; /// Print the pixi environment activation script. @@ -90,11 +90,13 @@ async fn generate_activation_script( async fn generate_environment_json(environment: &Environment<'_>) -> miette::Result { let environment_variables = environment .project() - .get_env_variables(environment, false) + .get_activated_environment_variables(environment, CurrentEnvVarBehavior::Exclude) .await?; + let shell_env = ShellEnv { environment_variables, }; + serde_json::to_string(&shell_env).into_diagnostic() } diff --git a/src/lib.rs b/src/lib.rs index ab0fab5bc..bf47f74f8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -mod activation; +pub mod activation; pub mod cli; pub(crate) mod conda_pypi_clobber; pub mod config; @@ -24,7 +24,6 @@ mod uv_reporter; pub mod pypi_mapping; mod repodata; -pub use activation::get_activation_env; pub use lock_file::load_lock_file; pub use lock_file::UpdateLockFileOptions; pub use project::{ diff --git a/src/lock_file/update.rs b/src/lock_file/update.rs index a734f5dd7..8a22e7fc5 100644 --- a/src/lock_file/update.rs +++ b/src/lock_file/update.rs @@ -27,11 +27,12 @@ use tracing::Instrument; use url::Url; use uv_normalize::ExtraName; -use crate::environment::{write_environment_file, EnvironmentFile}; use crate::{ + activation::CurrentEnvVarBehavior, config, consts, environment::{ - self, LockFileUsage, PerEnvironmentAndPlatform, PerGroup, PerGroupAndPlatform, PythonStatus, + self, write_environment_file, EnvironmentFile, LockFileUsage, PerEnvironmentAndPlatform, + PerGroup, PerGroupAndPlatform, PythonStatus, }, load_lock_file, lock_file::{ @@ -150,10 +151,11 @@ impl<'p> LockFileDerivedData<'p> { Some(context) => context.clone(), }; - let env_variables = environment - .project() - .get_env_variables(environment, false) + let env_variables = self + .project + .get_activated_environment_variables(environment, CurrentEnvVarBehavior::Exclude) .await?; + // Update the prefix with Pypi records environment::update_prefix_pypi( environment.name(), @@ -986,7 +988,7 @@ impl<'p> UpdateContext<'p> { .outdated_envs .pypi .iter() - .flat_map(|(env, platforms)| platforms.iter().map(move |p| (env.clone(), *p))) + .flat_map(|(env, platforms)| platforms.iter().map(move |p| (env, *p))) { let group = GroupedEnvironment::from(environment.clone()); @@ -1006,6 +1008,11 @@ impl<'p> UpdateContext<'p> { continue; } + // Get environment variables from the activation + let env_variables = project + .get_activated_environment_variables(environment, CurrentEnvVarBehavior::Exclude) + .await?; + // Construct a future that will resolve when we have the repodata available let repodata_future = self .get_latest_group_repodata_records(&group, platform) @@ -1024,9 +1031,6 @@ impl<'p> UpdateContext<'p> { Some(context) => context.clone(), }; - // Get environment variables from the activation - let env_variables = project.get_env_variables(&environment, false).await?; - let locked_group_records = self .locked_grouped_pypi_records .get(&group) diff --git a/src/project/environment.rs b/src/project/environment.rs index 590ea2d7e..b57c5bd9d 100644 --- a/src/project/environment.rs +++ b/src/project/environment.rs @@ -1,15 +1,3 @@ -use super::{ - errors::{UnknownTask, UnsupportedPlatformError}, - manifest::{self, EnvironmentName, Feature, FeatureName, SystemRequirements}, - SolveGroup, -}; -use crate::project::has_features::HasFeatures; - -use crate::consts; -use crate::task::TaskName; -use crate::{task::Task, Project}; -use itertools::Either; -use rattler_conda_types::{Arch, Platform}; use std::{ collections::{HashMap, HashSet}, fmt::Debug, @@ -18,6 +6,21 @@ use std::{ sync::Once, }; +use itertools::Either; +use rattler_conda_types::{Arch, Platform}; + +use super::{ + errors::{UnknownTask, UnsupportedPlatformError}, + manifest::{self, EnvironmentName, Feature, FeatureName, SystemRequirements}, + SolveGroup, +}; +use crate::{ + consts, + project::has_features::HasFeatures, + task::{Task, TaskName}, + Project, +}; + /// Describes a single environment from a project manifest. This is used to describe environments /// that can be installed and activated. /// @@ -297,13 +300,14 @@ impl<'p> Hash for Environment<'p> { #[cfg(test)] mod tests { - use crate::project::CondaDependencies; + use std::{collections::HashSet, path::Path}; - use super::*; use insta::assert_snapshot; use itertools::Itertools; use rattler_conda_types::Channel; - use std::{collections::HashSet, path::Path}; + + use super::*; + use crate::project::CondaDependencies; #[test] fn test_default_channels() { diff --git a/src/project/mod.rs b/src/project/mod.rs index a78855d02..47b67f1d4 100644 --- a/src/project/mod.rs +++ b/src/project/mod.rs @@ -13,7 +13,6 @@ use std::os::unix::fs::symlink; use std::{ borrow::Borrow, collections::{HashMap, HashSet}, - env, fmt::{Debug, Formatter}, hash::Hash, path::{Path, PathBuf}, @@ -35,7 +34,7 @@ use xxhash_rust::xxh3::xxh3_64; use self::manifest::{pyproject::PyProjectToml, Environments}; use crate::{ - activation::{get_environment_variables, run_activation}, + activation::{initialize_env_variables, CurrentEnvVarBehavior}, config::Config, consts::{self, PROJECT_MANIFEST, PYPROJECT_MANIFEST}, project::{grouped_environment::GroupedEnvironment, manifest::ProjectManifest}, @@ -91,6 +90,40 @@ impl SpecType { } } +/// Environment variable cache for different activations +#[derive(Debug, Clone)] +pub struct EnvironmentVars { + clean: Arc>>, + pixi_only: Arc>>, + full: Arc>>, +} + +impl EnvironmentVars { + /// Create a new instance with empty AsyncCells + pub fn new() -> Self { + Self { + clean: Arc::new(AsyncCell::new()), + pixi_only: Arc::new(AsyncCell::new()), + full: Arc::new(AsyncCell::new()), + } + } + + /// Get the clean environment variables + pub fn clean(&self) -> &Arc>> { + &self.clean + } + + /// Get the pixi_only environment variables + pub fn pixi_only(&self) -> &Arc>> { + &self.pixi_only + } + + /// Get the full environment variables + pub fn full(&self) -> &Arc>> { + &self.full + } +} + /// The pixi project, this main struct to interact with the project. This struct /// holds the `Manifest` and has functions to modify or request information from /// it. This allows in the future to have multiple environments or manifests @@ -108,8 +141,9 @@ pub struct Project { repodata_gateway: OnceLock, /// The manifest for the project pub(crate) manifest: Manifest, - /// The cache that contains environment variables - env_vars: HashMap>>>, + /// The environment variables that are activated when the environment is activated. + /// Cached per environment, for both clean and normal + env_vars: HashMap, /// The cache that contains mapping mapping_source: OnceCell, /// The global configuration as loaded from the config file(s) @@ -154,13 +188,11 @@ impl Project { } } - //Initialize empty map of environments variables - fn init_env_vars( - environments: &Environments, - ) -> HashMap>>> { + /// Initialize empty map of environments variables + fn init_env_vars(environments: &Environments) -> HashMap { environments .iter() - .map(|environment| (environment.name.clone(), Arc::new(AsyncCell::new()))) + .map(|environment| (environment.name.clone(), EnvironmentVars::new())) .collect() } @@ -323,7 +355,8 @@ impl Project { } } - /// Returns the default environment directory without interacting with config. + /// Returns the default environment directory without interacting with + /// config. pub fn default_environments_dir(&self) -> PathBuf { self.pixi_dir().join(consts::ENVIRONMENTS_DIR) } @@ -372,7 +405,8 @@ impl Project { default_envs_dir } - /// Returns the default solve group environments directory, without interacting with config + /// Returns the default solve group environments directory, without + /// interacting with config pub fn default_solve_group_environments_dir(&self) -> PathBuf { self.default_environments_dir() .join(consts::SOLVE_GROUP_ENVIRONMENTS_DIR) @@ -393,7 +427,8 @@ impl Project { self.manifest.path.clone() } - /// Returns the path to the lock file of the project [consts::PROJECT_LOCK_FILE] + /// Returns the path to the lock file of the project + /// [consts::PROJECT_LOCK_FILE] pub fn lock_file_path(&self) -> PathBuf { self.root.join(consts::PROJECT_LOCK_FILE) } @@ -438,6 +473,42 @@ impl Project { .ok_or_else(|| miette::miette!("unknown environment '{environment_name}'")) } + /// Get or initialize the activated environment variables + pub async fn get_activated_environment_variables( + &self, + environment: &Environment<'_>, + current_env_var_behavior: CurrentEnvVarBehavior, + ) -> miette::Result<&HashMap> { + let vars = self.env_vars.get(environment.name()).ok_or_else(|| { + miette::miette!( + "{} environment should be already created during project creation", + environment.name() + ) + })?; + match current_env_var_behavior { + CurrentEnvVarBehavior::Clean => { + vars.clean() + .get_or_try_init(async { + initialize_env_variables(environment, current_env_var_behavior).await + }) + .await + } + CurrentEnvVarBehavior::Exclude => { + vars.pixi_only() + .get_or_try_init(async { + initialize_env_variables(environment, current_env_var_behavior).await + }) + .await + } + CurrentEnvVarBehavior::Include => { + vars.full() + .get_or_try_init(async { + initialize_env_variables(environment, current_env_var_behavior).await + }) + .await + } + } + } /// Returns all the solve groups in the project. pub fn solve_groups(&self) -> Vec { self.manifest @@ -513,34 +584,6 @@ impl Project { &self.config } - /// Return a combination of static environment variables generated from the - /// project and the environment and from running activation script - pub async fn get_env_variables( - &self, - environment: &Environment<'_>, - clean_env: bool, - ) -> miette::Result<&HashMap> { - let cell = self.env_vars.get(environment.name()).ok_or_else(|| { - miette::miette!( - "{} environment should be already created during project creation", - environment.name() - ) - })?; - - cell.get_or_try_init::(async { - let activation_env = run_activation(environment, clean_env).await?; - - let environment_variables = get_environment_variables(environment); - - let all_variables: HashMap = activation_env - .into_iter() - .chain(environment_variables.into_iter()) - .collect(); - Ok(all_variables) - }) - .await - } - pub(crate) fn task_cache_folder(&self) -> PathBuf { self.pixi_dir().join(consts::TASK_CACHE_DIR) } @@ -550,7 +593,7 @@ impl Project { /// returns the manifest path in the first directory path that contains the /// [`consts::PROJECT_MANIFEST`] or [`consts::PYPROJECT_MANIFEST`]. pub fn find_project_manifest() -> Option { - let current_dir = env::current_dir().ok()?; + let current_dir = std::env::current_dir().ok()?; std::iter::successors(Some(current_dir.as_path()), |prev| prev.parent()).find_map(|dir| { [PROJECT_MANIFEST, PYPROJECT_MANIFEST] .iter() diff --git a/src/task/executable_task.rs b/src/task/executable_task.rs index 477d4bca8..7dd456546 100644 --- a/src/task/executable_task.rs +++ b/src/task/executable_task.rs @@ -239,7 +239,7 @@ impl<'p> ExecutableTask<'p> { /// that caused the task to not be skipped - we can use this later to update the cache file quickly. pub(crate) async fn can_skip( &self, - lock_file: &LockFileDerivedData<'_>, + lock_file: &LockFileDerivedData<'p>, ) -> Result { tracing::info!("Checking if task can be skipped"); let cache_name = self.cache_name(); diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 68036ae73..c0ad8442a 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -333,7 +333,7 @@ impl PixiControl { None => { let env = get_task_env(&mut lock_file, &task.run_environment, args.clean_env).await?; - task_env.insert(env) as &_ + task_env.insert(env) } Some(task_env) => task_env, }; diff --git a/tests/test_activation.rs b/tests/test_activation.rs new file mode 100644 index 000000000..5cb261dfd --- /dev/null +++ b/tests/test_activation.rs @@ -0,0 +1,71 @@ +use crate::common::PixiControl; +use pixi::activation::CurrentEnvVarBehavior; + +mod common; + +#[cfg(windows)] +const HOME: &str = "HOMEPATH"; +#[cfg(unix)] +const HOME: &str = "HOME"; + +#[tokio::test] +async fn test_pixi_only_env_activation() { + let pixi = PixiControl::new().unwrap(); + pixi.init().await.unwrap(); + + let project = pixi.project().unwrap(); + let default_env = project.default_environment(); + + let pixi_only_env = project + .get_activated_environment_variables(&default_env, CurrentEnvVarBehavior::Exclude) + .await + .unwrap(); + + std::env::set_var("DIRTY_VAR", "Dookie"); + + assert!(pixi_only_env.get("CONDA_PREFIX").is_some()); + assert!(pixi_only_env.get("DIRTY_VAR").is_none()); + // This is not a pixi var, so it is not included in pixi_only. + assert!(pixi_only_env.get(HOME).is_none()); +} + +#[tokio::test] +async fn test_full_env_activation() { + let pixi = PixiControl::new().unwrap(); + pixi.init().await.unwrap(); + + let project = pixi.project().unwrap(); + let default_env = project.default_environment(); + + std::env::set_var("DIRTY_VAR", "Dookie"); + + let full_env = project + .get_activated_environment_variables(&default_env, CurrentEnvVarBehavior::Include) + .await + .unwrap(); + assert!(full_env.get("CONDA_PREFIX").is_some()); + assert!(full_env.get("DIRTY_VAR").is_some()); + assert!(full_env.get(HOME).is_some()); +} + +#[cfg(target_family = "unix")] +#[tokio::test] +async fn test_clean_env_activation() { + let pixi = PixiControl::new().unwrap(); + pixi.init().await.unwrap(); + + let project = pixi.project().unwrap(); + let default_env = project.default_environment(); + + std::env::set_var("DIRTY_VAR", "Dookie"); + + let clean_env = project + .get_activated_environment_variables(&default_env, CurrentEnvVarBehavior::Clean) + .await + .unwrap(); + assert!(clean_env.get("CONDA_PREFIX").is_some()); + assert!(clean_env.get("DIRTY_VAR").is_none()); + + // This is not a pixi var, but it is passed into a clean env. + assert!(clean_env.get(HOME).is_some()); +} From 89e6d698222ead6560a6774040662db696be1d9d Mon Sep 17 00:00:00 2001 From: Ruben Arts Date: Fri, 14 Jun 2024 16:32:55 +0200 Subject: [PATCH 2/6] bump: version to 0.24.2 --- CHANGELOG.md | 21 ++++ CITATION.cff | 4 +- Cargo.lock | 2 +- Cargo.toml | 2 +- docs/advanced/github_actions.md | 2 +- install/install.ps1 | 2 +- install/install.sh | 2 +- pixi.lock | 180 ++++++++++++++++++++++++++++++++ pixi.toml | 4 +- schema/schema.json | 4 +- src/cli/mod.rs | 2 +- tbump.toml | 4 +- 12 files changed, 216 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d22453229..807ab8f8d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,27 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.24.2] - 2024-06-14 +### ✨ Highlights + + + +### 📃 Details + +#### Documentation +- Add readthedocs examples by @bollwyvl in [#1423](https://github.com/prefix-dev/pixi/pull/1423) +- Fix typo in project_configuration.md by @RaulPL in [#1502](https://github.com/prefix-dev/pixi/pull/1502) + +#### Fixed +- Too much shell variables in activation of `pixi shell` by @ruben-arts in [#1507](https://github.com/prefix-dev/pixi/pull/1507) + +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + ## [0.24.1] - 2024-06-12 ### 📃 Details #### Fixed diff --git a/CITATION.cff b/CITATION.cff index 21659b127..5f867dd7f 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -24,8 +24,8 @@ authors: name-particle: de family-names: Jager email: tdejager89@gmail.com -repository-code: 'https://github.com/prefix-dev/pixi/releases/tag/v0.24.1' -url: 'https://pixi.sh/v0.24.1' +repository-code: 'https://github.com/prefix-dev/pixi/releases/tag/v0.24.2' +url: 'https://pixi.sh/v0.24.2' abstract: >- A cross-platform, language agnostic, package/project management tool for development in virtual environments. diff --git a/Cargo.lock b/Cargo.lock index f16bf6b46..50e299718 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3282,7 +3282,7 @@ dependencies = [ [[package]] name = "pixi" -version = "0.24.1" +version = "0.24.2" dependencies = [ "ahash 0.8.11", "assert_matches", diff --git a/Cargo.toml b/Cargo.toml index f045b691c..5b0517c34 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pixi" -version = "0.24.1" +version = "0.24.2" description = "A package management and workflow tool" edition = "2021" authors = ["pixi contributors "] diff --git a/docs/advanced/github_actions.md b/docs/advanced/github_actions.md index d47b27394..8360f0071 100644 --- a/docs/advanced/github_actions.md +++ b/docs/advanced/github_actions.md @@ -15,7 +15,7 @@ We created [prefix-dev/setup-pixi](https://github.com/prefix-dev/setup-pixi) to ```yaml - uses: prefix-dev/setup-pixi@v0.7.0 with: - pixi-version: v0.24.1 + pixi-version: v0.24.2 cache: true auth-host: prefix.dev auth-token: ${{ secrets.PREFIX_DEV_TOKEN }} diff --git a/install/install.ps1 b/install/install.ps1 index 7f5dc7951..70d4914e0 100644 --- a/install/install.ps1 +++ b/install/install.ps1 @@ -18,7 +18,7 @@ .LINK https://github.com/prefix-dev/pixi .NOTES - Version: v0.24.1 + Version: v0.24.2 #> param ( [string] $PixiVersion = 'latest', diff --git a/install/install.sh b/install/install.sh index eab377712..9a9191e56 100644 --- a/install/install.sh +++ b/install/install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash set -euo pipefail -# Version: v0.24.1 +# Version: v0.24.2 __wrap__() { diff --git a/pixi.lock b/pixi.lock index f061aea07..842857914 100644 --- a/pixi.lock +++ b/pixi.lock @@ -59,6 +59,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-12.3.0-h5877db1_6.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ghp-import-2.1.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/git-2.42.0-pl5321h7bc287a_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/git-cliff-2.2.1-he0a03d5_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/gxx-12.3.0-h915e2ae_7.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-12.3.0-h2a574ab_7.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-12.3.0-ha28b414_6.conda @@ -90,6 +91,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/libgettextpo-0.22.5-h59595ed_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libgettextpo-devel-0.22.5-h59595ed_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-13.2.0-hca663fb_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgit2-1.7.2-h76de150_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libglib-2.78.4-h783c2da_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-13.2.0-h77fa898_7.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.17-hd590300_2.conda @@ -235,6 +237,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/gettext-tools-0.22.5-h5ff76d1_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ghp-import-2.1.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/git-2.42.0-pl5321hba7a703_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/git-cliff-2.2.1-hc76a939_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/icu-73.2-hf5e326d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/identify-2.5.36-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.7-pyhd8ed1ab_0.conda @@ -258,6 +261,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.4.2-h0d85af4_5.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/libgettextpo-0.22.5-h5ff76d1_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libgettextpo-devel-0.22.5-h5ff76d1_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libgit2-1.7.2-h33a806c_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libglib-2.78.4-hab64008_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libiconv-1.17-hd75f5a5_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libintl-0.22.5-h5ff76d1_2.conda @@ -387,6 +391,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gettext-tools-0.22.5-h8fbad5d_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ghp-import-2.1.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/git-2.42.0-pl5321h6e320eb_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/git-cliff-2.2.1-h46549a6_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-73.2-hc8870d7_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/identify-2.5.36-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.7-pyhd8ed1ab_0.conda @@ -410,6 +415,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.4.2-h3422bc3_5.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgettextpo-0.22.5-h8fbad5d_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgettextpo-devel-0.22.5-h8fbad5d_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgit2-1.7.2-h9878266_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libglib-2.78.4-h1635a5e_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libiconv-1.17-h0d3ecfb_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libintl-0.22.5-h8fbad5d_2.conda @@ -535,6 +541,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/freetype-2.12.1-hdaf720e_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ghp-import-2.1.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/git-2.42.0-h57928b3_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/git-cliff-2.3.0-hdf088c3_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/icu-73.2-h63175ca_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/identify-2.5.36-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.7-pyhd8ed1ab_0.conda @@ -549,12 +556,14 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.20-hcfcfb64_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.6.2-h63175ca_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.4.2-h8ffe710_5.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/win-64/libgit2-1.8.1-hd33bead_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libglib-2.80.2-h0df6a38_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libiconv-1.17-hcfcfb64_2.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libintl-0.22.5-h5728263_2.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libjpeg-turbo-3.0.0-hcfcfb64_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.43-h19919ed_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.46.0-h2466b09_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libssh2-1.11.0-h7dfc565_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libtiff-4.6.0-hddb2be6_3.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libwebp-base-1.4.0-hcfcfb64_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libxcb-1.15-hcd874cb_0.conda @@ -676,6 +685,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/gettext-0.22.5-h59595ed_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/gettext-tools-0.22.5-h59595ed_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ghp-import-2.1.0-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/linux-64/git-cliff-2.2.1-he0a03d5_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-73.2-h59595ed_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-7.1.0-pyha770c72_0.conda @@ -693,6 +703,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-13.2.0-h77fa898_7.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libgettextpo-0.22.5-h59595ed_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libgettextpo-devel-0.22.5-h59595ed_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgit2-1.7.2-h76de150_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libglib-2.78.4-h783c2da_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-13.2.0-h77fa898_7.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.17-hd590300_2.conda @@ -700,6 +711,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hd590300_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.43-h2797004_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.46.0-hde9e2c9_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.0-h0841786_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-13.2.0-hc0a3c3a_7.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.6.0-h1dd3fc0_3.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda @@ -796,6 +808,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/gettext-0.22.5-h5ff76d1_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/gettext-tools-0.22.5-h5ff76d1_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ghp-import-2.1.0-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/osx-64/git-cliff-2.2.1-hc76a939_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/icu-73.2-hf5e326d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-7.1.0-pyha770c72_0.conda @@ -812,6 +825,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.4.2-h0d85af4_5.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/libgettextpo-0.22.5-h5ff76d1_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libgettextpo-devel-0.22.5-h5ff76d1_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libgit2-1.7.2-h33a806c_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libglib-2.78.4-hab64008_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libiconv-1.17-hd75f5a5_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libintl-0.22.5-h5ff76d1_2.conda @@ -819,6 +833,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/libjpeg-turbo-3.0.0-h0dc2134_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libpng-1.6.43-h92b6c6a_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.46.0-h1b8f9f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libssh2-1.11.0-hd019ec5_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libtiff-4.6.0-h129831d_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libwebp-base-1.4.0-h10d778d_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libxcb-1.15-hb7f2c08_0.conda @@ -903,6 +918,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gettext-0.22.5-h8fbad5d_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gettext-tools-0.22.5-h8fbad5d_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ghp-import-2.1.0-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/git-cliff-2.2.1-h46549a6_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-73.2-hc8870d7_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-7.1.0-pyha770c72_0.conda @@ -919,6 +935,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.4.2-h3422bc3_5.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgettextpo-0.22.5-h8fbad5d_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgettextpo-devel-0.22.5-h8fbad5d_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgit2-1.7.2-h9878266_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libglib-2.78.4-h1635a5e_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libiconv-1.17-h0d3ecfb_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libintl-0.22.5-h8fbad5d_2.conda @@ -926,6 +943,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libjpeg-turbo-3.0.0-hb547adb_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libpng-1.6.43-h091b4b1_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.46.0-hfb93653_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libssh2-1.11.0-h7a5bd25_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libtiff-4.6.0-h07db509_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libwebp-base-1.4.0-h93a5062_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxcb-1.15-hf346824_0.conda @@ -1008,6 +1026,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/freetype-2.12.1-hdaf720e_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ghp-import-2.1.0-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/win-64/git-cliff-2.3.0-hdf088c3_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/icu-73.2-h63175ca_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-7.1.0-pyha770c72_0.conda @@ -1019,12 +1038,14 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.20-hcfcfb64_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.6.2-h63175ca_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.4.2-h8ffe710_5.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/win-64/libgit2-1.8.1-hd33bead_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libglib-2.80.2-h0df6a38_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libiconv-1.17-hcfcfb64_2.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libintl-0.22.5-h5728263_2.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libjpeg-turbo-3.0.0-hcfcfb64_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.43-h19919ed_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.46.0-h2466b09_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libssh2-1.11.0-h7dfc565_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libtiff-4.6.0-hddb2be6_3.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libwebp-base-1.4.0-hcfcfb64_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libxcb-1.15-hcd874cb_0.conda @@ -2763,6 +2784,71 @@ packages: license: GPL-2.0-or-later and LGPL-2.1-or-later size: 7744105 timestamp: 1701087084155 +- kind: conda + name: git-cliff + version: 2.2.1 + build: h46549a6_0 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/git-cliff-2.2.1-h46549a6_0.conda + sha256: 68bc598c29dbfe3d5478f4ecf9f8e751d23f461eeea97d08fbce97cfca309368 + md5: b1638762bb0eca6437e3188cb67ab786 + depends: + - libgit2 >=1.7.2,<1.8.0a0 + - libzlib >=1.2.13,<2.0.0a0 + constrains: + - __osx >=11.0 + license: MIT OR Apache-2.0 + size: 3884665 + timestamp: 1712832631720 +- kind: conda + name: git-cliff + version: 2.2.1 + build: hc76a939_0 + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/git-cliff-2.2.1-hc76a939_0.conda + sha256: a92dc6e88e70abd5f05e797d448db2da5b89d9b94cbb2da7952c3dcc181cc47f + md5: 4c808ebedc883bba200325cfbce65951 + depends: + - libgit2 >=1.7.2,<1.8.0a0 + - libzlib >=1.2.13,<2.0.0a0 + constrains: + - __osx >=10.12 + license: MIT OR Apache-2.0 + size: 3973588 + timestamp: 1712832662138 +- kind: conda + name: git-cliff + version: 2.2.1 + build: he0a03d5_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/git-cliff-2.2.1-he0a03d5_0.conda + sha256: 210eda8e8edea66555f804d9858eee3270b9f450be2ccd1268486721ef9f1689 + md5: d1e34f32164d4d94e3b50ed62c4cbb71 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc-ng >=12 + - libgit2 >=1.7.2,<1.8.0a0 + - libzlib >=1.2.13,<2.0.0a0 + license: MIT OR Apache-2.0 + size: 4534595 + timestamp: 1712831738612 +- kind: conda + name: git-cliff + version: 2.3.0 + build: hdf088c3_0 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/git-cliff-2.3.0-hdf088c3_0.conda + sha256: 80f4bd7e000e24fed56fb53d2b80fd423b0f84f12182c892fdb974e59dcbcc3a + md5: ff8c01018691696fb311ac3ebb0651e4 + depends: + - libgit2 >=1.8.1,<1.9.0a0 + - libzlib >=1.2.13,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: MIT OR Apache-2.0 + size: 3946248 + timestamp: 1717433580475 - kind: conda name: gxx version: 12.3.0 @@ -3790,6 +3876,82 @@ packages: license_family: GPL size: 1441361 timestamp: 1715016068766 +- kind: conda + name: libgit2 + version: 1.7.2 + build: h33a806c_0 + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/libgit2-1.7.2-h33a806c_0.conda + sha256: 7996dad91ce0c283abc63edffdca28c5d4fa5ab2a4ba471f7f936121904487d1 + md5: f61327c0e1f59ae6a623fe548271143f + depends: + - libcxx >=16 + - libiconv >=1.17,<2.0a0 + - libssh2 >=1.11.0,<2.0a0 + - libzlib >=1.2.13,<2.0.0a0 + - openssl >=3.2.1,<4.0a0 + - pcre2 >=10.42,<10.43.0a0 + license: GPL-2.0-only WITH GCC-exception-2.0 + license_family: GPL + size: 740648 + timestamp: 1707261553812 +- kind: conda + name: libgit2 + version: 1.7.2 + build: h76de150_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/libgit2-1.7.2-h76de150_0.conda + sha256: f868e84138d67c3dbe3ad6f272c877b839c3c4affc5b4e82de1ab1bf2df87e83 + md5: bce998bdc0492ba70cc6b72d3352d0a6 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc-ng >=12 + - libssh2 >=1.11.0,<2.0a0 + - libstdcxx-ng >=12 + - libzlib >=1.2.13,<2.0.0a0 + - openssl >=3.2.1,<4.0a0 + - pcre2 >=10.42,<10.43.0a0 + license: GPL-2.0-only WITH GCC-exception-2.0 + license_family: GPL + size: 862111 + timestamp: 1707261141079 +- kind: conda + name: libgit2 + version: 1.7.2 + build: h9878266_0 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/libgit2-1.7.2-h9878266_0.conda + sha256: cf3c7cbfd019bb2544278d7eed2bb86f12e2833a0d9422dc64df9be3db921bb8 + md5: 4f92b01347c6e6631d01d99136f76ea9 + depends: + - libcxx >=16 + - libiconv >=1.17,<2.0a0 + - libssh2 >=1.11.0,<2.0a0 + - libzlib >=1.2.13,<2.0.0a0 + - openssl >=3.2.1,<4.0a0 + - pcre2 >=10.42,<10.43.0a0 + license: GPL-2.0-only WITH GCC-exception-2.0 + license_family: GPL + size: 717184 + timestamp: 1707261609859 +- kind: conda + name: libgit2 + version: 1.8.1 + build: hd33bead_0 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/libgit2-1.8.1-hd33bead_0.conda + sha256: e2f180aebb795c1cbf602903fcd64dfd635581a66b982bd6d0fcc346ca14b66b + md5: fe3bdd36df1b6f5e42acbdb9ee25d178 + depends: + - libssh2 >=1.11.0,<2.0a0 + - libzlib >=1.2.13,<2.0.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: GPL-2.0-only WITH GCC-exception-2.0 + license_family: GPL + size: 1141628 + timestamp: 1715880623123 - kind: conda name: libglib version: 2.78.4 @@ -4312,6 +4474,24 @@ packages: license_family: BSD size: 255610 timestamp: 1685837894256 +- kind: conda + name: libssh2 + version: 1.11.0 + build: h7dfc565_0 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/libssh2-1.11.0-h7dfc565_0.conda + sha256: 813fd04eed2a2d5d9c36e53c554f9c1f08e9324e2922bd60c9c52dbbed2dbcec + md5: dc262d03aae04fe26825062879141a41 + depends: + - libzlib >=1.2.13,<2.0.0a0 + - openssl >=3.1.1,<4.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: BSD-3-Clause + license_family: BSD + size: 266806 + timestamp: 1685838242099 - kind: conda name: libssh2 version: 1.11.0 diff --git a/pixi.toml b/pixi.toml index f5a7607e5..e713fcf3d 100644 --- a/pixi.toml +++ b/pixi.toml @@ -17,7 +17,7 @@ install = "cargo install --path . --locked" test = "cargo test" test-all = "cargo test --all-features" lint = "pre-commit run --all" -bump = "tbump --only-patch" +bump = "tbump --only-patch $RELEASE_VERSION" pypi-proxy = "python ./tests/pypi_proxy.py" [feature.dev.dependencies] @@ -44,6 +44,7 @@ pillow = ">=9.4.0" cairosvg = "2.7.1.*" mike = "2.0.0.*" mkdocs-redirects = ">=1.2.1,<2" +git-cliff = ">=2.2.1,<2.4" [feature.docs.tasks] build-docs = "mkdocs build --strict" @@ -51,6 +52,7 @@ docs = "mkdocs serve" deploy-latest = "mike deploy --push --update-aliases $RELEASE_VERSION latest" deploy-dev = "mike deploy --push dev devel" mike-serve = "mike serve" +bump-changelog = "git-cliff --unreleased --prepend CHANGELOG.md --tag $RELEASE_VERSION" [feature.schema.tasks] generate-schema = { cmd = "python model.py > schema.json", cwd = "schema" } diff --git a/schema/schema.json b/schema/schema.json index 92fe00cd8..e588e3549 100644 --- a/schema/schema.json +++ b/schema/schema.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "https://pixi.sh/v0.24.1/schema/manifest/schema.json", + "$id": "https://pixi.sh/v0.24.2/schema/manifest/schema.json", "title": "`pixi.toml` manifest file", "description": "The configuration for a [`pixi`](https://pixi.sh) project.", "type": "object", @@ -13,7 +13,7 @@ "title": "Schema", "description": "The schema identifier for the project's configuration", "type": "string", - "default": "https://pixi.sh/v0.24.1/schema/manifest/schema.json", + "default": "https://pixi.sh/v0.24.2/schema/manifest/schema.json", "format": "uri-reference" }, "activation": { diff --git a/src/cli/mod.rs b/src/cli/mod.rs index e576464d1..668d54934 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -38,7 +38,7 @@ pub mod upload; #[command( version, about = " -Pixi [version 0.24.1] - Developer Workflow and Environment Management for Multi-Platform, Language-Agnostic Projects. +Pixi [version 0.24.2] - Developer Workflow and Environment Management for Multi-Platform, Language-Agnostic Projects. Pixi is a versatile developer workflow tool designed to streamline the management of your project's dependencies, tasks, and environments. Built on top of the Conda ecosystem, Pixi offers seamless integration with the PyPI ecosystem. diff --git a/tbump.toml b/tbump.toml index 68cce663c..dcb0e1c47 100644 --- a/tbump.toml +++ b/tbump.toml @@ -1,7 +1,7 @@ github_url = "https://github.com/prefix-dev/pixi" [version] -current = "0.24.1" +current = "0.24.2" # Example of a semver regexp. # Make sure this matches current_version before @@ -19,7 +19,7 @@ regex = ''' [git] # The current version will get updated when tbump is run -message_template = "Bump version: 0.24.1 → {new_version}" +message_template = "Bump version: 0.24.2 → {new_version}" tag_template = "v{new_version}" # For each file to patch, add a [[file]] config From ebe618cf9cc06c4ee3fbcc7d0d86ca0dac9c284b Mon Sep 17 00:00:00 2001 From: Ruben Arts Date: Fri, 14 Jun 2024 16:40:37 +0200 Subject: [PATCH 3/6] docs(dev): Add release flow document for other maintainers --- docs/dev-release-steps.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 docs/dev-release-steps.md diff --git a/docs/dev-release-steps.md b/docs/dev-release-steps.md new file mode 100644 index 000000000..d1c8e5b20 --- /dev/null +++ b/docs/dev-release-steps.md @@ -0,0 +1,31 @@ +# Making a release of pixi + +## Prep +- Make sure main is up-to-date and ci passes: [![build-badge](https://img.shields.io/github/actions/workflow/status/prefix-dev/pixi/rust.yml?style=flat-square&branch=main)](https://github.com/prefix-dev/pixi/actions/workflows/rust.yml?query=branch%3Amain+) +- Set the variable `export RELEASE_VERSION=X.Y.Z` in your shell +- Make a new branch for the release: `git fetch upstream && git checkout -b bump/prepare-v$RELEASE_VERSION upstream/main` +- Bump all versions: `pixi run bump` +- Update the changelog: `pixi run bump-changelog` + - Don't forget to update the "Highlights" section. +- Commit the changes: `git commit -am "chore: version to $RELEASE_VERSION"` +- Push the changes: `git push origin` + +## Release prep PR +- Create a PR to check off the change with the peers +- Merge that PR + +## Tagging the release +- Checkout main: `git fetch && git checkout upstream/main` +- Tag the release: `git tag v$RELEASE_VERSION -m "Release $RELEASE_VERSION"` +- Push the tag: `git push upstream v$RELEASE_VERSION` + +## Publishing the release +- After that, update the Release which has CI created for you (after the first build) and add the changelog to the release notes. +- Make sure all the artifacts are there and the CI is green!!! +- Publish the release and make sure it is set as latest. + +## Test the release using the install script: +- `curl -fsSL https://pixi.sh/install.sh | bash` or `iwr -useb https://pixi.sh/install.ps1 | iex` +- `pixi --version` should show the new version + +DONE! From 7262acc72c2c0c64fa2cc4235efb939bb5861bb2 Mon Sep 17 00:00:00 2001 From: Ruben Arts Date: Fri, 14 Jun 2024 16:44:03 +0200 Subject: [PATCH 4/6] fix: lint --- docs/dev-release-steps.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/dev-release-steps.md b/docs/dev-release-steps.md index d1c8e5b20..58674314c 100644 --- a/docs/dev-release-steps.md +++ b/docs/dev-release-steps.md @@ -3,13 +3,13 @@ ## Prep - Make sure main is up-to-date and ci passes: [![build-badge](https://img.shields.io/github/actions/workflow/status/prefix-dev/pixi/rust.yml?style=flat-square&branch=main)](https://github.com/prefix-dev/pixi/actions/workflows/rust.yml?query=branch%3Amain+) - Set the variable `export RELEASE_VERSION=X.Y.Z` in your shell -- Make a new branch for the release: `git fetch upstream && git checkout -b bump/prepare-v$RELEASE_VERSION upstream/main` +- Make a new branch for the release: `git checkout main && git pull upstream main && git checkout -b bump/prepare-v$RELEASE_VERSION` - Bump all versions: `pixi run bump` - Update the changelog: `pixi run bump-changelog` - Don't forget to update the "Highlights" section. - Commit the changes: `git commit -am "chore: version to $RELEASE_VERSION"` - Push the changes: `git push origin` - + ## Release prep PR - Create a PR to check off the change with the peers - Merge that PR From 84b1322ed07bb1adf6516c33dce4ab5a5703e7d8 Mon Sep 17 00:00:00 2001 From: Ruben Arts Date: Fri, 14 Jun 2024 16:50:52 +0200 Subject: [PATCH 5/6] fix: changelog --- CHANGELOG.md | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 807ab8f8d..127a95ecd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,12 +6,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [0.24.2] - 2024-06-14 -### ✨ Highlights - - - -### 📃 Details - #### Documentation - Add readthedocs examples by @bollwyvl in [#1423](https://github.com/prefix-dev/pixi/pull/1423) - Fix typo in project_configuration.md by @RaulPL in [#1502](https://github.com/prefix-dev/pixi/pull/1502) @@ -19,13 +13,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 #### Fixed - Too much shell variables in activation of `pixi shell` by @ruben-arts in [#1507](https://github.com/prefix-dev/pixi/pull/1507) -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - ## [0.24.1] - 2024-06-12 ### 📃 Details #### Fixed From f8f84d305673976600689aca74d8bdc312b63561 Mon Sep 17 00:00:00 2001 From: Sjouke <38879865+Sjouks@users.noreply.github.com> Date: Sat, 15 Jun 2024 08:00:47 +0200 Subject: [PATCH 6/6] fix: tiny error in basic_usage.md (#1513) --- docs/basic_usage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/basic_usage.md b/docs/basic_usage.md index 0fbd42f12..7e8c210ee 100644 --- a/docs/basic_usage.md +++ b/docs/basic_usage.md @@ -55,7 +55,7 @@ Use the `shell` command to activate the environment and start a new shell in the ```shell pixi shell python -exit +exit() ``` You've just learned the basic features of pixi: