summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormagnusrodseth <59113973+magnusrodseth@users.noreply.github.com>2022-08-17 16:31:53 +0200
committermagnusrodseth <59113973+magnusrodseth@users.noreply.github.com>2022-08-17 16:31:53 +0200
commit6f44cb1dd237f4d53aa3ecd4676e50cf850c99fe (patch)
treecd74cefb493ec715c13b4f0bdb0bc47c9bd0cf98 /src
parentd0c7b06eff3e8959b261145e10f1aaa57ba1e4c3 (diff)
feat: Add reset command, given a filename
Diffstat (limited to 'src')
-rw-r--r--src/main.rs78
-rw-r--r--src/run.rs15
2 files changed, 74 insertions, 19 deletions
diff --git a/src/main.rs b/src/main.rs
index 531533e..3610f82 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,7 +1,10 @@
-use crate::exercise::{Exercise, ExerciseList};
use crate::project::RustAnalyzerProject;
use crate::run::run;
use crate::verify::verify;
+use crate::{
+ exercise::{Exercise, ExerciseList},
+ run::reset,
+};
use argh::FromArgs;
use console::Emoji;
use notify::DebouncedEvent;
@@ -47,6 +50,7 @@ enum Subcommands {
Verify(VerifyArgs),
Watch(WatchArgs),
Run(RunArgs),
+ Reset(ResetArgs),
Hint(HintArgs),
List(ListArgs),
Lsp(LspArgs),
@@ -72,6 +76,15 @@ struct RunArgs {
}
#[derive(FromArgs, PartialEq, Debug)]
+#[argh(subcommand, name = "reset")]
+/// Resets a single exercise
+struct ResetArgs {
+ #[argh(positional)]
+ /// the name of the exercise
+ name: String,
+}
+
+#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "hint")]
/// Returns a hint for the given exercise
struct HintArgs {
@@ -85,7 +98,6 @@ struct HintArgs {
/// Enable rust-analyzer for exercises
struct LspArgs {}
-
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "list")]
/// Lists the exercises available in Rustlings
@@ -164,7 +176,9 @@ fn main() {
"Pending"
};
let solve_cond = {
- (e.looks_done() && subargs.solved) || (!e.looks_done() && subargs.unsolved) || (!subargs.solved && !subargs.unsolved)
+ (e.looks_done() && subargs.solved)
+ || (!e.looks_done() && subargs.unsolved)
+ || (!subargs.solved && !subargs.unsolved)
};
if solve_cond && (filter_cond || subargs.filter.is_none()) {
let line = if subargs.paths {
@@ -205,6 +219,12 @@ fn main() {
run(exercise, verbose).unwrap_or_else(|_| std::process::exit(1));
}
+ Subcommands::Reset(subargs) => {
+ let exercise = find_exercise(&subargs.name, &exercises);
+
+ reset(exercise).unwrap_or_else(|_| std::process::exit(1));
+ }
+
Subcommands::Hint(subargs) => {
let exercise = find_exercise(&subargs.name, &exercises);
@@ -212,7 +232,8 @@ fn main() {
}
Subcommands::Verify(_subargs) => {
- verify(&exercises, (0, exercises.len()), verbose).unwrap_or_else(|_| std::process::exit(1));
+ verify(&exercises, (0, exercises.len()), verbose)
+ .unwrap_or_else(|_| std::process::exit(1));
}
Subcommands::Lsp(_subargs) => {
@@ -236,12 +257,18 @@ fn main() {
Subcommands::Watch(_subargs) => match watch(&exercises, verbose) {
Err(e) => {
- println!("Error: Could not watch your progress. Error message was {:?}.", e);
+ println!(
+ "Error: Could not watch your progress. Error message was {:?}.",
+ e
+ );
println!("Most likely you've run out of disk space or your 'inotify limit' has been reached.");
std::process::exit(1);
}
Ok(WatchStatus::Finished) => {
- println!("{emoji} All exercises completed! {emoji}", emoji = Emoji("🎉", "★"));
+ println!(
+ "{emoji} All exercises completed! {emoji}",
+ emoji = Emoji("🎉", "★")
+ );
println!("\n{}\n", FENISH_LINE);
}
Ok(WatchStatus::Unfinished) => {
@@ -252,8 +279,10 @@ fn main() {
}
}
-
-fn spawn_watch_shell(failed_exercise_hint: &Arc<Mutex<Option<String>>>, should_quit: Arc<AtomicBool>) {
+fn spawn_watch_shell(
+ failed_exercise_hint: &Arc<Mutex<Option<String>>>,
+ should_quit: Arc<AtomicBool>,
+) {
let failed_exercise_hint = Arc::clone(failed_exercise_hint);
println!("Welcome to watch mode! You can type 'help' to get an overview of the commands you can use here.");
thread::spawn(move || loop {
@@ -290,16 +319,22 @@ fn spawn_watch_shell(failed_exercise_hint: &Arc<Mutex<Option<String>>>, should_q
fn find_exercise<'a>(name: &str, exercises: &'a [Exercise]) -> &'a Exercise {
if name.eq("next") {
- exercises.iter().find(|e| !e.looks_done()).unwrap_or_else(|| {
- println!("🎉 Congratulations! You have done all the exercises!");
- println!("🔚 There are no more exercises to do next!");
- std::process::exit(1)
- })
+ exercises
+ .iter()
+ .find(|e| !e.looks_done())
+ .unwrap_or_else(|| {
+ println!("🎉 Congratulations! You have done all the exercises!");
+ println!("🔚 There are no more exercises to do next!");
+ std::process::exit(1)
+ })
} else {
- exercises.iter().find(|e| e.name == name).unwrap_or_else(|| {
- println!("No exercise found for '{}'!", name);
- std::process::exit(1)
- })
+ exercises
+ .iter()
+ .find(|e| e.name == name)
+ .unwrap_or_else(|| {
+ println!("No exercise found for '{}'!", name);
+ std::process::exit(1)
+ })
}
}
@@ -337,8 +372,13 @@ fn watch(exercises: &[Exercise], verbose: bool) -> notify::Result<WatchStatus> {
let filepath = b.as_path().canonicalize().unwrap();
let pending_exercises = exercises
.iter()
- .find(|e| filepath.ends_with(&e.path)).into_iter()
- .chain(exercises.iter().filter(|e| !e.looks_done() && !filepath.ends_with(&e.path)));
+ .find(|e| filepath.ends_with(&e.path))
+ .into_iter()
+ .chain(
+ exercises
+ .iter()
+ .filter(|e| !e.looks_done() && !filepath.ends_with(&e.path)),
+ );
let num_done = exercises.iter().filter(|e| e.looks_done()).count();
clear_screen();
match verify(pending_exercises, (num_done, exercises.len()), verbose) {
diff --git a/src/run.rs b/src/run.rs
index eb55885..826f00a 100644
--- a/src/run.rs
+++ b/src/run.rs
@@ -1,3 +1,5 @@
+use std::process::Command;
+
use crate::exercise::{Exercise, Mode};
use crate::verify::test;
use indicatif::ProgressBar;
@@ -15,6 +17,19 @@ pub fn run(exercise: &Exercise, verbose: bool) -> Result<(), ()> {
Ok(())
}
+// Resets the exercise by stashing the changes.
+pub fn reset(exercise: &Exercise) -> Result<(), ()> {
+ let command = Command::new("git")
+ .args(["stash", "--"])
+ .arg(&exercise.path)
+ .spawn();
+
+ match command {
+ Ok(_) => Ok(()),
+ Err(_) => Err(()),
+ }
+}
+
// Invoke the rust compiler on the path of the given exercise
// and run the ensuing binary.
// This is strictly for non-test binaries, so output is displayed