1
1
mirror of https://github.com/orhun/git-cliff.git synced 2024-12-01 22:24:42 +03:00

chore(args): update arg parsing to clap v3 (#49)

* Update arg parsing to clap v3

* Refactor code

* Add help heading for flag arguments

* Reformat code

* chore(args): update help message of arguments

* chore(args): enable wrap_help feature of clap

* docs(readme): update command line arguments

* Add expect message for parsing sort_commits

Co-authored-by: Orhun Parmaksız <orhunparmaksiz@gmail.com>
This commit is contained in:
Marcin Puc 2022-01-31 23:06:57 +01:00 committed by GitHub
parent 848d8a587e
commit d961b53ba5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 164 additions and 159 deletions

134
Cargo.lock generated
View File

@ -11,15 +11,6 @@ dependencies = [
"memchr", "memchr",
] ]
[[package]]
name = "ansi_term"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
dependencies = [
"winapi",
]
[[package]] [[package]]
name = "ansi_term" name = "ansi_term"
version = "0.12.1" version = "0.12.1"
@ -160,17 +151,42 @@ dependencies = [
[[package]] [[package]]
name = "clap" name = "clap"
version = "2.33.3" version = "3.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" checksum = "7a30c3bf9ff12dfe5dae53f0a96e0febcd18420d1c0e7fad77796d9d5c4b5375"
dependencies = [ dependencies = [
"ansi_term 0.11.0",
"atty", "atty",
"bitflags", "bitflags",
"clap_derive",
"indexmap",
"lazy_static",
"os_str_bytes",
"strsim", "strsim",
"term_size", "termcolor",
"terminal_size",
"textwrap", "textwrap",
"unicode-width", ]
[[package]]
name = "clap_complete"
version = "3.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d044e9db8cd0f68191becdeb5246b7462e4cf0c069b19ae00d1bf3fa9889498d"
dependencies = [
"clap",
]
[[package]]
name = "clap_derive"
version = "3.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "517358c28fcef6607bf6f76108e02afad7e82297d132a6b846dcc1fc3efcd153"
dependencies = [
"heck",
"proc-macro-error",
"proc-macro2",
"quote",
"syn",
] ]
[[package]] [[package]]
@ -341,12 +357,13 @@ dependencies = [
name = "git-cliff" name = "git-cliff"
version = "0.5.0" version = "0.5.0"
dependencies = [ dependencies = [
"clap",
"clap_complete",
"dirs-next", "dirs-next",
"git-cliff-core", "git-cliff-core",
"log", "log",
"pretty_assertions", "pretty_assertions",
"pretty_env_logger", "pretty_env_logger",
"structopt",
] ]
[[package]] [[package]]
@ -432,12 +449,9 @@ checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
[[package]] [[package]]
name = "heck" name = "heck"
version = "0.3.3" version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
dependencies = [
"unicode-segmentation",
]
[[package]] [[package]]
name = "hermit-abi" name = "hermit-abi"
@ -664,6 +678,15 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]]
name = "os_str_bytes"
version = "6.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "output_vt100" name = "output_vt100"
version = "0.1.2" version = "0.1.2"
@ -788,7 +811,7 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0cfe1b2403f172ba0f234e500906ee0a3e493fb81092dac23ebefe129301cc" checksum = "ec0cfe1b2403f172ba0f234e500906ee0a3e493fb81092dac23ebefe129301cc"
dependencies = [ dependencies = [
"ansi_term 0.12.1", "ansi_term",
"ctor", "ctor",
"diff", "diff",
"output_vt100", "output_vt100",
@ -1066,33 +1089,9 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]] [[package]]
name = "strsim" name = "strsim"
version = "0.8.0" version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "structopt"
version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40b9788f4202aa75c240ecc9c15c65185e6a39ccdeb0fd5d008b98825464c87c"
dependencies = [
"clap",
"lazy_static",
"structopt-derive",
]
[[package]]
name = "structopt-derive"
version = "0.4.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0"
dependencies = [
"heck",
"proc-macro-error",
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "syn" name = "syn"
@ -1127,16 +1126,6 @@ dependencies = [
"unic-segment", "unic-segment",
] ]
[[package]]
name = "term_size"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e4129646ca0ed8f45d09b929036bafad5377103edd06e50bf574b353d2b08d9"
dependencies = [
"libc",
"winapi",
]
[[package]] [[package]]
name = "termcolor" name = "termcolor"
version = "1.1.2" version = "1.1.2"
@ -1147,13 +1136,22 @@ dependencies = [
] ]
[[package]] [[package]]
name = "textwrap" name = "terminal_size"
version = "0.11.0" version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df"
dependencies = [ dependencies = [
"term_size", "libc",
"unicode-width", "winapi",
]
[[package]]
name = "textwrap"
version = "0.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80"
dependencies = [
"terminal_size",
] ]
[[package]] [[package]]
@ -1307,18 +1305,6 @@ dependencies = [
"tinyvec", "tinyvec",
] ]
[[package]]
name = "unicode-segmentation"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b"
[[package]]
name = "unicode-width"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
[[package]] [[package]]
name = "unicode-xid" name = "unicode-xid"
version = "0.2.2" version = "0.2.2"

