Skip to content

Commit

Permalink
feat: build recipe yaml directly as a dependency (prefix-dev#2568)
Browse files Browse the repository at this point in the history
  • Loading branch information
wolfv authored and jjjermiah committed Nov 30, 2024
1 parent 590e6a7 commit a02a4ba
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 24 deletions.
1 change: 1 addition & 0 deletions crates/pixi_build_frontend/src/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ pub enum DiscoveryError {
NotADirectory,
#[error("failed to discover a valid project manifest, the source path '{}' could not be found", .0.display())]
NotFound(PathBuf),

#[error("unable to discover communication protocol, the source directory does not contain a supported manifest")]
#[diagnostic(help(
"Ensure that the source directory contains a valid pixi.toml or meta.yaml file."
Expand Down
55 changes: 31 additions & 24 deletions crates/pixi_build_frontend/src/protocols/builders/rattler_build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,17 @@ use crate::{
BackendOverride,
};

const DEFAULT_BUILD_TOOL: &str = "pixi-build-rattler-build";

#[derive(Debug, Error, Diagnostic)]
pub enum FinishError {
#[error(transparent)]
Tool(#[from] ToolCacheError),

#[error(transparent)]
#[diagnostic(transparent)]
Init(#[from] InitializeError),

#[error("failed to setup a build backend, the project manifest at {0} does not contain a [build] section")]
NoBuildSection(PathBuf),
}
Expand All @@ -45,7 +49,7 @@ pub struct ProtocolBuilder {
recipe_dir: PathBuf,

/// The path to the manifest file.
manifest_path: PathBuf,
manifest_path: Option<PathBuf>,

/// The backend tool to install.
backend_spec: Option<ToolSpec>,
Expand All @@ -59,29 +63,20 @@ pub struct ProtocolBuilder {

impl ProtocolBuilder {
/// Discovers the protocol for the given source directory.
/// We discover a `pixi.toml` file in the source directory and/or a `recipe.yaml / recipe/recipe.yaml` file.
pub fn discover(source_dir: &Path) -> Result<Option<Self>, ProtocolBuildError> {
// first we need to discover that pixi protocol also can be built.
// it is used to get the manifest

// Ignore the error if we cannot find the pixi protocol.
let pixi_protocol = match pixi::ProtocolBuilder::discover(source_dir) {
Ok(inner_value) => inner_value,
Err(_) => return Ok(None), // Handle the case where the Option is None
};

// we cannot find pixi protocol, so we cannot build rattler-build protocol.
let manifest = if let Some(pixi_protocol) = pixi_protocol {
pixi_protocol.manifest().clone()
} else {
return Ok(None);
let manifest = match pixi::ProtocolBuilder::discover(source_dir) {
Ok(protocol) => protocol.map(|protocol| protocol.manifest().clone()),
Err(_) => None,
};

let recipe_dir = source_dir.join("recipe");

let protocol = if source_dir.join("recipe.yaml").is_file() {
Self::new(source_dir, source_dir, &manifest)
Self::new(source_dir, source_dir, manifest)
} else if recipe_dir.join("recipe.yaml").is_file() {
Self::new(source_dir, &recipe_dir, &manifest)
Self::new(source_dir, &recipe_dir, manifest)
} else {
return Ok(None);
};
Expand All @@ -90,15 +85,19 @@ impl ProtocolBuilder {
}

/// Constructs a new instance from a manifest.
pub fn new(source_dir: &Path, recipe_dir: &Path, manifest: &Manifest) -> Self {
let backend_spec = manifest
.build_section()
.map(IsolatedToolSpec::from_build_section);
pub fn new(source_dir: &Path, recipe_dir: &Path, manifest: Option<Manifest>) -> Self {
let backend_spec = if let Some(manifest) = &manifest {
manifest
.build_section()
.map(IsolatedToolSpec::from_build_section)
} else {
None
};

Self {
source_dir: source_dir.to_path_buf(),
recipe_dir: recipe_dir.to_path_buf(),
manifest_path: manifest.path.clone(),
manifest_path: manifest.map(|m| m.path.clone()),
backend_spec: backend_spec.map(Into::into),
_channel_config: ChannelConfig::default_with_root_dir(PathBuf::new()),
cache_dir: None,
Expand Down Expand Up @@ -134,9 +133,17 @@ impl ProtocolBuilder {
tool: &ToolCache,
build_id: usize,
) -> Result<JsonRPCBuildProtocol, FinishError> {
let tool_spec = self
.backend_spec
.ok_or(FinishError::NoBuildSection(self.manifest_path.clone()))?;
// If we have a manifest path, that means we found a `pixi.toml` file. In that case
// we should use the backend spec from the manifest.
let tool_spec = if let Some(manifest_path) = &self.manifest_path {
self.backend_spec
.ok_or(FinishError::NoBuildSection(manifest_path.clone()))?
} else {
ToolSpec::Isolated(
IsolatedToolSpec::from_specs([DEFAULT_BUILD_TOOL.parse().unwrap()])
.with_command(DEFAULT_BUILD_TOOL),
)
};

let tool = tool
.instantiate(tool_spec)
Expand Down

0 comments on commit a02a4ba

Please sign in to comment.