From 08ac11ff2250190a47a74a767c2efa3a71ce1e73 Mon Sep 17 00:00:00 2001
From: mo8it <mo8it@proton.me>
Date: Sun, 2 Jun 2024 00:11:41 +0200
Subject: [PATCH] Add --require-solutions option to `dev check`

---
 src/dev.rs       |  8 ++++++--
 src/dev/check.rs | 10 +++++++---
 2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/src/dev.rs b/src/dev.rs
index fada8b33..5f7e64c8 100644
--- a/src/dev.rs
+++ b/src/dev.rs
@@ -19,7 +19,11 @@ pub enum DevCommands {
         no_git: bool,
     },
     /// Run checks on the exercises
-    Check,
+    Check {
+        /// Require that every exercise has a solution
+        #[arg(short, long)]
+        require_solutions: bool,
+    },
     /// Update the `Cargo.toml` file for the exercises
     Update,
 }
@@ -34,7 +38,7 @@ impl DevCommands {
 
                 new::new(&path, no_git).context(INIT_ERR)
             }
-            Self::Check => check::check(),
+            Self::Check { require_solutions } => check::check(require_solutions),
             Self::Update => update::update(),
         }
     }
diff --git a/src/dev/check.rs b/src/dev/check.rs
index 15ff0880..ef45cd28 100644
--- a/src/dev/check.rs
+++ b/src/dev/check.rs
@@ -166,7 +166,7 @@ fn check_exercises(info_file: &InfoFile) -> Result<()> {
     Ok(())
 }
 
-fn check_solutions(info_file: &InfoFile) -> Result<()> {
+fn check_solutions(require_solutions: bool, info_file: &InfoFile) -> Result<()> {
     let mut paths = hashbrown::HashSet::with_capacity(info_file.exercises.len());
     let target_dir = parse_target_dir()?;
     let mut output = Vec::with_capacity(OUTPUT_CAPACITY);
@@ -174,6 +174,10 @@ fn check_solutions(info_file: &InfoFile) -> Result<()> {
     for exercise_info in &info_file.exercises {
         let path = exercise_info.sol_path();
         if !Path::new(&path).exists() {
+            if require_solutions {
+                bail!("Exercise {} is missing a solution", exercise_info.name);
+            }
+
             // No solution to check.
             continue;
         }
@@ -197,7 +201,7 @@ fn check_solutions(info_file: &InfoFile) -> Result<()> {
     Ok(())
 }
 
-pub fn check() -> Result<()> {
+pub fn check(require_solutions: bool) -> Result<()> {
     let info_file = InfoFile::parse()?;
 
     // A hack to make `cargo run -- dev check` work when developing Rustlings.
@@ -214,7 +218,7 @@ pub fn check() -> Result<()> {
     }
 
     check_exercises(&info_file)?;
-    check_solutions(&info_file)?;
+    check_solutions(require_solutions, &info_file)?;
 
     println!("\nEverything looks fine!");