View File

@ -131,7 +131,7 @@ CARGO_TARGET_DIR=target cargo build --release
### Command Line Arguments ### Command Line Arguments
``` ```
git-cliff [FLAGS] [OPTIONS] [RANGE] git-cliff [FLAGS] [OPTIONS] [--] [RANGE]
``` ```
**Flags:** **Flags:**
@ -156,12 +156,12 @@ git-cliff [FLAGS] [OPTIONS] [RANGE]
--include-path <PATTERN>... Sets the path to include related commits [env: INCLUDE_PATH=] --include-path <PATTERN>... Sets the path to include related commits [env: INCLUDE_PATH=]
--exclude-path <PATTERN>... Sets the path to exclude related commits [env: EXCLUDE_PATH=] --exclude-path <PATTERN>... Sets the path to exclude related commits [env: EXCLUDE_PATH=]
--with-commit <MSG>... Sets custom commit messages to include in the changelog [env: WITH_COMMIT=] --with-commit <MSG>... Sets custom commit messages to include in the changelog [env: WITH_COMMIT=]
-p, --prepend <PATH> Prepends entries to the given changelog file [env: PREPEND= -p, --prepend <PATH> Prepends entries to the given changelog file [env: PREPEND=]
-o, --output <PATH> Writes output to the given file [env: OUTPUT=] -o, --output <PATH> Writes output to the given file [env: OUTPUT=]
-t, --tag <TAG> Sets the tag for the latest version [env: TAG=] -t, --tag <TAG> Sets the tag for the latest version [env: TAG=]
-b, --body <TEMPLATE> Sets the template for the changelog body [env: TEMPLATE=] -b, --body <TEMPLATE> Sets the template for the changelog body [env: TEMPLATE=]
-s, --strip <PART> Strips the given parts from the changelog [possible values: header, footer, all] -s, --strip <PART> Strips the given parts from the changelog [possible values: header, footer, all]
--sort <sort> Sets sorting of the commits inside sections [default: oldest] [possible values: oldest, newest] --sort <SORT> Sets sorting of the commits inside sections [default: oldest] [possible values: oldest, newest]
``` ```
**Args:** **Args:**

View File

@ -20,15 +20,15 @@ path = "src/bin/completions.rs"
pretty_env_logger = "0.4.0" pretty_env_logger = "0.4.0"
log = "0.4.14" log = "0.4.14"
dirs-next = "2.0.0" dirs-next = "2.0.0"
clap_complete = "3.0"
[dependencies.git-cliff-core] [dependencies.git-cliff-core]
version = "0.5.0" # managed by release.sh version = "0.5.0" # managed by release.sh
path = "../git-cliff-core" path = "../git-cliff-core"
[dependencies.structopt] [dependencies.clap]
version = "0.3.25" version = "3.0"
default-features = false features = ["derive", "env", "wrap_help"]
features = ["suggestions", "color", "wrap_help"]
[dev-dependencies] [dev-dependencies]
pretty_assertions = "1.0.0" pretty_assertions = "1.0.0"

View File

@ -1,29 +1,44 @@
use clap::{
AppSettings,
ArgEnum,
Parser,
};
use git_cliff_core::glob::Pattern; use git_cliff_core::glob::Pattern;
use git_cliff_core::DEFAULT_CONFIG; use git_cliff_core::DEFAULT_CONFIG;
use std::path::PathBuf; use std::path::PathBuf;
use structopt::clap::AppSettings;
use structopt::StructOpt; #[derive(Debug, Clone, Copy, ArgEnum)]
pub enum Strip {
Header,
Footer,
All,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, ArgEnum)]
pub enum Sort {
Oldest,
Newest,
}
/// Command-line arguments to parse. /// Command-line arguments to parse.
#[derive(Debug, StructOpt)] #[derive(Debug, Parser)]
#[structopt( #[clap(
name = env!("CARGO_PKG_NAME"), version,
version = env!("CARGO_PKG_VERSION"), author,
author = env!("CARGO_PKG_AUTHORS"), about,
about = env!("CARGO_PKG_DESCRIPTION"), global_setting = AppSettings::DeriveDisplayOrder,
global_settings(&[ rename_all_env = "screaming-snake",
AppSettings::ColorAuto, help_heading = Some("OPTIONS"),
AppSettings::ColoredHelp, override_usage = "git-cliff [FLAGS] [OPTIONS] [--] [RANGE]",
AppSettings::DeriveDisplayOrder, mut_arg("help", |arg| arg.help("Prints help information").help_heading("FLAGS")),
]), mut_arg("version", |arg| arg.help("Prints version information").help_heading("FLAGS"))
rename_all_env = "screaming-snake"
)] )]
pub struct Opt { pub struct Opt {
/// Increases the logging verbosity. /// Increases the logging verbosity.
#[structopt(short, long, parse(from_occurrences), alias = "debug")] #[clap(short, long, parse(from_occurrences), alias = "debug", help_heading = Some("FLAGS"))]
pub verbose: u8, pub verbose: u8,
/// Sets the configuration file. /// Sets the configuration file.
#[structopt( #[clap(
short, short,
long, long,
env, env,
@ -32,31 +47,31 @@ pub struct Opt {
)] )]
pub config: PathBuf, pub config: PathBuf,
/// Sets the working directory. /// Sets the working directory.
#[structopt(short, long, env, value_name = "PATH")] #[clap(short, long, env, value_name = "PATH")]
pub workdir: Option<PathBuf>, pub workdir: Option<PathBuf>,
/// Sets the git repository. /// Sets the git repository.
#[structopt(short, long, env, value_name = "PATH")] #[clap(short, long, env, value_name = "PATH")]
pub repository: Option<PathBuf>, pub repository: Option<PathBuf>,
/// Sets the path to include related commits. /// Sets the path to include related commits.
#[structopt(long, env, value_name = "PATTERN")] #[clap(long, env, value_name = "PATTERN", multiple_values = true)]
pub include_path: Option<Vec<Pattern>>, pub include_path: Option<Vec<Pattern>>,
/// Sets the path to exclude related commits. /// Sets the path to exclude related commits.
#[structopt(long, env, value_name = "PATTERN")] #[clap(long, env, value_name = "PATTERN", multiple_values = true)]
pub exclude_path: Option<Vec<Pattern>>, pub exclude_path: Option<Vec<Pattern>>,
/// Sets custom commit messages to include in the changelog. /// Sets custom commit messages to include in the changelog.
#[structopt(long, env, value_name = "MSG")] #[clap(long, env, value_name = "MSG", multiple_values = true)]
pub with_commit: Option<Vec<String>>, pub with_commit: Option<Vec<String>>,
/// Prepends entries to the given changelog file. /// Prepends entries to the given changelog file.
#[structopt(short, long, env, value_name = "PATH")] #[clap(short, long, env, value_name = "PATH")]
pub prepend: Option<PathBuf>, pub prepend: Option<PathBuf>,
/// Writes output to the given file. /// Writes output to the given file.
#[structopt(short, long, env, value_name = "PATH")] #[clap(short, long, env, value_name = "PATH")]
pub output: Option<PathBuf>, pub output: Option<PathBuf>,
/// Sets the tag for the latest version. /// Sets the tag for the latest version.
#[structopt(short, long, env, value_name = "TAG", allow_hyphen_values = true)] #[clap(short, long, env, value_name = "TAG", allow_hyphen_values = true)]
pub tag: Option<String>, pub tag: Option<String>,
/// Sets the template for the changelog body. /// Sets the template for the changelog body.
#[structopt( #[clap(
short, short,
long, long,
env = "TEMPLATE", env = "TEMPLATE",
@ -65,36 +80,31 @@ pub struct Opt {
)] )]
pub body: Option<String>, pub body: Option<String>,
/// Writes the default configuration file to cliff.toml /// Writes the default configuration file to cliff.toml
#[structopt(short, long)] #[clap(short, long, help_heading = Some("FLAGS"))]
pub init: bool, pub init: bool,
/// Processes the commits starting from the latest tag. /// Processes the commits starting from the latest tag.
#[structopt(short, long)] #[clap(short, long, help_heading = Some("FLAGS"))]
pub latest: bool, pub latest: bool,
/// Processes the commits that belong to the current tag. /// Processes the commits that belong to the current tag.
#[structopt(long)] #[clap(long, help_heading = Some("FLAGS"))]
pub current: bool, pub current: bool,
/// Processes the commits that do not belong to a tag. /// Processes the commits that do not belong to a tag.
#[structopt(short, long)] #[clap(short, long, help_heading = Some("FLAGS"))]
pub unreleased: bool, pub unreleased: bool,
/// Sorts the tags topologically. /// Sorts the tags topologically.
#[structopt(long)] #[clap(long, help_heading = Some("FLAGS"))]
pub topo_order: bool, pub topo_order: bool,
/// Strips the given parts from the changelog. /// Strips the given parts from the changelog.
#[structopt( #[clap(short, long, value_name = "PART", arg_enum)]
short, pub strip: Option<Strip>,
long,
value_name = "PART",
possible_values = &["header", "footer", "all"]
)]
pub strip: Option<String>,
/// Sets the commit range to process.
#[structopt(value_name = "RANGE")]
pub range: Option<String>,
/// Sets sorting of the commits inside sections. /// Sets sorting of the commits inside sections.
#[structopt( #[clap(
long, long,
possible_values = &["oldest", "newest"], arg_enum,
default_value = "oldest" default_value_t = Sort::Oldest
)] )]
pub sort: String, pub sort: Sort,
/// Sets the commit range to process.
#[clap(value_name = "RANGE", help_heading = Some("ARGS"))]
pub range: Option<String>,
} }

