Repository: casey/just
Pull request #700 (2020-10-11 00:39:30)

Allow choosing multiple recipes to run
Modifies the `--choose` subcommand to allow a chooser to return
space-separated recipe names recipes to run.


Patch:
diff --git a/README.adoc b/README.adoc
index e7947017..5b083aec 100644
--- a/README.adoc
+++ b/README.adoc
@@ -986,11 +986,11 @@ echo 'Bar!'
 Bar!
 ```
 
-=== Selecting a Recipe to Run With an Interactive Chooser
+=== Selecting Recipes to Run With an Interactive Chooser
 
-The `--choose` subcommand makes just invoke a chooser to select which recipe to
-run. Choosers should read lines containing recipe names from standard input and
-print one of those names to standard output.
+The `--choose` subcommand makes just invoke a chooser to select which recipes
+to run. Choosers should read lines containing recipe names from standard input
+and print one or more of those names separated by spaces to standard output.
 
 Because there is currenly no way to run a recipe that requires arguments with
 `--choose`, such recipes will not be given to the chooser. Private recipes and
@@ -1007,7 +1007,7 @@ chooser is `fzf`, it will be invoked with `sh -cu 'fzf'`, and if the shell, or
 the shell arguments are overridden, the chooser invocation will respect those
 overrides.
 
-If you'd like `just` to default to selecting a recipe with a chooser, you can
+If you'd like `just` to default to selecting recipes with a chooser, you can
 use this as your default recipe:
 
 ```make
