Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[wasm-metadata] pretty-print cli output #1946

Merged
Merged
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
37 changes: 37 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ anyhow = "1.0.58"
arbitrary = "1.1.0"
clap = { version = "4.0.0", features = ["derive"] }
clap_complete = "4.4.7"
comfy-table = { version = "7.1.3", default-features = false }
criterion = { version = "0.5.1", default-features = false }
env_logger = "0.11"
indexmap = { version = "2.0.0", default-features = false }
Expand Down Expand Up @@ -122,6 +123,7 @@ env_logger = { workspace = true }
log = { workspace = true }
clap = { workspace = true, features = ['wrap_help'] }
clap_complete = { workspace = true, optional = true }
comfy-table = { workspace = true }
tempfile = "3.2.0"
wat = { workspace = true, features = ['dwarf', 'component-model'] }
termcolor = { workspace = true }
Expand Down
45 changes: 0 additions & 45 deletions crates/wasm-metadata/src/payload.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use std::fmt::{self, Display};
use std::ops::Range;

use anyhow::Result;
Expand Down Expand Up @@ -181,48 +180,4 @@ impl Payload {
Self::Component { children, .. } => children.push(child),
}
}

fn display(&self, f: &mut fmt::Formatter, indent: usize) -> fmt::Result {
let spaces = std::iter::repeat(" ").take(indent).collect::<String>();
match self {
Self::Module(Metadata {
name, producers, ..
}) => {
if let Some(name) = name {
writeln!(f, "{spaces}module {name}:")?;
} else {
writeln!(f, "{spaces}module:")?;
}
if let Some(producers) = producers {
producers.display(f, indent + 4)?;
}
Ok(())
}
Self::Component {
children,
metadata: Metadata {
name, producers, ..
},
} => {
if let Some(name) = name {
writeln!(f, "{spaces}component {name}:")?;
} else {
writeln!(f, "{spaces}component:")?;
}
if let Some(producers) = producers {
producers.display(f, indent + 4)?;
}
for c in children {
c.display(f, indent + 4)?;
}
Ok(())
}
}
}
}

impl Display for Payload {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.display(f, 0)
}
}
22 changes: 0 additions & 22 deletions crates/wasm-metadata/src/producers.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use anyhow::Result;
use indexmap::{map::Entry, IndexMap};
use serde_derive::Serialize;
use std::fmt;
use wasm_encoder::Encode;
use wasmparser::{BinaryReader, KnownCustom, Parser, ProducersSectionReader};

Expand Down Expand Up @@ -150,27 +149,6 @@ impl Producers {
pub fn add_to_wasm(&self, input: &[u8]) -> Result<Vec<u8>> {
rewrite_wasm(&None, self, &None, &None, &None, &None, &None, input)
}

pub(crate) fn display(&self, f: &mut fmt::Formatter, indent: usize) -> fmt::Result {
let indent = std::iter::repeat(" ").take(indent).collect::<String>();
for (fieldname, fieldvalues) in self.0.iter() {
writeln!(f, "{indent}{fieldname}:")?;
for (name, version) in fieldvalues {
if version.is_empty() {
writeln!(f, "{indent} {name}")?;
} else {
writeln!(f, "{indent} {name}: {version}")?;
}
}
}
Ok(())
}
}

impl fmt::Display for Producers {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.display(f, 0)
}
}

/// Contents of a producers field
Expand Down
86 changes: 82 additions & 4 deletions src/bin/wasm-tools/metadata.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
use anyhow::Result;
use std::io::Write;

use anyhow::Result;
use comfy_table::modifiers::UTF8_ROUND_CORNERS;
use comfy_table::presets::UTF8_FULL;
use comfy_table::{ContentArrangement, Table};
use termcolor::WriteColor;
use wasm_metadata::{Metadata, Payload};

/// Manipulate metadata (module name, producers) to a WebAssembly file.
#[derive(clap::Parser)]
pub enum Opts {
Expand Down Expand Up @@ -44,11 +50,11 @@ impl ShowOpts {
let input = self.io.parse_input_wasm()?;
let mut output = self.io.output_writer()?;

let metadata = wasm_metadata::Payload::from_binary(&input)?;
let payload = wasm_metadata::Payload::from_binary(&input)?;
if self.json {
write!(output, "{}", serde_json::to_string(&metadata)?)?;
write!(output, "{}", serde_json::to_string(&payload)?)?;
} else {
write!(output, "{metadata}")?;
fmt_payload(&payload, &mut output)?;
}
Ok(())
}
Expand Down Expand Up @@ -82,3 +88,75 @@ impl AddOpts {
Ok(())
}
}

