Skip to content

Commit

Permalink
Improve the --out-dir flag of component wit
Browse files Browse the repository at this point in the history
* Lift files in `deps` outside of their folders to be `deps/*.wit`
  instead of `deps/*/main.wit` since this structure is now supported.
* Handle multi-package input documents by placing each package in the
  main folder.
* Name the main wit file after the package name.
* Add some tests for these cases.
  • Loading branch information
alexcrichton committed Jul 9, 2024
1 parent b92dd79 commit a1a5f7b
Show file tree
Hide file tree
Showing 13 changed files with 105 additions and 32 deletions.
19 changes: 11 additions & 8 deletions crates/wit-component/src/printing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,13 @@ impl WitPrinter {
}

/// Print a set of one or more WIT packages into a string.
pub fn print(&mut self, resolve: &Resolve, pkg_ids: &[PackageId]) -> Result<String> {
let has_multiple_packages = pkg_ids.len() > 1;
pub fn print(
&mut self,
resolve: &Resolve,
pkg_ids: &[PackageId],
force_print_package_in_curlies: bool,
) -> Result<String> {
let print_package_in_curlies = force_print_package_in_curlies || pkg_ids.len() > 1;
for (i, pkg_id) in pkg_ids.into_iter().enumerate() {
if i > 0 {
self.output.push_str("\n\n");
Expand All @@ -68,9 +73,8 @@ impl WitPrinter {
self.output.push_str(&format!("@{version}"));
}

if has_multiple_packages {
self.output.push_str("{");
self.output.indent += 1
if print_package_in_curlies {
self.output.push_str(" {\n");
} else {
self.print_semicolon();
self.output.push_str("\n\n");
Expand All @@ -96,9 +100,8 @@ impl WitPrinter {
writeln!(&mut self.output, "}}")?;
}

if has_multiple_packages {
self.output.push_str("}");
self.output.indent -= 1
if print_package_in_curlies {
self.output.push_str("}\n");
}
}

Expand Down
2 changes: 1 addition & 1 deletion crates/wit-component/tests/components.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ fn run_test(path: &Path) -> Result<()> {
}
};
let wit = WitPrinter::default()
.print(&resolve, &[pkg])
.print(&resolve, &[pkg], false)
.context("failed to print WIT")?;
assert_output(&wit, &component_wit_path)?;

Expand Down
2 changes: 1 addition & 1 deletion crates/wit-component/tests/interfaces.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ fn run_test(path: &Path, is_dir: bool) -> Result<()> {
}

fn assert_print(resolve: &Resolve, pkg_ids: &[PackageId], path: &Path, is_dir: bool) -> Result<()> {
let output = WitPrinter::default().print(resolve, &pkg_ids)?;
let output = WitPrinter::default().print(resolve, &pkg_ids, false)?;
for pkg_id in pkg_ids {
let pkg = &resolve.packages[*pkg_id];
let expected = if is_dir {
Expand Down
2 changes: 1 addition & 1 deletion crates/wit-component/tests/merge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ fn merging() -> Result<()> {
.join("merge")
.join(&pkg.name.name)
.with_extension("wit");
let output = WitPrinter::default().print(&into, &[id])?;
let output = WitPrinter::default().print(&into, &[id], false)?;
assert_output(&expected, &output)?;
}
}
Expand Down
36 changes: 18 additions & 18 deletions src/bin/wasm-tools/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -523,9 +523,7 @@ impl WitOpts {
// This interprets all of the output options and performs such a task.
if self.json {
self.emit_json(&decoded)?;
return Ok(());
}
if self.wasm || self.wat {
} else if self.wasm || self.wat {
self.emit_wasm(&decoded)?;
} else {
self.emit_wit(&decoded)?;
Expand Down Expand Up @@ -618,7 +616,6 @@ impl WitOpts {
assert!(!self.wasm && !self.wat);

let resolve = decoded.resolve();
let main = decoded.packages();

let mut printer = WitPrinter::default();
printer.emit_docs(!self.no_docs);
Expand All @@ -641,28 +638,31 @@ impl WitOpts {
*cnt += 1;
}

let main = decoded.packages();
for (id, pkg) in resolve.packages.iter() {
let output = printer.print(resolve, &[id])?;
let out_dir = if main.contains(&id) {
let is_main = main.contains(&id);
let output = printer.print(resolve, &[id], is_main)?;
let out_dir = if is_main {
dir.clone()
} else {
let dir = dir.join("deps");
let packages_with_same_name = &names[&pkg.name.name];
if packages_with_same_name.len() == 1 {
dir.join(&pkg.name.name)
dir.join("deps")
};
let packages_with_same_name = &names[&pkg.name.name];
let stem = if packages_with_same_name.len() == 1 {
pkg.name.name.clone()
} else {
let packages_with_same_namespace =
packages_with_same_name[&pkg.name.namespace];
if packages_with_same_namespace == 1 {
format!("{}:{}", pkg.name.namespace, pkg.name.name)
} else {
let packages_with_same_namespace =
packages_with_same_name[&pkg.name.namespace];
if packages_with_same_namespace == 1 {
dir.join(format!("{}:{}", pkg.name.namespace, pkg.name.name))
} else {
dir.join(pkg.name.to_string())
}
pkg.name.to_string()
}
};
std::fs::create_dir_all(&out_dir)
.with_context(|| format!("failed to create directory: {out_dir:?}"))?;
let path = out_dir.join("main.wit");
let filename = format!("{stem}.wit");
let path = out_dir.join(&filename);
std::fs::write(&path, &output)
.with_context(|| format!("failed to write file: {path:?}"))?;
println!("Writing: {}", path.display());
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ impl OutputArg {
ids,
mut printer,
} => {
let output = printer.print(resolve, ids)?;
let output = printer.print(resolve, ids, false)?;
self.output_str(&output)
}
}
Expand Down
11 changes: 9 additions & 2 deletions tests/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ use std::env;
use std::io::Write;
use std::path::{Path, PathBuf};
use std::process::{Command, Output, Stdio};
use tempfile::TempDir;

fn main() {
let mut tests = Vec::new();
Expand Down Expand Up @@ -76,13 +77,16 @@ fn run_test(test: &Path, bless: bool) -> Result<()> {

let mut cmd = wasm_tools_exe();
let mut stdin = None;
let tempdir = TempDir::new()?;
for arg in line.split_whitespace() {
if arg == "|" {
let output = execute(&mut cmd, stdin.as_deref(), false)?;
stdin = Some(output.stdout);
cmd = wasm_tools_exe();
} else if arg == "%" {
cmd.arg(test);
} else if arg == "%tmpdir" {
cmd.arg(tempdir.path());
} else {
cmd.arg(arg);
}
Expand All @@ -94,12 +98,14 @@ fn run_test(test: &Path, bless: bool) -> Result<()> {
bless,
&output.stdout,
&test.with_extension(&format!("{extension}.stdout")),
&tempdir,
)
.context("failed to check stdout expectation (auto-update with BLESS=1)")?;
assert_output(
bless,
&output.stderr,
&test.with_extension(&format!("{extension}.stderr")),
&tempdir,
)
.context("failed to check stderr expectation (auto-update with BLESS=1)")?;
Ok(())
Expand Down Expand Up @@ -145,7 +151,9 @@ fn execute(cmd: &mut Command, stdin: Option<&[u8]>, should_fail: bool) -> Result
Ok(output)
}

fn assert_output(bless: bool, output: &[u8], path: &Path) -> Result<()> {
fn assert_output(bless: bool, output: &[u8], path: &Path, tempdir: &TempDir) -> Result<()> {
let tempdir = tempdir.path().to_str().unwrap();
let output = String::from_utf8_lossy(output).replace(tempdir, "%tmpdir");
if bless {
if output.is_empty() {
drop(std::fs::remove_file(path));
Expand All @@ -162,7 +170,6 @@ fn assert_output(bless: bool, output: &[u8], path: &Path) -> Result<()> {
Ok(())
}
} else {
let output = std::str::from_utf8(output)?;
let contents = std::fs::read_to_string(path)
.with_context(|| format!("failed to read {path:?}"))?
.replace("\r\n", "\n");
Expand Down
14 changes: 14 additions & 0 deletions tests/cli/wit-directory-output-in-deps-folder.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// RUN: component embed --dummy % --world a:b/c | component wit --out-dir %tmpdir

package a:b {
interface foo {}

world c {
import foo;
import a:c/foo;
}
}

package a:c {
interface foo {}
}
3 changes: 3 additions & 0 deletions tests/cli/wit-directory-output-in-deps-folder.wit.stdout
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Writing: %tmpdir/root.wit
Writing: %tmpdir/deps/b.wit
Writing: %tmpdir/deps/c.wit
14 changes: 14 additions & 0 deletions tests/cli/wit-directory-output-valid.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// RUN: component wit % --out-dir %tmpdir | component wit %tmpdir

package a:b {
interface foo {}

world c {
import foo;
import a:c/foo;
}
}

package a:c {
interface foo {}
}
16 changes: 16 additions & 0 deletions tests/cli/wit-directory-output-valid.wit.stdout
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package a:c {
interface foo {
}

}


package a:b {
interface foo {
}

world c {
import foo;
import a:c/foo;
}
}
14 changes: 14 additions & 0 deletions tests/cli/wit-directory-output.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// RUN: component wit % --out-dir %tmpdir

package a:b {
interface foo {}

world c {
import foo;
import a:c/foo;
}
}

package a:c {
interface foo {}
}
2 changes: 2 additions & 0 deletions tests/cli/wit-directory-output.wit.stdout
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Writing: %tmpdir/c.wit
Writing: %tmpdir/b.wit

0 comments on commit a1a5f7b

Please sign in to comment.