ability to generate only selected packages and dependencies

This commit is contained in:
Janis 2023-06-29 17:24:14 +02:00
parent caf49d4890
commit 5b11e2998a

View file

@ -23,6 +23,8 @@ pub struct Build {
single_file: bool, single_file: bool,
#[arg(short, long, default_value = "true")] #[arg(short, long, default_value = "true")]
feature_gate: bool, feature_gate: bool,
#[arg(long, value_delimiter = ',', num_args = 1..)]
packages: Option<Vec<String>>,
} }
#[derive(Subcommand)] #[derive(Subcommand)]
@ -257,10 +259,19 @@ pub mod rust {
} }
pub fn build(self, args: &super::Build) -> anyhow::Result<BTreeMap<String, TokenStream>> { pub fn build(self, args: &super::Build) -> anyhow::Result<BTreeMap<String, TokenStream>> {
let packages = self let pkgs = if let Some(packages) = &args.packages {
.sdk let deps = self.dependencies_for_package_names(packages);
.packages log::debug!("all dependencies: {deps:?}");
.values()
deps.iter()
.map(|id| self.sdk.packages.get(id).unwrap())
.collect::<Vec<_>>()
} else {
self.sdk.packages.values().collect::<Vec<_>>()
};
let packages = pkgs
.into_iter()
.map(|pkg| { .map(|pkg| {
let name = canonicalize_name(&pkg.name).to_string(); let name = canonicalize_name(&pkg.name).to_string();
let tokens = self.generate_package(pkg, args.feature_gate)?; let tokens = self.generate_package(pkg, args.feature_gate)?;
@ -272,6 +283,43 @@ pub mod rust {
Ok(packages) Ok(packages)
} }
fn get_package_by_name(&self, name: &str) -> Option<PackageRef> {
self.sdk
.packages
.iter()
.find(|(_, pkg)| &pkg.name == name)
.map(|(id, _)| *id)
}
fn dependencies_for_package_names(&self, names: &Vec<String>) -> BTreeSet<PackageRef> {
names
.iter()
.filter_map(|name| self.get_package_by_name(name))
.flat_map(|id| self.dependencies(self.sdk.packages.get(&id).unwrap()))
.collect::<BTreeSet<_>>()
}
fn dependencies(&self, pkg: &ProcessedPackage) -> BTreeSet<PackageRef> {
let mut set = BTreeSet::new();
self.dependencies_inner(pkg, &mut set);
set
}
fn dependencies_inner(&self, pkg: &ProcessedPackage, pkgs: &mut BTreeSet<PackageRef>) {
pkgs.insert(pkg.package_object);
// depth first, does that matter?
for id in pkg.dependencies.iter() {
if !pkgs.contains(id) {
if let Some(pkg) = self.sdk.packages.get(id) {
self.dependencies_inner(pkg, pkgs);
}
}
}
}
pub fn build_in_dir<P: AsRef<Path>>( pub fn build_in_dir<P: AsRef<Path>>(
self, self,
path: P, path: P,