Skip to content

Commit

Permalink
refactor: switch coco arg parsing to structopt
Browse files Browse the repository at this point in the history
  • Loading branch information
tranzystorekk authored and oknozor committed Nov 30, 2021
1 parent 618499e commit 5b185d8
Show file tree
Hide file tree
Showing 4 changed files with 354 additions and 427 deletions.
65 changes: 64 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ shell-words = "^1"
which = "^4"
lazy_static = "^1"
toml = "^0"
clap = { version = "^2", optional = true }
structopt = { version = "^0", optional = true }
conventional_commit_parser = "^0"

[dev-dependencies]
Expand All @@ -40,7 +40,7 @@ speculoos = "0.7.0"

[features]
default = ["cli"]
cli = [ "clap"]
cli = ["structopt"]

[lib]
name = "cocogitto"
Expand All @@ -49,13 +49,13 @@ path = "src/lib.rs"
[[bin]]
name = "cog"
path = "src/bin/cog.rs"
required-features = ["clap"]
required-features = ["structopt"]

[[bin]]
name = "coco"
path = "src/bin/coco.rs"
required-features = ["clap"]
required-features = ["structopt"]

[[test]]
name = "all"
path = "tests/common.rs"
path = "tests/common.rs"
126 changes: 47 additions & 79 deletions src/bin/coco.rs
Original file line number Diff line number Diff line change
@@ -1,103 +1,71 @@
#![cfg(not(tarpaulin_include))]
use anyhow::Result;
use clap::{App, AppSettings, Arg, Shell, SubCommand};
use structopt::clap::{AppSettings, Shell};
use structopt::StructOpt;

use cocogitto::CocoGitto;
use cocogitto::COMMITS_METADATA;

const APP_SETTINGS: &[AppSettings] = &[
AppSettings::ArgsNegateSubcommands,
AppSettings::SubcommandsNegateReqs,
AppSettings::UnifiedHelpMessage,
AppSettings::ColoredHelp,
AppSettings::VersionlessSubcommands,
AppSettings::DeriveDisplayOrder,
];

const SUBCOMMAND_SETTINGS: &[AppSettings] = &[
AppSettings::UnifiedHelpMessage,
AppSettings::ColoredHelp,
AppSettings::VersionlessSubcommands,
AppSettings::DeriveDisplayOrder,
];
fn metadata_as_commit_types() -> Vec<&'static str> {
COMMITS_METADATA
.iter()
.map(|(commit_type, _)| commit_type.as_ref())
.collect()
}

/// A command line tool to create conventional commits
#[derive(StructOpt)]
#[structopt(name = "Coco", author = "Paul D. <paul.delafosse@protonmail.com>", settings = APP_SETTINGS)]
struct Cli {
/// Conventional commit type
#[structopt(name = "type", possible_values = &metadata_as_commit_types(), default_value_if("completion", None, "chore"))]
typ: String,

/// Commit description
#[structopt(default_value_if("completion", None, ""))]
message: String,

/// Conventional commit scope
scope: Option<String>,

const GENERATE_COMPLETIONS: &str = "generate-completions";
/// Commit message body
body: Option<String>,

/// Commit message footer
footer: Option<String>,

/// Create a BREAKING CHANGE commit
#[structopt(short = "B", long)]
breaking_change: bool,

/// Generate shell completions
#[structopt(long, conflicts_with = "type")]
completion: Option<Shell>,
}

fn main() -> Result<()> {
let matches = app().get_matches();
let cli = Cli::from_args();

if let Some(subcommand) = matches.subcommand_matches(GENERATE_COMPLETIONS) {
let for_shell = match subcommand.value_of("type").unwrap() {
"bash" => Shell::Bash,
"elvish" => Shell::Elvish,
"fish" => Shell::Fish,
"zsh" => Shell::Zsh,
_ => unreachable!(),
};
app().gen_completions_to("coco", for_shell, &mut std::io::stdout());
if let Some(shell) = cli.completion {
Cli::clap().gen_completions_to("coco", shell, &mut std::io::stdout());
} else {
let cocogitto = CocoGitto::get()?;

let commit_type = matches.value_of("type").unwrap().to_string();
let message = matches.value_of("message").unwrap().to_string();
let scope = matches.value_of("scope").map(|scope| scope.to_string());
let body = matches.value_of("body").map(|body| body.to_string());
let footers = matches.value_of("footer").map(|footer| footer.to_string());
let breaking_change = matches.is_present("breaking-change");

cocogitto.conventional_commit(
&commit_type,
scope,
message,
body,
footers,
breaking_change,
&cli.typ,
cli.scope,
cli.message,
cli.body,
cli.footer,
cli.breaking_change,
)?;
}

Ok(())
}

fn app<'a, 'b>() -> App<'a, 'b> {
let keys: Vec<&str> = COMMITS_METADATA
.iter()
.map(|(commit_type, _)| commit_type.as_ref())
.collect();

App::new("Coco")
.settings(APP_SETTINGS)
.version(env!("CARGO_PKG_VERSION"))
.author("Paul D. <paul.delafosse@protonmail.com>")
.about("A command line tool to create conventional commits")
.arg(
Arg::with_name("type")
.help("The type of the commit message")
.possible_values(&keys)
.required(true),
)
.arg(
Arg::with_name("message")
.help("The type of the commit message")
.required(true),
)
.arg(Arg::with_name("scope").help("The scope of the commit message"))
.arg(Arg::with_name("body").help("The body of the commit message"))
.arg(Arg::with_name("footer").help("The footer of the commit message"))
.arg(
Arg::with_name("breaking-change")
.help("BREAKING CHANGE commit")
.short("B")
.long("breaking-change"),
)
.subcommand(
SubCommand::with_name(GENERATE_COMPLETIONS)
.settings(SUBCOMMAND_SETTINGS)
.about("Generate shell completions")
.arg(
Arg::with_name("type")
.possible_values(&["bash", "elvish", "fish", "zsh"])
.required(true)
.takes_value(true)
.help("Type of completions to generate"),
),
)
}
Loading

0 comments on commit 5b185d8

Please sign in to comment.