Skip to content

Commit f3840de

Browse files
feat(*)!: Uses wasm-pkg-client for loading dependencies
This is a fairly large PR because this dependency is used everywhere. cargo component now uses the new wasm-pkg-tools toolchain to load deps, which means that both OCI and Warg are supported. This tries to stay as close to the original code style as possible, but I did have to make large changes to how dependencies were being resolved to account for the new library. There are a couple major breaking changes to be aware of and one question to answer. This PR is already quite large, so I figured it would be better to probably merge this and then deal with follow ups to any of the outstanding questions below: - Bindings are now generated every time. Where the actual dependency is being loaded from is now abstracted away by the client, so we can't check if those files have changed on disk. I personally don't think this is the worst thing, but if people really want that functionality, we can add support for that into the package tools. - Offline deps currently does not work, but that is something that will be added into wasm-pkg-client instead of doing checks within cargo component itself. - Currently the registries specified within Cargo.toml are not used in favor of using the config file for wasm-pkg-tools. I am not sure if we wanted to use that to override the wasm-pkg-tools config or just drop it entirely. I would like to address this one before merge. - Until wasm-pkg-client has support for publishing, I have left support in to use warg directly. Once we have that added to wasm-pkg-tools, we can change the behavior here Signed-off-by: Taylor Thomas <taylor@cosmonic.com>
1 parent 7cf7368 commit f3840de

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+2596
-1935
lines changed

Cargo.lock

Lines changed: 1017 additions & 478 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 64 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -18,95 +18,102 @@ keywords = ["webassembly", "wasm", "components", "component-model"]
1818
repository = "https://github.com/bytecodealliance/cargo-component"
1919

2020
[dependencies]
21-
cargo-component-core = { workspace = true }
2221
anyhow = { workspace = true }
22+
bytes = { workspace = true }
23+
cargo_metadata = { workspace = true }
24+
cargo-component-core = { workspace = true }
25+
cargo-config2 = { workspace = true }
2326
clap = { workspace = true }
24-
toml_edit = { workspace = true }
25-
pretty_env_logger = { workspace = true }
26-
log = { workspace = true }
27-
tokio = { workspace = true }
28-
tokio-util = { workspace = true }
27+
futures = { workspace = true }
2928
heck = { workspace = true }
30-
semver = { workspace = true }
31-
serde = { workspace = true }
32-
serde_json = { workspace = true }
3329
indexmap = { workspace = true }
34-
url = { workspace = true }
35-
wit-bindgen-rust = { workspace = true }
36-
wit-bindgen-core = { workspace = true }
37-
wit-parser = { workspace = true }
38-
wit-component = { workspace = true }
39-
wasm-metadata = { workspace = true }
40-
wasmparser = { workspace = true }
41-
parse_arg = { workspace = true }
42-
cargo_metadata = { workspace = true }
43-
cargo-config2 = { workspace = true }
4430
libc = { workspace = true }
45-
warg-protocol = { workspace = true }
46-
warg-crypto = { workspace = true }
47-
warg-client = { workspace = true }
31+
log = { workspace = true }
4832
p256 = { workspace = true }
33+
parse_arg = { workspace = true }
34+
pretty_env_logger = { workspace = true }
4935
rand_core = { workspace = true }
5036
rpassword = { workspace = true }
51-
futures = { workspace = true }
52-
bytes = { workspace = true }
53-
which = { workspace = true }
37+
semver = { workspace = true }
38+
serde = { workspace = true }
39+
serde_json = { workspace = true }
5440
shell-escape = "0.1.5"
5541
tempfile = { workspace = true }
42+
tokio = { workspace = true }
43+
tokio-util = { workspace = true }
44+
toml_edit = { workspace = true }
45+
url = { workspace = true }
46+
warg-client = { workspace = true }
47+
warg-crypto = { workspace = true }
48+
warg-protocol = { workspace = true }
49+
wasm-metadata = { workspace = true }
50+
wasm-pkg-client = { workspace = true }
51+
wasmparser = { workspace = true }
52+
which = { workspace = true }
53+
wit-bindgen-core = { workspace = true }
54+
wit-bindgen-rust = { workspace = true }
55+
wit-component = { workspace = true }
56+
wit-parser = { workspace = true }
5657

