Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
bahugo authored Nov 24, 2024
2 parents ab3ecda + 1650d6a commit bd54a35
Show file tree
Hide file tree
Showing 65 changed files with 1,771 additions and 237 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ jobs:
cache: true
- uses: Swatinem/rust-cache@v2
with:
workspaces: ". -> target-pixi"
workspaces: ". -> target/pixi"
key: ${{ hashFiles('pixi.lock') }}
- name: Test pixi
run: pixi run test-slow
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test_common_wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
name: ${{ matrix.arch.name }} - Test Installation of Common Wheels
runs-on: ${{ matrix.arch.os }}
env:
TARGET_RELEASE: "${{ github.workspace }}/target-pixi/release"
TARGET_RELEASE: "${{ github.workspace }}/target/pixi/release"
LOGS_DIR: "${{ github.workspace }}/tests/wheel_tests/.logs"
SUMMARY_FILE: "${{ github.workspace }}/tests/wheel_tests/.summary.md"
PYTHONIOENCODING: utf-8
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test_downstream.yml
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ jobs:
timeout-minutes: 30
runs-on: ${{ matrix.arch.os }}
env:
TARGET_RELEASE: "${{ github.workspace }}/target-pixi/release"
TARGET_RELEASE: "${{ github.workspace }}/target/pixi/release"
strategy:
fail-fast: false
matrix:
Expand Down
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,3 @@ __pycache__
site/
.cache
pytest-temp
target-pixi
116 changes: 113 additions & 3 deletions crates/pixi_config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ use reqwest_middleware::ClientWithMiddleware;
use serde::{de::IntoDeserializer, Deserialize, Serialize};
use url::Url;

const EXPERIMENTAL: &str = "experimental";

