diff --git a/lib/backend-api/src/query.rs b/lib/backend-api/src/query.rs index bf4169c5a42..341761e184b 100644 --- a/lib/backend-api/src/query.rs +++ b/lib/backend-api/src/query.rs @@ -193,7 +193,7 @@ pub async fn tag_package_release( homepage: Option<&str>, license: Option<&str>, license_file: Option<&str>, - manifest: &str, + manifest: Option<&str>, name: &str, namespace: Option<&str>, package_release_id: &cynic::Id, diff --git a/lib/backend-api/src/types.rs b/lib/backend-api/src/types.rs index e06a03e06b0..90bc16c29bb 100644 --- a/lib/backend-api/src/types.rs +++ b/lib/backend-api/src/types.rs @@ -288,7 +288,7 @@ mod queries { pub homepage: Option<&'a str>, pub license: Option<&'a str>, pub license_file: Option<&'a str>, - pub manifest: &'a str, + pub manifest: Option<&'a str>, pub name: &'a str, pub namespace: Option<&'a str>, pub package_release_id: &'a cynic::Id, diff --git a/lib/cli/src/commands/package/publish.rs b/lib/cli/src/commands/package/publish.rs index c49b41ed6d8..e8ace005ca6 100644 --- a/lib/cli/src/commands/package/publish.rs +++ b/lib/cli/src/commands/package/publish.rs @@ -118,8 +118,15 @@ impl PackagePublish { non_interactive: self.non_interactive, package_path: self.package_path.clone(), package_hash, + package_id: None, } - .tag(client, manifest, manifest_path, true, allow_unnamed) + .tag( + client, + Some(manifest), + Some(manifest_path), + true, + allow_unnamed, + ) .await } } diff --git a/lib/cli/src/commands/package/tag.rs b/lib/cli/src/commands/package/tag.rs index d46be8248f9..c3099db0186 100644 --- a/lib/cli/src/commands/package/tag.rs +++ b/lib/cli/src/commands/package/tag.rs @@ -14,7 +14,9 @@ use std::{ str::FromStr, }; use wasmer_api::WasmerClient; -use wasmer_config::package::{Manifest, NamedPackageId, PackageBuilder, PackageHash, PackageIdent}; +use wasmer_config::package::{ + Manifest, NamedPackageId, NamedPackageIdent, PackageBuilder, PackageHash, PackageIdent, +}; use super::PublishWait; @@ -66,11 +68,14 @@ pub struct PackageTag { #[clap(name = "hash")] pub package_hash: PackageHash, - /// + /// The package to tag. + #[clap(name = "package_ident")] + pub package_id: Option, + /// Directory containing the `wasmer.toml`, or a custom *.toml manifest file. /// /// Defaults to current working directory. - #[clap(name = "path", default_value = ".")] + #[clap(long = "path", default_value = ".")] pub package_path: PathBuf, /// Wait for package to be available on the registry before exiting. @@ -88,11 +93,17 @@ pub struct PackageTag { impl PackageTag { async fn update_manifest_name( &self, - manifest_path: &Path, - manifest: &Manifest, + manifest_path: Option<&Path>, + manifest: Option<&Manifest>, full_name: &str, - ) -> anyhow::Result { - let mut new_manifest = manifest.clone(); + ) -> anyhow::Result> { + if manifest_path.is_none() && manifest.is_none() { + return Ok(None); + } + + let mut new_manifest = manifest.cloned().unwrap(); + let manifest_path = manifest_path.unwrap(); + if let Some(pkg) = &mut new_manifest.package { pkg.name = Some(full_name.to_string()); } else { @@ -106,16 +117,22 @@ impl PackageTag { .await .context("while trying to serialize the manifest")?; - Ok(new_manifest) + Ok(Some(new_manifest)) } async fn update_manifest_version( &self, - manifest_path: &Path, - manifest: &Manifest, + manifest_path: Option<&Path>, + manifest: Option<&Manifest>, user_version: &semver::Version, - ) -> anyhow::Result { - let mut new_manifest = manifest.clone(); + ) -> anyhow::Result> { + if manifest_path.is_none() && manifest.is_none() { + return Ok(None); + } + + let mut new_manifest = manifest.cloned().unwrap(); + let manifest_path = manifest_path.unwrap(); + if let Some(pkg) = &mut new_manifest.package { pkg.version = Some(user_version.clone()); } else { @@ -131,14 +148,14 @@ impl PackageTag { .await .context("while trying to serialize the manifest")?; - Ok(new_manifest) + Ok(Some(new_manifest)) } async fn do_tag( &self, client: &WasmerClient, id: &NamedPackageId, - manifest: &Manifest, + manifest: Option<&Manifest>, package_release_id: &wasmer_api::types::Id, ) -> anyhow::Result<()> { tracing::info!( @@ -151,24 +168,27 @@ impl PackageTag { let NamedPackageId { full_name, version } = id; let maybe_description = manifest - .package - .as_ref() + .and_then(|m| m.package.as_ref()) .and_then(|p| p.description.clone()); - let maybe_homepage = manifest.package.as_ref().and_then(|p| p.homepage.clone()); - let maybe_license = manifest.package.as_ref().and_then(|p| p.license.clone()); + let maybe_homepage = manifest + .and_then(|m| m.package.as_ref()) + .and_then(|p| p.homepage.clone()); + let maybe_license = manifest + .and_then(|m| m.package.as_ref()) + .and_then(|p| p.license.clone()); let maybe_license_file = manifest - .package - .as_ref() + .and_then(|m| m.package.as_ref()) .and_then(|p| p.license_file.clone()) .map(|f| f.to_string_lossy().to_string()); let maybe_readme = manifest - .package - .as_ref() + .and_then(|m| m.package.as_ref()) .and_then(|p| p.readme.clone()) .map(|f| f.to_string_lossy().to_string()); - let maybe_repository = manifest.package.as_ref().and_then(|p| p.repository.clone()); + let maybe_repository = manifest + .and_then(|m| m.package.as_ref()) + .and_then(|p| p.repository.clone()); - let private = if let Some(pkg) = &manifest.package { + let private = if let Some(pkg) = &manifest.and_then(|m| m.package.as_ref()) { Some(pkg.private) } else { Some(false) @@ -176,7 +196,11 @@ impl PackageTag { let version = version.to_string(); - let manifest_raw = toml::to_string(&manifest)?; + let manifest_raw = if let Some(manifest) = manifest { + Some(toml::to_string(&manifest)?) + } else { + None + }; let r = wasmer_api::query::tag_package_release( client, @@ -184,7 +208,7 @@ impl PackageTag { maybe_homepage.as_deref(), maybe_license.as_deref(), maybe_license_file.as_deref(), - &manifest_raw, + manifest_raw.as_deref(), full_name, None, package_release_id, @@ -276,12 +300,21 @@ impl PackageTag { Ok(pkg.id) } - fn get_name(&self, manifest: &Manifest, allow_unnamed: bool) -> anyhow::Result> { + fn get_name( + &self, + manifest: Option<&Manifest>, + allow_unnamed: bool, + ) -> anyhow::Result> { + if let Some(name) = &self.package_id.as_ref().map(|id| id.name.clone()) { + return Ok(Some(name.clone())); + } + + // REMOVE ME: This is here for backwards compatibility, but we should remove the flag. if let Some(name) = &self.package_name { return Ok(Some(name.clone())); } - if let Some(pkg) = &manifest.package { + if let Some(pkg) = &manifest.and_then(|m| m.package.as_ref()) { if let Some(ns) = &pkg.name { if let Some(name) = ns.split('/').nth(1) { return Ok(Some(name.to_string())); @@ -311,13 +344,18 @@ impl PackageTag { async fn get_namespace( &self, client: &WasmerClient, - manifest: &Manifest, + manifest: Option<&Manifest>, ) -> anyhow::Result { + if let Some(namespace) = self.package_id.as_ref().and_then(|id| id.namespace.clone()) { + return Ok(namespace); + } + + // REMOVE ME: This is here for backwards compatibility, but we should remove the flag. if let Some(namespace) = &self.package_namespace { return Ok(namespace.clone()); } - if let Some(pkg) = &manifest.package { + if let Some(pkg) = manifest.and_then(|m| m.package.clone()) { if let Some(name) = &pkg.name { if let Some(ns) = name.split('/').next() { return Ok(ns.to_string()); @@ -337,16 +375,26 @@ impl PackageTag { async fn get_version( &self, client: &WasmerClient, - manifest: &Manifest, - manifest_path: &Path, + manifest: Option<&Manifest>, + manifest_path: Option<&Path>, full_pkg_name: &str, ) -> anyhow::Result { + if let Some(wasmer_config::package::Tag::VersionReq(r)) = + self.package_id.as_ref().and_then(|id| id.tag.clone()) + { + let mut version = r.to_string(); + version.remove(0); + let version = semver::Version::parse(&version)?; + return Ok(version); + } + + // REMOVE ME: This is here for backwards compatibility, but we should remove the flag. if let Some(version) = &self.package_version { // If a user specified a version, then they meant it. return Ok(version.clone()); } - let user_version = if let Some(pkg) = &manifest.package { + let user_version = if let Some(pkg) = manifest.and_then(|m| m.package.as_ref()) { pkg.version.clone() } else { None @@ -422,8 +470,8 @@ impl PackageTag { async fn synthesize_id( &self, client: &WasmerClient, - manifest: &Manifest, - manifest_path: &Path, + manifest: Option<&Manifest>, + manifest_path: Option<&Path>, allow_unnamed: bool, ) -> anyhow::Result> { let name = match self.get_name(manifest, allow_unnamed)? { @@ -433,7 +481,7 @@ impl PackageTag { let namespace = self.get_namespace(client, manifest).await?; let full_name = format!("{namespace}/{name}"); - let should_update_name = match &manifest.package { + let should_update_name = match &manifest.and_then(|m| m.package.as_ref()) { Some(pkg) => match &pkg.name { Some(n) => n.as_str() != full_name.as_str(), None => true, @@ -445,11 +493,11 @@ impl PackageTag { self.update_manifest_name(manifest_path, manifest, &full_name) .await? } else { - manifest.clone() + manifest.cloned() }; let version = self - .get_version(client, &manifest, manifest_path, &full_name) + .get_version(client, manifest.as_ref(), manifest_path, &full_name) .await?; Ok(Some(NamedPackageId { full_name, version })) @@ -458,11 +506,12 @@ impl PackageTag { pub async fn tag( &self, client: &WasmerClient, - manifest: &Manifest, - manifest_path: &Path, + manifest: Option<&Manifest>, + manifest_path: Option<&Path>, after_push: bool, allow_unnamed: bool, ) -> anyhow::Result { + tracing::debug!("{:?}", self); let package_id = self .get_package_id(client, &self.package_hash, after_push) .await?; @@ -491,6 +540,13 @@ impl PackageTag { // Check if a package with the same hash, namespace, name and version already exists. In such a // case, don't tag the package again. async fn should_tag(&self, client: &WasmerClient, id: &NamedPackageId) -> anyhow::Result { + if self.dry_run { + if !self.quiet { + eprintln!("Skipping tagging {id} as `--dry-run` was set"); + } + return Ok(false); + } + if let Some(pkg) = wasmer_api::query::get_package_version( client, id.full_name.clone(), @@ -518,12 +574,22 @@ impl AsyncCliCommand for PackageTag { let client = login_user(&self.api, &self.env, !self.non_interactive, "tag a package").await?; - tracing::info!("Loading manifest"); - let (manifest_path, manifest) = get_manifest(&self.package_path)?; - tracing::info!("Got manifest at path {}", manifest_path.display()); + let (manifest_path, manifest) = match get_manifest(&self.package_path) { + Ok((manifest_path, manifest)) => { + tracing::info!("Got manifest at path {}", manifest_path.display()); + (Some(manifest_path), Some(manifest)) + } + Err(_) => (None, None), + }; let id = self - .tag(&client, &manifest, &manifest_path, false, false) + .tag( + &client, + manifest.as_ref(), + manifest_path.as_deref(), + false, + false, + ) .await?; match id { diff --git a/lib/cli/src/opts.rs b/lib/cli/src/opts.rs index ca2504ba3c5..d943edc681c 100644 --- a/lib/cli/src/opts.rs +++ b/lib/cli/src/opts.rs @@ -33,8 +33,11 @@ fn parse_registry_url(registry: &str) -> Result { #[derive(clap::Parser, Debug, Clone, Default)] pub struct ApiOpts { + /// The (optional) authorization token to pass to the registry #[clap(long, env = "WASMER_TOKEN")] pub token: Option, + + /// Change the current registry #[clap(long, value_parser = parse_registry_url, env = "WASMER_REGISTRY")] pub registry: Option, }