5758
[dev-dependencies]
5859
assert_cmd = { workspace = true }
5960
predicates = { workspace = true }
60-
wat = { workspace = true }
61-
warg-server = { workspace = true }
6261
tempfile = { workspace = true }
62+
warg-server = { workspace = true }
6363
wasmprinter = { workspace = true }
64+
wat = { workspace = true }
6465

6566
[workspace]
6667
members = ["crates/core", "crates/wit"]
6768

6869
[workspace.dependencies]
69-
cargo-component-core = { path = "crates/core", version = "0.15.0-dev" }
70-
warg-protocol = "0.7.0"
71-
warg-crypto = "0.7.0"
72-
warg-client = "0.7.0"
73-
warg-server = "0.7.0"
7470
anyhow = "1.0.82"
75-
clap = { version = "4.5.4", features = ["derive"] }
76-
toml_edit = { version = "0.22.9", features = ["serde"] }
77-
pretty_env_logger = "0.5.0"
78-
log = "0.4.21"
79-
tokio = { version = "1.37.0", default-features = false, features = ["macros", "rt-multi-thread"] }
80-
tokio-util = "0.7.10"
81-
heck = "0.5.0"
82-
semver = "1.0.22"
83-
serde = { version = "1.0.197", features = ["derive"] }
84-
serde_json = "1.0.115"
85-
indexmap = "2.2.6"
86-
url = { version = "2.5.0", features = ["serde"] }
87-
wit-parser = "0.208.1"
88-
wit-component = "0.208.1"
89-
wasm-metadata = "0.208.1"
90-
parse_arg = "0.1.4"
71+
assert_cmd = "2.0.14"
72+
bytes = "1.6.0"
9173
cargo_metadata = "0.18.1"
74+
cargo-component-core = { path = "crates/core", version = "0.15.0-dev" }
9275
cargo-config2 = "0.1.24"
76+
clap = { version = "4.5.4", features = ["derive", "env"] }
77+
dirs = "5"
78+
futures = "0.3.30"
79+
heck = "0.5.0"
80+
indexmap = "2.2.6"
9381
libc = "0.2.153"
82+
log = "0.4.21"
83+
oci-distribution = "0.11"
9484
owo-colors = "4.0.0"
95-
unicode-width = "0.1.11"
9685
p256 = "0.13.2"
86+
parse_arg = "0.1.4"
87+
predicates = "3.1.0"
88+
pretty_env_logger = "0.5.0"
9789
rand_core = "0.6.4"
9890
rpassword = "7.3.1"
99-
futures = "0.3.30"
100-
bytes = "1.6.0"
101-
which = "6.0.1"
102-
wit-bindgen-rust = "0.25.0"
103-
wit-bindgen-core = "0.25.0"
91+
semver = "1"
92+
serde = { version = "1.0.197", features = ["derive"] }
93+
serde_json = "1.0.115"
10494
tempfile = "3.10.1"
105-
assert_cmd = "2.0.14"
106-
predicates = "3.1.0"
95+
tokio = { version = "1.37.0", default-features = false, features = [
96+
"macros",
97+
"rt-multi-thread",
98+
] }
99+
tokio-util = "0.7.10"
100+
toml_edit = { version = "0.22.9", features = ["serde"] }
101+
unicode-width = "0.1.11"
102+
url = { version = "2.5.0", features = ["serde"] }
103+
warg-client = "0.7.0"
104+
warg-crypto = "0.7.0"
105+
warg-protocol = "0.7.0"
106+
warg-server = "0.7.0"
107+
wasm-metadata = "0.208.1"
108+
wasm-pkg-client = { git = "https://github.com/thomastaylor312/wasm-pkg-tools.git", branch = "fix/cached_versions" }
107109
wasmparser = "0.208.1"
108-
wat = "1.208.1"
109110
wasmprinter = "0.208.1"
111+
wat = "1.208.1"
112+
which = "6.0.1"
113+
wit-bindgen-core = "0.25.0"
114+
wit-bindgen-rust = "0.25.0"
115+
wit-component = "0.208.1"
116+
wit-parser = "0.208.1"
110117

