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

Code reorganization and doc improvements #53

Closed
wants to merge 2 commits into from
Closed
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
4 changes: 4 additions & 0 deletions Cargo.lock

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

10 changes: 9 additions & 1 deletion crates/wasm-pkg-common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,23 @@ license.workspace = true

[features]
metadata-client = ["dep:reqwest"]
tokio = ["dep:tokio"]

[dependencies]
anyhow = "1.0"
bytes = "1.6.0"
dirs = "5.0.1"
futures-util = "0.3.30"
http = "1.1.0"
reqwest = { version = "0.12.0", features = ["json"], optional = true }
semver = "1.0.23"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
sha2 = "0.10.8"
tokio = { workspace = true, features = ["io-util"], optional = true }
toml = "0.8.13"
thiserror = "1.0"
tracing = "0.1"
tracing = "0.1"

[dev-dependencies]
tokio = { workspace = true, features = ["macros", "rt"] }
6 changes: 4 additions & 2 deletions crates/wasm-pkg-common/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,8 @@ impl Config {

/// Returns a registry for the given namespace.
///
/// Does not fall back to the default registry; see [`Self::resolve`].
/// Does not fall back to the default registry; see
/// [`Self::resolve_registry`].
pub fn namespace_registry(&self, namespace: &Label) -> Option<&Registry> {
self.namespace_registries.get(namespace)
}
Expand All @@ -181,7 +182,8 @@ impl Config {

/// Returns a registry override configured for the given package.
///
/// Does not fall back to namespace or default registries; see [`Self::resolve`].
/// Does not fall back to namespace or default registries; see
/// [`Self::resolve_registry`].
pub fn package_registry_override(&self, package: &PackageRef) -> Option<&Registry> {
self.package_registry_overrides.get(package)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,19 @@ use std::path::Path;
use bytes::Bytes;
use futures_util::{future::ready, stream::once, Stream, StreamExt, TryStream, TryStreamExt};
use sha2::{Digest, Sha256};
use tokio::io::AsyncReadExt;
use wasm_pkg_common::package::Version;

use crate::Error;

#[derive(Clone, Debug)]
pub struct Release {
pub version: Version,
pub content_digest: ContentDigest,
}

/// A cryptographic digest (hash) of some content.
#[derive(Clone, Debug, PartialEq)]
pub enum ContentDigest {
Sha256 { hex: String },
}

impl ContentDigest {
#[cfg(feature = "tokio")]
pub async fn sha256_from_file(path: impl AsRef<Path>) -> Result<Self, std::io::Error> {
use tokio::io::AsyncReadExt;
let mut file = tokio::fs::File::open(path).await?;
let mut hasher = Sha256::new();
let mut buf = [0; 4096];
Expand Down
1 change: 1 addition & 0 deletions crates/wasm-pkg-common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use http::uri::InvalidUri;
use label::Label;

pub mod config;
pub mod digest;
pub mod label;
pub mod metadata;
pub mod package;
Expand Down
4 changes: 3 additions & 1 deletion crates/wasm-pkg-common/src/package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ use crate::{label::Label, Error};

pub use semver::Version;

/// A package reference, consisting of kebab-case namespace and name, e.g. `wasm-pkg:loader`.
/// A package reference, consisting of kebab-case namespace and name.
///
/// Ex: `wasm-pkg:loader`
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(into = "String", try_from = "String")]
pub struct PackageRef {
Expand Down
4 changes: 3 additions & 1 deletion crates/wasm-pkg-common/src/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ use serde::{Deserialize, Serialize};

use crate::Error;

/// A registry identifier, which should be a valid HTTP Host.
/// A registry identifier.
///
/// This must be a valid HTTP Host.
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(into = "String", try_from = "String")]
pub struct Registry(Authority);
Expand Down
10 changes: 5 additions & 5 deletions crates/wasm-pkg-loader/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
[package]
name = "wasm-pkg-loader"
description = "Wasm package loader"
authors.workspace = true
repository = "https://github.com/bytecodealliance/wasm-pkg-tools/tree/main/crates/wasm-pkg-loader"
edition.workspace = true
version.workspace = true
authors.workspace = true
license.workspace = true
edition.workspace = true
repository = "https://github.com/bytecodealliance/wasm-pkg-tools/tree/main/crates/wasm-pkg-loader"

[dependencies]
anyhow = "1.0.79"
Expand All @@ -22,12 +22,12 @@ serde = { version = "1.0.194", features = ["derive"] }
serde_json = "1.0.110"
sha2 = "0.10.8"
thiserror = "1.0.51"
tokio = { version = "1.35.1", features = ["rt", "macros"] }
tokio = { workspace = true, features = ["rt", "macros"] }
tokio-util = { version = "0.7.10", features = ["io"] }
toml = "0.8.8"
tracing = "0.1.40"
tracing-subscriber = { workspace = true }
url = "2.5.0"
warg-client = "0.7.0"
warg-protocol = "0.7.0"
wasm-pkg-common = { workspace = true, features = ["metadata-client"] }
wasm-pkg-common = { workspace = true, features = ["metadata-client", "tokio"] }
56 changes: 46 additions & 10 deletions crates/wasm-pkg-loader/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,35 @@
mod release;
pub mod source;
//! Wasm Package Loader
//!
//! [`Client`] implements a unified interface for loading package content from
//! multiple kinds of package registries.
//!
//! # Example
//!
//! ```no_run
//! # async fn example() -> anyhow::Result<()> {
//! // Initialize client from global configuration.
//! let mut client = wasm_pkg_loader::Client::with_global_defaults()?;
//!
//! // Get a specific package release version.
//! let pkg = "example:pkg".parse()?;
//! let version = "1.0.0".parse()?;
//! let release = client.get_release(&pkg, &version).await?;
//!
//! // Stream release content to a file.
//! let mut stream = client.stream_content(&pkg, &release).await?;
//! let mut file = tokio::fs::File::create("output.wasm").await?;
//! use futures_util::TryStreamExt;
//! use tokio::io::AsyncWriteExt;
//! while let Some(chunk) = stream.try_next().await? {
//! file.write_all(&chunk).await?;
//! }
//! # Ok(()) }
//! ```

mod local;
pub mod oci;
mod source;
pub mod warg;

use std::collections::HashMap;

Expand All @@ -9,30 +39,27 @@ use futures_util::stream::BoxStream;

use wasm_pkg_common::metadata::RegistryMetadata;

use crate::source::{
local::LocalSource, oci::OciSource, warg::WargSource, PackageSource, VersionInfo,
use crate::{
local::LocalSource, oci::source::OciSource, source::PackageSource, source::VersionInfo,
warg::source::WargSource,
};

/// Re-exported to ease configuration.
pub use oci_distribution::client as oci_client;

pub use wasm_pkg_common::{
config::Config,
digest::ContentDigest,
package::{PackageRef, Version},
registry::Registry,
Error,
};

pub use crate::release::{ContentDigest, Release};

/// A read-only registry client.
pub struct Client {
config: Config,
sources: HashMap<Registry, Box<dyn PackageSource>>,
}

impl Client {
/// Returns a new client with the given [`ClientConfig`].
/// Returns a new client with the given [`Config`].
pub fn new(config: Config) -> Self {
Self {
config,
Expand Down Expand Up @@ -137,3 +164,12 @@ impl Client {
Ok(self.sources.get_mut(&registry).unwrap().as_mut())
}
}

/// Package release details.
///
/// Returned by [`Client::get_release`] and passed to [`Client::stream_content`].
#[derive(Clone, Debug)]
pub struct Release {
pub version: Version,
pub content_digest: ContentDigest,
}
13 changes: 13 additions & 0 deletions crates/wasm-pkg-loader/src/oci.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//! OCI package loader.
//!
//! This follows the CNCF TAG Runtime guidance for [Wasm OCI Artifacts][1].
//!
//! [1]: https://tag-runtime.cncf.io/wgs/wasm/deliverables/wasm-oci-artifact/

mod config;
pub(crate) mod source;

/// Re-exported for convenience.
pub use oci_distribution::client;

pub use config::{BasicCredentials, OciRegistryConfig};
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,16 @@ use secrecy::{ExposeSecret, SecretString};
use serde::Deserialize;
use wasm_pkg_common::{config::RegistryConfig, Error};

/// Registry configuration for OCI backends.
///
/// See: [`RegistryConfig::backend_config`]
#[derive(Default)]
pub struct OciConfig {
pub struct OciRegistryConfig {
pub client_config: ClientConfig,
pub credentials: Option<BasicCredentials>,
}

impl Clone for OciConfig {
impl Clone for OciRegistryConfig {
fn clone(&self) -> Self {
let client_config = ClientConfig {
protocol: self.client_config.protocol.clone(),
Expand All @@ -29,7 +32,7 @@ impl Clone for OciConfig {
}
}

impl std::fmt::Debug for OciConfig {
impl std::fmt::Debug for OciRegistryConfig {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("OciConfig")
.field("client_config", &"...")
Expand All @@ -38,7 +41,7 @@ impl std::fmt::Debug for OciConfig {
}
}

impl TryFrom<&RegistryConfig> for OciConfig {
impl TryFrom<&RegistryConfig> for OciRegistryConfig {
type Error = Error;

fn try_from(registry_config: &RegistryConfig) -> Result<Self, Self::Error> {
Expand Down Expand Up @@ -143,7 +146,7 @@ mod tests {
"#;
let cfg = wasm_pkg_common::config::Config::from_toml(toml_config).unwrap();

let oci_config: OciConfig = cfg
let oci_config: OciRegistryConfig = cfg
.registry_config(&"example.com".parse().unwrap())
.unwrap()
.try_into()
Expand All @@ -156,7 +159,7 @@ mod tests {
oci_config.client_config.protocol
);

let oci_config: OciConfig = cfg
let oci_config: OciRegistryConfig = cfg
.registry_config(&"wasi.dev".parse().unwrap())
.unwrap()
.try_into()
Expand Down
Loading
Loading