Skip to content

Commit 9f7b7eb

Browse files
committed
feat(cli): Add package build/download/unpack commands
Adds a new CLI command for working with packages: * package download: download a package from a registry * build: build a package from a wasmer.toml manifest * unpack: extract package contents
1 parent 54b8253 commit 9f7b7eb

File tree

12 files changed

+487
-57
lines changed

12 files changed

+487
-57
lines changed

Cargo.lock

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ version = "4.2.3"
8686
[workspace.dependencies]
8787
memoffset = "0.9.0"
8888
wasmer-toml = "0.9.2"
89-
webc = { version = "5.6.0", default-features = false, features = ["package"] }
89+
webc = { version = "5.8.0", default-features = false, features = ["package"] }
9090

9191
[build-dependencies]
9292
test-generator = { path = "tests/lib/test-generator" }

lib/cli/Cargo.toml

+10-50
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ once_cell = "1.17.1"
113113
indicatif = "0.17.5"
114114
opener = "0.6.1"
115115
hyper = { version = "0.14.27", features = ["server"] }
116+
http = "0.2.9"
117+
futures = "0.3.29"
116118

117119
# NOTE: Must use different features for clap because the "color" feature does not
118120
# work on wasi due to the anstream dependency not compiling.
@@ -155,71 +157,29 @@ unix_mode = "0.1.3"
155157
[features]
156158
# Don't add the compiler features in default, please add them on the Makefile
157159
# since we might want to autoconfigure them depending on the availability on the host.
158-
default = [
159-
"sys",
160-
"wat",
161-
"wast",
162-
"compiler",
163-
"wasmer-artifact-create",
164-
"static-artifact-create",
165-
]
160+
default = ["sys", "wat", "wast", "compiler", "wasmer-artifact-create", "static-artifact-create"]
166161
backend = []
167162
coredump = ["wasm-coredump-builder"]
168163
sys = ["compiler", "wasmer-vm"]
169164
jsc = ["backend", "wasmer/jsc", "wasmer/std"]
170165
wast = ["wasmer-wast"]
171166
host-net = ["virtual-net/host-net"]
172167
wat = ["wasmer/wat"]
173-
compiler = [
174-
"backend",
175-
"wasmer/compiler",
176-
"wasmer-compiler/translator",
177-
"wasmer-compiler/compiler",
178-
]
179-
wasmer-artifact-create = [
180-
"compiler",
181-
"wasmer/wasmer-artifact-load",
182-
"wasmer/wasmer-artifact-create",
183-
"wasmer-compiler/wasmer-artifact-load",
184-
"wasmer-compiler/wasmer-artifact-create",
185-
"wasmer-object",
186-
]
187-
static-artifact-create = [
188-
"compiler",
189-
"wasmer/static-artifact-load",
190-
"wasmer/static-artifact-create",
191-
"wasmer-compiler/static-artifact-load",
192-
"wasmer-compiler/static-artifact-create",
193-
"wasmer-object",
194-
]
195-
wasmer-artifact-load = [
196-
"compiler",
197-
"wasmer/wasmer-artifact-load",
198-
"wasmer-compiler/wasmer-artifact-load",
199-
]
200-
static-artifact-load = [
201-
"compiler",
202-
"wasmer/static-artifact-load",
203-
"wasmer-compiler/static-artifact-load",
204-
]
168+
compiler = ["backend", "wasmer/compiler", "wasmer-compiler/translator", "wasmer-compiler/compiler"]
169+
wasmer-artifact-create = ["compiler", "wasmer/wasmer-artifact-load", "wasmer/wasmer-artifact-create", "wasmer-compiler/wasmer-artifact-load", "wasmer-compiler/wasmer-artifact-create", "wasmer-object"]
170+
static-artifact-create = ["compiler", "wasmer/static-artifact-load", "wasmer/static-artifact-create", "wasmer-compiler/static-artifact-load", "wasmer-compiler/static-artifact-create", "wasmer-object"]
171+
wasmer-artifact-load = ["compiler", "wasmer/wasmer-artifact-load", "wasmer-compiler/wasmer-artifact-load"]
172+
static-artifact-load = ["compiler", "wasmer/static-artifact-load", "wasmer-compiler/static-artifact-load"]
205173
experimental-io-devices = ["wasmer-wasix-experimental-io-devices"]
206174
singlepass = ["wasmer-compiler-singlepass", "compiler"]
207175
cranelift = ["wasmer-compiler-cranelift", "compiler"]
208176
llvm = ["wasmer-compiler-llvm", "compiler"]
209-
disable-all-logging = [
210-
"wasmer-wasix/disable-all-logging",
211-
"log/release_max_level_off",
212-
]
177+
disable-all-logging = ["wasmer-wasix/disable-all-logging", "log/release_max_level_off"]
213178
headless = []
214179
headless-minimal = ["headless", "disable-all-logging"]
215180

