Repository: casey/just
Pull request #795 (2021-04-06 04:35:56)

Allow filtering varaibles to evaluate
If variable names are passed to `--evaluate`, only print those
variables.


Patch:
diff --git a/completions/just.elvish b/completions/just.elvish
index ccce21f5..9d3258c6 100644
--- a/completions/just.elvish
+++ b/completions/just.elvish
@@ -43,7 +43,7 @@ edit:completion:arg-completer[just] = [@words]{
             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`'
-            cand --evaluate 'Print evaluated variables'
+            cand --evaluate 'Evaluate and print all variables. If positional arguments are present, only print the variables whose names are given as arguments.'
             cand --init 'Initialize new justfile in project root'
             cand -l 'List available recipes and their arguments'
             cand --list 'List available recipes and their arguments'
diff --git a/completions/just.fish b/completions/just.fish
index 879bd1ec..5cdfd509 100644
--- a/completions/just.fish
+++ b/completions/just.fish
@@ -31,7 +31,7 @@ complete -c just -n "__fish_use_subcommand" -s v -l verbose -d 'Use verbose outp
 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'
+complete -c just -n "__fish_use_subcommand" -l evaluate -d 'Evaluate and print all variables. If positional arguments are present, only print the variables whose names are given as arguments.'
 complete -c just -n "__fish_use_subcommand" -l init -d 'Initialize new justfile in project root'
 complete -c just -n "__fish_use_subcommand" -s l -l list -d 'List available recipes and their arguments'
 complete -c just -n "__fish_use_subcommand" -l summary -d 'List names of available recipes'
diff --git a/completions/just.powershell b/completions/just.powershell
index be8250cd..c4e79c6e 100644
--- a/completions/just.powershell
+++ b/completions/just.powershell
@@ -48,7 +48,7 @@ Register-ArgumentCompleter -Native -CommandName 'just' -ScriptBlock {
             [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`')
-            [CompletionResult]::new('--evaluate', 'evaluate', [CompletionResultType]::ParameterName, 'Print evaluated variables')
+            [CompletionResult]::new('--evaluate', 'evaluate', [CompletionResultType]::ParameterName, 'Evaluate and print all variables. If positional arguments are present, only print the variables whose names are given as arguments.')
             [CompletionResult]::new('--init', 'init', [CompletionResultType]::ParameterName, 'Initialize new justfile in project root')
             [CompletionResult]::new('-l', 'l', [CompletionResultType]::ParameterName, 'List available recipes and their arguments')
             [CompletionResult]::new('--list', 'list', [CompletionResultType]::ParameterName, 'List available recipes and their arguments')
diff --git a/completions/just.zsh b/completions/just.zsh
index 740a7e77..705aeeec 100644
--- a/completions/just.zsh
+++ b/completions/just.zsh
@@ -44,7 +44,7 @@ _just() {
 '--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`]' \
-'--evaluate[Print evaluated variables]' \
+'--evaluate[Evaluate and print all variables. If positional arguments are present, only print the variables whose names are given as arguments.]' \
 '--init[Initialize new justfile in project root]' \
 '-l[List available recipes and their arguments]' \
 '--list[List available recipes and their arguments]' \
diff --git a/src/config.rs b/src/config.rs
index 0d66f9c6..38286783 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -246,11 +246,10 @@ impl Config {
           .long("edit")
           .help("Edit justfile with editor given by $VISUAL or $EDITOR, falling back to `vim`"),
       )
-      .arg(
-        Arg::with_name(cmd::EVALUATE)
-          .long("evaluate")
-          .help("Print evaluated variables"),
-      )
+      .arg(Arg::with_name(cmd::EVALUATE).long("evaluate").help(
+        "Evaluate and print all variables. If positional arguments are present, only print the \
+         variables whose names are given as arguments.",
+      ))
       .arg(
         Arg::with_name(cmd::INIT)
           .long("init")
@@ -421,13 +420,10 @@ impl Config {
         name: name.to_owned(),
       }
     } else if matches.is_present(cmd::EVALUATE) {
-      if !positional.arguments.is_empty() {
-        return Err(ConfigError::SubcommandArguments {
-          subcommand: format!("--{}", cmd::EVALUATE.to_lowercase()),
-          arguments:  positional.arguments,
-        });
+      Subcommand::Evaluate {
+        variables: positional.arguments,
+        overrides,
       }
-      Subcommand::Evaluate { overrides }
     } else if matches.is_present(cmd::VARIABLES) {
       Subcommand::Variables
     } else {
@@ -516,7 +512,7 @@ impl Config {
       Choose { overrides, chooser } =>
         self.choose(justfile, &search, overrides, chooser.as_deref())?,
       Dump => Self::dump(justfile),
-      Evaluate { overrides } => self.run(justfile, &search, overrides, &[])?,
+      Evaluate { overrides, .. } => self.run(justfile, &search, overrides, &[])?,
       List => self.list(justfile),
       Run {
         arguments,
@@ -877,7 +873,9 @@ FLAGS:
         --dump                Print entire justfile
     -e, --edit                Edit justfile with editor given by $VISUAL or $EDITOR, falling back \
                                  to `vim`
-        --evaluate            Print evaluated variables
+        --evaluate            Evaluate and print all variables. If positional arguments are \
+                                 present, only print the
+                              variables whose names are given as arguments.
         --highlight           Highlight echoed recipe lines in bold
         --init                Initialize new justfile in project root
     -l, --list                List available recipes and their arguments
@@ -1332,6 +1330,7 @@ ARGS:
     args: ["--evaluate"],
     subcommand: Subcommand::Evaluate {
       overrides: map!{},
+      variables: vec![],
     },
   }
 
@@ -1340,6 +1339,16 @@ ARGS:
     args: ["--evaluate", "x=y"],
     subcommand: Subcommand::Evaluate {
       overrides: map!{"x": "y"},
+      variables: vec![],
+    },
+  }
+
+  test! {
+    name: subcommand_evaluate_overrides_with_argument,
+    args: ["--evaluate", "x=y", "foo"],
+    subcommand: Subcommand::Evaluate {
+      overrides: map!{"x": "y"},
+      variables: vec!["foo".to_owned()],
     },
   }
 
@@ -1583,16 +1592,6 @@ ARGS:
     },
   }
 
-  error! {
-    name: evaluate_arguments,
-    args: ["--evaluate", "bar"],
-    error: ConfigError::SubcommandArguments { subcommand, arguments },
-    check: {
-      assert_eq!(subcommand, "--evaluate");
-      assert_eq!(arguments, &["bar"]);
-    },
-  }
-
   error! {
     name: dump_arguments,
     args: ["--dump", "bar"],
diff --git a/src/justfile.rs b/src/justfile.rs
index 36c4472d..8145d28b 100644
--- a/src/justfile.rs
+++ b/src/justfile.rs
@@ -107,14 +107,26 @@ impl<'src> Justfile<'src> {
       )?
     };
 
-    if let Subcommand::Evaluate { .. } = config.subcommand {
+    if let Subcommand::Evaluate { variables, .. } = &config.subcommand {
       let mut width = 0;
 
       for name in scope.names() {
+        if !variables.is_empty() && !variables.iter().any(|variable| variable == name) {
+          continue;
+        }
+
         width = cmp::max(name.len(), width);
       }
 
       for binding in scope.bindings() {
+        if !variables.is_empty()
+          && !variables
+            .iter()
+            .any(|variable| variable == binding.name.lexeme())
+        {
+          continue;
+        }
+
         println!(
           "{0:1$} := \"{2}\"",
           binding.name.lexeme(),
@@ -122,6 +134,7 @@ impl<'src> Justfile<'src> {
           binding.value
         );
       }
+
       return Ok(());
     }
 
diff --git a/src/subcommand.rs b/src/subcommand.rs
index 53e7399f..379c681f 100644
--- a/src/subcommand.rs
+++ b/src/subcommand.rs
@@ -13,6 +13,7 @@ pub(crate) enum Subcommand {
   Edit,
   Evaluate {
     overrides: BTreeMap<String, String>,
+    variables: Vec<String>,
   },
   Init,
   List,


Test patch:
diff --git a/tests/evaluate.rs b/tests/evaluate.rs
index 4f11d77e..277ae8c4 100644
--- a/tests/evaluate.rs
+++ b/tests/evaluate.rs
@@ -27,3 +27,17 @@ test! {
     a := "foo"
   "#,
 }
+
+test! {
+  name:     evaluate_arguments,
+  justfile: "
+    a := 'x'
+    b := 'y'
+    c := 'z'
+  ",
+  args:     ("--evaluate", "a", "c"),
+  stdout:   r#"
+    a := "x"
+    c := "z"
+  "#,
+}