From bd5895f573f3e147a300ed39a86effa7dccb2761 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C5=9Bkowicz?= Date: Thu, 30 Nov 2023 14:45:37 +0100 Subject: [PATCH] add `--dev` flag to `add` and `rm` add info in docs fix docs commit-id:2ccf4af8 dev-dependencies -> development dependencies --- scarb/src/bin/scarb/args.rs | 41 ++++++++++++++ scarb/src/bin/scarb/commands/add.rs | 15 +++-- scarb/src/bin/scarb/commands/remove.rs | 15 +++-- scarb/src/manifest_editor/add.rs | 5 +- scarb/src/manifest_editor/dep_type.rs | 28 ++++++++++ scarb/src/manifest_editor/mod.rs | 2 + scarb/src/manifest_editor/remove.rs | 11 ++-- scarb/tests/add.rs | 20 +++++++ scarb/tests/remove.rs | 56 +++++++++++++++++++ website/docs/cheatsheet.md | 8 +++ website/docs/guides/dependencies.md | 21 +++++++ website/docs/reference/manifest.md | 4 ++ .../docs/reference/specifying-dependencies.md | 13 +++++ 13 files changed, 225 insertions(+), 14 deletions(-) create mode 100644 scarb/src/manifest_editor/dep_type.rs diff --git a/scarb/src/bin/scarb/args.rs b/scarb/src/bin/scarb/args.rs index 85ac8ea75..31632254b 100644 --- a/scarb/src/bin/scarb/args.rs +++ b/scarb/src/bin/scarb/args.rs @@ -17,6 +17,7 @@ use url::Url; use scarb::compiler::Profile; use scarb::core::PackageName; use scarb::manifest_editor::DepId; +use scarb::manifest_editor::SectionArgs; use scarb::version; use scarb_ui::args::PackagesFilter; use scarb_ui::OutputFormat; @@ -277,6 +278,10 @@ pub struct AddArgs { /// _Source_ section. #[command(flatten, next_help_heading = "Source")] pub source: AddSourceArgs, + + /// _Section_ section. + #[command(flatten, next_help_heading = "Section")] + pub section: AddSectionArgs, } /// _Source_ section of [`AddArgs`]. @@ -297,6 +302,24 @@ pub struct AddSourceArgs { pub git_ref: GitRefGroup, } +/// _Section_ section of [`AddArgs`]. +#[derive(Parser, Clone, Debug)] +pub struct AddSectionArgs { + /// Add as development dependency. + /// + /// Dev-dependencies are only used when compiling tests. + /// + /// These dependencies are not propagated to other packages which depend on this package. + #[arg(long)] + pub dev: bool, +} + +impl SectionArgs for AddSectionArgs { + fn dev(&self) -> bool { + self.dev + } +} + /// Arguments accepted by the `remove` command. #[derive(Parser, Clone, Debug)] pub struct RemoveArgs { @@ -310,6 +333,24 @@ pub struct RemoveArgs { #[command(flatten)] pub packages_filter: PackagesFilter, + + /// _Section_ section. + #[command(flatten, next_help_heading = "Section")] + pub section: RemoveSectionArgs, +} + +/// _Section_ section of [`RemoveArgs`]. +#[derive(Parser, Clone, Debug)] +pub struct RemoveSectionArgs { + /// Remove as development dependency. + #[arg(long)] + pub dev: bool, +} + +impl SectionArgs for RemoveSectionArgs { + fn dev(&self) -> bool { + self.dev + } } /// Arguments accepted by the `test` command. diff --git a/scarb/src/bin/scarb/commands/add.rs b/scarb/src/bin/scarb/commands/add.rs index 0bb5eeab3..b05920f04 100644 --- a/scarb/src/bin/scarb/commands/add.rs +++ b/scarb/src/bin/scarb/commands/add.rs @@ -1,10 +1,10 @@ use anyhow::Result; use scarb::core::Config; -use scarb::manifest_editor::{AddDependency, DepId, EditManifestOptions, Op}; +use scarb::manifest_editor::{AddDependency, DepId, DepType, EditManifestOptions, Op}; use scarb::{manifest_editor, ops}; -use crate::args::{AddArgs, AddSourceArgs}; +use crate::args::{AddArgs, AddSectionArgs, AddSourceArgs}; #[tracing::instrument(skip_all, level = "info")] pub fn run(args: AddArgs, config: &mut Config) -> Result<()> { @@ -14,7 +14,7 @@ pub fn run(args: AddArgs, config: &mut Config) -> Result<()> { manifest_editor::edit( package.manifest_path(), - build_ops(args.packages, args.source), + build_ops(args.packages, args.source, args.section), EditManifestOptions { config, dry_run: args.dry_run, @@ -34,7 +34,13 @@ pub fn run(args: AddArgs, config: &mut Config) -> Result<()> { Ok(()) } -fn build_ops(packages: Vec, source: AddSourceArgs) -> Vec> { +fn build_ops( + packages: Vec, + source: AddSourceArgs, + section: AddSectionArgs, +) -> Vec> { + let dep_type = DepType::from_section(§ion); + let template = AddDependency { dep: DepId::unspecified(), path: source.path, @@ -42,6 +48,7 @@ fn build_ops(packages: Vec, source: AddSourceArgs) -> Vec> { branch: source.git_ref.branch, tag: source.git_ref.tag, rev: source.git_ref.rev, + dep_type, }; if packages.is_empty() { diff --git a/scarb/src/bin/scarb/commands/remove.rs b/scarb/src/bin/scarb/commands/remove.rs index 925f07bcf..c8795f4ef 100644 --- a/scarb/src/bin/scarb/commands/remove.rs +++ b/scarb/src/bin/scarb/commands/remove.rs @@ -4,7 +4,8 @@ use scarb::core::{Config, PackageName}; use scarb::manifest_editor::{EditManifestOptions, Op, RemoveDependency}; use scarb::{manifest_editor, ops}; -use crate::args::RemoveArgs; +use crate::args::{RemoveArgs, RemoveSectionArgs}; +use scarb::manifest_editor::DepType; #[tracing::instrument(skip_all, level = "info")] pub fn run(args: RemoveArgs, config: &mut Config) -> Result<()> { @@ -14,7 +15,7 @@ pub fn run(args: RemoveArgs, config: &mut Config) -> Result<()> { manifest_editor::edit( package.manifest_path(), - build_ops(args.packages), + build_ops(args.packages, args.section), EditManifestOptions { config, dry_run: args.dry_run, @@ -34,9 +35,15 @@ pub fn run(args: RemoveArgs, config: &mut Config) -> Result<()> { Ok(()) } -fn build_ops(packages: Vec) -> Vec> { +fn build_ops(packages: Vec, section: RemoveSectionArgs) -> Vec> { + let dep_type = DepType::from_section(§ion); packages .into_iter() - .map(|dep| -> Box { Box::new(RemoveDependency { dep }) }) + .map(|dep| -> Box { + Box::new(RemoveDependency { + dep, + dep_type: dep_type.clone(), + }) + }) .collect() } diff --git a/scarb/src/manifest_editor/add.rs b/scarb/src/manifest_editor/add.rs index cf0906364..2db52862c 100644 --- a/scarb/src/manifest_editor/add.rs +++ b/scarb/src/manifest_editor/add.rs @@ -10,7 +10,7 @@ use crate::internal::fsx; use crate::sources::canonical_url::CanonicalUrl; use super::tomlx::get_table_mut; -use super::{DepId, Op, OpCtx}; +use super::{DepId, DepType, Op, OpCtx}; #[derive(Clone, Debug, Default)] pub struct AddDependency { @@ -20,6 +20,7 @@ pub struct AddDependency { pub branch: Option, pub tag: Option, pub rev: Option, + pub dep_type: DepType, } struct Dep { @@ -49,7 +50,7 @@ struct GitSource { impl Op for AddDependency { #[tracing::instrument(level = "trace", skip(doc, ctx))] fn apply_to(self: Box, doc: &mut Document, ctx: OpCtx<'_>) -> Result<()> { - let tab = get_table_mut(doc, &["dependencies"])?; + let tab = get_table_mut(doc, &[self.dep_type.toml_section_str()])?; let dep = Dep::resolve(*self, ctx)?; diff --git a/scarb/src/manifest_editor/dep_type.rs b/scarb/src/manifest_editor/dep_type.rs new file mode 100644 index 000000000..50de9e565 --- /dev/null +++ b/scarb/src/manifest_editor/dep_type.rs @@ -0,0 +1,28 @@ +pub trait SectionArgs { + fn dev(&self) -> bool; +} + +#[derive(Clone, Debug, Default)] +pub enum DepType { + #[default] + Normal, + Dev, +} + +impl DepType { + pub fn toml_section_str(&self) -> &str { + match self { + DepType::Normal => "dependencies", + DepType::Dev => "dev-dependencies", + } + } +} +impl DepType { + pub fn from_section(section_args: &impl SectionArgs) -> DepType { + if section_args.dev() { + DepType::Dev + } else { + DepType::Normal + } + } +} diff --git a/scarb/src/manifest_editor/mod.rs b/scarb/src/manifest_editor/mod.rs index 4dcf273e2..2679ac727 100644 --- a/scarb/src/manifest_editor/mod.rs +++ b/scarb/src/manifest_editor/mod.rs @@ -8,6 +8,7 @@ use toml_edit::Document; pub use add::AddDependency; pub use dep_id::DepId; +pub use dep_type::{DepType, SectionArgs}; pub use remove::RemoveDependency; use crate::core::Config; @@ -15,6 +16,7 @@ use crate::internal::fsx; mod add; mod dep_id; +mod dep_type; mod remove; mod tomlx; diff --git a/scarb/src/manifest_editor/remove.rs b/scarb/src/manifest_editor/remove.rs index cd31ccd6a..3d7e2f417 100644 --- a/scarb/src/manifest_editor/remove.rs +++ b/scarb/src/manifest_editor/remove.rs @@ -4,6 +4,7 @@ use toml_edit::Document; use scarb_ui::components::Status; use crate::core::PackageName; +use crate::manifest_editor::DepType; use super::tomlx::get_table_mut; use super::{Op, OpCtx}; @@ -11,17 +12,18 @@ use super::{Op, OpCtx}; #[derive(Debug)] pub struct RemoveDependency { pub dep: PackageName, + pub dep_type: DepType, } impl Op for RemoveDependency { #[tracing::instrument(level = "trace", skip(doc, ctx))] fn apply_to(self: Box, doc: &mut Document, ctx: OpCtx<'_>) -> Result<()> { - let tab = get_table_mut(doc, &["dependencies"])?; + let tab = get_table_mut(doc, &[self.dep_type.toml_section_str()])?; // section is hardcoded as there's no support for other section types yet ctx.opts.config.ui().print(Status::new( "Removing", - &format!("{} from dependencies", self.dep), + &format!("{} from {}", self.dep, self.dep_type.toml_section_str()), )); tab.as_table_like_mut() @@ -29,8 +31,9 @@ impl Op for RemoveDependency { .remove(self.dep.as_str()) .ok_or_else(|| { anyhow!( - "the dependency `{}` could not be found in `dependencies`", - self.dep + "the dependency `{}` could not be found in `{}`", + self.dep, + self.dep_type.toml_section_str(), ) })?; diff --git a/scarb/tests/add.rs b/scarb/tests/add.rs index c85d76c58..7d8cb9e3e 100644 --- a/scarb/tests/add.rs +++ b/scarb/tests/add.rs @@ -464,3 +464,23 @@ fn should_not_sort_if_already_unsorted() { "#}) .run(); } + +#[test] +fn add_dev_dep() { + ManifestEditHarness::offline() + .args(["add", "--dev", "foo@1.0.0"]) + .input(indoc! {r#" + [package] + name = "hello" + version = "1.0.0" + "#}) + .output(indoc! {r#" + [package] + name = "hello" + version = "1.0.0" + + [dev-dependencies] + foo = "1.0.0" + "#}) + .run(); +} diff --git a/scarb/tests/remove.rs b/scarb/tests/remove.rs index 1873a1a53..7e400036f 100644 --- a/scarb/tests/remove.rs +++ b/scarb/tests/remove.rs @@ -116,3 +116,59 @@ fn dry_run() { "#}) .run(); } + +#[test] +fn remove_dev_dep() { + ManifestEditHarness::offline() + .args(["rm", "--dev", "foo"]) + .input(indoc! {r#" + [package] + name = "hello" + version = "1.0.0" + + [dev-dependencies] + dep = "1.0.0" + foo = "1.0.0" + bar = "1.0.0" + "#}) + .output(indoc! {r#" + [package] + name = "hello" + version = "1.0.0" + + [dev-dependencies] + dep = "1.0.0" + bar = "1.0.0" + "#}) + .stdout_matches(" Removing foo from dev-dependencies\n") + .run(); +} + +#[test] +fn remove_undefined_dev_dep() { + ManifestEditHarness::offline() + .args(["rm", "--dev", "foo"]) + .input(indoc! {r#" + [package] + name = "hello" + version = "1.0.0" + + [dev-dependencies] + dep = "1.0.0" + bar = "1.0.0" + "#}) + .output(indoc! {r#" + [package] + name = "hello" + version = "1.0.0" + + [dev-dependencies] + dep = "1.0.0" + bar = "1.0.0" + "#}) + .failure() + .stdout_matches(indoc! {r#" Removing foo from dev-dependencies + error: the dependency `foo` could not be found in `dev-dependencies` + "#}) + .run(); +} diff --git a/website/docs/cheatsheet.md b/website/docs/cheatsheet.md index 7e35c8d1b..827fa483d 100644 --- a/website/docs/cheatsheet.md +++ b/website/docs/cheatsheet.md @@ -84,6 +84,10 @@ You can add `branch`, `tag` and `rev` fields to Git dependencies. You can use `ssh://` URLs, Scarb uses local `git` installation for all network operations. ::: +::: info +You can add development dependencies in `[dev-dependencies]` section. +::: + ### Via `scarb add` Add dependency hosted on a Git repository: @@ -110,6 +114,10 @@ You can specify package version like this: `alexandria_math@0.1.0`, but see rema `scarb rm` removes a dependency. ::: +::: info +`--dev` flag adds/removes a development dependency. +::: + ## Formatting Format Cairo code: diff --git a/website/docs/guides/dependencies.md b/website/docs/guides/dependencies.md index 247650bbd..c216099ac 100644 --- a/website/docs/guides/dependencies.md +++ b/website/docs/guides/dependencies.md @@ -58,6 +58,15 @@ fn main() -> felt252 { } ``` +## Development dependencies + +You can add a `[dev-dependencies]` section to your Scarb.toml whose format is equivalent to `[dependencies]`: + +```toml +[dev-dependencies] +alexandria_math = { git = "https://github.com/keep-starknet-strange/alexandria.git" } +``` + ## Adding a dependency via `scarb add` If you prefer, you can also ask Scarb to edit `Scarb.toml` to add a dependency automagically for you. @@ -69,6 +78,12 @@ For example, the above example of dependency on `alexandria_math`, can be also a scarb add alexandria_math --git https://github.com/keep-starknet-strange/alexandria.git --rev 27fbf5b ``` +You can add development dependencies similarly by passing `--dev` flag: + +```shell +scarb add --dev alexandria_math --git https://github.com/keep-starknet-strange/alexandria.git --rev 27fbf5b +``` + ## Removing a dependency To remove a dependency, simply remove related lines from your `Scarb.toml`. @@ -78,3 +93,9 @@ As a quick shortcut, the `scarb remove` (also available in short `scarb rm`) can ```shell scarb rm alexandria_math ``` + +Removing development dependencies, like in `scarb add`, requires passing `--dev` flag: + +```shell +scarb rm --dev alexandria_math +``` diff --git a/website/docs/reference/manifest.md b/website/docs/reference/manifest.md index 0d178b90f..145bc8738 100644 --- a/website/docs/reference/manifest.md +++ b/website/docs/reference/manifest.md @@ -199,6 +199,10 @@ Keys are human-readable link names, and values are URLs. See [Specifying Dependencies](./specifying-dependencies) page. +## `[dev-dependencies]` + +See [Specifying Dependencies](./specifying-dependencies) page. + ## Target tables: `[lib]` and `[[target]]` See [Targets](./targets) page. diff --git a/website/docs/reference/specifying-dependencies.md b/website/docs/reference/specifying-dependencies.md index f69c8115c..76aae9fe8 100644 --- a/website/docs/reference/specifying-dependencies.md +++ b/website/docs/reference/specifying-dependencies.md @@ -47,6 +47,19 @@ hello_utils = { path = "hello_utils" } Scarb does not cache path dependencies, any changes made in them will be reflected immediately in builds of your package. +## Development dependencies + +In order to add development dependency, specify it under `[dev-dependencies]` section: + +```toml +[dev-dependencies] +alexandria_math = { git = "https://github.com/keep-starknet-strange/alexandria.git" } +``` + +Development dependencies are not used when compiling a package for building, but are used for compiling tests. + +These dependencies are not propagated to other packages which depend on this package. + ## Version requirements Scarb allows you to specify version requirements of dependencies with the `version` key: