Skip to content

Commit

Permalink
feat: add package specific targets and errors
Browse files Browse the repository at this point in the history
  • Loading branch information
baszalmstra committed Nov 24, 2024
1 parent 5768546 commit 157e924
Show file tree
Hide file tree
Showing 37 changed files with 787 additions and 280 deletions.
9 changes: 9 additions & 0 deletions crates/pixi_build_frontend/src/protocols/pixi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ pub enum ProtocolBuildError {
#[error("failed to setup a build backend, the {} could not be parsed", .0.file_name().and_then(std::ffi::OsStr::to_str).unwrap_or("manifest"))]
#[diagnostic(help("Ensure that the manifest at '{}' is a valid pixi project manifest", .0.display()))]
FailedToParseManifest(PathBuf, #[diagnostic_source] miette::Report),

#[error("the {} does not describe a package", .0.file_name().and_then(std::ffi::OsStr::to_str).unwrap_or("manifest"))]
#[diagnostic(help("A [package] section is missing in the manifest"))]
NotAPackage(PathBuf),
}

#[derive(Debug, Error, Diagnostic)]
Expand Down Expand Up @@ -106,6 +110,11 @@ impl ProtocolBuilder {
if let Some(manifest_path) = find_pixi_manifest(source_dir) {
match Manifest::from_path(&manifest_path) {
Ok(manifest) => {
// Make sure the manifest describes a package.
if manifest.package.is_none() {
return Err(ProtocolBuildError::NotAPackage(manifest_path));
}

let builder = Self::new(source_dir.to_path_buf(), manifest)?;
return Ok(Some(builder));
}
Expand Down
44 changes: 43 additions & 1 deletion crates/pixi_build_frontend/tests/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,40 @@ async fn test_missing_backend() {
insta::assert_snapshot!(snapshot);
}

#[tokio::test]
async fn test_not_a_package() {
// Setup a temporary project
let source_dir = tempfile::TempDir::new().unwrap();
let manifest = source_dir
.path()
.join(pixi_consts::consts::PROJECT_MANIFEST);
tokio::fs::write(
&manifest,
r#"
[workspace]
name = "some-workspace"
platforms = []
channels = []
preview = ['pixi-build']
"#,
)
.await
.unwrap();

let err = BuildFrontend::default()
.setup_protocol(SetupRequest {
source_dir: source_dir.path().to_path_buf(),
build_tool_override: Default::default(),
build_id: 0,
})
.await
.unwrap_err();

let snapshot = error_to_snapshot(&err);
let snapshot = replace_source_dir(&snapshot, source_dir.path());
insta::assert_snapshot!(snapshot);
}

#[tokio::test]
async fn test_invalid_backend() {
// Setup a temporary project
Expand All @@ -143,10 +177,18 @@ async fn test_invalid_backend() {
&manifest,
r#"
[workspace]
name = "project"
platforms = []
channels = []
preview = ['pixi-build']
[package]
version = "0.1.0"
name = "project"
[build-system]
dependencies = []
channels = []
build-backend = "ipc"
"#,
)
.await
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
source: crates/pixi_build_frontend/tests/diagnostics.rs
expression: snapshot
---
× the pixi.toml does not describe a package
help: A [package] section is missing in the manifest
26 changes: 26 additions & 0 deletions crates/pixi_manifest/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ pub enum TomlError {
},
#[error("Could not convert pep508 to pixi pypi requirement")]
Conversion(#[from] Box<Pep508ToPyPiRequirementError>),
#[error(transparent)]
InvalidNonPackageDependencies(#[from] InvalidNonPackageDependencies),
}

impl From<toml_edit::TomlError> for TomlError {
Expand Down Expand Up @@ -113,6 +115,7 @@ impl Diagnostic for TomlError {
span.clone().map(SourceSpan::from)
}
TomlError::FeatureNotEnabled(err) => return err.labels(),
TomlError::InvalidNonPackageDependencies(err) => return err.labels(),
_ => None,
};

Expand All @@ -137,6 +140,7 @@ impl Diagnostic for TomlError {
Some(Box::new("Run `pixi init` to create a new project manifest"))
}
TomlError::FeatureNotEnabled(err) => err.help(),
TomlError::InvalidNonPackageDependencies(err) => err.help(),
_ => None,
}
}
Expand Down Expand Up @@ -214,3 +218,25 @@ impl miette::Diagnostic for UnknownFeature {
}
}
}

/// An error that indicates that some package sections are only valid when the
/// manifest describes a package instead of a workspace.
#[derive(Debug, Error, Clone)]
#[error("build-, host- and run-dependency sections are only valid for packages.")]
pub struct InvalidNonPackageDependencies {
pub invalid_dependency_sections: Vec<Range<usize>>,
}

impl Diagnostic for InvalidNonPackageDependencies {
fn help<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
Some(Box::new(
"These sections are only valid when the manifest describes a package instead of a workspace.\nAdd a `[package]` section to the manifest to fix this error or remove the offending sections.",
))
}

fn labels(&self) -> Option<Box<dyn Iterator<Item = LabeledSpan> + '_>> {
Some(Box::new(self.invalid_dependency_sections.iter().map(
|range| LabeledSpan::new_with_span(None, SourceSpan::from(range.clone())),
)))
}
}
6 changes: 3 additions & 3 deletions crates/pixi_manifest/src/feature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use crate::{
pypi::{pypi_options::PypiOptions, PyPiPackageName},
target::Targets,
utils::PixiSpanned,
PyPiRequirement, SpecType, SystemRequirements,
PyPiRequirement, SpecType, SystemRequirements, WorkspaceTarget,
};

