From 7d3c740999b0dd8cc826c37622098cbf0b7f4ea7 Mon Sep 17 00:00:00 2001 From: Maksim Zdobnikau <43750648+DelevoXDG@users.noreply.github.com> Date: Thu, 11 Jul 2024 14:52:09 +0200 Subject: [PATCH] Add `publish` field to Scarb.toml to mark package as not publishable to the registry (#1421) Closes #636 --- scarb/src/core/manifest/mod.rs | 2 ++ scarb/src/core/manifest/toml_manifest.rs | 4 +++ scarb/src/core/package/mod.rs | 4 +++ .../core/publishing/manifest_normalization.rs | 13 +++++++++- scarb/src/ops/publish.rs | 11 ++++++++ scarb/tests/local_registry.rs | 26 +++++++++++++++++++ scarb/tests/package.rs | 23 ++++++++++++++++ 7 files changed, 82 insertions(+), 1 deletion(-) diff --git a/scarb/src/core/manifest/mod.rs b/scarb/src/core/manifest/mod.rs index 767f5ace2..74d130c8a 100644 --- a/scarb/src/core/manifest/mod.rs +++ b/scarb/src/core/manifest/mod.rs @@ -48,6 +48,8 @@ pub struct Manifest { #[builder(default)] pub edition: Edition, #[builder(default)] + pub publish: bool, + #[builder(default)] pub metadata: ManifestMetadata, #[builder(default = "ManifestCompilerConfig::default_for_profile(&Profile::DEV)")] pub compiler_config: ManifestCompilerConfig, diff --git a/scarb/src/core/manifest/toml_manifest.rs b/scarb/src/core/manifest/toml_manifest.rs index 9a40ab91e..80ace84aa 100644 --- a/scarb/src/core/manifest/toml_manifest.rs +++ b/scarb/src/core/manifest/toml_manifest.rs @@ -186,6 +186,7 @@ pub struct TomlPackage { pub name: PackageName, pub version: MaybeWorkspaceField, pub edition: Option>, + pub publish: Option, pub authors: Option>>, pub urls: Option>, pub description: Option>, @@ -456,6 +457,8 @@ impl TomlManifest { let targets = self.collect_targets(package.name.to_smol_str(), root)?; + let publish = package.publish.unwrap_or(true); + let summary = Summary::builder() .package_id(package_id) .dependencies(dependencies) @@ -576,6 +579,7 @@ impl TomlManifest { let manifest = ManifestBuilder::default() .summary(summary) .targets(targets) + .publish(publish) .edition(edition) .metadata(metadata) .compiler_config(compiler_config) diff --git a/scarb/src/core/package/mod.rs b/scarb/src/core/package/mod.rs index e88a8c356..09c2be4f8 100644 --- a/scarb/src/core/package/mod.rs +++ b/scarb/src/core/package/mod.rs @@ -70,6 +70,10 @@ impl Package { self.manifest.targets.iter().any(Target::is_cairo_plugin) } + pub fn is_publishable(&self) -> bool { + self.manifest.publish + } + pub fn classify(&self) -> PackageClass { if self.is_cairo_plugin() { PackageClass::CairoPlugin diff --git a/scarb/src/core/publishing/manifest_normalization.rs b/scarb/src/core/publishing/manifest_normalization.rs index 552db2f83..767405f28 100644 --- a/scarb/src/core/publishing/manifest_normalization.rs +++ b/scarb/src/core/publishing/manifest_normalization.rs @@ -1,6 +1,6 @@ use std::collections::BTreeMap; -use anyhow::{bail, Result}; +use anyhow::{bail, ensure, Result}; use camino::Utf8PathBuf; use indoc::formatdoc; @@ -14,6 +14,16 @@ use crate::{ }; pub fn prepare_manifest_for_publish(pkg: &Package) -> Result { + ensure!( + pkg.is_publishable(), + formatdoc! { + r#" + publishing disabled for package {package_name} + help: set `publish = true` in package manifest + "#, + package_name = pkg.id.name, + } + ); let package = Some(generate_package(pkg)); let dependencies = Some(generate_dependencies( @@ -58,6 +68,7 @@ fn generate_package(pkg: &Package) -> Box { name: summary.package_id.name.clone(), version: MaybeWorkspace::Defined(summary.package_id.version.clone()), edition: Some(MaybeWorkspace::Defined(pkg.manifest.edition)), + publish: (!pkg.manifest.publish).then_some(false), authors: metadata.authors.clone().map(MaybeWorkspace::Defined), urls: metadata.urls.clone(), description: metadata.description.clone().map(MaybeWorkspace::Defined), diff --git a/scarb/src/ops/publish.rs b/scarb/src/ops/publish.rs index 613e47737..ce85e069b 100644 --- a/scarb/src/ops/publish.rs +++ b/scarb/src/ops/publish.rs @@ -1,4 +1,5 @@ use anyhow::{ensure, Context, Result}; +use indoc::formatdoc; use url::Url; use scarb_ui::components::Status; @@ -17,6 +18,16 @@ pub struct PublishOpts { #[tracing::instrument(level = "debug", skip(opts, ws))] pub fn publish(package_id: PackageId, opts: &PublishOpts, ws: &Workspace<'_>) -> Result<()> { let package = ws.fetch_package(&package_id)?.clone(); + ensure!( + package.is_publishable(), + formatdoc! { + r#" + publishing disabled for package {package_id} + help: set `publish = true` in package manifest + "#, + package_id = package_id + } + ); let source_id = SourceId::for_registry(&opts.index_url)?; let registry_client = RegistrySource::create_client(source_id, ws.config())?; diff --git a/scarb/tests/local_registry.rs b/scarb/tests/local_registry.rs index 7199bee9e..c2cefece1 100644 --- a/scarb/tests/local_registry.rs +++ b/scarb/tests/local_registry.rs @@ -216,6 +216,32 @@ fn publish() { ); } +#[test] +fn publish_disabled() { + let t = TempDir::new().unwrap(); + let index = TempDir::new().unwrap(); + + ProjectBuilder::start() + .name("foobar") + .version("1.0.0") + .manifest_package_extra("publish = false") + .lib_cairo("fn main() -> felt252 { 0 }") + .build(&t); + + Scarb::quick_snapbox() + .arg("publish") + .arg("--no-verify") + .arg("--index") + .arg(Url::from_directory_path(&index).unwrap().to_string()) + .current_dir(&t) + .assert() + .failure() + .stdout_matches(indoc! {r#" + error: publishing disabled for package foobar v1.0.0 ([..]Scarb.toml) + help: set `publish = true` in package manifest + "#}); +} + #[test] fn publish_overwrites_existing() { let index = TempDir::new().unwrap(); diff --git a/scarb/tests/package.rs b/scarb/tests/package.rs index 971d11990..2e397c284 100644 --- a/scarb/tests/package.rs +++ b/scarb/tests/package.rs @@ -1326,3 +1326,26 @@ fn package_without_publish_metadata() { [..] Packaged [..] files, [..] ([..] compressed) "#}); } + +#[test] +fn package_with_publish_disabled() { + let t = TempDir::new().unwrap(); + ProjectBuilder::start() + .name("foo") + .version("1.0.0") + .manifest_package_extra("publish = false") + .build(&t); + + Scarb::quick_snapbox() + .arg("package") + .arg("--no-metadata") + .arg("--no-verify") + .current_dir(&t) + .assert() + .failure() + .stdout_matches(indoc! {r#" + [..] Packaging [..] + error: publishing disabled for package foo + help: set `publish = true` in package manifest + "#}); +}