111118
[profile.release]
112119
panic = "abort"

crates/core/Cargo.toml

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,26 @@ repository = { workspace = true }
1111

1212
[dependencies]
1313
anyhow = { workspace = true }
14+
clap = { workspace = true }
15+
dirs = { workspace = true }
16+
futures = { workspace = true }
17+
indexmap = { workspace = true }
1418
libc = { workspace = true }
19+
log = { workspace = true }
1520
owo-colors = { workspace = true }
16-
unicode-width = { workspace = true }
17-
warg-crypto = { workspace = true }
18-
warg-protocol = { workspace = true }
19-
warg-client = { workspace = true }
20-
toml_edit = { workspace = true }
2121
semver = { workspace = true }
2222
serde = { workspace = true }
23-
indexmap = { workspace = true }
24-
futures = { workspace = true }
23+
tokio = { workspace = true }
24+
tokio-util = { workspace = true, features = ["io"] }
25+
toml_edit = { workspace = true }
26+
unicode-width = { workspace = true }
2527
url = { workspace = true }
28+
warg-client = { workspace = true }
29+
warg-crypto = { workspace = true }
30+
warg-protocol = { workspace = true }
31+
wasm-pkg-client = { workspace = true }
2632
wit-component = { workspace = true }
2733
wit-parser = { workspace = true }
28-
log = { workspace = true }
29-
tokio = { workspace = true }
30-
clap = { workspace = true }
3134

3235
[target.'cfg(windows)'.dependencies.windows-sys]
3336
version = "0.52"

crates/core/src/command.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
//! Module for common command implementation.
2+
use std::path::PathBuf;
23

3-
use crate::terminal::{Color, Terminal, Verbosity};
44
use clap::{ArgAction, Args};
55

6+
use crate::terminal::{Color, Terminal, Verbosity};
7+
8+
/// The environment variable name for setting a cache directory location
9+
pub const CACHE_DIR_ENV_VAR: &str = "CARGO_COMPONENT_CACHE_DIR";
10+
/// The environment variable name for setting a path to a config file
11+
pub const CONFIG_FILE_ENV_VAR: &str = "CARGO_COMPONENT_CONFIG_FILE";
12+
613
/// Common options for commands.
714
#[derive(Args)]
815
#[command(
@@ -24,6 +31,14 @@ pub struct CommonOptions {
2431
/// Coloring: auto, always, never
2532
#[clap(long = "color", value_name = "WHEN")]
2633
pub color: Option<Color>,
34+
35+
/// The path to the cache directory to store component dependencies.
36+
#[clap(long = "cache-dir", env = CACHE_DIR_ENV_VAR)]
37+
pub cache_dir: Option<PathBuf>,
38+
39+
/// The path to the pkg-tools config file
40+
#[clap(long = "config", env = CONFIG_FILE_ENV_VAR)]
41+
pub config: Option<PathBuf>,
2742
}
2843

