Skip to content

Commit c228bff

Browse files
authored
Support passing Scarb profiles in snforge test (#3565)
<!-- Reference any GitHub issues resolved by this PR --> Closes #1619 ## Introduced changes <!-- A brief description of the changes --> - Enabled passing the same profile flags as in Scarb - Moved all Scarb related flags to separate struct `ScarbArgs` (refactor)
1 parent 1d9b000 commit c228bff

File tree

11 files changed

+111
-19
lines changed

11 files changed

+111
-19
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1212
#### Added
1313

1414
- `interact_with_state` cheatcode to enable effective use of `contract_state_for_testing` in snforge tests
15+
- Support for using [Scarb profiles](https://docs.swmansion.com/scarb/docs/reference/profiles.html) with `snforge test`, allowing to pass the same profile flags as in Scarb (`--release`, `--dev`, `--profile`) to build artifacts using a specific profile
1516

1617
#### Deprecated
1718

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ test-case = "3.3.1"
8383
scarb-metadata = "1.14.0"
8484
flatten-serde-json = "0.1.0"
8585
snapbox = "0.4.17"
86-
scarb-ui = "0.1.5"
86+
scarb-ui = "0.1.7"
8787
semver = "1.0.26"
8888
bimap = "0.6.3"
8989
primitive-types = "0.13.1"

crates/forge/src/lib.rs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use foundry_ui::components::warning::WarningMessage;
1010
use foundry_ui::{Message, UI};
1111
use run_tests::workspace::run_for_workspace;
1212
use scarb_api::{ScarbCommand, metadata::MetadataCommandExt};
13-
use scarb_ui::args::{FeaturesSpec, PackagesFilter};
13+
use scarb_ui::args::{FeaturesSpec, PackagesFilter, ProfileSpec};
1414
use semver::Version;
1515
use shared::auto_completions::{Completions, generate_completions};
1616
use std::cell::RefCell;
@@ -162,9 +162,6 @@ pub struct TestArgs {
162162
#[arg(short = 'x', long)]
163163
exit_first: bool,
164164

165-
#[command(flatten)]
166-
packages_filter: PackagesFilter,
167-
168165
/// Number of fuzzer runs
169166
#[arg(short = 'r', long)]
170167
fuzzer_runs: Option<NonZeroU32>,
@@ -207,10 +204,6 @@ pub struct TestArgs {
207204
#[arg(long)]
208205
max_n_steps: Option<u32>,
209206

210-
/// Specify features to enable
211-
#[command(flatten)]
212-
pub features: FeaturesSpec,
213-
214207
/// Build contracts separately in the scarb starknet contract target
215208
#[arg(long)]
216209
no_optimization: bool,
@@ -222,6 +215,21 @@ pub struct TestArgs {
222215
/// Additional arguments for cairo-coverage or cairo-profiler
223216
#[arg(last = true)]
224217
additional_args: Vec<OsString>,
218+
219+
#[command(flatten)]
220+
scarb_args: ScarbArgs,
221+
}
222+
223+
#[derive(Parser, Debug)]
224+
pub struct ScarbArgs {
225+
#[command(flatten)]
226+
packages_filter: PackagesFilter,
227+
228+
#[command(flatten)]
229+
features: FeaturesSpec,
230+
231+
#[command(flatten)]
232+
profile: ProfileSpec,
225233
}
226234

227235
#[derive(ValueEnum, Display, Debug, Clone)]

crates/forge/src/run_tests/workspace.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,11 @@ pub async fn run_for_workspace(args: TestArgs, ui: Arc<UI>) -> Result<ExitStatus
3232
ColorOption::Auto => (),
3333
}
3434

35-
let scarb_metadata = ScarbCommand::metadata().inherit_stderr().run()?;
35+
let mut metadata_command = ScarbCommand::metadata();
36+
if let Some(profile) = &args.scarb_args.profile.specified() {
37+
metadata_command.profile(profile.clone());
38+
}
39+
let scarb_metadata = metadata_command.inherit_stderr().run()?;
3640

3741
if args.coverage {
3842
can_coverage_be_generated(&scarb_metadata)?;
@@ -46,6 +50,7 @@ pub async fn run_for_workspace(args: TestArgs, ui: Arc<UI>) -> Result<ExitStatus
4650
target_dir_for_workspace(&scarb_metadata).join(&scarb_metadata.current_profile);
4751

4852
let packages: Vec<PackageMetadata> = args
53+
.scarb_args
4954
.packages_filter
5055
.match_many(&scarb_metadata)
5156
.context("Failed to find any packages matching the specified filter")?;
@@ -63,7 +68,8 @@ pub async fn run_for_workspace(args: TestArgs, ui: Arc<UI>) -> Result<ExitStatus
6368

6469
build_artifacts_with_scarb(
6570
filter.clone(),
66-
args.features.clone(),
71+
args.scarb_args.features.clone(),
72+
args.scarb_args.profile.clone(),
6773
&scarb_metadata.app_version_info.version,
6874
args.no_optimization,
6975
)?;

crates/forge/src/scarb.rs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use forge_runner::package_tests::TestTargetLocation;
77
use forge_runner::package_tests::raw::TestTargetRaw;
88
use scarb_api::{ScarbCommand, test_targets_by_name};
99
use scarb_metadata::PackageMetadata;
10-
use scarb_ui::args::{FeaturesSpec, PackagesFilter};
10+
use scarb_ui::args::{FeaturesSpec, PackagesFilter, ProfileSpec};
1111
use semver::Version;
1212
use std::fs;
1313
use std::io::ErrorKind;
@@ -40,32 +40,43 @@ pub fn should_compile_starknet_contract_target(
4040
pub fn build_artifacts_with_scarb(
4141
filter: PackagesFilter,
4242
features: FeaturesSpec,
43+
profile: ProfileSpec,
4344
scarb_version: &Version,
4445
no_optimization: bool,
4546
) -> Result<()> {
4647
if should_compile_starknet_contract_target(scarb_version, no_optimization) {
47-
build_contracts_with_scarb(filter.clone(), features.clone())?;
48+
build_contracts_with_scarb(filter.clone(), features.clone(), profile.clone())?;
4849
}
49-
build_test_artifacts_with_scarb(filter, features)?;
50+
build_test_artifacts_with_scarb(filter, features, profile)?;
5051
Ok(())
5152
}
5253

53-
fn build_contracts_with_scarb(filter: PackagesFilter, features: FeaturesSpec) -> Result<()> {
54+
fn build_contracts_with_scarb(
55+
filter: PackagesFilter,
56+
features: FeaturesSpec,
57+
profile: ProfileSpec,
58+
) -> Result<()> {
5459
ScarbCommand::new_with_stdio()
5560
.arg("build")
5661
.packages_filter(filter)
5762
.features(features)
63+
.profile(profile)
5864
.run()
5965
.context("Failed to build contracts with Scarb")?;
6066
Ok(())
6167
}
6268

63-
fn build_test_artifacts_with_scarb(filter: PackagesFilter, features: FeaturesSpec) -> Result<()> {
69+
fn build_test_artifacts_with_scarb(
70+
filter: PackagesFilter,
71+
features: FeaturesSpec,
72+
profile: ProfileSpec,
73+
) -> Result<()> {
6474
ScarbCommand::new_with_stdio()
6575
.arg("build")
6676
.arg("--test")
6777
.packages_filter(filter)
6878
.features(features)
79+
.profile(profile)
6980
.run()
7081
.context("Failed to build test artifacts with Scarb")?;
7182
Ok(())

crates/forge/tests/data/empty/Scarb.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,9 @@ snforge_std = { path = "../../../../../snforge_std" }
1313

1414
[[target.starknet-contract]]
1515
sierra = true
16+
17+
[profile.custom-profile]
18+
inherits = "release"
19+
20+
[profile.custom-profile.cairo]
21+
sierra-replace-ids = true

crates/forge/tests/e2e/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ mod forking;
2020
mod fuzzing;
2121
mod io_operations;
2222
mod new;
23+
mod profiles;
2324
mod requirements;
2425
mod running;
2526
mod steps;

crates/forge/tests/e2e/profiles.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
use super::common::runner::{setup_package, test_runner};
2+
use indoc::indoc;
3+
use shared::test_utils::output_assert::assert_stdout_contains;
4+
5+
#[test]
6+
fn release() {
7+
let temp = setup_package("empty");
8+
9+
let output = test_runner(&temp).arg("--release").assert().code(0);
10+
11+
assert_stdout_contains(
12+
output,
13+
indoc! {r"
14+
[..]Compiling[..]
15+
[..]Finished `release` profile target(s) in [..]
16+
17+
18+
Collected 0 test(s) from empty package
19+
Tests: 0 passed, 0 failed, 0 ignored, 0 filtered out
20+
"},
21+
);
22+
}
23+
24+
#[test]
25+
fn custom() {
26+
let temp = setup_package("empty");
27+
28+
let output = test_runner(&temp)
29+
.args(["--profile", "custom-profile"])
30+
.assert()
31+
.code(0);
32+
33+
assert_stdout_contains(
34+
output,
35+
indoc! {r"
36+
[..]Compiling[..]
37+
[..]Finished `custom-profile` profile target(s) in [..]
38+
39+
40+
Collected 0 test(s) from empty package
41+
Tests: 0 passed, 0 failed, 0 ignored, 0 filtered out
42+
"},
43+
);
44+
}

crates/scarb-api/src/command.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::metadata::MetadataCommand;
22
use crate::version::VersionCommand;
33
use anyhow::Context;
4-
use scarb_ui::args::{FeaturesSpec, PackagesFilter, ToEnvVars};
4+
use scarb_ui::args::{FeaturesSpec, PackagesFilter, ProfileSpec, ToEnvVars};
55
use std::collections::HashMap;
66
use std::ffi::{OsStr, OsString};
77
use std::path::PathBuf;
@@ -101,6 +101,12 @@ impl ScarbCommand {
101101
self
102102
}
103103

104+
/// Pass profile to `scarb` call.
105+
pub fn profile(&mut self, profile: ProfileSpec) -> &mut Self {
106+
self.envs(profile.to_env_vars());
107+
self
108+
}
109+
104110
/// Current directory of the `scarb` process.
105111
pub fn current_dir(&mut self, path: impl Into<PathBuf>) -> &mut Self {
106112
self.current_dir = Some(path.into());

0 commit comments

Comments
 (0)