Skip to content

Commit

Permalink
ref(*)!: Updates all code to use the new publish functionality in wkg
Browse files Browse the repository at this point in the history
This finishes replacing a direct dependency on warg with the newly
released published functionality in wasm-pkg-tools. Please note that
this removes some warg specific flags and it updates tests.

Signed-off-by: Taylor Thomas <[email protected]>
  • Loading branch information
thomastaylor312 committed Sep 4, 2024
1 parent bcb2087 commit f1a2417
Show file tree
Hide file tree
Showing 20 changed files with 462 additions and 730 deletions.
487 changes: 265 additions & 222 deletions Cargo.lock

Large diffs are not rendered by default.

16 changes: 8 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,6 @@ tokio = { workspace = true }
tokio-util = { workspace = true }
toml_edit = { workspace = true }
url = { workspace = true }
warg-client = { workspace = true }
warg-crypto = { workspace = true }
warg-protocol = { workspace = true }
wasi-preview1-component-adapter-provider = { workspace = true }
wasm-metadata = { workspace = true }
wasm-pkg-client = { workspace = true }
Expand All @@ -60,6 +57,9 @@ wit-parser = { workspace = true }
assert_cmd = { workspace = true }
predicates = { workspace = true }
tempfile = { workspace = true }
warg-client = { workspace = true }
warg-crypto = { workspace = true }
warg-protocol = { workspace = true }
warg-server = { workspace = true }
wasmprinter = { workspace = true }
wat = { workspace = true }
Expand Down Expand Up @@ -101,13 +101,13 @@ tokio-util = "0.7.10"
toml_edit = { version = "0.22.9", features = ["serde"] }
unicode-width = "0.1.11"
url = { version = "2.5.0", features = ["serde"] }
warg-client = "0.7.0"
warg-crypto = "0.7.0"
warg-protocol = "0.7.0"
warg-server = "0.7.0"
warg-client = "0.8"
warg-crypto = "0.8"
warg-protocol = "0.8"
warg-server = "0.8"
wasi-preview1-component-adapter-provider = "23.0.1"
wasm-metadata = "0.208.1"
wasm-pkg-client = { git = "https://github.com/bytecodealliance/wasm-pkg-tools.git", rev = "c48006aa1bcff1e69f4f8fc6689249b314985ab1" }
wasm-pkg-client = { git = "https://github.com/bytecodealliance/wasm-pkg-tools.git", rev = "75d76192c30e718d5b76123720c79153083ed3e6" }
wasmparser = "0.208.1"
wasmprinter = "0.208.1"
wat = "1.208.1"
Expand Down
3 changes: 0 additions & 3 deletions crates/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@ tokio-util = { workspace = true, features = ["io"] }
toml_edit = { workspace = true }
unicode-width = { workspace = true }
url = { workspace = true }
warg-client = { workspace = true }
warg-crypto = { workspace = true }
warg-protocol = { workspace = true }
wasm-pkg-client = { workspace = true }
wit-component = { workspace = true }
wit-parser = { workspace = true }
Expand Down
43 changes: 1 addition & 42 deletions crates/core/src/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,59 +17,18 @@ use serde::{
};

use tokio::io::AsyncReadExt;
use url::Url;
use warg_client::{Config as WargConfig, FileSystemClient, StorageLockResult};
use wasm_pkg_client::{
caching::{CachingClient, FileCache},
Client, Config, ContentDigest, Error as WasmPkgError, PackageRef, Release, VersionInfo,
};
use wit_component::DecodedWasm;
use wit_parser::{PackageId, PackageName, Resolve, UnresolvedPackage, WorldId};

use crate::{
lock::{LockFileResolver, LockedPackageVersion},
terminal::{Colors, Terminal},
};
use crate::lock::{LockFileResolver, LockedPackageVersion};

/// The name of the default registry.
pub const DEFAULT_REGISTRY_NAME: &str = "default";

