Repository: denoland/deno
Pull request: feat(bench): add `--permit-no-files`

Closes #26946 

This PR adds the `--permit-no-files` cli options to the `bench` subcommand. This will cause `deno bench --permit-no-files` to not return an error when no bench files where found. 

Changed files:
filename: cli/args/flags.rs
patch: @@ -102,6 +102,7 @@ pub struct BenchFlags {
   pub filter: Option<String>,
   pub json: bool,
   pub no_run: bool,
+  pub permit_no_files: bool,
   pub watch: Option<WatchFlags>,
 }
 
@@ -1754,6 +1755,12 @@ If you specify a directory instead of a file, the path is expanded to all contai
           .help("Cache bench modules, but don't run benchmarks")
           .action(ArgAction::SetTrue),
       )
+      .arg(
+        Arg::new("permit-no-files")
+          .long("permit-no-files")
+          .help("Don't return an error code if no bench files were found")
+          .action(ArgAction::SetTrue)
+      )
       .arg(watch_arg(false))
       .arg(watch_exclude_arg())
       .arg(no_clear_screen_arg())
@@ -4482,6 +4489,7 @@ fn bench_parse(
   flags.permissions.no_prompt = true;
 
   let json = matches.get_flag("json");
+  let permit_no_files = matches.get_flag("permit-no-files");
 
   let ignore = match matches.remove_many::<String>("ignore") {
     Some(f) => f
@@ -4511,6 +4519,7 @@ fn bench_parse(
     filter,
     json,
     no_run,
+    permit_no_files,
     watch: watch_arg_parse(matches)?,
   });
 
@@ -10804,6 +10813,7 @@ mod tests {
             ignore: vec![],
           },
           watch: Default::default(),
+          permit_no_files: false,
         }),
         no_npm: true,
         no_remote: true,
@@ -10835,6 +10845,34 @@ mod tests {
             ignore: vec![],
           },
           watch: Some(Default::default()),
+          permit_no_files: false
+        }),
+        permissions: PermissionFlags {
+          no_prompt: true,
+          ..Default::default()
+        },
+        type_check_mode: TypeCheckMode::Local,
+        ..Flags::default()
+      }
+    );
+  }
+
+  #[test]
+  fn bench_no_files() {
+    let r = flags_from_vec(svec!["deno", "bench", "--permit-no-files"]);
+    assert_eq!(
+      r.unwrap(),
+      Flags {
+        subcommand: DenoSubcommand::Bench(BenchFlags {
+          filter: None,
+          json: false,
+          no_run: false,
+          files: FileFlags {
+            include: vec![],
+            ignore: vec![],
+          },
+          watch: None,
+          permit_no_files: true
         }),
         permissions: PermissionFlags {
           no_prompt: true,

filename: cli/args/mod.rs
patch: @@ -159,6 +159,7 @@ pub struct WorkspaceBenchOptions {
   pub filter: Option<String>,
   pub json: bool,
   pub no_run: bool,
+  pub permit_no_files: bool,
 }
 
 impl WorkspaceBenchOptions {
@@ -167,6 +168,7 @@ impl WorkspaceBenchOptions {
       filter: bench_flags.filter.clone(),
       json: bench_flags.json,
       no_run: bench_flags.no_run,
+      permit_no_files: bench_flags.permit_no_files,
     }
   }
 }

filename: cli/tools/bench/mod.rs
patch: @@ -456,7 +456,7 @@ pub async fn run_benchmarks(
     .flatten()
     .collect::<Vec<_>>();
 
-  if specifiers.is_empty() {
+  if !workspace_bench_options.permit_no_files && specifiers.is_empty() {
     return Err(anyhow!("No bench modules found"));
   }
 

filename: tests/specs/bench/no_files/__test__.jsonc
patch: @@ -0,0 +1,14 @@
+{
+  "tests": {
+    "error": {
+      "args": "bench",
+      "output": "error.out",
+      "exitCode": 1
+    },
+    "permit_no_files": {
+      "args": "bench --permit-no-files",
+      "output": "",
+      "exitCode": 0
+    }
+  }
+}

filename: tests/specs/bench/no_files/error.out
patch: @@ -0,0 +1 @@
+error: No bench modules found