pub fn default_channel_config() -> ChannelConfig {
ChannelConfig::default_with_root_dir(
std::env::current_dir().expect("Could not retrieve the current directory"),
Expand Down Expand Up @@ -122,9 +124,17 @@ pub struct ConfigCliPrompt {
#[arg(long)]
change_ps1: Option<bool>,
}
impl From<ConfigCliPrompt> for Config {
fn from(cli: ConfigCliPrompt) -> Self {
Self {
change_ps1: cli.change_ps1,
..Default::default()
}
}
}

impl ConfigCliPrompt {
pub fn merge_with_config(self, config: Config) -> Config {
pub fn merge_config(self, config: Config) -> Config {
let mut config = config;
config.change_ps1 = self.change_ps1.or(config.change_ps1);
config
Expand Down Expand Up @@ -168,6 +178,29 @@ impl RepodataConfig {
}
}

#[derive(Parser, Debug, Default, Clone)]
pub struct ConfigCliActivation {
/// Do not use the environment activation cache. (default: true except in experimental mode)
#[arg(long)]
force_activate: bool,
}

impl ConfigCliActivation {
pub fn merge_config(self, config: Config) -> Config {
let mut config = config;
config.force_activate = Some(self.force_activate);
config
}
}

impl From<ConfigCliActivation> for Config {
fn from(cli: ConfigCliActivation) -> Self {
Self {
force_activate: Some(cli.force_activate),
..Default::default()
}
}
}
#[derive(Clone, Default, Debug, Deserialize, Serialize)]
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
pub struct RepodataChannelConfig {
Expand Down Expand Up @@ -273,6 +306,33 @@ impl Default for DetachedEnvironments {
}
}

#[derive(Default, Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
pub struct ExperimentalConfig {
/// The option to opt into the environment activation cache feature.
/// This is an experimental feature and may be removed in the future or made default.
#[serde(default)]
#[serde(skip_serializing_if = "Option::is_none")]
pub use_environment_activation_cache: Option<bool>,
}

impl ExperimentalConfig {
pub fn merge(self, other: Self) -> Self {
Self {
use_environment_activation_cache: other
.use_environment_activation_cache
.or(self.use_environment_activation_cache),
}
}
pub fn use_environment_activation_cache(&self) -> bool {
self.use_environment_activation_cache.unwrap_or(false)
}

pub fn is_default(&self) -> bool {
self.use_environment_activation_cache.is_none()
}
}

impl PyPIConfig {
/// Merge the given PyPIConfig into the current one.
pub fn merge(self, other: Self) -> Self {
Expand Down Expand Up @@ -479,6 +539,16 @@ pub struct Config {
/// it back to the .pixi folder.
#[serde(skip_serializing_if = "Option::is_none")]
pub detached_environments: Option<DetachedEnvironments>,

/// The option to disable the environment activation cache
#[serde(default)]
#[serde(skip_serializing_if = "Option::is_none")]
pub force_activate: Option<bool>,

/// Experimental features that can be enabled.
#[serde(default)]
#[serde(skip_serializing_if = "ExperimentalConfig::is_default")]
pub experimental: ExperimentalConfig,
}

impl Default for Config {
Expand All @@ -495,6 +565,8 @@ impl Default for Config {
pypi_config: PyPIConfig::default(),
detached_environments: Some(DetachedEnvironments::default()),
pinning_strategy: Default::default(),
force_activate: None,
experimental: Default::default(),
}
}
}
Expand Down Expand Up @@ -666,10 +738,13 @@ impl Config {
let mut config = Self::load_system();

for p in config_path_global() {
if !p.is_file() {
continue;
}
match Self::from_path(&p) {
Ok(c) => config = config.merge_config(c),
Err(e) => tracing::debug!(
"Failed to load global config: {} (error: {})",
Err(e) => tracing::warn!(
"Failed to load global config '{}' with error: {}",
p.display(),
e
),
Expand Down Expand Up @@ -732,6 +807,7 @@ impl Config {
"pypi-config.index-url",
"pypi-config.extra-index-urls",
"pypi-config.keyring-provider",
"experimental.use-environment-activation-cache",
]
}

Expand Down Expand Up @@ -760,6 +836,8 @@ impl Config {
pypi_config: other.pypi_config.merge(self.pypi_config),
detached_environments: other.detached_environments.or(self.detached_environments),
pinning_strategy: other.pinning_strategy.or(self.pinning_strategy),
force_activate: other.force_activate,
experimental: other.experimental.merge(self.experimental),
}
}

Expand Down Expand Up @@ -817,6 +895,14 @@ impl Config {
self.detached_environments.clone().unwrap_or_default()
}

pub fn force_activate(&self) -> bool {
self.force_activate.unwrap_or(false)
}

pub fn experimental_activation_cache_usage(&self) -> bool {
self.experimental.use_environment_activation_cache()
}

/// Modify this config with the given key and value
///
/// # Note
Expand Down Expand Up @@ -940,6 +1026,29 @@ impl Config {
_ => return Err(err),
}
}
key if key.starts_with(EXPERIMENTAL) => {
if key == EXPERIMENTAL {
if let Some(value) = value {
self.experimental = serde_json::de::from_str(&value).into_diagnostic()?;
} else {
self.experimental = ExperimentalConfig::default();
}
return Ok(());
} else if !key.starts_with(format!("{EXPERIMENTAL}.").as_str()) {
return Err(err);
}

let subkey = key
.strip_prefix(format!("{EXPERIMENTAL}.").as_str())
.unwrap();
match subkey {
"use-environment-activation-cache" => {
self.experimental.use_environment_activation_cache =
value.map(|v| v.parse()).transpose().into_diagnostic()?;
}
_ => return Err(err),
}
}
_ => return Err(err),
}

Expand Down Expand Up @@ -1088,6 +1197,7 @@ UNUSED = "unused"
config.authentication_override_file,
Some(PathBuf::from("path.json"))
);
assert!(!config.experimental.use_environment_activation_cache());
}

#[test]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,8 @@ Config {
true,
),
),
force_activate: None,
experimental: ExperimentalConfig {
use_environment_activation_cache: None,
},
}
1 change: 1 addition & 0 deletions crates/pixi_consts/src/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub const SOLVE_GROUP_ENVIRONMENTS_DIR: &str = "solve-group-envs";
pub const PYPI_DEPENDENCIES: &str = "pypi-dependencies";
pub const DEPENDENCIES: &str = "dependencies";
pub const TASK_CACHE_DIR: &str = "task-cache-v0";
pub const ACTIVATION_ENV_CACHE_DIR: &str = "activation-env-v0";
pub const PIXI_UV_INSTALLER: &str = "uv-pixi";
pub const CONDA_PACKAGE_CACHE_DIR: &str = rattler_cache::PACKAGE_CACHE_DIR;
pub const CONDA_REPODATA_CACHE_DIR: &str = rattler_cache::REPODATA_CACHE_DIR;
Expand Down
53 changes: 45 additions & 8 deletions crates/pixi_manifest/src/pypi/pypi_requirement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ pub enum PyPiRequirement {
version: VersionOrStar,
#[serde(default)]
extras: Vec<ExtraName>,
#[serde(default)]
index: Option<Url>,
},
RawVersion(VersionOrStar),
}
Expand Down Expand Up @@ -138,6 +140,10 @@ struct RawPyPiRequirement {

// Git and Url only
pub subdirectory: Option<String>,

// Pinned index
#[serde(default)]
pub index: Option<Url>,
}

