Skip to content

Commit

Permalink
feat: add caching of regular build (#3238)
Browse files Browse the repository at this point in the history
  • Loading branch information
tdejager authored Feb 28, 2025
1 parent 8a6af5e commit 069acdd
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 10 deletions.
17 changes: 16 additions & 1 deletion src/build/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,13 @@ pub struct SourceCheckout {
pub pinned: PinnedSourceSpec,
}

impl SourceCheckout {
/// Create a new source checkout from a pinned source specification.
pub fn new(path: PathBuf, pinned: PinnedSourceSpec) -> Self {
Self { path, pinned }
}
}

/// The metadata of a source checkout.
#[derive(Debug)]
pub struct SourceMetadata {
Expand Down Expand Up @@ -885,7 +892,7 @@ fn normalize_absolute_path(path: &Path) -> Result<PathBuf, std::io::Error> {

/// A key to uniquely identify a work directory. If there is a source build with
/// the same key they will share the same working directory.
struct WorkDirKey {
pub(crate) struct WorkDirKey {
/// The location of the source
source: SourceCheckout,

Expand All @@ -898,6 +905,14 @@ struct WorkDirKey {
}

impl WorkDirKey {
pub fn new(source: SourceCheckout, host_platform: Platform, build_backend: String) -> Self {
Self {
source,
host_platform,
build_backend,
}
}

pub fn key(&self) -> String {
let mut hasher = Xxh3::new();
self.source.pinned.to_string().hash(&mut hasher);
Expand Down
44 changes: 35 additions & 9 deletions src/cli/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ use pixi_build_types::{
};
use pixi_config::ConfigCli;
use pixi_manifest::FeaturesExt;
use pixi_record::{PinnedPathSpec, PinnedSourceSpec};
use rattler_conda_types::{GenericVirtualPackage, Platform};
use typed_path::Utf8TypedPath;

use crate::{
build::BuildContext,
build::{BuildContext, SourceCheckout, WorkDirKey},
cli::cli_config::WorkspaceConfig,
repodata::Repodata,
utils::{move_file, MoveError},
Expand All @@ -35,6 +37,10 @@ pub struct Args {
/// The output directory to place the build artifacts
#[clap(long, short, default_value = ".")]
pub output_dir: PathBuf,

/// Whether to build incrementally if possible
#[clap(long, short)]
pub no_incremental: bool,
}

struct ProgressReporter {
Expand Down Expand Up @@ -113,8 +119,6 @@ pub async fn execute(args: Args) -> miette::Result<()> {
.into_diagnostic()
.wrap_err("unable to setup the build-backend to build the workspace")?;

// Construct a temporary directory to build the package in. This path is also
// automatically removed after the build finishes.
let pixi_dir = &workspace.pixi_dir();
tokio::fs::create_dir_all(pixi_dir)
.await
Expand All @@ -126,11 +130,33 @@ pub async fn execute(args: Args) -> miette::Result<()> {
)
})?;

let work_dir = tempfile::Builder::new()
.prefix("pixi-build-")
.tempdir_in(workspace.pixi_dir())
.into_diagnostic()
.context("failed to create temporary working directory in the .pixi directory")?;
let incremental = !args.no_incremental;
// Determine if we want to re-use existing build data
let (_tmp, work_dir) = if incremental {
// Specify the cache directory
let key = WorkDirKey::new(
SourceCheckout::new(
workspace.root().to_path_buf(),
PinnedSourceSpec::Path(PinnedPathSpec {
path: Utf8TypedPath::derive(&workspace.root().to_string_lossy()).to_path_buf(),
}),
),
args.target_platform,
protocol.identifier().to_string(),
)
.key();
(None, workspace.pixi_dir().join(key))
} else {
// Construct a temporary directory to build the package in. This path is also
// automatically removed after the build finishes.
let tmp = tempfile::Builder::new()
.prefix("pixi-build-")
.tempdir_in(workspace.pixi_dir())
.into_diagnostic()
.context("failed to create temporary working directory in the .pixi directory")?;
let work_dir = tmp.path().to_path_buf();
(Some(tmp), work_dir)
};

let progress = Arc::new(ProgressReporter::new(workspace.name()));
// Build platform virtual packages
Expand Down Expand Up @@ -174,7 +200,7 @@ pub async fn execute(args: Args) -> miette::Result<()> {
},
outputs: None,
editable: false,
work_directory: work_dir.path().to_path_buf(),
work_directory: work_dir,
variant_configuration: Some(build_context.resolve_variant(args.target_platform)),
},
progress.clone(),
Expand Down

0 comments on commit 069acdd

Please sign in to comment.