diff --git a/crates/pixi_build_discovery/src/discovery.rs b/crates/pixi_build_discovery/src/discovery.rs index ef5abe8090..633b8000dd 100644 --- a/crates/pixi_build_discovery/src/discovery.rs +++ b/crates/pixi_build_discovery/src/discovery.rs @@ -254,12 +254,12 @@ impl DiscoveredBackend { .expect("points to a file") .to_path_buf(), project_model: Some(project_model), - configuration: build_system.configuration.map(|config| { + configuration: build_system.config.map(|config| { config .deserialize_into() .expect("Configuration dictionary needs to be serializable to JSON") }), - target_configuration: build_system.target_configuration.map(|c| { + target_configuration: build_system.target_config.map(|c| { c.into_iter() .map(|(selector, config)| { ( diff --git a/crates/pixi_manifest/src/build_system.rs b/crates/pixi_manifest/src/build_system.rs index 8f2b270c7b..c7b1066fac 100644 --- a/crates/pixi_manifest/src/build_system.rs +++ b/crates/pixi_manifest/src/build_system.rs @@ -6,7 +6,7 @@ use rattler_conda_types::NamedChannelOrUrl; use crate::TargetSelector; use crate::{ - TomlError, + TomlError, WithWarnings, toml::{FromTomlStr, TomlPackageBuild}, }; @@ -28,10 +28,10 @@ pub struct PackageBuild { pub source: Option, /// Additional configuration for the build backend. - pub configuration: Option, + pub config: Option, /// Target-specific configuration for different platforms - pub target_configuration: Option>, + pub target_config: Option>, } impl PackageBuild { @@ -42,8 +42,8 @@ impl PackageBuild { channels: Some(channels), additional_dependencies: IndexMap::default(), source: None, - configuration: None, - target_configuration: None, + config: None, + target_config: None, } } } @@ -59,7 +59,7 @@ pub struct BuildBackend { impl PackageBuild { /// Parses the specified string as a toml representation of a build system. - pub fn from_toml_str(source: &str) -> Result { + pub fn from_toml_str(source: &str) -> Result, TomlError> { TomlPackageBuild::from_toml_str(source).and_then(TomlPackageBuild::into_build_system) } } @@ -75,7 +75,7 @@ mod tests { "#; let build = PackageBuild::from_toml_str(toml).unwrap(); - assert_eq!(build.backend.name.as_source(), "pixi-build-python"); + assert_eq!(build.value.backend.name.as_source(), "pixi-build-python"); } #[test] @@ -90,9 +90,12 @@ mod tests { "#; let build = PackageBuild::from_toml_str(toml).unwrap(); - assert_eq!(build.backend.name.as_source(), "pixi-build-rattler-build"); - assert!(build.source.is_some()); - assert!(!build.source.unwrap().is_git()); + assert_eq!( + build.value.backend.name.as_source(), + "pixi-build-rattler-build" + ); + assert!(build.value.source.is_some()); + assert!(!build.value.source.unwrap().is_git()); } #[test] @@ -107,9 +110,12 @@ mod tests { "#; let build = PackageBuild::from_toml_str(toml).unwrap(); - assert_eq!(build.backend.name.as_source(), "pixi-build-rattler-build"); - assert!(build.source.is_some()); - assert!(build.source.unwrap().is_git()); + assert_eq!( + build.value.backend.name.as_source(), + "pixi-build-rattler-build" + ); + assert!(build.value.source.is_some()); + assert!(build.value.source.unwrap().is_git()); } #[test] @@ -124,9 +130,12 @@ mod tests { "#; let build = PackageBuild::from_toml_str(toml).unwrap(); - assert_eq!(build.backend.name.as_source(), "pixi-build-rattler-build"); - assert!(build.source.is_some()); - assert!(!build.source.as_ref().unwrap().is_git()); + assert_eq!( + build.value.backend.name.as_source(), + "pixi-build-rattler-build" + ); + assert!(build.value.source.is_some()); + assert!(!build.value.source.as_ref().unwrap().is_git()); } #[test] @@ -141,11 +150,14 @@ mod tests { "#; let build = PackageBuild::from_toml_str(toml).unwrap(); - assert_eq!(build.backend.name.as_source(), "pixi-build-rattler-build"); - assert!(build.source.is_some()); + assert_eq!( + build.value.backend.name.as_source(), + "pixi-build-rattler-build" + ); + assert!(build.value.source.is_some()); // Verify it's a path source and contains the relative path - if let Some(source) = &build.source { + if let Some(source) = &build.value.source { match &source { pixi_spec::SourceLocationSpec::Path(path_spec) => { assert_eq!(path_spec.path.as_str(), "../other-source"); @@ -167,11 +179,14 @@ mod tests { "#; let build = PackageBuild::from_toml_str(toml).unwrap(); - assert_eq!(build.backend.name.as_source(), "pixi-build-rattler-build"); - assert!(build.source.is_some()); + assert_eq!( + build.value.backend.name.as_source(), + "pixi-build-rattler-build" + ); + assert!(build.value.source.is_some()); // Verify it's a path source and contains the home directory path - if let Some(source) = &build.source { + if let Some(source) = &build.value.source { match &source { pixi_spec::SourceLocationSpec::Path(path_spec) => { assert_eq!(path_spec.path.as_str(), "~/my-source"); @@ -195,9 +210,9 @@ mod tests { "#; let build = PackageBuild::from_toml_str(toml).unwrap(); - assert!(build.source.is_some()); + assert!(build.value.source.is_some()); - if let Some(source) = &build.source { + if let Some(source) = &build.value.source { match &source { pixi_spec::SourceLocationSpec::Path(path_spec) => { // Test that the path spec can resolve relative paths correctly @@ -224,9 +239,9 @@ mod tests { "#; let build = PackageBuild::from_toml_str(toml).unwrap(); - assert!(build.source.is_some()); + assert!(build.value.source.is_some()); - if let Some(source) = &build.source { + if let Some(source) = &build.value.source { match &source { pixi_spec::SourceLocationSpec::Path(path_spec) => { // Test that absolute paths are returned as-is during resolution @@ -261,9 +276,9 @@ mod tests { ); let build = PackageBuild::from_toml_str(&toml).unwrap(); - assert!(build.source.is_some(), "Failed for path: {}", path); + assert!(build.value.source.is_some(), "Failed for path: {}", path); - if let Some(source) = &build.source { + if let Some(source) = &build.value.source { match &source { pixi_spec::SourceLocationSpec::Path(path_spec) => { // Verify the path is preserved correctly diff --git a/crates/pixi_manifest/src/toml/build_backend.rs b/crates/pixi_manifest/src/toml/build_backend.rs index c6c9f46318..48441ab6dd 100644 --- a/crates/pixi_manifest/src/toml/build_backend.rs +++ b/crates/pixi_manifest/src/toml/build_backend.rs @@ -8,11 +8,12 @@ use std::borrow::Cow; use toml_span::{DeserError, Error, Spanned, Value, de_helpers::TableHelper, value::ValueInner}; use crate::{ - PackageBuild, TargetSelector, TomlError, + PackageBuild, TargetSelector, TomlError, WithWarnings, build_system::BuildBackend, error::GenericError, toml::build_target::TomlPackageBuildTarget, utils::{PixiSpanned, package_map::UniquePackageMap}, + warning::Deprecation, }; #[derive(Debug)] @@ -23,6 +24,7 @@ pub struct TomlPackageBuild { pub source: Option, pub configuration: Option, pub target: IndexMap, TomlPackageBuildTarget>, + pub warnings: Vec, } #[derive(Debug)] @@ -34,7 +36,7 @@ pub struct TomlBuildBackend { } impl TomlPackageBuild { - pub fn into_build_system(self) -> Result { + pub fn into_build_system(self) -> Result, TomlError> { // Parse the build backend and ensure it is a binary spec. let build_backend_spec = self.backend.value.spec.into_spec().map_err(|e| { TomlError::Generic( @@ -76,7 +78,7 @@ impl TomlPackageBuild { }; // Convert target-specific build configurations - let target_configuration = self + let target_config = self .target .into_iter() .flat_map(|(selector, target)| { @@ -86,20 +88,23 @@ impl TomlPackageBuild { }) .collect::>(); - Ok(PackageBuild { - backend: BuildBackend { - name: self.backend.value.name.value, - spec: build_backend_spec, - }, - additional_dependencies, - channels, - source: self.source, - configuration: self.configuration, - target_configuration: if target_configuration.is_empty() { - None - } else { - Some(target_configuration) + Ok(WithWarnings { + value: PackageBuild { + backend: BuildBackend { + name: self.backend.value.name.value, + spec: build_backend_spec, + }, + additional_dependencies, + channels, + source: self.source, + config: self.configuration, + target_config: if target_config.is_empty() { + None + } else { + Some(target_config) + }, }, + warnings: self.warnings, }) } } @@ -181,6 +186,8 @@ fn spec_from_spanned_toml_location( impl<'de> toml_span::Deserialize<'de> for TomlPackageBuild { fn deserialize(value: &mut Value<'de>) -> Result { let mut th = TableHelper::new(value)?; + let mut warnings = Vec::new(); + let build_backend: PixiSpanned = th.required_s("backend")?.into(); let channels = th .optional_s::>>>("channels") @@ -196,10 +203,15 @@ impl<'de> toml_span::Deserialize<'de> for TomlPackageBuild { .map(spec_from_spanned_toml_location) .transpose()?; - let configuration = th - .take("configuration") - .map(|(_, mut value)| convert_toml_to_serde(&mut value)) - .transpose()?; + // Try the new "config" key first, then fall back to deprecated "configuration" + let configuration = if let Some((_, mut value)) = th.take("config") { + Some(convert_toml_to_serde(&mut value)?) + } else if let Some((key, mut value)) = th.table.remove_entry("configuration") { + warnings.push(Deprecation::renamed_field("configuration", "config", key.span).into()); + Some(convert_toml_to_serde(&mut value)?) + } else { + None + }; let target = th .optional::>>("target") @@ -255,6 +267,7 @@ impl<'de> toml_span::Deserialize<'de> for TomlPackageBuild { source, configuration, target, + warnings, }) } } @@ -286,6 +299,37 @@ mod test { insta::assert_debug_snapshot!(parsed); } + #[test] + fn test_config_parsing() { + let toml = r#" + backend = { name = "foobar", version = "*" } + config = { key = "value", other = ["foo", "bar"], integer = 1234, nested = { abc = "def" } } + "#; + let parsed = ::from_toml_str(toml) + .and_then(TomlPackageBuild::into_build_system) + .expect("parsing should succeed"); + + assert!(parsed.warnings.is_empty()); + insta::assert_debug_snapshot!(parsed.value); + } + + #[test] + fn test_configuration_deprecation_warning() { + let toml = r#" + backend = { name = "foobar", version = "*" } + configuration = { key = "value" } + "#; + let parsed = ::from_toml_str(toml) + .and_then(TomlPackageBuild::into_build_system) + .expect("parsing should succeed"); + + assert_eq!(parsed.warnings.len(), 1); + insta::assert_snapshot!(format_parse_error( + toml, + parsed.warnings.into_iter().next().unwrap() + )); + } + #[test] fn test_missing_version_specifier() { assert_snapshot!(expect_parse_failure( @@ -347,7 +391,7 @@ mod test { .and_then(TomlPackageBuild::into_build_system) .expect("parsing should succeed"); - assert_eq!(parsed.channels.unwrap().len(), 1); + assert_eq!(parsed.value.channels.unwrap().len(), 1); } #[test] @@ -360,7 +404,7 @@ mod test { .and_then(TomlPackageBuild::into_build_system) .expect("parsing should succeed"); - assert_eq!(parsed.channels.unwrap().len(), 1); + assert_eq!(parsed.value.channels.unwrap().len(), 1); } #[test] @@ -374,7 +418,7 @@ mod test { .expect("parsing should succeed"); // Should use backend.channels, not top-level channels - let channels = parsed.channels.unwrap(); + let channels = parsed.value.channels.unwrap(); assert_eq!(channels.len(), 1); assert_eq!( channels[0].to_string(), @@ -400,9 +444,10 @@ mod test { .and_then(TomlPackageBuild::into_build_system) .expect("parsing should succeed"); - assert!(!parsed.additional_dependencies.is_empty()); + assert!(!parsed.value.additional_dependencies.is_empty()); assert!( parsed + .value .additional_dependencies .contains_key(&"git".parse::().unwrap()) ); @@ -418,9 +463,10 @@ mod test { .and_then(TomlPackageBuild::into_build_system) .expect("parsing should succeed"); - assert!(!parsed.additional_dependencies.is_empty()); + assert!(!parsed.value.additional_dependencies.is_empty()); assert!( parsed + .value .additional_dependencies .contains_key(&"git".parse::().unwrap()) ); @@ -437,14 +483,16 @@ mod test { .expect("parsing should succeed"); // Should prioritize backend.additional-dependencies - assert!(!parsed.additional_dependencies.is_empty()); + assert!(!parsed.value.additional_dependencies.is_empty()); assert!( parsed + .value .additional_dependencies .contains_key(&"rust".parse::().unwrap()) ); assert!( !parsed + .value .additional_dependencies .contains_key(&"git".parse::().unwrap()) ); diff --git a/crates/pixi_manifest/src/toml/package.rs b/crates/pixi_manifest/src/toml/package.rs index d1bcad6ef4..7368316463 100644 --- a/crates/pixi_manifest/src/toml/package.rs +++ b/crates/pixi_manifest/src/toml/package.rs @@ -351,7 +351,10 @@ impl TomlPackage { preview: &Preview, root_directory: Option<&Path>, ) -> Result, TomlError> { - let warnings = Vec::new(); + let mut warnings = Vec::new(); + + let build_result = self.build.into_build_system()?; + warnings.extend(build_result.warnings); // Resolve fields with 3-tier hierarchy: direct → workspace → package defaults → // error @@ -496,7 +499,7 @@ impl TomlPackage { "documentation", )?, }, - build: self.build.into_build_system()?, + build: build_result.value, targets: Targets::from_default_and_user_defined(default_package_target, targets), }) .with_warnings(warnings)) diff --git a/crates/pixi_manifest/src/toml/snapshots/pixi_manifest__toml__build_backend__test__additional_keys.snap b/crates/pixi_manifest/src/toml/snapshots/pixi_manifest__toml__build_backend__test__additional_keys.snap index 21757ce2c3..a2e3bcbdd4 100644 --- a/crates/pixi_manifest/src/toml/snapshots/pixi_manifest__toml__build_backend__test__additional_keys.snap +++ b/crates/pixi_manifest/src/toml/snapshots/pixi_manifest__toml__build_backend__test__additional_keys.snap @@ -1,8 +1,9 @@ --- source: crates/pixi_manifest/src/toml/build_backend.rs expression: "expect_parse_failure(r#\"\n backend = { name = \"foobar\", version = \"*\" }\n additional = \"key\"\n \"#)" +snapshot_kind: text --- - × Unexpected keys, expected only 'backend', 'channels', 'additional-dependencies', 'source', 'configuration', 'target' + × Unexpected keys, expected only 'backend', 'channels', 'additional-dependencies', 'source', 'config', 'target' ╭─[pixi.toml:3:13] 2 │ backend = { name = "foobar", version = "*" } 3 │ additional = "key" diff --git a/crates/pixi_manifest/src/toml/snapshots/pixi_manifest__toml__build_backend__test__config_parsing.snap b/crates/pixi_manifest/src/toml/snapshots/pixi_manifest__toml__build_backend__test__config_parsing.snap new file mode 100644 index 0000000000..35b072a046 --- /dev/null +++ b/crates/pixi_manifest/src/toml/snapshots/pixi_manifest__toml__build_backend__test__config_parsing.snap @@ -0,0 +1,71 @@ +--- +source: crates/pixi_manifest/src/toml/build_backend.rs +expression: parsed.value +snapshot_kind: text +--- +PackageBuild { + backend: BuildBackend { + name: PackageName { + normalized: None, + source: "foobar", + }, + spec: DetailedVersion( + DetailedSpec { + version: Some( + Any, + ), + build: None, + build_number: None, + file_name: None, + channel: None, + subdir: None, + license: None, + md5: None, + sha256: None, + }, + ), + }, + additional_dependencies: {}, + channels: None, + source: None, + config: Some( + Map( + { + String( + "integer", + ): I64( + 1234, + ), + String( + "key", + ): String( + "value", + ), + String( + "nested", + ): Map( + { + String( + "abc", + ): String( + "def", + ), + }, + ), + String( + "other", + ): Seq( + [ + String( + "foo", + ), + String( + "bar", + ), + ], + ), + }, + ), + ), + target_config: None, +} diff --git a/crates/pixi_manifest/src/toml/snapshots/pixi_manifest__toml__build_backend__test__configuration_deprecation_warning.snap b/crates/pixi_manifest/src/toml/snapshots/pixi_manifest__toml__build_backend__test__configuration_deprecation_warning.snap new file mode 100644 index 0000000000..7ad1d06454 --- /dev/null +++ b/crates/pixi_manifest/src/toml/snapshots/pixi_manifest__toml__build_backend__test__configuration_deprecation_warning.snap @@ -0,0 +1,13 @@ +--- +source: crates/pixi_manifest/src/toml/build_backend.rs +expression: "format_parse_error(toml, parsed.warnings.into_iter().next().unwrap())" +snapshot_kind: text +--- + ⚠ The `configuration` field is deprecated. Use `config` instead. + ╭─[pixi.toml:3:13] + 2 │ backend = { name = "foobar", version = "*" } + 3 │ configuration = { key = "value" } + · ──────┬────── + · ╰── replace this with 'config' + 4 │ + ╰──── diff --git a/crates/pixi_manifest/src/toml/snapshots/pixi_manifest__toml__build_backend__test__configuration_parsing.snap b/crates/pixi_manifest/src/toml/snapshots/pixi_manifest__toml__build_backend__test__configuration_parsing.snap index 5008a2b2fd..f4a405f6b4 100644 --- a/crates/pixi_manifest/src/toml/snapshots/pixi_manifest__toml__build_backend__test__configuration_parsing.snap +++ b/crates/pixi_manifest/src/toml/snapshots/pixi_manifest__toml__build_backend__test__configuration_parsing.snap @@ -1,6 +1,7 @@ --- source: crates/pixi_manifest/src/toml/build_backend.rs expression: parsed +snapshot_kind: text --- TomlPackageBuild { backend: PixiSpanned { @@ -96,4 +97,26 @@ TomlPackageBuild { ), ), target: {}, + warnings: [ + Deprecation( + Deprecation { + message: "The `configuration` field is deprecated. Use `config` instead.", + labels: [ + LabeledSpan { + label: Some( + "replace this with 'config'", + ), + span: SourceSpan { + offset: SourceOffset( + 70, + ), + length: 13, + }, + primary: true, + }, + ], + help: None, + }, + ), + ], } diff --git a/docs/source_files/pixi_tomls/pixi-package-manifest.toml b/docs/source_files/pixi_tomls/pixi-package-manifest.toml index 183bad9c9f..992d13087d 100644 --- a/docs/source_files/pixi_tomls/pixi-package-manifest.toml +++ b/docs/source_files/pixi_tomls/pixi-package-manifest.toml @@ -19,7 +19,7 @@ repository = "https://github.com/user/repo" backend = { name = "pixi-build-cmake", version = "0.3.*" } # not required: channels = ["https://prefix.dev/conda-forge"] -configuration = { key = "value" } # Optional configuration, specific to the build backend +config = { key = "value" } # Optional configuration, specific to the build backend # --8<-- [end:build-system] diff --git a/docs/source_files/pixi_workspaces/pixi_build/cpp/pixi.toml b/docs/source_files/pixi_workspaces/pixi_build/cpp/pixi.toml index 01988b4806..7a265bc54b 100644 --- a/docs/source_files/pixi_workspaces/pixi_build/cpp/pixi.toml +++ b/docs/source_files/pixi_workspaces/pixi_build/cpp/pixi.toml @@ -17,7 +17,7 @@ version = "0.1.0" [package.build] backend = { name = "pixi-build-cmake", version = "0.3.*" } -[package.build.configuration] +[package.build.config] extra-args = ["-DCMAKE_BUILD_TYPE=Release"] # (9)! [package.host-dependencies] diff --git a/schema/model.py b/schema/model.py index 42d63cb462..f4304c982a 100644 --- a/schema/model.py +++ b/schema/model.py @@ -698,7 +698,7 @@ class Package(StrictBaseModel): class BuildTarget(StrictBaseModel): """Target-specific build configuration for different platforms""" - configuration: dict[str, Any] = Field( + config: dict[str, Any] = Field( None, description="Target-specific configuration for the build backend" ) @@ -728,13 +728,11 @@ class Build(StrictBaseModel): additional_dependencies: Dependencies = Field( None, description="Additional dependencies to install alongside the build backend" ) - configuration: dict[str, Any] = Field( - None, description="The configuration of the build backend" - ) + config: dict[str, Any] = Field(None, description="The configuration of the build backend") target: dict[TargetName, BuildTarget] | None = Field( None, description="Target-specific build configuration for different platforms", - examples=[{"linux-64": {"configuration": {"key": "value"}}}], + examples=[{"linux-64": {"config": {"key": "value"}}}], ) source: SourceLocation = Field( None, diff --git a/schema/schema.json b/schema/schema.json index 1030647057..ec491a4b9c 100644 --- a/schema/schema.json +++ b/schema/schema.json @@ -330,8 +330,8 @@ ] } }, - "configuration": { - "title": "Configuration", + "config": { + "title": "Config", "description": "The configuration of the build backend", "type": "object", "additionalProperties": true @@ -358,7 +358,7 @@ "examples": [ { "linux-64": { - "configuration": { + "config": { "key": "value" } } @@ -527,8 +527,8 @@ "type": "object", "additionalProperties": false, "properties": { - "configuration": { - "title": "Configuration", + "config": { + "title": "Config", "description": "Target-specific configuration for the build backend", "type": "object", "additionalProperties": true diff --git a/tests/data/workspaces/host-dependency/package-a/pixi.toml b/tests/data/workspaces/host-dependency/package-a/pixi.toml index d267fb44c3..2d50467a23 100644 --- a/tests/data/workspaces/host-dependency/package-a/pixi.toml +++ b/tests/data/workspaces/host-dependency/package-a/pixi.toml @@ -8,5 +8,5 @@ backend = { name = "in-memory", version = "*" } [package.host-dependencies] package-b = { path = "../package-b" } -[package.build.configuration] +[package.build.config] package = "package-a-0.1.0-h4616a5c_0.conda" diff --git a/tests/data/workspaces/host-dependency/package-b/pixi.toml b/tests/data/workspaces/host-dependency/package-b/pixi.toml index 76c694ba68..98c1d23ed8 100644 --- a/tests/data/workspaces/host-dependency/package-b/pixi.toml +++ b/tests/data/workspaces/host-dependency/package-b/pixi.toml @@ -5,6 +5,6 @@ version = "0.1.0" [package.build] backend = { name = "in-memory", version = "*" } -[package.build.configuration] +[package.build.config] build-globs = ["TOUCH*"] package = "package-b-0.1.0-h4616a5c_0.conda" diff --git a/tests/data/workspaces/host-dependency/package-c/pixi.toml b/tests/data/workspaces/host-dependency/package-c/pixi.toml index 69756757da..a047ad2496 100644 --- a/tests/data/workspaces/host-dependency/package-c/pixi.toml +++ b/tests/data/workspaces/host-dependency/package-c/pixi.toml @@ -8,5 +8,5 @@ backend = { name = "in-memory", version = "*" } [package.run-dependencies] package-b = { path = "../package-b" } -[package.build.configuration] +[package.build.config] package = "package-c-0.1.0-h4616a5c_0.conda" diff --git a/tests/data/workspaces/source-backends/package-d/pixi.toml b/tests/data/workspaces/source-backends/package-d/pixi.toml index 2c4951801c..03ef7c782b 100644 --- a/tests/data/workspaces/source-backends/package-d/pixi.toml +++ b/tests/data/workspaces/source-backends/package-d/pixi.toml @@ -6,5 +6,5 @@ version = "0.1.0" backend = { name = "package-e", path = "../package-e" } -[package.build.configuration] +[package.build.config] package = "package-d-0.1.0-h4616a5c_0.conda" diff --git a/tests/data/workspaces/source-backends/package-e/pixi.toml b/tests/data/workspaces/source-backends/package-e/pixi.toml index 823d494579..698107ce2f 100644 --- a/tests/data/workspaces/source-backends/package-e/pixi.toml +++ b/tests/data/workspaces/source-backends/package-e/pixi.toml @@ -8,5 +8,5 @@ backend = { name = "in-memory", version = "*" } [package.run-dependencies] pixi-build-api-version = "*" -[package.build.configuration] +[package.build.config] package = "package-e-0.1.0-h4616a5c_0.conda"