Skip to content

Commit

Permalink
feat: new variant resolving / rendering (#1122)
Browse files Browse the repository at this point in the history
  • Loading branch information
wolfv authored Dec 9, 2024
1 parent b3f6bd2 commit 2c7f0e9
Show file tree
Hide file tree
Showing 34 changed files with 1,038 additions and 707 deletions.
5 changes: 5 additions & 0 deletions examples/rich/recipe.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ tests:
- python:
imports:
- rich
- script:
- python -e "print(\"foo\")"
requirements:
run:
- python

about:
homepage: https://github.com/Textualize/rich
Expand Down
55 changes: 2 additions & 53 deletions src/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,13 @@
use std::{path::PathBuf, vec};

use miette::{Context, IntoDiagnostic};
use rattler_conda_types::{Channel, MatchSpec, ParseStrictness, Platform};
use rattler_solve::SolveStrategy;
use rattler_conda_types::{Channel, MatchSpec, ParseStrictness};

use crate::{
metadata::{build_reindexed_channels, Output},
package_test::{self, TestConfiguration},
recipe::parser::TestType,
render::solver::load_repodatas,
tool_configuration::{self, TestStrategy},
tool_configuration,
};

/// Check if the build should be skipped because it already exists in any of the
Expand Down Expand Up @@ -148,8 +146,6 @@ pub async fn run_build(

// We run all the package content tests
for test in output.recipe.tests() {
// TODO we could also run each of the (potentially multiple) test scripts and
// collect the errors
if let TestType::PackageContents { package_contents } = test {
package_contents
.run_test(&paths_json, &output.build_configuration.target_platform)
Expand All @@ -161,53 +157,6 @@ pub async fn run_build(
directories.clean().into_diagnostic()?;
}

// Decide whether the tests should be skipped or not
let (skip_test, skip_test_reason) = match tool_configuration.test_strategy {
TestStrategy::Skip => (true, "the argument --test=skip was set".to_string()),
TestStrategy::Native => {
// Skip if `host_platform != build_platform` and `target_platform != noarch`
if output.build_configuration.target_platform != Platform::NoArch
&& output.build_configuration.host_platform.platform
!= output.build_configuration.build_platform.platform
{
let reason = format!("the argument --test=native was set and the build is a cross-compilation (target_platform={}, build_platform={}, host_platform={})", output.build_configuration.target_platform, output.build_configuration.build_platform.platform, output.build_configuration.host_platform.platform);

(true, reason)
} else {
(false, "".to_string())
}
}
TestStrategy::NativeAndEmulated => (false, "".to_string()),
};

if skip_test {
tracing::info!("Skipping tests because {}", skip_test_reason);
build_reindexed_channels(&output.build_configuration, tool_configuration)
.into_diagnostic()
.context("failed to reindex output channel")?;
} else {
package_test::run_test(
&result,
&TestConfiguration {
test_prefix: directories.work_dir.join("test"),
target_platform: Some(output.build_configuration.target_platform),
host_platform: Some(output.build_configuration.host_platform.clone()),
current_platform: output.build_configuration.build_platform.clone(),
keep_test_prefix: tool_configuration.no_clean,
//channels: output.reindex_channels().into_diagnostic()?,
channels: build_reindexed_channels(&output.build_configuration, tool_configuration)
.into_diagnostic()
.context("failed to reindex output channel")?,
channel_priority: tool_configuration.channel_priority,
solve_strategy: SolveStrategy::Highest,
tool_configuration: tool_configuration.clone(),
},
None,
)
.await
.into_diagnostic()?;
}

drop(enter);

if !tool_configuration.no_clean {
Expand Down
2 changes: 1 addition & 1 deletion src/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ impl Output {
// intersect variant with requirements
let mut selected_variant = BTreeMap::new();
for key in requirement_names.iter() {
if let Some(value) = self.variant().get(key) {
if let Some(value) = self.variant().get(&key.as_str().into()) {
selected_variant.insert(key.as_ref(), value.clone());
}
}
Expand Down
20 changes: 7 additions & 13 deletions src/env_vars.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,10 @@ pub fn python_vars(output: &Output) -> HashMap<String, Option<String>> {
}

// find python in the host dependencies
let mut python_version = output.variant().get("python").map(|s| s.to_string());
let mut python_version = output
.variant()
.get(&"python".into())
.map(|s| s.to_string());
if python_version.is_none() {
if let Some((record, requested)) = output.find_resolved_package("python") {
if requested {
Expand Down Expand Up @@ -79,7 +82,7 @@ pub fn python_vars(output: &Output) -> HashMap<String, Option<String>> {
insert!(result, "SP_DIR", site_packages_dir.to_string_lossy());
}

if let Some(npy_version) = output.variant().get("numpy") {
if let Some(npy_version) = output.variant().get(&"numpy".into()) {
let npy_ver: Vec<_> = npy_version.split('.').take(2).collect();
let npy_ver = npy_ver.join(".");
insert!(result, "NPY_VER", npy_ver);
Expand All @@ -99,7 +102,7 @@ pub fn python_vars(output: &Output) -> HashMap<String, Option<String>> {
pub fn r_vars(output: &Output) -> HashMap<String, Option<String>> {
let mut result = HashMap::new();

if let Some(r_ver) = output.variant().get("r-base") {
if let Some(r_ver) = output.variant().get(&"r-base".into()) {
insert!(result, "R_VER", r_ver);

let r_bin = if output.host_platform().platform.is_windows() {
Expand Down Expand Up @@ -270,16 +273,7 @@ pub fn vars(output: &Output, build_state: &str) -> HashMap<String, Option<String
);

let hash = output.build_configuration.hash.clone();
insert!(
vars,
"PKG_BUILD_STRING",
output
.recipe
.build()
.string()
.resolve(&hash, output.recipe.build().number)
.into_owned()
);
insert!(vars, "PKG_BUILD_STRING", output.build_string().to_string());
insert!(vars, "PKG_HASH", hash);

if output.build_configuration.cross_compilation() {
Expand Down
31 changes: 15 additions & 16 deletions src/hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ use serde::{Deserialize, Serialize};
use serde_json::ser::Formatter;
use sha1::{Digest, Sha1};

use crate::normalized_key::NormalizedKey;

/// A hash will be added if all of these are true for any dependency:
///
/// 1. package is an explicit dependency in build, host, or run deps
Expand Down Expand Up @@ -94,7 +96,7 @@ pub struct HashInput(String);

impl HashInput {
/// Create a new hash input from a variant
pub fn from_variant(variant: &BTreeMap<String, String>) -> Self {
pub fn from_variant(variant: &BTreeMap<NormalizedKey, String>) -> Self {
let mut buf = Vec::new();
let mut ser = serde_json::Serializer::with_formatter(&mut buf, PythonFormatter {});

Expand Down Expand Up @@ -124,15 +126,15 @@ impl std::fmt::Display for HashInfo {
}

impl HashInfo {
fn hash_prefix(variant: &BTreeMap<String, String>, noarch: &NoArchType) -> String {
fn hash_prefix(variant: &BTreeMap<NormalizedKey, String>, noarch: &NoArchType) -> String {
if noarch.is_python() {
return "py".to_string();
}

let mut map: HashMap<String, String> = HashMap::new();

for (variant_key, version_spec) in variant.iter() {
let prefix = match variant_key.as_str() {
let prefix = match variant_key.normalize().as_str() {
"numpy" => "np",
"python" => "py",
"perl" => "pl",
Expand Down Expand Up @@ -174,7 +176,7 @@ impl HashInfo {
}

/// Compute the build string for a given variant
pub fn from_variant(variant: &BTreeMap<String, String>, noarch: &NoArchType) -> Self {
pub fn from_variant(variant: &BTreeMap<NormalizedKey, String>, noarch: &NoArchType) -> Self {
Self {
hash: Self::hash_from_input(&HashInput::from_variant(variant)),
prefix: Self::hash_prefix(variant, noarch),
Expand All @@ -190,21 +192,18 @@ mod tests {
#[test]
fn test_hash() {
let mut input = BTreeMap::new();
input.insert("rust_compiler".to_string(), "rust".to_string());
input.insert("build_platform".to_string(), "osx-64".to_string());
input.insert("c_compiler".to_string(), "clang".to_string());
input.insert("target_platform".to_string(), "osx-arm64".to_string());
input.insert("openssl".to_string(), "3".to_string());
input.insert("rust_compiler".into(), "rust".to_string());
input.insert("build_platform".into(), "osx-64".to_string());
input.insert("c_compiler".into(), "clang".to_string());
input.insert("target_platform".into(), "osx-arm64".to_string());
input.insert("openssl".into(), "3".to_string());
input.insert(
"CONDA_BUILD_SYSROOT".to_string(),
"CONDA_BUILD_SYSROOT".into(),
"/Applications/Xcode_13.2.1.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.0.sdk".to_string(),
);
input.insert(
"channel_targets".to_string(),
"conda-forge main".to_string(),
);
input.insert("python".to_string(), "3.11.* *_cpython".to_string());
input.insert("c_compiler_version".to_string(), "14".to_string());
input.insert("channel_targets".into(), "conda-forge main".to_string());
input.insert("python".into(), "3.11.* *_cpython".to_string());
input.insert("c_compiler_version".into(), "14".to_string());

let build_string_from_output = HashInfo::from_variant(&input, &NoArchType::none());
assert_eq!(build_string_from_output.to_string(), "py311h507f6e9");
Expand Down
Loading

0 comments on commit 2c7f0e9

Please sign in to comment.