cargo-build-bpf/cargo-test-bpf now support --workspace/--all

This commit is contained in:
Michael Vines 2020-11-06 10:50:28 -08:00
parent fe1e08b9ad
commit 0ea795caa8
2 changed files with 114 additions and 62 deletions

View File

@ -15,9 +15,9 @@ struct Config {
bpf_sdk: PathBuf, bpf_sdk: PathBuf,
dump: bool, dump: bool,
features: Vec<String>, features: Vec<String>,
manifest_path: Option<PathBuf>,
no_default_features: bool, no_default_features: bool,
verbose: bool, verbose: bool,
workspace: bool,
} }
impl Default for Config { impl Default for Config {
@ -32,9 +32,9 @@ impl Default for Config {
bpf_out_dir: None, bpf_out_dir: None,
dump: false, dump: false,
features: vec![], features: vec![],
manifest_path: None,
no_default_features: false, no_default_features: false,
verbose: false, verbose: false,
workspace: false,
} }
} }
} }
@ -65,27 +65,13 @@ where
} }
} }
fn build_bpf(config: Config) { fn build_bpf_package(
let mut metadata_command = cargo_metadata::MetadataCommand::new(); config: &Config,
if let Some(manifest_path) = config.manifest_path { target_directory: &PathBuf,
metadata_command.manifest_path(manifest_path); package: &cargo_metadata::Package,
} ) {
let metadata = metadata_command.exec().unwrap_or_else(|err| {
eprintln!("Failed to obtain package metadata: {}", err);
exit(1);
});
let root_package = metadata.root_package().unwrap_or_else(|| {
eprintln!(
"Workspace does not have a root package: {}",
metadata.workspace_root.display()
);
exit(1);
});
let program_name = { let program_name = {
let cdylib_targets = root_package let cdylib_targets = package
.targets .targets
.iter() .iter()
.filter_map(|target| { .filter_map(|target| {
@ -101,7 +87,7 @@ fn build_bpf(config: Config) {
0 => { 0 => {
println!( println!(
"Note: {} crate does not contain a cdylib target", "Note: {} crate does not contain a cdylib target",
root_package.name package.name
); );
None None
} }
@ -109,29 +95,29 @@ fn build_bpf(config: Config) {
_ => { _ => {
eprintln!( eprintln!(
"{} crate contains multiple cdylib targets: {:?}", "{} crate contains multiple cdylib targets: {:?}",
root_package.name, cdylib_targets package.name, cdylib_targets
); );
exit(1); exit(1);
} }
} }
}; };
let legacy_program_feature_present = root_package.name == "solana-sdk"; let legacy_program_feature_present = package.name == "solana-sdk";
let root_package_dir = &root_package.manifest_path.parent().unwrap_or_else(|| { let root_package_dir = &package.manifest_path.parent().unwrap_or_else(|| {
eprintln!( eprintln!(
"Unable to get directory of {}", "Unable to get directory of {}",
root_package.manifest_path.display() package.manifest_path.display()
); );
exit(1); exit(1);
}); });
let bpf_out_dir = config let bpf_out_dir = config
.bpf_out_dir .bpf_out_dir
.unwrap_or_else(|| metadata.target_directory.join("deploy")); .as_ref()
.cloned()
.unwrap_or_else(|| target_directory.join("deploy"));
let target_build_directory = metadata let target_build_directory = target_directory.join("bpfel-unknown-unknown/release");
.target_directory
.join("bpfel-unknown-unknown/release");
env::set_current_dir(&root_package_dir).unwrap_or_else(|err| { env::set_current_dir(&root_package_dir).unwrap_or_else(|err| {
eprintln!( eprintln!(
@ -220,6 +206,38 @@ fn build_bpf(config: Config) {
} }
} }
fn build_bpf(config: Config, manifest_path: Option<PathBuf>) {
let mut metadata_command = cargo_metadata::MetadataCommand::new();
if let Some(manifest_path) = manifest_path {
metadata_command.manifest_path(manifest_path);
}
let metadata = metadata_command.exec().unwrap_or_else(|err| {
eprintln!("Failed to obtain package metadata: {}", err);
exit(1);
});
if let Some(root_package) = metadata.root_package() {
if !config.workspace {
build_bpf_package(&config, &metadata.target_directory, root_package);
return;
}
}
let all_bpf_packages = metadata
.packages
.iter()
.filter(|package| {
package.manifest_path.with_file_name("Xargo.toml").exists()
&& metadata.workspace_members.contains(&package.id)
})
.collect::<Vec<_>>();
for package in all_bpf_packages {
build_bpf_package(&config, &metadata.target_directory, package);
}
}
fn main() { fn main() {
let default_config = Config::default(); let default_config = Config::default();
let default_bpf_sdk = format!("{}", default_config.bpf_sdk.display()); let default_bpf_sdk = format!("{}", default_config.bpf_sdk.display());
@ -285,6 +303,13 @@ fn main() {
.takes_value(true) .takes_value(true)
.help("Place final BPF build artifacts in this directory"), .help("Place final BPF build artifacts in this directory"),
) )
.arg(
Arg::with_name("workspace")
.long("workspace")
.takes_value(false)
.alias("all")
.help("Build all BPF packages in the workspace"),
)
.get_matches_from(args); .get_matches_from(args);
let bpf_sdk = value_t_or_exit!(matches, "bpf_sdk", PathBuf); let bpf_sdk = value_t_or_exit!(matches, "bpf_sdk", PathBuf);
@ -312,9 +337,10 @@ fn main() {
features: values_t!(matches, "features", String) features: values_t!(matches, "features", String)
.ok() .ok()
.unwrap_or_else(Vec::new), .unwrap_or_else(Vec::new),
manifest_path: value_t!(matches, "manifest_path", PathBuf).ok(),
no_default_features: matches.is_present("no_default_features"), no_default_features: matches.is_present("no_default_features"),
verbose: matches.is_present("verbose"), verbose: matches.is_present("verbose"),
workspace: matches.is_present("workspace"),
}; };
build_bpf(config); let manifest_path = value_t!(matches, "manifest_path", PathBuf).ok();
build_bpf(config, manifest_path);
} }

View File

@ -16,9 +16,9 @@ struct Config {
cargo_build_bpf: PathBuf, cargo_build_bpf: PathBuf,
extra_cargo_test_args: Vec<String>, extra_cargo_test_args: Vec<String>,
features: Vec<String>, features: Vec<String>,
manifest_path: Option<String>,
no_default_features: bool, no_default_features: bool,
verbose: bool, verbose: bool,
workspace: bool,
} }
impl Default for Config { impl Default for Config {
@ -30,9 +30,9 @@ impl Default for Config {
cargo_build_bpf: PathBuf::from("cargo-build-bpf"), cargo_build_bpf: PathBuf::from("cargo-build-bpf"),
extra_cargo_test_args: vec![], extra_cargo_test_args: vec![],
features: vec![], features: vec![],
manifest_path: None,
no_default_features: false, no_default_features: false,
verbose: false, verbose: false,
workspace: false,
} }
} }
} }
@ -63,31 +63,21 @@ where
} }
} }
fn test_bpf(config: Config) { fn test_bpf_package(
let mut metadata_command = cargo_metadata::MetadataCommand::new(); config: &Config,
if let Some(manifest_path) = config.manifest_path.as_ref() { target_directory: &PathBuf,
metadata_command.manifest_path(manifest_path); package: &cargo_metadata::Package,
} ) {
let set_test_bpf_feature = package.features.contains_key("test-bpf");
let metadata = metadata_command.exec().unwrap_or_else(|err| {
eprintln!("Failed to obtain package metadata: {}", err);
exit(1);
});
let root_package = metadata.root_package().unwrap_or_else(|| {
eprintln!(
"Workspace does not have a root package: {}",
metadata.workspace_root.display()
);
exit(1);
});
let set_test_bpf_feature = root_package.features.contains_key("test-bpf");
let bpf_out_dir = config let bpf_out_dir = config
.bpf_out_dir .bpf_out_dir
.unwrap_or_else(|| format!("{}", metadata.target_directory.join("deploy").display())); .as_ref()
.cloned()
.unwrap_or_else(|| format!("{}", target_directory.join("deploy").display()));
let mut cargo_args = vec![]; let manifest_path = format!("{}", package.manifest_path.display());
let mut cargo_args = vec!["--manifest-path", &manifest_path];
if config.no_default_features { if config.no_default_features {
cargo_args.push("--no-default-features"); cargo_args.push("--no-default-features");
} }
@ -95,10 +85,6 @@ fn test_bpf(config: Config) {
cargo_args.push("--features"); cargo_args.push("--features");
cargo_args.push(feature); cargo_args.push(feature);
} }
if let Some(manifest_path) = config.manifest_path.as_ref() {
cargo_args.push("--manifest-path");
cargo_args.push(&manifest_path);
}
if config.verbose { if config.verbose {
cargo_args.push("--verbose"); cargo_args.push("--verbose");
} }
@ -130,6 +116,38 @@ fn test_bpf(config: Config) {
spawn(&config.cargo, &cargo_args); spawn(&config.cargo, &cargo_args);
} }
fn test_bpf(config: Config, manifest_path: Option<PathBuf>) {
let mut metadata_command = cargo_metadata::MetadataCommand::new();
if let Some(manifest_path) = manifest_path.as_ref() {
metadata_command.manifest_path(manifest_path);
}
let metadata = metadata_command.exec().unwrap_or_else(|err| {
eprintln!("Failed to obtain package metadata: {}", err);
exit(1);
});
if let Some(root_package) = metadata.root_package() {
if !config.workspace {
test_bpf_package(&config, &metadata.target_directory, root_package);
return;
}
}
let all_bpf_packages = metadata
.packages
.iter()
.filter(|package| {
package.manifest_path.with_file_name("Xargo.toml").exists()
&& metadata.workspace_members.contains(&package.id)
})
.collect::<Vec<_>>();
for package in all_bpf_packages {
test_bpf_package(&config, &metadata.target_directory, package);
}
}
fn main() { fn main() {
let mut args = env::args().collect::<Vec<_>>(); let mut args = env::args().collect::<Vec<_>>();
// When run as a cargo subcommand, the first program argument is the subcommand name. // When run as a cargo subcommand, the first program argument is the subcommand name.
@ -189,6 +207,13 @@ fn main() {
.takes_value(false) .takes_value(false)
.help("Use verbose output"), .help("Use verbose output"),
) )
.arg(
Arg::with_name("workspace")
.long("workspace")
.takes_value(false)
.alias("all")
.help("Test all BPF packages in the workspace"),
)
.arg( .arg(
Arg::with_name("extra_cargo_test_args") Arg::with_name("extra_cargo_test_args")
.value_name("extra args for cargo test and the test binary") .value_name("extra args for cargo test and the test binary")
@ -207,9 +232,9 @@ fn main() {
features: values_t!(matches, "features", String) features: values_t!(matches, "features", String)
.ok() .ok()
.unwrap_or_else(Vec::new), .unwrap_or_else(Vec::new),
manifest_path: value_t!(matches, "manifest_path", String).ok(),
no_default_features: matches.is_present("no_default_features"), no_default_features: matches.is_present("no_default_features"),
verbose: matches.is_present("verbose"), verbose: matches.is_present("verbose"),
workspace: matches.is_present("workspace"),
..Config::default() ..Config::default()
}; };
@ -235,5 +260,6 @@ fn main() {
config.extra_cargo_test_args.insert(0, em_dash); config.extra_cargo_test_args.insert(0, em_dash);
} }
test_bpf(config); let manifest_path = value_t!(matches, "manifest_path", PathBuf).ok();
test_bpf(config, manifest_path);
} }