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

ref(*)!: Updates all code to use the new publish functionality in wkg #331

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
1,509 changes: 617 additions & 892 deletions Cargo.lock

Large diffs are not rendered by default.

20 changes: 10 additions & 10 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,15 +101,15 @@ 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"
wasi-preview1-component-adapter-provider = "23.0.1"
warg-client = "0.9.0"
warg-crypto = "0.9.0"
warg-protocol = "0.9.0"
warg-server = "0.9.0"
wasi-preview1-component-adapter-provider = "24"
wasm-metadata = "0.215.0"
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 = "5f92186a928b78b740a220fa0d4c66887cbdd382" }
wasmparser = "0.215.0"
wasmprinter = "0.215.0"
wasmprinter = "0.216.0"
wat = "1.208.1"
which = "6.0.1"
wit-bindgen-core = "0.30.0"
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, UnresolvedPackageGroup, 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,
registry: 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, UnresolvedPackageGroup};

Expand Down Expand Up @@ -229,7 +228,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 @@ -259,12 +258,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,
registry: Option<&'a Registry>,
package: Option<&'a PackageRef>,
dry_run: bool,
cache: FileCache,
}
Expand Down Expand Up @@ -319,11 +315,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 @@ -336,53 +332,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.registry.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