View File

@ -1,23 +1,26 @@
use git_cliff::args::Opt; use clap::{
use std::{ ArgEnum,
env, IntoApp,
str::FromStr,
}; };
use structopt::clap::Shell; use clap_complete::Shell;
use structopt::StructOpt; use git_cliff::args::Opt;
use std::env;
/// Shell completions can be created with: /// Shell completions can be created with:
/// `cargo run --bin git-cliff-completions` /// `cargo run --bin git-cliff-completions`
/// in a directory specified by the environment variable OUT_DIR. /// in a directory specified by the environment variable OUT_DIR.
/// See <https://doc.rust-lang.org/cargo/reference/environment-variables.html> /// See <https://doc.rust-lang.org/cargo/reference/environment-variables.html>
fn main() { fn main() -> Result<(), std::io::Error> {
let out_dir = env::var("OUT_DIR").expect("OUT_DIR is not set"); let out_dir = env::var("OUT_DIR").expect("OUT_DIR is not set");
let mut app = Opt::clap(); let mut app = Opt::into_app();
for variant in Shell::variants() for &shell in Shell::value_variants() {
.iter() clap_complete::generate_to(
.filter_map(|v| Shell::from_str(v).ok()) shell,
{ &mut app,
app.gen_completions(env!("CARGO_PKG_NAME"), variant, &out_dir); env!("CARGO_PKG_NAME"),
&out_dir,
)?;
} }
println!("Completion scripts are generated in {:?}", out_dir); println!("Completion scripts are generated in {:?}", out_dir);
Ok(())
} }

