Skip to content

Commit 324fc03

Browse files
committed
feat: add support for multiple wit paths
Signed-off-by: Ho Kim <ho.kim@ulagbulag.io>
1 parent 309a28b commit 324fc03

File tree

4 files changed

+53
-35
lines changed

4 files changed

+53
-35
lines changed

src/command.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,12 @@ pub struct Options {
2424

2525
#[derive(clap::Args, Clone, Debug)]
2626
pub struct Common {
27-
/// File or directory containing WIT document(s)
27+
/// File or directory containing WIT document(s).
28+
///
29+
/// This may be specified more than once, for example:
30+
/// `-d ./wit/deps -d ./wit/app`
2831
#[arg(short = 'd', long)]
29-
pub wit_path: Option<PathBuf>,
32+
pub wit_path: Vec<PathBuf>,
3033

3134
/// Name of world to target (or default world if `None`)
3235
#[arg(short = 'w', long)]
@@ -151,9 +154,7 @@ pub fn run<T: Into<OsString> + Clone, I: IntoIterator<Item = T>>(args: I) -> Res
151154

152155
fn generate_bindings(common: Common, bindings: Bindings) -> Result<()> {
153156
crate::generate_bindings(
154-
&common
155-
.wit_path
156-
.unwrap_or_else(|| Path::new("wit").to_owned()),
157+
&common.wit_path,
157158
common.world.as_deref(),
158159
&common.features,
159160
common.all_features,
@@ -185,7 +186,7 @@ fn componentize(common: Common, componentize: Componentize) -> Result<()> {
185186
}
186187

187188
Runtime::new()?.block_on(crate::componentize(
188-
common.wit_path.as_deref(),
189+
&common.wit_path,
189190
common.world.as_deref(),
190191
&common.features,
191192
common.all_features,
@@ -338,7 +339,7 @@ mod tests {
338339

339340
// When generating the bindings for this WIT world
340341
let common = Common {
341-
wit_path: Some(wit.path().into()),
342+
wit_path: vec![wit.path().into()],
342343
world: None,
343344
world_module: Some("bindings".into()),
344345
quiet: false,
@@ -368,7 +369,7 @@ mod tests {
368369

369370
// When generating the bindings for this WIT world
370371
let common = Common {
371-
wit_path: Some(wit.path().into()),
372+
wit_path: vec![wit.path().into()],
372373
world: None,
373374
world_module: Some("bindings".into()),
374375
quiet: false,
@@ -398,7 +399,7 @@ mod tests {
398399

399400
// When generating the bindings for this WIT world
400401
let common = Common {
401-
wit_path: Some(wit.path().into()),
402+
wit_path: vec![wit.path().into()],
402403
world: None,
403404
world_module: Some("bindings".into()),
404405
quiet: false,
@@ -426,7 +427,7 @@ mod tests {
426427
let wit = gated_x_wit_file()?;
427428
let out_dir = tempfile::tempdir()?;
428429
let common = Common {
429-
wit_path: Some(wit.path().into()),
430+
wit_path: vec![wit.path().into()],
430431
world: None,
431432
world_module: Some("bindings".into()),
432433
quiet: false,

src/lib.rs

Lines changed: 38 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ impl Invoker for MyInvoker {
182182

183183
#[allow(clippy::too_many_arguments)]
184184
pub fn generate_bindings(
185-
wit_path: &Path,
185+
wit_path: &[impl AsRef<Path>],
186186
world: Option<&str>,
187187
features: &[String],
188188
all_features: bool,
@@ -217,7 +217,7 @@ pub fn generate_bindings(
217217

218218
#[allow(clippy::type_complexity, clippy::too_many_arguments)]
219219
pub async fn componentize(
220-
wit_path: Option<&Path>,
220+
wit_path: &[impl AsRef<Path>],
221221
world: Option<&str>,
222222
features: &[String],
223223
all_features: bool,
@@ -245,11 +245,12 @@ pub async fn componentize(
245245

246246
// Next, iterate over all the WIT directories, merging them into a single `Resolve`, and matching Python
247247
// packages to `WorldId`s.
248-
let (mut resolve, mut main_world) = if let Some(path) = wit_path {
249-
let (resolve, world) = parse_wit(path, world, features, all_features)?;
250-
(Some(resolve), Some(world))
251-
} else {
252-
(None, None)
248+
let (mut resolve, mut main_world) = match wit_path {
249+
[] => (None, None),
250+
paths => {
251+
let (resolve, world) = parse_wit(paths, world, features, all_features)?;
252+
(Some(resolve), Some(world))
253+
}
253254
};
254255

255256
let import_interface_names = import_interface_names
@@ -281,7 +282,8 @@ pub async fn componentize(
281282
.map(|(module, (config, world))| {
282283
Ok((module, match (world, config.config.wit_directory.as_deref()) {
283284
(_, Some(wit_path)) => {
284-
let (my_resolve, mut world) = parse_wit(&config.path.join(wit_path), *world, features, all_features)?;
285+
let paths = &[config.path.join(wit_path)];
286+
let (my_resolve, mut world) = parse_wit(paths, *world, features, all_features)?;
285287

286288
if let Some(resolve) = &mut resolve {
287289
let remap = resolve.merge(my_resolve)?;
@@ -303,13 +305,13 @@ pub async fn componentize(
303305
let resolve = if let Some(resolve) = resolve {
304306
resolve
305307
} else {
306-
// If no WIT directory was provided as a parameter and none were referenced by Python packages, use ./wit
307-
// by default.
308-
let (my_resolve, world) = parse_wit(Path::new("wit"), world, features, all_features)
309-
.context(
310-
"no WIT files found; please specify the directory or file \
308+
// If no WIT directory was provided as a parameter and none were referenced by Python packages, use
309+
// the default values.
310+
let paths: &[&Path] = &[];
311+
let (my_resolve, world) = parse_wit(paths, world, features, all_features).context(
312+
"no WIT files found; please specify the directory or file \
311313
containing the WIT world you wish to target",
312-
)?;
314+
)?;
313315
main_world = Some(world);
314316
my_resolve
315317
};
@@ -556,11 +558,19 @@ pub async fn componentize(
556558
}
557559

558560
fn parse_wit(
559-
path: &Path,
561+
paths: &[impl AsRef<Path>],
560562
world: Option<&str>,
561563
features: &[String],
562564
all_features: bool,
563565
) -> Result<(Resolve, WorldId)> {
566+
// If no WIT directory was provided as a parameter and none were referenced by Python packages, use ./wit
567+
// by default.
568+
if paths.is_empty() {
569+
let paths = &[Path::new("wit")];
570+
return parse_wit(paths, world, features, all_features);
571+
}
572+
debug_assert!(!paths.is_empty(), "The paths should not be empty");
573+
564574
let mut resolve = Resolve {
565575
all_features,
566576
..Default::default()
@@ -574,12 +584,19 @@ fn parse_wit(
574584
resolve.features.insert(feature.to_string());
575585
}
576586
}
577-
let pkg = if path.is_dir() {
578-
resolve.push_dir(path)?.0
579-
} else {
580-
let pkg = UnresolvedPackageGroup::parse_file(path)?;
581-
resolve.push_group(pkg)?
582-
};
587+
588+
let mut last_pkg = None;
589+
for path in paths.iter().map(AsRef::as_ref) {
590+
let pkg = if path.is_dir() {
591+
resolve.push_dir(path)?.0
592+
} else {
593+
let pkg = UnresolvedPackageGroup::parse_file(path)?;
594+
resolve.push_group(pkg)?
595+
};
596+
last_pkg = Some(pkg);
597+
}
598+
599+
let pkg = last_pkg.unwrap(); // The paths should not be empty
583600
let world = resolve.select_world(pkg, world)?;
584601
Ok((resolve, world))
585602
}

src/python.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use {
1919
#[pyo3(name = "componentize")]
2020
#[pyo3(signature = (wit_path, world, features, all_features, world_module, python_path, module_worlds, app_name, output_path, stub_wasi, import_interface_names, export_interface_names))]
2121
fn python_componentize(
22-
wit_path: Option<PathBuf>,
22+
wit_path: Vec<PathBuf>,
2323
world: Option<&str>,
2424
features: Vec<String>,
2525
all_features: bool,
@@ -34,7 +34,7 @@ fn python_componentize(
3434
) -> PyResult<()> {
3535
(|| {
3636
Runtime::new()?.block_on(crate::componentize(
37-
wit_path.as_deref(),
37+
&wit_path,
3838
world,
3939
&features,
4040
all_features,
@@ -66,7 +66,7 @@ fn python_componentize(
6666
#[pyo3(name = "generate_bindings")]
6767
#[pyo3(signature = (wit_path, world, features, all_features, world_module, output_dir, import_interface_names, export_interface_names))]
6868
fn python_generate_bindings(
69-
wit_path: PathBuf,
69+
wit_path: Vec<PathBuf>,
7070
world: Option<&str>,
7171
features: Vec<String>,
7272
all_features: bool,

src/test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ async fn make_component(
6161
}
6262

6363
crate::componentize(
64-
Some(&tempdir.path().join("app.wit")),
64+
&[tempdir.path().join("app.wit")],
6565
None,
6666
&[],
6767
false,

0 commit comments

Comments
 (0)