diff --git a/completions/just.elvish b/completions/just.elvish
index dbc86ce1..e36ca57e 100644
--- a/completions/just.elvish
+++ b/completions/just.elvish
@@ -37,7 +37,7 @@ edit:completion:arg-completer[just] = [@words]{
             cand --unsorted 'Return list and summary entries in source order'
             cand -v 'Use verbose output'
             cand --verbose 'Use verbose output'
-            cand --choose 'Select a recipe to run using a binary. If `--chooser` is not passed the chooser defaults to the value of $JUST_CHOOSER, falling back to `fzf`'
+            cand --choose 'Select one or more recipes to run using a binary. If `--chooser` is not passed the chooser defaults to the value of $JUST_CHOOSER, falling back to `fzf`'
             cand --dump 'Print entire justfile'
             cand -e 'Edit justfile with editor given by $VISUAL or $EDITOR, falling back to `vim`'
             cand --edit 'Edit justfile with editor given by $VISUAL or $EDITOR, falling back to `vim`'
diff --git a/completions/just.fish b/completions/just.fish
index 4ee53e10..d0a2f1d9 100644
--- a/completions/just.fish
+++ b/completions/just.fish
@@ -26,7 +26,7 @@ complete -c just -n "__fish_use_subcommand" -s q -l quiet -d 'Suppress all outpu
 complete -c just -n "__fish_use_subcommand" -l clear-shell-args -d 'Clear shell arguments'
 complete -c just -n "__fish_use_subcommand" -s u -l unsorted -d 'Return list and summary entries in source order'
 complete -c just -n "__fish_use_subcommand" -s v -l verbose -d 'Use verbose output'
-complete -c just -n "__fish_use_subcommand" -l choose -d 'Select a recipe to run using a binary. If `--chooser` is not passed the chooser defaults to the value of $JUST_CHOOSER, falling back to `fzf`'
+complete -c just -n "__fish_use_subcommand" -l choose -d 'Select one or more recipes to run using a binary. If `--chooser` is not passed the chooser defaults to the value of $JUST_CHOOSER, falling back to `fzf`'
 complete -c just -n "__fish_use_subcommand" -l dump -d 'Print entire justfile'
 complete -c just -n "__fish_use_subcommand" -s e -l edit -d 'Edit justfile with editor given by $VISUAL or $EDITOR, falling back to `vim`'
 complete -c just -n "__fish_use_subcommand" -l evaluate -d 'Print evaluated variables'
diff --git a/completions/just.powershell b/completions/just.powershell
index 32d0dd5f..4396482e 100644
--- a/completions/just.powershell
+++ b/completions/just.powershell
@@ -42,7 +42,7 @@ Register-ArgumentCompleter -Native -CommandName 'just' -ScriptBlock {
             [CompletionResult]::new('--unsorted', 'unsorted', [CompletionResultType]::ParameterName, 'Return list and summary entries in source order')
             [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'Use verbose output')
             [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'Use verbose output')
-            [CompletionResult]::new('--choose', 'choose', [CompletionResultType]::ParameterName, 'Select a recipe to run using a binary. If `--chooser` is not passed the chooser defaults to the value of $JUST_CHOOSER, falling back to `fzf`')
+            [CompletionResult]::new('--choose', 'choose', [CompletionResultType]::ParameterName, 'Select one or more recipes to run using a binary. If `--chooser` is not passed the chooser defaults to the value of $JUST_CHOOSER, falling back to `fzf`')
             [CompletionResult]::new('--dump', 'dump', [CompletionResultType]::ParameterName, 'Print entire justfile')
             [CompletionResult]::new('-e', 'e', [CompletionResultType]::ParameterName, 'Edit justfile with editor given by $VISUAL or $EDITOR, falling back to `vim`')
             [CompletionResult]::new('--edit', 'edit', [CompletionResultType]::ParameterName, 'Edit justfile with editor given by $VISUAL or $EDITOR, falling back to `vim`')
diff --git a/completions/just.zsh b/completions/just.zsh
index 86140370..0dda625e 100644
--- a/completions/just.zsh
+++ b/completions/just.zsh
@@ -38,7 +38,7 @@ _just() {
 '--unsorted[Return list and summary entries in source order]' \
 '*-v[Use verbose output]' \
 '*--verbose[Use verbose output]' \
-'--choose[Select a recipe to run using a binary. If `--chooser` is not passed the chooser defaults to the value of $JUST_CHOOSER, falling back to `fzf`]' \
+'--choose[Select one or more recipes to run using a binary. If `--chooser` is not passed the chooser defaults to the value of $JUST_CHOOSER, falling back to `fzf`]' \
 '--dump[Print entire justfile]' \
 '-e[Edit justfile with editor given by $VISUAL or $EDITOR, falling back to `vim`]' \
 '--edit[Edit justfile with editor given by $VISUAL or $EDITOR, falling back to `vim`]' \
diff --git a/src/config.rs b/src/config.rs
index 70b91b80..4af000d8 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -5,9 +5,9 @@ use clap::{App, AppSettings, Arg, ArgGroup, ArgMatches, ArgSettings};
 // These three strings should be kept in sync:
 pub(crate) const CHOOSER_DEFAULT: &str = "fzf";
 pub(crate) const CHOOSER_ENVIRONMENT_KEY: &str = "JUST_CHOOSER";
-pub(crate) const CHOOSE_HELP: &str = "Select a recipe to run using a binary. If `--chooser` is \
-                                      not passed the chooser defaults to the value of \
-                                      $JUST_CHOOSER, falling back to `fzf`";
+pub(crate) const CHOOSE_HELP: &str = "Select one or more recipes to run using a binary. If \
+                                      `--chooser` is not passed the chooser defaults to the value \
+                                      of $JUST_CHOOSER, falling back to `fzf`";
 
 pub(crate) const DEFAULT_SHELL: &str = "sh";
 pub(crate) const DEFAULT_SHELL_ARG: &str = "-cu";
@@ -585,7 +585,13 @@ impl Config {
 
     let stdout = String::from_utf8_lossy(&output.stdout);
 
-    self.run(justfile, search, overrides, &[stdout.trim().to_string()])
+    let recipes = stdout
+      .trim()
+      .split_whitespace()
+      .map(str::to_owned)
+      .collect::<Vec<String>>();
+
+    self.run(justfile, search, overrides, &recipes)
   }
 
   fn dump(justfile: Justfile) -> Result<(), i32> {
@@ -812,9 +818,9 @@ USAGE:
     just [FLAGS] [OPTIONS] [--] [ARGUMENTS]...
 
 FLAGS:
-        --choose              Select a recipe to run using a binary. If `--chooser` is not passed \
-                                 the chooser defaults
-                              to the value of $JUST_CHOOSER, falling back to `fzf`
+        --choose              Select one or more recipes to run using a binary. If `--chooser` is \
+                                 not passed the chooser
+                              defaults to the value of $JUST_CHOOSER, falling back to `fzf`
         --clear-shell-args    Clear shell arguments
         --dry-run             Print what just would do without doing it
         --dump                Print entire justfile


Test patch:
diff --git a/tests/choose.rs b/tests/choose.rs
index 32496529..f6c5b626 100644
--- a/tests/choose.rs
+++ b/tests/choose.rs
@@ -99,6 +99,20 @@ test! {
   status: EXIT_FAILURE,
 }
 
+test! {
+  name: multiple_recipes,
+  justfile: "
+    foo:
+      echo foo
+
+    bar:
+      echo bar
+  ",
+  args: ("--choose", "--chooser", "echo foo bar"),
+  stdout: "foo\nbar\n",
+  stderr: "echo foo\necho bar\n",
+}
+
 #[test]
 fn default() {
   let tmp = tmptree! {