/// The name of a feature. This is either a string or default for the default
Expand Down Expand Up @@ -143,7 +143,7 @@ pub struct Feature {
pub pypi_options: Option<PypiOptions>,

/// Target specific configuration.
pub targets: Targets,
pub targets: Targets<WorkspaceTarget>,
}

impl Feature {
Expand All @@ -157,7 +157,7 @@ impl Feature {
system_requirements: SystemRequirements::default(),
pypi_options: None,

targets: <Targets as Default>::default(),
targets: <Targets<WorkspaceTarget> as Default>::default(),
}
}

Expand Down
21 changes: 0 additions & 21 deletions crates/pixi_manifest/src/has_environment_dependencies.rs

This file was deleted.

4 changes: 1 addition & 3 deletions crates/pixi_manifest/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ mod environments;
mod error;
mod feature;
mod features_ext;
mod has_environment_dependencies;
mod has_features_iter;
mod has_manifest_ref;
mod manifests;
Expand All @@ -33,7 +32,6 @@ pub use environment::{Environment, EnvironmentName};
pub use error::TomlError;
pub use feature::{Feature, FeatureName};
pub use features_ext::FeaturesExt;
pub use has_environment_dependencies::HasEnvironmentDependencies;
pub use has_features_iter::HasFeaturesIter;
pub use has_manifest_ref::HasManifestRef;
use itertools::Itertools;
Expand All @@ -44,7 +42,7 @@ pub use pypi::pypi_requirement::PyPiRequirement;
use rattler_conda_types::Platform;
pub use spec_type::SpecType;
pub use system_requirements::{LibCSystemRequirement, SystemRequirements};
pub use target::{Target, TargetSelector, Targets};
pub use target::{TargetSelector, Targets, WorkspaceTarget};
pub use task::{Task, TaskName};
use thiserror::Error;
pub use workspace::Workspace;
Expand Down
8 changes: 4 additions & 4 deletions crates/pixi_manifest/src/manifests/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ use crate::{
to_options,
toml::{ExternalWorkspaceProperties, TomlDocument, TomlManifest},
BuildSystem, DependencyOverwriteBehavior, Environment, EnvironmentName, Feature, FeatureName,
GetFeatureError, PrioritizedChannel, PypiDependencyLocation, SpecType, Target, TargetSelector,
Task, TaskName, WorkspaceManifest,
GetFeatureError, PrioritizedChannel, PypiDependencyLocation, SpecType, TargetSelector, Task,
TaskName, WorkspaceManifest, WorkspaceTarget,
};

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -668,7 +668,7 @@ impl Manifest {
&mut self,
platform: Option<Platform>,
name: Option<&FeatureName>,
) -> &mut Target {
) -> &mut WorkspaceTarget {
let feature = match name {
Some(feature) => self.get_or_insert_feature_mut(feature),
None => self.default_feature_mut(),
Expand All @@ -683,7 +683,7 @@ impl Manifest {
&mut self,
platform: Option<Platform>,
name: &FeatureName,
) -> Option<&mut Target> {
) -> Option<&mut WorkspaceTarget> {
self.feature_mut(name)
.unwrap()
.targets
Expand Down
6 changes: 5 additions & 1 deletion crates/pixi_manifest/src/manifests/package.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::{package::Package, BuildSystem};
use crate::target::PackageTarget;
use crate::{package::Package, BuildSystem, Targets};

/// Holds the parsed content of the package part of a pixi manifest. This
/// describes the part related to the package only.
Expand All @@ -9,4 +10,7 @@ pub struct PackageManifest {

/// Information about the build system for the package
pub build_system: BuildSystem,

/// Defines the dependencies of the package
pub targets: Targets<PackageTarget>,
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
source: crates/pixi_manifest/src/manifests/workspace.rs
expression: "expect_parse_failure(&format!(\"{PROJECT_BOILERPLATE}\\n[foobar]\"))"
---
× unknown field `foobar`, expected one of `project`, `workspace`, `package`, `system-requirements`, `target`, `dependencies`, `host-dependencies`, `build-dependencies`, `pypi-dependencies`,
`activation`, `tasks`, `feature`, `environments`, `pypi-options`, `build-system`, `$schema`, `tool`
× unknown field `foobar`, expected one of `project`, `workspace`, `package`, `system-requirements`, `target`, `dependencies`, `host-dependencies`, `build-dependencies`, `run-dependencies`, `pypi-
dependencies`, `activation`, `tasks`, `feature`, `environments`, `pypi-options`, `build-system`, `$schema`, `tool`
╭─[pixi.toml:8:2]
7
8 │ [foobar]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
source: crates/pixi_manifest/src/manifests/workspace.rs
expression: "expect_parse_failure(&format!(\"{PROJECT_BOILERPLATE}\\n[target.win-64.hostdependencies]\"))"
---
× unknown field `hostdependencies`, expected one of `dependencies`, `host-dependencies`, `build-dependencies`, `pypi-dependencies`, `activation`, `tasks`
× unknown field `hostdependencies`, expected one of `dependencies`, `host-dependencies`, `build-dependencies`, `run-dependencies`, `pypi-dependencies`, `activation`, `tasks`
╭─[pixi.toml:8:16]
7
8 │ [target.win-64.hostdependencies]
Expand Down
Loading

0 comments on commit 157e924

Please sign in to comment.