View File

@ -6,8 +6,13 @@ pub mod changelog;
#[macro_use] #[macro_use]
extern crate log; extern crate log;
use args::Opt; use args::{
Opt,
Sort,
Strip,
};
use changelog::Changelog; use changelog::Changelog;
use clap::ArgEnum;
use git_cliff_core::commit::Commit; use git_cliff_core::commit::Commit;
use git_cliff_core::config::Config; use git_cliff_core::config::Config;
use git_cliff_core::embed::EmbeddedConfig; use git_cliff_core::embed::EmbeddedConfig;
@ -76,18 +81,18 @@ pub fn run(mut args: Opt) -> Result<()> {
} }
// Update the configuration based on command line arguments and vice versa. // Update the configuration based on command line arguments and vice versa.
match args.strip.as_deref() { match args.strip {
Some("header") => { Some(Strip::Header) => {
config.changelog.header = None; config.changelog.header = None;
} }
Some("footer") => { Some(Strip::Footer) => {
config.changelog.footer = None; config.changelog.footer = None;
} }
Some("all") => { Some(Strip::All) => {
config.changelog.header = None; config.changelog.header = None;
config.changelog.footer = None; config.changelog.footer = None;
} }
_ => {} None => {}
} }
if args.prepend.is_some() { if args.prepend.is_some() {
config.changelog.footer = None; config.changelog.footer = None;
@ -100,9 +105,10 @@ pub fn run(mut args: Opt) -> Result<()> {
if args.body.is_some() { if args.body.is_some() {
config.changelog.body = args.body; config.changelog.body = args.body;
} }
if args.sort == "oldest" { if args.sort == Sort::Oldest {
if let Some(ref sort_commits) = config.git.sort_commits { if let Some(ref sort_commits) = config.git.sort_commits {
args.sort = sort_commits.to_string(); args.sort = Sort::from_str(sort_commits, true)
.expect("Incorrect config value for 'sort_commits'");
} }
} }
if !args.topo_order { if !args.topo_order {
@ -204,7 +210,7 @@ pub fn run(mut args: Opt) -> Result<()> {
for git_commit in commits.into_iter().rev() { for git_commit in commits.into_iter().rev() {
let commit = Commit::from(&git_commit); let commit = Commit::from(&git_commit);
let commit_id = commit.id.to_string(); let commit_id = commit.id.to_string();
if args.sort == "newest" { if args.sort == Sort::Newest {
releases[release_index].commits.insert(0, commit); releases[release_index].commits.insert(0, commit);
} else { } else {
releases[release_index].commits.push(commit); releases[release_index].commits.push(commit);

View File

@ -1,10 +1,10 @@
use clap::Parser;
use git_cliff::args::Opt; use git_cliff::args::Opt;
use std::env; use std::env;
use std::process; use std::process;
use structopt::StructOpt;
fn main() { fn main() {
let args = Opt::from_args(); let args = Opt::parse();
if args.verbose == 1 { if args.verbose == 1 {
env::set_var("RUST_LOG", "debug"); env::set_var("RUST_LOG", "debug");
} else if args.verbose > 1 { } else if args.verbose > 1 {