216181
# Optional
217-
enable-serde = [
218-
"wasmer/enable-serde",
219-
"wasmer-vm/enable-serde",
220-
"wasmer-compiler/enable-serde",
221-
"wasmer-wasix/enable-serde",
222-
]
182+
enable-serde = ["wasmer/enable-serde", "wasmer-vm/enable-serde", "wasmer-compiler/enable-serde", "wasmer-wasix/enable-serde"]
223183

224184
[dev-dependencies]
225185
assert_cmd = "2.0.11"

lib/cli/src/cli.rs

+11-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ use crate::commands::CreateExe;
99
#[cfg(feature = "wast")]
1010
use crate::commands::Wast;
1111
use crate::commands::{
12-
Add, Cache, Config, Init, Inspect, Login, Publish, Run, SelfUpdate, Validate, Whoami,
12+
Add, Cache, CmdPackage, Config, Init, Inspect, Login, Publish, Run, SelfUpdate, Validate,
13+
Whoami,
1314
};
1415
#[cfg(feature = "static-artifact-create")]
1516
use crate::commands::{CreateObj, GenCHeader};
@@ -108,6 +109,11 @@ impl Args {
108109
Some(Cmd::Init(init)) => init.execute(),
109110
Some(Cmd::Login(login)) => login.execute(),
110111
Some(Cmd::Publish(publish)) => publish.execute(),
112+
Some(Cmd::Package(cmd)) => match cmd {
113+
CmdPackage::Download(cmd) => cmd.execute(),
114+
CmdPackage::Unpack(cmd) => cmd.execute(),
115+
CmdPackage::Build(cmd) => cmd.execute(),
116+
},
111117
/*
112118
Some(Cmd::Connect(connect)) => connect.execute(),
113119
*/
@@ -258,7 +264,10 @@ enum Cmd {
258264
#[clap(alias = "run-unstable")]
259265
Run(Run),
260266

261-
// DEPLOY commands
267+
#[clap(subcommand)]
268+
Package(crate::commands::CmdPackage),
269+
270+
// Edge commands
262271
/// Deploy apps to the Wasmer Edge.
263272
Deploy(wasmer_deploy_cli::cmd::deploy::CmdDeploy),
264273

lib/cli/src/commands/container/mod.rs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
mod unpack;
2+
3+
pub use unpack::PackageUnpack;
4+
5+
/// Container related commands. (inspecting, unpacking, ...)
6+
#[derive(clap::Subcommand, Debug)]
7+
// Allowing missing_docs because the comment would override the doc comment on
8+
// the command struct.
9+
#[allow(missing_docs)]
10+
pub enum Container {
11+
Unpack(PackageUnpack),
12+
}
+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
use std::path::PathBuf;
2+
3+
use anyhow::Context;
4+
5+
/// Extract contents of a container to a directory.
6+
#[derive(clap::Parser, Debug)]
7+
pub struct PackageUnpack {
8+
/// The output directory.
9+
#[clap(short = 'o', long)]
10+
out_dir: PathBuf,
11+
12+
/// Overwrite existing directories/files.
13+
#[clap(long)]
14+
overwrite: bool,
15+
16+
/// Path to the package.
17+
package_path: PathBuf,
18+
}
19+
20+
impl PackageUnpack {
21+
pub(crate) fn execute(&self) -> Result<(), anyhow::Error> {
22+
eprintln!("Unpacking...");
23+
24+
let pkg = webc::compat::Container::from_disk(&self.package_path).with_context(|| {
25+
format!(
26+
"could not open package at '{}'",
27+
self.package_path.display()
28+
)
29+
})?;
30+
31+
let outdir = &self.out_dir;
32+
std::fs::create_dir_all(outdir)
33+
.with_context(|| format!("could not create output directory '{}'", outdir.display()))?;
34+
35+
pkg.unpack(outdir, self.overwrite)
36+
.with_context(|| "could not extract package".to_string())?;
37+
38+
eprintln!("Extracted package contents to '{}'", self.out_dir.display());
39+
40+
Ok(())
41+
}
42+
}
43+
44+
#[cfg(test)]
45+
mod tests {
46+
use super::*;
47+
48+
/// Download a package from the dev registry.
49+
#[test]
50+
fn test_cmd_package_extract() {
51+
let dir = tempfile::tempdir().unwrap();
52+
53+
let package_path = std::env::var("CARGO_MANIFEST_DIR").map(PathBuf::from).unwrap()
54+
.parent().unwrap()
55+
.parent().unwrap()
56+
.join("tests/integration/cli/tests/webc/hello-0.1.0-665d2ddc-80e6-4845-85d3-4587b1693bb7.webc");
57+
58+
assert!(package_path.is_file());
59+
60+
let cmd = PackageUnpack {
61+
out_dir: dir.path().to_owned(),
62+
overwrite: false,
63+
package_path,
64+
};
65+
66+
cmd.execute().unwrap();
67+
68+
let mut items = std::fs::read_dir(dir.path())
69+
.unwrap()
70+
.map(|x| {
71+
x.unwrap()
72+
.path()
73+
.file_name()
74+
.unwrap()
75+
.to_str()
76+
.unwrap()
77+
.to_string()
78+
})
79+
.collect::<Vec<_>>();
80+
items.sort();
81+
assert_eq!(
82+
items,
83+
vec![
84+
"atom".to_string(),
85+
"manifest.json".to_string(),
86+
"metadata".to_string(),
87+
]
88+
);
89+
}
90+
}

lib/cli/src/commands/mod.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ mod cache;
66
#[cfg(feature = "compiler")]
77
mod compile;
88
mod config;
9+
mod container;
910
#[cfg(any(feature = "static-artifact-create", feature = "wasmer-artifact-create"))]
1011
mod create_exe;
1112
#[cfg(feature = "static-artifact-create")]
@@ -15,6 +16,7 @@ mod gen_c_header;
1516
mod init;
1617
mod inspect;
1718
mod login;
19+
mod package;
1820
mod publish;
1921
mod run;
2022
mod self_update;
@@ -23,6 +25,11 @@ mod validate;
2325
mod wast;
2426
mod whoami;
2527

28+
pub use self::{
29+
add::*, cache::*, config::*, container::*, init::*, inspect::*, login::*, package::*,
30+
publish::*, run::Run, self_update::*, validate::*, whoami::*,
31+
};
32+
2633
#[cfg(target_os = "linux")]
2734
pub use binfmt::*;
2835
#[cfg(feature = "compiler")]
@@ -31,9 +38,5 @@ pub use compile::*;
3138
pub use create_exe::*;
3239
#[cfg(feature = "wast")]
3340
pub use wast::*;
34-
pub use {
35-
add::*, cache::*, config::*, init::*, inspect::*, login::*, publish::*, run::Run,
36-
self_update::*, validate::*, whoami::*,
37-
};
3841
#[cfg(feature = "static-artifact-create")]
3942
pub use {create_obj::*, gen_c_header::*};

0 commit comments

Comments
 (0)