Repository: casey/just
Pull request #932 (2021-07-31 20:10:54)

Print changelog with `--changelog` subcommand


Patch:
diff --git a/README.adoc b/README.adoc
index 00b72cf0..99ba8263 100644
--- a/README.adoc
+++ b/README.adoc
@@ -1576,6 +1576,10 @@ default:
   echo foo
 ```
 
+=== Changelog
+
+A changelog for the latest release is available in link:CHANGELOG.md[]. Changelogs for previous releases are avaiable on https://github.com/casey/just/releases[the releases page]. `just --changelog` can also be used to make a `just` binary print its changelog.
+
 == Miscellanea
 
 === Companion Tools
diff --git a/completions/just.bash b/completions/just.bash
index e97b3e95..56917091 100644
--- a/completions/just.bash
+++ b/completions/just.bash
@@ -20,7 +20,7 @@ _just() {
 
     case "${cmd}" in
         just)
-            opts=" -q -u -v -e -l -h -V -f -d -c -s  --dry-run --highlight --no-dotenv --no-highlight --quiet --shell-command --clear-shell-args --unsorted --unstable --verbose --choose --dump --edit --evaluate --fmt --init --list --summary --variables --help --version --chooser --color --list-heading --list-prefix --justfile --set --shell --shell-arg --working-directory --command --completions --show  <ARGUMENTS>... "
+            opts=" -q -u -v -e -l -h -V -f -d -c -s  --dry-run --highlight --no-dotenv --no-highlight --quiet --shell-command --clear-shell-args --unsorted --unstable --verbose --changelog --choose --dump --edit --evaluate --fmt --init --list --summary --variables --help --version --chooser --color --list-heading --list-prefix --justfile --set --shell --shell-arg --working-directory --command --completions --show  <ARGUMENTS>... "
                 if [[ ${cur} == -* ]] ; then
                     COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                     return 0
diff --git a/completions/just.elvish b/completions/just.elvish
index 2d24cc30..70e29868 100644
--- a/completions/just.elvish
+++ b/completions/just.elvish
@@ -43,6 +43,7 @@ edit:completion:arg-completer[just] = [@words]{
             cand --unstable 'Enable unstable features'
             cand -v 'Use verbose output'
             cand --verbose 'Use verbose output'
+            cand --changelog 'Print changelog'
             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`'
diff --git a/completions/just.fish b/completions/just.fish
index 92d3b5f6..48d1da5f 100644
--- a/completions/just.fish
+++ b/completions/just.fish
@@ -31,6 +31,7 @@ complete -c just -n "__fish_use_subcommand" -l clear-shell-args -d 'Clear shell
 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" -l unstable -d 'Enable unstable features'
 complete -c just -n "__fish_use_subcommand" -s v -l verbose -d 'Use verbose output'
+complete -c just -n "__fish_use_subcommand" -l changelog -d 'Print changelog'
 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`'
diff --git a/completions/just.powershell b/completions/just.powershell
index f9fa0090..031d68b0 100644
--- a/completions/just.powershell
+++ b/completions/just.powershell
@@ -48,6 +48,7 @@ Register-ArgumentCompleter -Native -CommandName 'just' -ScriptBlock {
             [CompletionResult]::new('--unstable', 'unstable', [CompletionResultType]::ParameterName, 'Enable unstable features')
             [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'Use verbose output')
             [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'Use verbose output')
+            [CompletionResult]::new('--changelog', 'changelog', [CompletionResultType]::ParameterName, 'Print changelog')
             [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`')