2944
impl CommonOptions {

crates/core/src/lib.rs

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,44 @@
22
33
#![deny(missing_docs)]
44

5+
use std::path::PathBuf;
6+
use std::str::FromStr;
7+
58
use anyhow::Context;
69
use semver::VersionReq;
7-
use std::str::FromStr;
8-
use warg_protocol::registry::PackageName;
10+
use wasm_pkg_client::PackageRef;
911

1012
pub mod command;
1113
pub mod lock;
1214
pub mod progress;
1315
pub mod registry;
1416
pub mod terminal;
1517

18+
/// The root directory name used for default cargo component directories
19+
pub const CARGO_COMPONENT_DIR: &str = "cargo-component";
20+
/// The cache directory name used by default
21+
pub const CACHE_DIR: &str = "cache";
22+
23+
/// Returns the path to the default cache directory, returning an error if a cache directory cannot be found.
24+
pub fn default_cache_dir() -> anyhow::Result<PathBuf> {
25+
dirs::cache_dir()
26+
.map(|p| p.join(CARGO_COMPONENT_DIR).join(CACHE_DIR))
27+
.ok_or_else(|| anyhow::anyhow!("failed to find cache directory"))
28+
}
29+
30+
/// A helper that fetches the default directory if the given directory is `None`.
31+
pub fn cache_dir(dir: Option<PathBuf>) -> anyhow::Result<PathBuf> {
32+
match dir {
33+
Some(dir) => Ok(dir),
34+
None => default_cache_dir(),
35+
}
36+
}
37+
1638
/// Represents a versioned component package name.
1739
#[derive(Clone)]
1840
pub struct VersionedPackageName {
1941
/// The package name.
20-
pub name: PackageName,
42+
pub name: PackageRef,
2143
/// The optional package version.
2244
pub version: Option<VersionReq>,
2345
}

crates/core/src/lock.rs

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ use std::{
1010
path::{Path, PathBuf},
1111
};
1212
use toml_edit::{DocumentMut, Item, Value};
13-
use warg_crypto::hash::AnyHash;
14-
use warg_protocol::registry::PackageName;
13+
use wasm_pkg_client::{ContentDigest, PackageRef};
1514

1615
/// The file format version of the lock file.
1716
const LOCK_FILE_VERSION: i64 = 1;
@@ -21,7 +20,7 @@ const LOCK_FILE_VERSION: i64 = 1;
2120
#[serde(rename_all = "kebab-case")]
2221
pub struct LockedPackage {
2322
/// The name of the locked package.
24-
pub name: PackageName,
23+
pub name: PackageRef,
2524
/// The registry the package was resolved from.
2625
///
2726
/// Defaults to the default registry if not specified.
@@ -37,9 +36,10 @@ pub struct LockedPackage {
3736

3837
impl LockedPackage {
3938
/// Gets the key used in sorting and searching the package list.
40-
pub fn key(&self) -> (&PackageName, &str) {
39+
pub fn key(&self) -> (&str, &str, &str) {
4140
(
42-
&self.name,
41+
self.name.namespace().as_ref(),
42+
self.name.name().as_ref(),
4343
self.registry.as_deref().unwrap_or(DEFAULT_REGISTRY_NAME),
4444
)
4545
}
@@ -53,7 +53,7 @@ pub struct LockedPackageVersion {
5353
/// The version the package is locked to.
5454
pub version: Version,
5555
/// The digest of the package contents.
56-
pub digest: AnyHash,
56+
pub digest: ContentDigest,
5757
}
5858

5959
impl LockedPackageVersion {
@@ -81,13 +81,20 @@ impl<'a> LockFileResolver<'a> {
8181
pub fn resolve(
8282
&'a self,
8383
registry: &str,
84-
name: &PackageName,
84+
package_ref: &PackageRef,
8585
requirement: &VersionReq,
8686
) -> Result<Option<&'a LockedPackageVersion>> {
8787
if let Some(pkg) = self
8888
.0
8989
.packages
90-
.binary_search_by_key(&(name, registry), LockedPackage::key)
90+
.binary_search_by_key(
91+
&(
92+
package_ref.namespace().as_ref(),
93+
package_ref.name().as_ref(),
94+
registry,
95+
),
96+
LockedPackage::key,
97+
)
9198
.ok()
9299
.map(|i| &self.0.packages[i])
93100
{
@@ -96,12 +103,12 @@ impl<'a> LockFileResolver<'a> {
96103
.binary_search_by_key(&requirement.to_string().as_str(), LockedPackageVersion::key)
97104
{
98105
let locked = &pkg.versions[index];
99-
log::info!("dependency package `{name}` from registry `{registry}` with requirement `{requirement}` was resolved by the lock file to version {version}", version = locked.version);
106+
log::info!("dependency package `{package_ref}` from registry `{registry}` with requirement `{requirement}` was resolved by the lock file to version {version}", version = locked.version);
100107
return Ok(Some(locked));
101108
}
102109
}
103110

104-
log::info!("dependency package `{name}` from registry `{registry}` with requirement `{requirement}` was not in the lock file");
111+
log::info!("dependency package `{package_ref}` from registry `{registry}` with requirement `{requirement}` was not in the lock file");
105112
Ok(None)
106113
}
107114
}

0 commit comments

Comments
 (0)