Skip to content

Commit 51f7015

Browse files
authored
Make scarb new and init command interactive (#1472)
Closes #1207 Closes [#1982](foundry-rs/starknet-foundry#1982) Make scarb new and init command interactive
1 parent 9d0e0ca commit 51f7015

File tree

13 files changed

+123
-9
lines changed

13 files changed

+123
-9
lines changed

Cargo.lock

+14
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ darling = "0.20"
6868
data-encoding = "2"
6969
deno_task_shell = ">=0.13"
7070
derive_builder = ">=0.12"
71+
dialoguer = "0.11.0"
7172
directories = "5"
7273
dunce = "1"
7374
expect-test = "1.5"

scarb-metadata/tests/command.rs

+1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ fn manifest_path() {
7070
fn init_project(t: &TempDir) {
7171
Command::new(scarb_bin())
7272
.args(["init", "--name", "hello"])
73+
.env("SCARB_INIT_TEST_RUNNER", "cairo-test")
7374
.current_dir(t)
7475
.assert()
7576
.success();

scarb-metadata/tests/scarb_command.rs

+1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ fn sample_project() {
4141
fn init_project(t: &TempDir) {
4242
Command::new(scarb_bin())
4343
.args(["init", "--name", "hello"])
44+
.env("SCARB_INIT_TEST_RUNNER", "cairo-test")
4445
.current_dir(t)
4546
.assert()
4647
.success();

scarb/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ create-output-dir = { path = "../utils/create-output-dir" }
4040
data-encoding.workspace = true
4141
deno_task_shell.workspace = true
4242
derive_builder.workspace = true
43+
dialoguer.workspace = true
4344
directories.workspace = true
4445
dunce.workspace = true
4546
fs4.workspace = true

scarb/src/bin/scarb/args.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,12 @@ pub struct ScriptsRunnerArgs {
272272
pub args: Vec<OsString>,
273273
}
274274

275+
#[derive(ValueEnum, Clone, Debug)]
276+
pub enum TestRunner {
277+
StarknetFoundry,
278+
CairoTest,
279+
}
280+
275281
/// Arguments accepted by the `init` command.
276282
#[derive(Parser, Clone, Debug)]
277283
pub struct InitArgs {
@@ -283,9 +289,9 @@ pub struct InitArgs {
283289
#[arg(long)]
284290
pub no_vcs: bool,
285291

286-
/// Use a Starknet Foundry Forge template.
287-
#[arg(long)]
288-
pub snforge: bool,
292+
/// Test runner to use. Starts interactive session if not specified.
293+
#[arg(long, env = "SCARB_INIT_TEST_RUNNER")]
294+
pub test_runner: Option<TestRunner>,
289295
}
290296

291297
/// Arguments accepted by the `metadata` command.

scarb/src/bin/scarb/commands/init.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ use camino::Utf8PathBuf;
66
use scarb::core::Config;
77
use scarb::ops::{self, VersionControl};
88

9-
use crate::args::InitArgs;
9+
use crate::args::{InitArgs, TestRunner};
10+
use crate::interactive::get_or_ask_for_test_runner;
1011

1112
#[tracing::instrument(skip_all, level = "info")]
1213
pub fn run(args: InitArgs, config: &Config) -> Result<()> {
@@ -24,7 +25,10 @@ pub fn run(args: InitArgs, config: &Config) -> Result<()> {
2425
} else {
2526
VersionControl::Git
2627
},
27-
snforge: args.snforge,
28+
snforge: matches!(
29+
get_or_ask_for_test_runner(args.test_runner)?,
30+
TestRunner::StarknetFoundry
31+
),
2832
},
2933
config,
3034
)?;

scarb/src/bin/scarb/commands/new.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ use anyhow::Result;
33
use scarb::core::Config;
44
use scarb::ops::{self, VersionControl};
55

6-
use crate::args::NewArgs;
6+
use crate::args::{NewArgs, TestRunner};
7+
use crate::interactive::get_or_ask_for_test_runner;
78

89
#[tracing::instrument(skip_all, level = "info")]
910
pub fn run(args: NewArgs, config: &Config) -> Result<()> {
@@ -18,7 +19,10 @@ pub fn run(args: NewArgs, config: &Config) -> Result<()> {
1819
} else {
1920
VersionControl::Git
2021
},
21-
snforge: args.init.snforge,
22+
snforge: matches!(
23+
get_or_ask_for_test_runner(args.init.test_runner)?,
24+
TestRunner::StarknetFoundry
25+
),
2226
},
2327
config,
2428
)?;

scarb/src/bin/scarb/interactive.rs

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
use std::io::{self, IsTerminal};
2+
3+
use crate::args::TestRunner;
4+
use anyhow::{ensure, Result};
5+
use dialoguer::theme::ColorfulTheme;
6+
use dialoguer::Select;
7+
use indoc::indoc;
8+
use which::which;
9+
10+
pub fn get_or_ask_for_test_runner(test_runner: Option<TestRunner>) -> Result<TestRunner> {
11+
Ok(test_runner)
12+
.transpose()
13+
.unwrap_or_else(ask_for_test_runner)
14+
}
15+
16+
fn ask_for_test_runner() -> Result<TestRunner> {
17+
ensure!(
18+
io::stdout().is_terminal(),
19+
indoc! {r"
20+
you are not running in terminal
21+
help: please provide the --test-runner flag
22+
"}
23+
);
24+
25+
let options = if which("snforge").is_ok() {
26+
vec!["Starknet Foundry (default)", "Cairo Test"]
27+
} else {
28+
vec![
29+
"Cairo Test (default)",
30+
"Starknet Foundry (recommended, requires snforge installed: https://github.com/foundry-rs/starknet-foundry)",
31+
]
32+
};
33+
34+
let selection = Select::with_theme(&ColorfulTheme::default())
35+
.with_prompt("Which test runner do you want to set up?")
36+
.items(&options)
37+
.default(0)
38+
.interact()?;
39+
40+
if options[selection].starts_with("Cairo Test") {
41+
Ok(TestRunner::CairoTest)
42+
} else {
43+
Ok(TestRunner::StarknetFoundry)
44+
}
45+
}

scarb/src/bin/scarb/main.rs

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use crate::errors::ErrorWithExitCode;
1717
mod args;
1818
mod commands;
1919
mod errors;
20+
mod interactive;
2021

2122
fn main() {
2223
let args = ScarbArgs::parse();

scarb/tests/new_and_init.rs

+36-1
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ fn new_no_path_arg() {
122122
error: the following required arguments were not provided:
123123
<PATH>
124124
125-
Usage: scarb[..] new <PATH>
125+
Usage: scarb[..] new [..] <PATH>
126126
127127
For more information, try '--help'.
128128
"#});
@@ -146,6 +146,41 @@ fn new_existing() {
146146
"#});
147147
}
148148

149+
#[test]
150+
fn new_interactive_not_in_terminal() {
151+
let pt = assert_fs::TempDir::new().unwrap();
152+
153+
Scarb::quick_snapbox()
154+
.arg("new")
155+
.arg("hello")
156+
.env_remove("SCARB_INIT_TEST_RUNNER")
157+
.current_dir(&pt)
158+
.assert()
159+
.failure()
160+
.stdout_eq(indoc! {r"
161+
error: you are not running in terminal
162+
help: please provide the --test-runner flag
163+
"});
164+
}
165+
166+
#[test]
167+
fn init_interactive_not_in_terminal() {
168+
let pt = assert_fs::TempDir::new().unwrap();
169+
let t = pt.child("hello");
170+
t.create_dir_all().unwrap();
171+
172+
Scarb::quick_snapbox()
173+
.arg("init")
174+
.env_remove("SCARB_INIT_TEST_RUNNER")
175+
.current_dir(&t)
176+
.assert()
177+
.failure()
178+
.stdout_eq(indoc! {r"
179+
error: you are not running in terminal
180+
help: please provide the --test-runner flag
181+
"});
182+
}
183+
149184
#[test]
150185
fn issue_148() {
151186
let pt = assert_fs::TempDir::new().unwrap();

scarb/tests/snforge_init.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ fn new_simple() {
1212
Scarb::quick_snapbox()
1313
.arg("new")
1414
.arg("hello")
15-
.arg("--snforge")
15+
.args(["--test-runner", "starknet-foundry"])
1616
.current_dir(&pt)
1717
.assert()
1818
.success();

utils/scarb-test-support/src/command.rs

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ impl Scarb {
5454
cmd.env("SCARB_LOG", self.log);
5555
cmd.env("SCARB_CACHE", self.cache.path());
5656
cmd.env("SCARB_CONFIG", self.config.path());
57+
cmd.env("SCARB_INIT_TEST_RUNNER", "cairo-test");
5758
cmd
5859
}
5960

0 commit comments

Comments
 (0)