diff --git a/completions/just.zsh b/completions/just.zsh
index bc57f54e..25746a82 100644
--- a/completions/just.zsh
+++ b/completions/just.zsh
@@ -44,6 +44,7 @@ _just() {
 '--unstable[Enable unstable features]' \
 '*-v[Use verbose output]' \
 '*--verbose[Use verbose output]' \
+'--changelog[Print changelog]' \
 '--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`]' \
diff --git a/src/config.rs b/src/config.rs
index 20bac561..a53ea7d5 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -33,7 +33,9 @@ pub(crate) struct Config {
 }
 
 mod cmd {
+  pub(crate) const CHANGELOG: &str = "CHANGELOG";
   pub(crate) const CHOOSE: &str = "CHOOSE";
+  pub(crate) const COMMAND: &str = "COMMAND";
   pub(crate) const COMPLETIONS: &str = "COMPLETIONS";
   pub(crate) const DUMP: &str = "DUMP";
   pub(crate) const EDIT: &str = "EDIT";
@@ -44,9 +46,9 @@ mod cmd {
   pub(crate) const SHOW: &str = "SHOW";
   pub(crate) const SUMMARY: &str = "SUMMARY";
   pub(crate) const VARIABLES: &str = "VARIABLES";
-  pub(crate) const COMMAND: &str = "COMMAND";
 
   pub(crate) const ALL: &[&str] = &[
+    CHANGELOG,
     CHOOSE,
     COMMAND,
     COMPLETIONS,
@@ -62,6 +64,7 @@ mod cmd {
   ];
 
   pub(crate) const ARGLESS: &[&str] = &[
+    CHANGELOG,
     COMPLETIONS,
     DUMP,
     EDIT,
@@ -239,6 +242,11 @@ impl Config {
           .help("Use <WORKING-DIRECTORY> as working directory. --justfile must also be set")
           .requires(arg::JUSTFILE),
       )
+      .arg(
+        Arg::with_name(cmd::CHANGELOG)
+          .long("changelog")
+          .help("Print changelog"),
+      )
       .arg(Arg::with_name(cmd::CHOOSE).long("choose").help(CHOOSE_HELP))
       .arg(
         Arg::with_name(cmd::COMMAND)
@@ -431,7 +439,9 @@ impl Config {
       }
     }
 
-    let subcommand = if matches.is_present(cmd::CHOOSE) {
+    let subcommand = if matches.is_present(cmd::CHANGELOG) {
+      Subcommand::Changelog
+    } else if matches.is_present(cmd::CHOOSE) {
       Subcommand::Choose {
         chooser: matches.value_of(arg::CHOOSER).map(str::to_owned),
         overrides,
@@ -565,6 +575,7 @@ USAGE:
     just [FLAGS] [OPTIONS] [--] [ARGUMENTS]...
 
 FLAGS:
+        --changelog           Print changelog
         --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`
@@ -963,6 +974,11 @@ ARGS:
     },
   }
 
+  error! {
+    name: subcommand_conflict_changelog,
+    args: ["--list", "--changelog"],
+  }
+
   error! {
     name: subcommand_conflict_summary,
     args: ["--list", "--summary"],
@@ -1294,6 +1310,16 @@ ARGS:
     },
   }
 
+  error! {
+    name: changelog_arguments,
+    args: ["--changelog", "bar"],
+    error: ConfigError::SubcommandArguments { subcommand, arguments },
+    check: {
+      assert_eq!(subcommand, cmd::CHANGELOG);
+      assert_eq!(arguments, &["bar"]);
+    },
+  }
+
   error! {
     name: list_arguments,
     args: ["--list", "bar"],
diff --git a/src/subcommand.rs b/src/subcommand.rs
index b7a072d8..b047a90b 100644
--- a/src/subcommand.rs
+++ b/src/subcommand.rs
@@ -4,6 +4,7 @@ const INIT_JUSTFILE: &str = "default:\n\techo 'Hello, world!'\n";
 
 #[derive(PartialEq, Clone, Debug)]
 pub(crate) enum Subcommand {
+  Changelog,
   Choose {
     overrides: BTreeMap<String, String>,
     chooser:   Option<String>,
@@ -40,12 +41,14 @@ impl Subcommand {
   pub(crate) fn run<'src>(&self, config: &Config, loader: &'src Loader) -> Result<(), Error<'src>> {
     use Subcommand::*;
 
-    if let Init = self {
-      return Self::init(config);
-    }
-
-    if let Completions { shell } = self {
-      return Self::completions(&shell);
+    match self {
+      Changelog => {
+        Self::changelog();
+        return Ok(());
+      },
+      Completions { shell } => return Self::completions(&shell),
+      Init => return Self::init(config),
+      _ => {},
     }
 
     let search = Search::find(&config.search_config, &config.invocation_directory)?;
@@ -81,12 +84,16 @@ impl Subcommand {
       Show { ref name } => Self::show(config, &name, justfile)?,
       Summary => Self::summary(config, justfile),
       Variables => Self::variables(justfile),
-      Completions { .. } | Edit | Init => unreachable!(),
+      Changelog | Completions { .. } | Edit | Init => unreachable!(),
     }
 
     Ok(())
   }
 
+  fn changelog() {
+    print!("{}", include_str!("../CHANGELOG.md"));
+  }
+
   fn choose<'src>(
     config: &Config,
     justfile: Justfile<'src>,


Test patch:
diff --git a/tests/changelog.rs b/tests/changelog.rs
new file mode 100644
index 00000000..85535353
--- /dev/null
+++ b/tests/changelog.rs
@@ -0,0 +1,9 @@
+use crate::common::*;
+
+#[test]
+fn print_changelog() {
+  Test::new()
+    .args(&["--changelog"])
+    .stdout(fs::read_to_string("CHANGELOG.md").unwrap())
+    .run();
+}
diff --git a/tests/command.rs b/tests/command.rs
index 13019e9d..c02f0eb0 100644
--- a/tests/command.rs
+++ b/tests/command.rs
@@ -32,7 +32,7 @@ test! {
 
     USAGE:
         just{} --color <COLOR> --shell <SHELL> --shell-arg <SHELL-ARG>... \
-        <--choose|--command <COMMAND>|--completions <SHELL>|--dump|--edit|\
+        <--changelog|--choose|--command <COMMAND>|--completions <SHELL>|--dump|--edit|\
         --evaluate|--fmt|--init|--list|--show <RECIPE>|--summary|--variables>
 
     For more information try --help
diff --git a/tests/lib.rs b/tests/lib.rs
index fe775008..650785e5 100644
--- a/tests/lib.rs
+++ b/tests/lib.rs
@@ -3,6 +3,7 @@ mod test;
 
 mod assert_stdout;
 mod assert_success;
+mod changelog;
 mod choose;
 mod command;
 mod common;