impl<'de> Deserialize<'de> for PyPiRequirement {
Expand Down Expand Up @@ -186,18 +192,24 @@ impl<'de> Deserialize<'de> for PyPiRequirement {
)));
}

let req = match (raw_req.url, raw_req.path, raw_req.git, raw_req.extras) {
(Some(url), None, None, extras) => PyPiRequirement::Url {
let req = match (
raw_req.url,
raw_req.path,
raw_req.git,
raw_req.extras,
raw_req.index,
) {
(Some(url), None, None, extras, None) => PyPiRequirement::Url {
url,
extras,
subdirectory: raw_req.subdirectory,
},
(None, Some(path), None, extras) => PyPiRequirement::Path {
(None, Some(path), None, extras, None) => PyPiRequirement::Path {
path,
editable: raw_req.editable,
extras,
},
(None, None, Some(git), extras) => PyPiRequirement::Git {
(None, None, Some(git), extras, None) => PyPiRequirement::Git {
url: ParsedGitUrl {
git,
branch: raw_req.branch,
Expand All @@ -207,13 +219,15 @@ impl<'de> Deserialize<'de> for PyPiRequirement {
},
extras,
},
(None, None, None, extras) => PyPiRequirement::Version {
(None, None, None, extras, index) => PyPiRequirement::Version {
version: raw_req.version.unwrap_or(VersionOrStar::Star),
extras,
index,
},
(_, _, _, extras) if !extras.is_empty() => PyPiRequirement::Version {
(_, _, _, extras, index) if !extras.is_empty() => PyPiRequirement::Version {
version: raw_req.version.unwrap_or(VersionOrStar::Star),
extras,
index,
},
_ => {
return Err(serde_untagged::de::Error::custom(
Expand Down Expand Up @@ -278,17 +292,35 @@ impl From<PyPiRequirement> for toml_edit::Value {
}
}

fn insert_index(table: &mut toml_edit::InlineTable, index: &Option<Url>) {
if let Some(index) = index {
table.insert(
"index",
toml_edit::Value::String(toml_edit::Formatted::new(index.to_string())),
);
}
}

match &val {
PyPiRequirement::Version { version, extras } if extras.is_empty() => {
PyPiRequirement::Version {
version,
extras,
index,
} if extras.is_empty() && index.is_none() => {
toml_edit::Value::from(version.to_string())
}
PyPiRequirement::Version { version, extras } => {
PyPiRequirement::Version {
version,
extras,
index,
} => {
let mut table = toml_edit::Table::new().into_inline_table();
table.insert(
"version",
toml_edit::Value::String(toml_edit::Formatted::new(version.to_string())),
);
insert_extras(&mut table, extras);
insert_index(&mut table, index);
toml_edit::Value::InlineTable(table.to_owned())
}
PyPiRequirement::Git {
Expand Down Expand Up @@ -423,6 +455,7 @@ impl TryFrom<pep508_rs::Requirement> for PyPiRequirement {
pep508_rs::VersionOrUrl::VersionSpecifier(v) => PyPiRequirement::Version {
version: v.into(),
extras: req.extras,
index: None,
},
pep508_rs::VersionOrUrl::Url(u) => {
let url = u.to_url();
Expand Down Expand Up @@ -494,6 +527,7 @@ impl TryFrom<pep508_rs::Requirement> for PyPiRequirement {
PyPiRequirement::Version {
version: VersionOrStar::Star,
extras: req.extras,
index: None,
}
} else {
PyPiRequirement::RawVersion(VersionOrStar::Star)
Expand Down Expand Up @@ -616,6 +650,7 @@ mod tests {
&PyPiRequirement::Version {
version: ">=3.12".parse().unwrap(),
extras: vec![ExtraName::from_str("bar").unwrap()],
index: None,
}
);

Expand All @@ -636,6 +671,7 @@ mod tests {
ExtraName::from_str("bar").unwrap(),
ExtraName::from_str("foo").unwrap(),
],
index: None,
}
);
}
Expand All @@ -659,6 +695,7 @@ mod tests {
ExtraName::from_str("feature1").unwrap(),
ExtraName::from_str("feature2").unwrap()
],
index: None,
}
);
}
Expand Down
Loading

0 comments on commit bd54a35

Please sign in to comment.