fn fmt_payload(payload: &Payload, f: &mut Box<dyn WriteColor>) -> Result<()> {
let mut table = Table::new();
table
.load_preset(UTF8_FULL)
.apply_modifier(UTF8_ROUND_CORNERS)
.set_content_arrangement(ContentArrangement::Dynamic)
.set_width(80)
.set_header(vec!["KIND", "VALUE"]);
let Metadata {
name,
author,
description,
producers,
licenses,
source,
homepage,
range,
} = payload.metadata();

// Print the basic information
let kind = match payload {
Payload::Component { .. } => "component",
Payload::Module(_) => "module",
};
table.add_row(vec!["kind", &kind]);
let name = name.as_deref().unwrap_or("<unknown>");
table.add_row(vec!["name", &name]);
table.add_row(vec![
"range",
&format!("0x{:x}..0x{:x}", range.start, range.end),
]);

// Print the OCI annotations
if let Some(description) = description {
table.add_row(vec!["description", &description.to_string()]);
}
if let Some(licenses) = licenses {
table.add_row(vec!["licenses", &licenses.to_string()]);
}
if let Some(author) = author {
table.add_row(vec!["author", &author.to_string()]);
}
if let Some(source) = source {
table.add_row(vec!["source", &source.to_string()]);
}
if let Some(homepage) = homepage {
table.add_row(vec!["homepage", &homepage.to_string()]);
}

if let Some(producers) = producers {
for (name, pairs) in producers.iter() {
for (field, version) in pairs.iter() {
match version.len() {
0 => table.add_row(vec![name, &format!("{field}")]),
_ => table.add_row(vec![name, &format!("{field} [{version}]")]),
};
}
}
}

// Write the table to the writer
writeln!(f, "{table}")?;

if let Payload::Component { children, .. } = payload {
for payload in children {
fmt_payload(payload, f)?;
}
}

Ok(())
}
21 changes: 15 additions & 6 deletions tests/cli/add-metadata-merge-sections.wat.stdout
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
module:
language:
foo: 3
bar: 1
sdk:
foo: 2
╭──────────┬───────────╮
│ KIND ┆ VALUE │
╞══════════╪═══════════╡
│ kind ┆ module │
├╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
│ name ┆ <unknown> │
├╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
│ range ┆ 0x0..0x36 │
├╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
│ language ┆ foo [3] │
├╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
│ language ┆ bar [1] │
├╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
│ sdk ┆ foo [2] │
╰──────────┴───────────╯
10 changes: 9 additions & 1 deletion tests/cli/add-metadata-overwrite-name.wat.stdout
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
module foo:
╭───────┬───────────╮
│ KIND ┆ VALUE │
╞═══════╪═══════════╡
│ kind ┆ module │
├╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
│ name ┆ foo │
├╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
│ range ┆ 0x0..0x15 │
╰───────┴───────────╯
22 changes: 15 additions & 7 deletions tests/cli/add-metadata.wat.stdout
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
module foo:
language:
bar: 1
processed-by:
baz: 1
sdk:
my-sdk: 2
╭──────────────┬────────────╮
│ KIND ┆ VALUE │
╞══════════════╪════════════╡
│ kind ┆ module │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
│ name ┆ foo │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
│ range ┆ 0x0..0x54 │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
│ language ┆ bar [1] │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
│ processed-by ┆ baz [1] │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
│ sdk ┆ my-sdk [2] │
╰──────────────┴────────────╯
24 changes: 20 additions & 4 deletions tests/cli/metadata-add-component.wat.stdout
Original file line number Diff line number Diff line change
@@ -1,4 +1,20 @@
component foo:
language:
foo: 1
module:
╭──────────┬───────────╮
│ KIND ┆ VALUE │
╞══════════╪═══════════╡
│ kind ┆ component │
├╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
│ name ┆ foo │
├╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
│ range ┆ 0x0..0x65 │
├╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
│ language ┆ foo [1] │
╰──────────┴───────────╯
╭───────┬───────────╮
│ KIND ┆ VALUE │
╞═══════╪═══════════╡
│ kind ┆ module │
├╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
│ name ┆ <unknown> │
├╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
│ range ┆ 0xa..0x31 │
╰───────┴───────────╯
30 changes: 27 additions & 3 deletions tests/cli/metadata-component.wat.stdout
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
component my-name:
module submodule:
module another submodule:
╭───────┬───────────╮
│ KIND ┆ VALUE │
╞═══════╪═══════════╡
│ kind ┆ component │
├╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
│ name ┆ my-name │
├╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
│ range ┆ 0x0..0x88 │
╰───────┴───────────╯
╭───────┬───────────╮
│ KIND ┆ VALUE │
╞═══════╪═══════════╡
│ kind ┆ module │
├╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
│ name ┆ submodule │
├╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
│ range ┆ 0xa..0x25 │
╰───────┴───────────╯
╭───────┬───────────────────╮
│ KIND ┆ VALUE │
╞═══════╪═══════════════════╡
│ kind ┆ module │
├╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ name ┆ another submodule │
├╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ range ┆ 0x27..0x4a │
╰───────┴───────────────────╯
Loading
Loading