Auto merge of #234 - jrvidal:no-prompt-on-run, r=fmoko

fix(run): makes `run` never prompt

`watch` and `verify` do prompt the user to actively move to the
next exercise. This change fixes `run` to never prompt. Previously
it was inconsistent between "test" and "compile" exercises.

BREAKING CHANGE: we again change the behavior of the `run` command
This commit is contained in:
bors 2019-11-12 10:50:19 +00:00
commit bc32a63c69
8 changed files with 96 additions and 20 deletions

28
Cargo.lock generated
View file

@ -168,6 +168,14 @@ dependencies = [
"redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "float-cmp"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "fsevent" name = "fsevent"
version = "0.4.0" version = "0.4.0"
@ -351,6 +359,11 @@ dependencies = [
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "normalize-line-endings"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "notify" name = "notify"
version = "4.0.12" version = "4.0.12"
@ -369,6 +382,14 @@ dependencies = [
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "num-traits"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "numtoa" name = "numtoa"
version = "0.1.0" version = "0.1.0"
@ -405,7 +426,10 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"float-cmp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"normalize-line-endings 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"predicates-core 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "predicates-core 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -613,6 +637,7 @@ dependencies = [
"glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"indicatif 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "indicatif 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"notify 4.0.12 (registry+https://github.com/rust-lang/crates.io-index)", "notify 4.0.12 (registry+https://github.com/rust-lang/crates.io-index)",
"predicates 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
@ -850,6 +875,7 @@ dependencies = [
"checksum encode_unicode 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "90b2c9496c001e8cb61827acdefad780795c42264c137744cae6f7d9e3450abd" "checksum encode_unicode 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "90b2c9496c001e8cb61827acdefad780795c42264c137744cae6f7d9e3450abd"
"checksum escargot 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ceb9adbf9874d5d028b5e4c5739d22b71988252b25c9c98fe7cf9738bee84597" "checksum escargot 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ceb9adbf9874d5d028b5e4c5739d22b71988252b25c9c98fe7cf9738bee84597"
"checksum filetime 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2f8c63033fcba1f51ef744505b3cad42510432b904c062afa67ad7ece008429d" "checksum filetime 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2f8c63033fcba1f51ef744505b3cad42510432b904c062afa67ad7ece008429d"
"checksum float-cmp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "134a8fa843d80a51a5b77d36d42bc2def9edcb0262c914861d08129fd1926600"
"checksum fsevent 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5ab7d1bd1bd33cc98b0889831b72da23c0aa4df9cec7e0702f46ecea04b35db6" "checksum fsevent 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5ab7d1bd1bd33cc98b0889831b72da23c0aa4df9cec7e0702f46ecea04b35db6"
"checksum fsevent-sys 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f41b048a94555da0f42f1d632e2e19510084fb8e303b0daa2816e733fb3644a0" "checksum fsevent-sys 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f41b048a94555da0f42f1d632e2e19510084fb8e303b0daa2816e733fb3644a0"
"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
@ -873,7 +899,9 @@ dependencies = [
"checksum mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "46e73a04c2fa6250b8d802134d56d554a9ec2922bf977777c805ea5def61ce40" "checksum mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "46e73a04c2fa6250b8d802134d56d554a9ec2922bf977777c805ea5def61ce40"
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
"checksum normalize-line-endings 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2e0a1a39eab95caf4f5556da9289b9e68f0aafac901b2ce80daaf020d3b733a8"
"checksum notify 4.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "3572d71f13ea8ed41867accd971fd564aa75934cf7a1fae03ddb8c74a8a49943" "checksum notify 4.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "3572d71f13ea8ed41867accd971fd564aa75934cf7a1fae03ddb8c74a8a49943"
"checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32"
"checksum numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" "checksum numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef"
"checksum parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa7767817701cce701d5585b9c4db3cdd02086398322c1d7e8bf5094a96a2ce7" "checksum parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa7767817701cce701d5585b9c4db3cdd02086398322c1d7e8bf5094a96a2ce7"
"checksum parking_lot_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cb88cb1cb3790baa6776844f968fea3be44956cf184fa1be5a03341f5491278c" "checksum parking_lot_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cb88cb1cb3790baa6776844f968fea3be44956cf184fa1be5a03341f5491278c"

View file

@ -19,4 +19,5 @@ path = "src/main.rs"
[dev-dependencies] [dev-dependencies]
assert_cmd = "0.11.0" assert_cmd = "0.11.0"
predicates = "1.0.1"
glob = "0.3.0" glob = "0.3.0"

View file

@ -5,9 +5,7 @@ use indicatif::ProgressBar;
pub fn run(exercise: &Exercise) -> Result<(), ()> { pub fn run(exercise: &Exercise) -> Result<(), ()> {
match exercise.mode { match exercise.mode {
Mode::Test => { Mode::Test => test(exercise)?,
test(exercise)?;
}
Mode::Compile => compile_and_run(exercise)?, Mode::Compile => compile_and_run(exercise)?,
} }
Ok(()) Ok(())

View file

@ -1,11 +1,11 @@
use crate::exercise::{ContextLine, Exercise, Mode, State}; use crate::exercise::{Exercise, Mode, State};
use console::{style, Emoji}; use console::{style, Emoji};
use indicatif::ProgressBar; use indicatif::ProgressBar;
pub fn verify<'a>(start_at: impl IntoIterator<Item = &'a Exercise>) -> Result<(), ()> { pub fn verify<'a>(start_at: impl IntoIterator<Item = &'a Exercise>) -> Result<(), ()> {
for exercise in start_at { for exercise in start_at {
let is_done = match exercise.mode { let is_done = match exercise.mode {
Mode::Test => test(&exercise)?, Mode::Test => compile_and_test_interactively(&exercise)?,
Mode::Compile => compile_only(&exercise)?, Mode::Compile => compile_only(&exercise)?,
}; };
if !is_done { if !is_done {
@ -15,6 +15,11 @@ pub fn verify<'a>(start_at: impl IntoIterator<Item = &'a Exercise>) -> Result<()
Ok(()) Ok(())
} }
pub fn test(exercise: &Exercise) -> Result<(), ()> {
compile_and_test(exercise, true)?;
Ok(())
}
fn compile_only(exercise: &Exercise) -> Result<bool, ()> { fn compile_only(exercise: &Exercise) -> Result<bool, ()> {
let progress_bar = ProgressBar::new_spinner(); let progress_bar = ProgressBar::new_spinner();
progress_bar.set_message(format!("Compiling {}...", exercise).as_str()); progress_bar.set_message(format!("Compiling {}...", exercise).as_str());
@ -25,12 +30,7 @@ fn compile_only(exercise: &Exercise) -> Result<bool, ()> {
let formatstr = format!("{} Successfully compiled {}!", Emoji("", ""), exercise); let formatstr = format!("{} Successfully compiled {}!", Emoji("", ""), exercise);
println!("{}", style(formatstr).green()); println!("{}", style(formatstr).green());
exercise.clean(); exercise.clean();
if let State::Pending(context) = exercise.state() { Ok(prompt_for_completion(&exercise))
print_everything_looks_good(exercise.mode, context);
Ok(false)
} else {
Ok(true)
}
} else { } else {
let formatstr = format!( let formatstr = format!(
"{} Compilation of {} failed! Compiler error message:\n", "{} Compilation of {} failed! Compiler error message:\n",
@ -44,7 +44,11 @@ fn compile_only(exercise: &Exercise) -> Result<bool, ()> {
} }
} }
pub fn test(exercise: &Exercise) -> Result<bool, ()> { fn compile_and_test_interactively(exercise: &Exercise) -> Result<bool, ()> {
compile_and_test(exercise, false)
}
fn compile_and_test(exercise: &Exercise, skip_prompt: bool) -> Result<bool, ()> {
let progress_bar = ProgressBar::new_spinner(); let progress_bar = ProgressBar::new_spinner();
progress_bar.set_message(format!("Testing {}...", exercise).as_str()); progress_bar.set_message(format!("Testing {}...", exercise).as_str());
progress_bar.enable_steady_tick(100); progress_bar.enable_steady_tick(100);
@ -60,12 +64,7 @@ pub fn test(exercise: &Exercise) -> Result<bool, ()> {
let formatstr = format!("{} Successfully tested {}!", Emoji("", ""), exercise); let formatstr = format!("{} Successfully tested {}!", Emoji("", ""), exercise);
println!("{}", style(formatstr).green()); println!("{}", style(formatstr).green());
exercise.clean(); exercise.clean();
if let State::Pending(context) = exercise.state() { Ok(skip_prompt || prompt_for_completion(exercise))
print_everything_looks_good(exercise.mode, context);
Ok(false)
} else {
Ok(true)
}
} else { } else {
let formatstr = format!( let formatstr = format!(
"{} Testing of {} failed! Please try again. Here's the output:", "{} Testing of {} failed! Please try again. Here's the output:",
@ -91,8 +90,13 @@ pub fn test(exercise: &Exercise) -> Result<bool, ()> {
} }
} }
fn print_everything_looks_good(mode: Mode, context: Vec<ContextLine>) { fn prompt_for_completion(exercise: &Exercise) -> bool {
let success_msg = match mode { let context = match exercise.state() {
State::Done => return true,
State::Pending(context) => context,
};
let success_msg = match exercise.mode {
Mode::Compile => "The code is compiling!", Mode::Compile => "The code is compiling!",
Mode::Test => "The code is compiling, and the tests pass!", Mode::Test => "The code is compiling, and the tests pass!",
}; };
@ -120,4 +124,6 @@ fn print_everything_looks_good(mode: Mode, context: Vec<ContextLine>) {
formatted_line formatted_line
); );
} }
false
} }

View file

@ -0,0 +1,5 @@
// fake_exercise
fn main() {
}

View file

@ -0,0 +1,11 @@
[[exercises]]
name = "pending_exercise"
path = "pending_exercise.rs"
mode = "compile"
hint = """"""
[[exercises]]
name = "pending_test_exercise"
path = "pending_test_exercise.rs"
mode = "test"
hint = """"""

View file

@ -0,0 +1,4 @@
// I AM NOT DONE
#[test]
fn it_works() {}

View file

@ -1,5 +1,6 @@
use assert_cmd::prelude::*; use assert_cmd::prelude::*;
use glob::glob; use glob::glob;
use predicates::boolean::PredicateBooleanExt;
use std::fs::File; use std::fs::File;
use std::io::Read; use std::io::Read;
use std::process::Command; use std::process::Command;
@ -136,3 +137,25 @@ fn all_exercises_require_confirmation() {
)); ));
} }
} }
#[test]
fn run_compile_exercise_does_not_prompt() {
Command::cargo_bin("rustlings")
.unwrap()
.args(&["r", "pending_exercise"])
.current_dir("tests/fixture/state")
.assert()
.code(0)
.stdout(predicates::str::contains("I AM NOT DONE").not());
}
#[test]
fn run_test_exercise_does_not_prompt() {
Command::cargo_bin("rustlings")
.unwrap()
.args(&["r", "pending_test_exercise"])
.current_dir("tests/fixture/state")
.assert()
.code(0)
.stdout(predicates::str::contains("I AM NOT DONE").not());
}