/// Finds the URL for the given registry name.
pub fn find_url<'a>(
name: Option<&str>,
urls: &'a HashMap<String, Url>,
default: Option<&'a str>,
) -> Result<&'a str> {
let name = name.unwrap_or(DEFAULT_REGISTRY_NAME);
match urls.get(name) {
Some(url) => Ok(url.as_str()),
None if name != DEFAULT_REGISTRY_NAME => {
bail!("component registry `{name}` does not exist in the configuration")
}
None => default.context("a default component registry has not been set"),
}
}

/// Creates a registry client with the given warg configuration.
pub async fn create_client(
config: &WargConfig,
url: &str,
terminal: &Terminal,
) -> Result<FileSystemClient> {
match FileSystemClient::try_new_with_config(Some(url), config, None).await? {
StorageLockResult::Acquired(client) => Ok(client),
StorageLockResult::NotAcquired(path) => {
terminal.status_with_color(
"Blocking",
format!("waiting for file lock on `{path}`", path = path.display()),
Colors::Cyan,
)?;

Ok(FileSystemClient::new_with_config(Some(url), config, None).await?)
}
}
}

/// Represents a WIT package dependency.
#[derive(Debug, Clone)]
pub enum Dependency {
Expand Down
6 changes: 3 additions & 3 deletions crates/wit/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,16 @@ tokio = { workspace = true }
toml_edit = { workspace = true }
url = { workspace = true }
wasm-pkg-client = { workspace = true }
warg-client = { workspace = true }
warg-crypto = { workspace = true }
warg-protocol = { workspace = true }
wasm-metadata = { workspace = true }
wit-component = { workspace = true }
wit-parser = { workspace = true }

[dev-dependencies]
assert_cmd = { workspace = true }
predicates = { workspace = true }
warg-client = { workspace = true }
warg-crypto = { workspace = true }
warg-protocol = { workspace = true }
warg-server = { workspace = true }
tokio-util = { workspace = true }
wasmparser = { workspace = true }
Expand Down
7 changes: 0 additions & 7 deletions crates/wit/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,13 +118,6 @@ To publish the WIT package to a registry, use the `publish` command:
wit publish
```

For new packages, the `--init` option must be used to initialize a new package
log for the package being published:

```
wit publish --init
```

The command will publish the package to the default registry using the default
signing key.

Expand Down
34 changes: 5 additions & 29 deletions crates/wit/src/commands/publish.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
use anyhow::{Context, Result};
use cargo_component_core::{cache_dir, command::CommonOptions, registry::find_url};
use cargo_component_core::{cache_dir, command::CommonOptions};
use clap::Args;
use warg_crypto::signing::PrivateKey;
use warg_protocol::registry::PackageName;
use wasm_pkg_client::caching::FileCache;
use wasm_pkg_client::{caching::FileCache, PackageRef, Registry};

use crate::{
config::{Config, CONFIG_FILE_NAME},
Expand All @@ -22,17 +20,13 @@ pub struct PublishCommand {
#[clap(long = "dry-run")]
pub dry_run: bool,

/// Initialize a new package in the registry.
#[clap(long = "init")]
pub init: bool,

/// Use the specified registry name when publishing the package.
#[clap(long = "registry", value_name = "REGISTRY")]
pub registry: Option<String>,
pub registry: Option<Registry>,

/// Override the package name to publish.
#[clap(long, value_name = "NAME")]
pub package: Option<PackageName>,
pub package: Option<PackageRef>,
}

impl PublishCommand {
Expand All @@ -44,7 +38,6 @@ impl PublishCommand {
.with_context(|| format!("failed to find configuration file `{CONFIG_FILE_NAME}`"))?;

let terminal = self.common.new_terminal();
let warg_config = warg_client::Config::from_default_file()?.unwrap_or_default();
let pkg_config = if let Some(config_file) = self.common.config {
wasm_pkg_client::Config::from_file(&config_file).context(format!(
"failed to load configuration file from {}",
Expand All @@ -55,31 +48,14 @@ impl PublishCommand {
};
let file_cache = FileCache::new(cache_dir(self.common.cache_dir)?).await?;

let url = find_url(
self.registry.as_deref(),
&config.registries,
warg_config.home_url.as_deref(),
)?;

let signing_key = if let Ok(key) = std::env::var("WIT_PUBLISH_KEY") {
Some(PrivateKey::decode(key).context(
"failed to parse signing key from `WIT_PUBLISH_KEY` environment variable",
)?)
} else {
None
};

publish_wit_package(
PublishOptions {
config: &config,
config_path: &config_path,
warg_config: &warg_config,
pkg_config,
cache: file_cache,
url,
signing_key,
url: self.registry.as_ref(),
package: self.package.as_ref(),
init: self.init,
dry_run: self.dry_run,
},
&terminal,
Expand Down
89 changes: 36 additions & 53 deletions crates/wit/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,21 @@
#![deny(missing_docs)]

use std::{collections::HashSet, path::Path, sync::Arc};

use anyhow::{bail, Context, Result};
use bytes::Bytes;
use cargo_component_core::{
lock::{LockFile, LockFileResolver, LockedPackage, LockedPackageVersion},
registry::{create_client, DecodedDependency, DependencyResolutionMap, DependencyResolver},
registry::{DecodedDependency, DependencyResolutionMap, DependencyResolver},
terminal::{Colors, Terminal},
};
use config::Config;
use indexmap::{IndexMap, IndexSet};
use lock::{acquire_lock_file_ro, acquire_lock_file_rw, to_lock_file};
use std::{collections::HashSet, path::Path, time::Duration};
use warg_client::storage::{ContentStorage, PublishEntry, PublishInfo};
use warg_crypto::signing::PrivateKey;
use warg_protocol::registry;
use wasm_metadata::{Link, LinkType, RegistryMetadata};
use wasm_pkg_client::caching::FileCache;
use wasm_pkg_client::{
caching::FileCache, warg::WargRegistryConfig, Client, PackageRef, PublishOpts, Registry,
};
use wit_component::DecodedWasm;
use wit_parser::{PackageId, PackageName, Resolve, UnresolvedPackage};

Expand Down Expand Up @@ -225,7 +224,7 @@ async fn build_wit_package(
pkg_config: wasm_pkg_client::Config,
terminal: &Terminal,
file_cache: FileCache,
) -> Result<(registry::PackageName, Vec<u8>)> {
) -> Result<(PackageRef, Vec<u8>)> {
let dependencies =
resolve_dependencies(config, config_path, pkg_config, terminal, true, file_cache).await?;

Expand Down Expand Up @@ -255,12 +254,9 @@ async fn build_wit_package(
struct PublishOptions<'a> {
config: &'a Config,
config_path: &'a Path,
warg_config: &'a warg_client::Config,
pkg_config: wasm_pkg_client::Config,
url: &'a str,
signing_key: Option<PrivateKey>,
package: Option<&'a registry::PackageName>,
init: bool,
url: Option<&'a Registry>,
package: Option<&'a PackageRef>,
dry_run: bool,
cache: FileCache,
}
Expand Down Expand Up @@ -315,11 +311,11 @@ fn add_registry_metadata(config: &Config, bytes: &[u8]) -> Result<Vec<u8>> {
.context("failed to add registry metadata to component")
}

async fn publish_wit_package(options: PublishOptions<'_>, terminal: &Terminal) -> Result<()> {
async fn publish_wit_package(mut options: PublishOptions<'_>, terminal: &Terminal) -> Result<()> {
let (name, bytes) = build_wit_package(
options.config,
options.config_path,
options.pkg_config,
options.pkg_config.clone(),
terminal,
options.cache,
)
Expand All @@ -332,53 +328,40 @@ async fn publish_wit_package(options: PublishOptions<'_>, terminal: &Terminal) -

let bytes = add_registry_metadata(options.config, &bytes)?;
let name = options.package.unwrap_or(&name);
let client = create_client(options.warg_config, options.url, terminal).await?;

let content = client
.content()
.store_content(
Box::pin(futures::stream::once(async { Ok(Bytes::from(bytes)) })),
None,
)
.await?;

terminal.status("Publishing", format!("package `{name}` ({content})"))?;

let mut info = PublishInfo {
name: name.clone(),
head: None,
entries: Default::default(),
};

if options.init {
info.entries.push(PublishEntry::Init);
if let Ok(key) = std::env::var("WIT_PUBLISH_KEY") {
let registry = options.pkg_config.resolve_registry(name).ok_or_else(|| anyhow::anyhow!("Tried to set a signing key, but registry was not set and no default registry was found. Try setting the `--registry` option."))?.to_owned();
// NOTE(thomastaylor312): If config doesn't already exist, this will essentially force warg
// usage because we'll be creating a config for warg, which means it will default to that
// protocol. So for all intents and purposes, setting a publish key forces warg usage.
let reg_config = options
.pkg_config
.get_or_insert_registry_config_mut(&registry);
let mut warg_conf = WargRegistryConfig::try_from(&*reg_config).unwrap_or_default();
warg_conf.signing_key = Some(Arc::new(
key.try_into().context("Failed to parse signing key")?,
));
reg_config.set_backend_config("warg", warg_conf)?;
}

info.entries.push(PublishEntry::Release {
version: options.config.version.clone(),
content,
});
terminal.status("Publishing", format!("package `{name}`"))?;

let record_id = if let Some(signing_key) = &options.signing_key {
client.publish_with_info(signing_key, info).await?
} else {
client.sign_with_keyring_and_publish(Some(info)).await?
};
client
.wait_for_publish(name, &record_id, Duration::from_secs(1))
let client = Client::new(options.pkg_config);

let (name, version) = client
.publish_release_data(
Box::pin(std::io::Cursor::new(bytes)),
PublishOpts {
package: Some((name.to_owned(), options.config.version.to_owned())),
registry: options.url.cloned(),
},
)
.await?;

terminal.status(
"Published",
format!(
"package `{name}` v{version}",
version = options.config.version
),
)?;
terminal.status("Published", format!("package `{name}` v{version}",))?;

Ok(())
}

/// Update the dependencies in the lock file.
pub async fn update_lockfile(
config: &Config,
Expand Down
6 changes: 3 additions & 3 deletions crates/wit/tests/add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ async fn validate_the_version_exists() -> Result<()> {
let project = server.project("foo", Vec::<String>::new())?;
project.file("foo.wit", "package test:bar;\n")?;
project
.wit(["publish", "--init"])
.wit(["publish"])
.env("WIT_PUBLISH_KEY", test_signing_key())
.assert()
.stderr(contains("Published package `test:bar` v0.1.0"))
Expand Down Expand Up @@ -95,7 +95,7 @@ async fn checks_for_duplicate_dependencies() -> Result<()> {
let project = server.project("foo", Vec::<String>::new())?;
project.file("foo.wit", "package test:bar;\n")?;
project
.wit(["publish", "--init"])
.wit(["publish"])
.env("WIT_PUBLISH_KEY", test_signing_key())
.assert()
.stderr(contains("Published package `test:bar` v0.1.0"))
Expand Down Expand Up @@ -129,7 +129,7 @@ async fn does_not_modify_manifest_for_dry_run() -> Result<()> {
let project = server.project("foo", Vec::<String>::new())?;
project.file("foo.wit", "package test:bar;\n")?;
project
.wit(["publish", "--init"])
.wit(["publish"])
.env("WIT_PUBLISH_KEY", test_signing_key())
.assert()
.stderr(contains("Published package `test:bar` v0.1.0"))
Expand Down
Loading

0 comments on commit f1a2417

Please sign in to comment.