Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ pub struct Prepare {
/// When --bin is specified, `cargo-chef` will ignore all members of the workspace
/// that are not necessary to successfully compile the specific binary.
#[arg(long)]
bin: Option<String>,
bin: Vec<String>,
}

#[derive(Parser)]
Expand Down Expand Up @@ -305,7 +305,7 @@ fn _main() -> Result<(), anyhow::Error> {
}
Command::Prepare(Prepare { recipe_path, bin }) => {
let recipe =
Recipe::prepare(current_directory, bin).context("Failed to compute recipe")?;
Recipe::prepare(current_directory, &bin).context("Failed to compute recipe")?;
let serialized =
serde_json::to_string(&recipe).context("Failed to serialize recipe.")?;
fs::write(recipe_path, serialized).context("Failed to save recipe to 'recipe.json'")?;
Expand Down
4 changes: 2 additions & 2 deletions src/recipe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ pub struct CookArgs {
}

impl Recipe {
pub fn prepare(base_path: PathBuf, member: Option<String>) -> Result<Self, anyhow::Error> {
let skeleton = Skeleton::derive(base_path, member)?;
pub fn prepare(base_path: PathBuf, members: &[String]) -> Result<Self, anyhow::Error> {
let skeleton = Skeleton::derive(base_path, members)?;
Ok(Recipe { skeleton })
}

Expand Down
50 changes: 27 additions & 23 deletions src/skeleton/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,22 +44,19 @@ pub(in crate::skeleton) struct ParsedManifest {

impl Skeleton {
/// Find all Cargo.toml files in `base_path` by traversing sub-directories recursively.
pub fn derive<P: AsRef<Path>>(
base_path: P,
member: Option<String>,
) -> Result<Self, anyhow::Error> {
pub fn derive<P: AsRef<Path>>(base_path: P, members: &[String]) -> Result<Self, anyhow::Error> {
// Use `--no-deps` to skip dependency resolution when we don't need the full graph
// (i.e. no `--bin` filtering). We still need full resolution when there's no existing
// Cargo.lock, since `cargo metadata` generates it as a side effect.
let no_deps = member.is_none() && base_path.as_ref().join("Cargo.lock").exists();
let no_deps = members.is_empty() && base_path.as_ref().join("Cargo.lock").exists();
let graph = extract_package_graph(base_path.as_ref(), no_deps)?;

// Read relevant files from the filesystem
let config_file = read::config(&base_path)?;
let mut manifests = read::manifests(&base_path, &graph)?;
let mut lock_file = read::lockfile(&base_path)?;
if let Some(member) = &member {
filter_to_member_closure(&mut manifests, &mut lock_file, &graph, member)?;
if !members.is_empty() {
filter_to_member_closure(&mut manifests, &mut lock_file, &graph, members)?;
}
let rust_toolchain_file = read::rust_toolchain(&base_path)?;

Expand Down Expand Up @@ -337,27 +334,34 @@ fn filter_to_member_closure(
manifests: &mut Vec<ParsedManifest>,
lock_file: &mut Option<toml::Value>,
graph: &PackageGraph,
member: &str,
members: &[String],
) -> Result<(), anyhow::Error> {
let ws = graph.workspace();
// `member` may be a package name or a binary target name (from --bin).
// Try package name first, then search for a binary target.
let pkg = match ws.member_by_name(member) {
Ok(pkg) => pkg,
Err(_) => ws
.iter()
.find(|pkg| {
pkg.build_targets().any(|t| {
matches!(t.id(), guppy::graph::BuildTargetId::Binary(name) if name == member)

let mut pkgs = Vec::with_capacity(members.len());

for member in members {
// `member` may be a package name or a binary target name (from --bin).
// Try package name first, then search for a binary target.
let pkg = match ws.member_by_name(member) {
Ok(pkg) => pkg,
Err(_) => ws
.iter()
.find(|pkg| {
pkg.build_targets().any(|t| {
matches!(t.id(), guppy::graph::BuildTargetId::Binary(name) if name == member)
})
})
})
.ok_or_else(|| {
anyhow::anyhow!("No workspace package or binary target named '{member}'")
})?,
};
.ok_or_else(|| {
anyhow::anyhow!("No workspace package or binary target named '{member}'")
})?,
};

pkgs.push(pkg.id().clone());
}

// Get transitive closure of all dependencies
let resolved = graph.query_forward(std::iter::once(pkg.id()))?.resolve();
let resolved = graph.query_forward(pkgs.iter())?.resolve();

// Collect workspace member names in the closure
let closure_members: HashSet<String> = ws
Expand Down
2 changes: 1 addition & 1 deletion tests/recipe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ fn quick_recipe(content: &str) -> Recipe {
bin_dir.child(filename).touch().unwrap();
test_dir.child(filename).touch().unwrap();
}
Recipe::prepare(recipe_directory.path().canonicalize().unwrap(), None).unwrap()
Recipe::prepare(recipe_directory.path().canonicalize().unwrap(), &[]).unwrap()
}

#[test]
Expand Down
28 changes: 14 additions & 14 deletions tests/skeletons/tests/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ path = "src/main.rs"
.build();

// Act
let skeleton = Skeleton::derive(project.path(), None).unwrap();
let skeleton = Skeleton::derive(project.path(), &[]).unwrap();
let cook_directory = TempDir::new().unwrap();
skeleton
.build_minimum_project(cook_directory.path(), false)
Expand All @@ -43,7 +43,7 @@ path = "src/main.rs"
.assert(predicate::path::exists());

// Act (no_std)
let skeleton = Skeleton::derive(project.path(), None).unwrap();
let skeleton = Skeleton::derive(project.path(), &[]).unwrap();
let cook_directory = TempDir::new().unwrap();
skeleton
.build_minimum_project(cook_directory.path(), true)
Expand Down Expand Up @@ -116,7 +116,7 @@ uuid = { version = "=0.8.0", features = ["v4"] }
.build();

// Act
let skeleton = Skeleton::derive(project.path(), None).unwrap();
let skeleton = Skeleton::derive(project.path(), &[]).unwrap();
let cook_directory = TempDir::new().unwrap();
skeleton
.build_minimum_project(cook_directory.path(), false)
Expand All @@ -138,7 +138,7 @@ uuid = { version = "=0.8.0", features = ["v4"] }
.assert("");

// Act (no_std)
let skeleton = Skeleton::derive(project.path(), None).unwrap();
let skeleton = Skeleton::derive(project.path(), &[]).unwrap();
let cook_directory = TempDir::new().unwrap();
skeleton
.build_minimum_project(cook_directory.path(), true)
Expand Down Expand Up @@ -192,7 +192,7 @@ harness = false
.build();

// Act
let skeleton = Skeleton::derive(project.path(), None).unwrap();
let skeleton = Skeleton::derive(project.path(), &[]).unwrap();
let cook_directory = TempDir::new().unwrap();
skeleton
.build_minimum_project(cook_directory.path(), false)
Expand Down Expand Up @@ -230,7 +230,7 @@ name = "foo"
.build();

// Act
let skeleton = Skeleton::derive(project.path(), None).unwrap();
let skeleton = Skeleton::derive(project.path(), &[]).unwrap();
let cook_directory = TempDir::new().unwrap();
skeleton
.build_minimum_project(cook_directory.path(), false)
Expand All @@ -243,7 +243,7 @@ name = "foo"
cook_directory.child("tests").child("foo.rs").assert("");

// Act (no_std)
let skeleton = Skeleton::derive(project.path(), None).unwrap();
let skeleton = Skeleton::derive(project.path(), &[]).unwrap();
let cook_directory = TempDir::new().unwrap();
skeleton
.build_minimum_project(cook_directory.path(), true)
Expand Down Expand Up @@ -293,7 +293,7 @@ harness = false
.build();

// Act
let skeleton = Skeleton::derive(project.path(), None).unwrap();
let skeleton = Skeleton::derive(project.path(), &[]).unwrap();
let cook_directory = TempDir::new().unwrap();
skeleton
.build_minimum_project(cook_directory.path(), false)
Expand Down Expand Up @@ -325,7 +325,7 @@ name = "foo"
.build();

// Act
let skeleton = Skeleton::derive(project.path(), None).unwrap();
let skeleton = Skeleton::derive(project.path(), &[]).unwrap();
let cook_directory = TempDir::new().unwrap();
skeleton
.build_minimum_project(cook_directory.path(), false)
Expand All @@ -341,7 +341,7 @@ name = "foo"
.assert("fn main() {}");

// Act (no_std)
let skeleton = Skeleton::derive(project.path(), None).unwrap();
let skeleton = Skeleton::derive(project.path(), &[]).unwrap();
let cook_directory = TempDir::new().unwrap();
skeleton
.build_minimum_project(cook_directory.path(), true)
Expand Down Expand Up @@ -387,14 +387,14 @@ edition = "2018"
.build();

// Act
let skeleton = Skeleton::derive(project.path(), None).unwrap();
let skeleton = Skeleton::derive(project.path(), &[]).unwrap();

// What we're testing is that auto-directories come back in the same order.
// Since it's possible that the directories just happen to come back in the
// same order randomly, we'll run this a few times to increase the
// likelihood of triggering the problem if it exists.
for _ in 0..5 {
let skeleton2 = Skeleton::derive(project.path(), None).unwrap();
let skeleton2 = Skeleton::derive(project.path(), &[]).unwrap();
assert_eq!(
skeleton, skeleton2,
"Skeletons of equal directories are not equal. Check [[bin]] ordering in manifest?"
Expand Down Expand Up @@ -436,7 +436,7 @@ workspace = true
.build();

// Act
let skeleton = Skeleton::derive(project.path(), None).unwrap();
let skeleton = Skeleton::derive(project.path(), &[]).unwrap();

// Assert - lints should be stripped from all manifests
for manifest in &skeleton.manifests {
Expand Down Expand Up @@ -489,7 +489,7 @@ reqwest = {
.build();

// Act
let skeleton = Skeleton::derive(project.path(), None).unwrap();
let skeleton = Skeleton::derive(project.path(), &[]).unwrap();

// Assert
assert_eq!(1, skeleton.manifests.len());
Expand Down
12 changes: 6 additions & 6 deletions tests/skeletons/tests/masking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ edition = "2018"
.build();

// Act
let skeleton = Skeleton::derive(project.path(), None).unwrap();
let skeleton = Skeleton::derive(project.path(), &[]).unwrap();
let cook_directory = TempDir::new().unwrap();
skeleton
.build_minimum_project(cook_directory.path(), false)
Expand Down Expand Up @@ -57,7 +57,7 @@ edition = "2018"
.build();

// Act
let skeleton = Skeleton::derive(project.path(), None).unwrap();
let skeleton = Skeleton::derive(project.path(), &[]).unwrap();
let cook_directory = TempDir::new().unwrap();
skeleton
.build_minimum_project(cook_directory.path(), false)
Expand Down Expand Up @@ -100,7 +100,7 @@ version = "1.2.3"
.build();

// Act
let skeleton = Skeleton::derive(project.path(), None).unwrap();
let skeleton = Skeleton::derive(project.path(), &[]).unwrap();
let cook_directory = TempDir::new().unwrap();
skeleton
.build_minimum_project(cook_directory.path(), false)
Expand Down Expand Up @@ -203,7 +203,7 @@ dependencies = [
.build();

// Act
let skeleton = Skeleton::derive(project.path(), None).unwrap();
let skeleton = Skeleton::derive(project.path(), &[]).unwrap();
let cook_directory = TempDir::new().unwrap();
skeleton
.build_minimum_project(cook_directory.path(), false)
Expand Down Expand Up @@ -346,7 +346,7 @@ crate-type = ["cdylib"]
.build();

// Act
let skeleton = Skeleton::derive(project.path(), None).unwrap();
let skeleton = Skeleton::derive(project.path(), &[]).unwrap();
let cook_directory = TempDir::new().unwrap();
skeleton
.build_minimum_project(cook_directory.path(), false)
Expand Down Expand Up @@ -479,7 +479,7 @@ edition = "2021"
.build();

// Act
let skeleton = Skeleton::derive(project.path(), None).unwrap();
let skeleton = Skeleton::derive(project.path(), &[]).unwrap();
let cook_directory = TempDir::new().unwrap();
skeleton
.build_minimum_project(cook_directory.path(), false)
Expand Down
18 changes: 9 additions & 9 deletions tests/skeletons/tests/toolchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ edition = "2021"
.build();

// Act
let skeleton = Skeleton::derive(project.path(), None).unwrap();
let skeleton = Skeleton::derive(project.path(), &[]).unwrap();
let cook_directory = TempDir::new().unwrap();
skeleton
.build_minimum_project(cook_directory.path(), false)
Expand Down Expand Up @@ -68,7 +68,7 @@ channel = "1.75.0"
.build();

// Act
let skeleton = Skeleton::derive(project.path(), None).unwrap();
let skeleton = Skeleton::derive(project.path(), &[]).unwrap();
let cook_directory = TempDir::new().unwrap();
skeleton
.build_minimum_project(cook_directory.path(), false)
Expand Down Expand Up @@ -202,7 +202,7 @@ uuid = { version = "=0.8.0", features = ["v4"] }

// Act
let path = project.path();
let all = Skeleton::derive(&path, None).unwrap();
let all = Skeleton::derive(&path, &[]).unwrap();
assert_eq!(
manifest_content_dirs(&all),
vec![
Expand All @@ -214,37 +214,37 @@ uuid = { version = "=0.8.0", features = ["v4"] }
]
);

let project_a = Skeleton::derive(&path, Some("project_a".into())).unwrap();
let project_a = Skeleton::derive(&path, &["project_a".into()]).unwrap();
assert_eq!(
manifest_content_dirs(&project_a),
vec!["crates/client/project_a"]
);

let project_b = Skeleton::derive(&path, Some("project_b".into())).unwrap();
let project_b = Skeleton::derive(&path, &["project_b".into()]).unwrap();
assert_eq!(
manifest_content_dirs(&project_b),
vec!["crates/client/project_b"]
);

let project_c = Skeleton::derive(&path, Some("project_c".into())).unwrap();
let project_c = Skeleton::derive(&path, &["project_c".into()]).unwrap();
assert_eq!(
manifest_content_dirs(&project_c),
vec!["crates/server/project_c"]
);

let project_d = Skeleton::derive(&path, Some("project_d".into())).unwrap();
let project_d = Skeleton::derive(&path, &["project_d".into()]).unwrap();
assert_eq!(
manifest_content_dirs(&project_d),
vec!["crates/server/project_d"]
);

let project_e = Skeleton::derive(&path, Some("project_e".into())).unwrap();
let project_e = Skeleton::derive(&path, &["project_e".into()]).unwrap();
assert_eq!(
manifest_content_dirs(&project_e),
vec!["vendored/project_e"]
);

let project_f = Skeleton::derive(&path, Some("project_f".into())).unwrap();
let project_f = Skeleton::derive(&path, &["project_f".into()]).unwrap();
assert_eq!(manifest_content_dirs(&project_f), vec!["project_f"]);

// TODO: If multiple binaries are valid in `cargo chef prepare`, then testing
Expand Down
Loading