Skip to content

Commit

Permalink
feat: add the completion sub-command
Browse files Browse the repository at this point in the history
  • Loading branch information
tmorin committed Jun 7, 2022
1 parent 2cbf9a5 commit f0a9549
Show file tree
Hide file tree
Showing 8 changed files with 375 additions and 439 deletions.
652 changes: 280 additions & 372 deletions Cargo.lock

Large diffs are not rendered by default.

6 changes: 2 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,10 @@ include = [
[[bin]]
name = "plantuml-generator"

[build-dependencies]
clap = "2"

[dependencies]
chrono = "0.4"
clap = "2"
clap_complete = "3.1"
clap = { version = "3.1", features = ["env", "cargo"] }
env_logger = { version = "0.8", default_features = false }
glob = "0.3"
heck = "0.3"
Expand Down
5 changes: 0 additions & 5 deletions build.rs

This file was deleted.

25 changes: 16 additions & 9 deletions src/app.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use clap_complete::{generate, Shell};
use std::ffi::OsString;
use std::io;
use std::str::FromStr;

use crate::cli::build_cli;
Expand All @@ -14,10 +16,10 @@ where
{
let app = build_cli();

let app_matches = match app.clone().get_matches_from_safe(args) {
let app_matches = match app.clone().try_get_matches_from(args) {
Ok(app_matches) => app_matches,
Err(e) => {
eprintln!("{}", e.message);
eprintln!("{}", e);
return if e.use_stderr() { 1 } else { 0 };
}
};
Expand All @@ -42,8 +44,8 @@ where
}

return match app_matches.subcommand() {
("library", Some(m)) => match m.subcommand() {
("generate", Some(m)) => {
Some(("library", m)) => match m.subcommand() {
Some(("generate", m)) => {
return match execute_library_generate(m) {
Ok(_) => 0,
Err(e) => {
Expand All @@ -55,14 +57,14 @@ where
_ => {
log::warn!("the SUBCOMMAND is missing");
app.clone()
.write_help(&mut std::io::stderr())
.write_help(&mut io::stderr())
.expect("unable to write help message");
eprintln!();
2
}
},
("diagram", Some(m)) => match m.subcommand() {
("generate", Some(m)) => {
Some(("diagram", m)) => match m.subcommand() {
Some(("generate", m)) => {
return match execute_diagram_generate(m) {
Ok(_) => 0,
Err(e) => {
Expand All @@ -74,16 +76,21 @@ where
_ => {
log::warn!("the SUBCOMMAND is missing");
app.clone()
.write_help(&mut std::io::stderr())
.write_help(&mut io::stderr())
.expect("unable to write help message");
eprintln!();
2
}
},
Some(("completion", m)) => {
let v: Shell = m.value_of_t("SHELL").unwrap();
generate(v, &mut build_cli(), "plantuml-generator", &mut io::stdout());
return 1;
}
_ => {
log::warn!("the SUBCOMMAND is missing");
app.clone()
.write_help(&mut std::io::stderr())
.write_help(&mut io::stderr())
.expect("unable to write help message");
eprintln!();
2
Expand Down
116 changes: 73 additions & 43 deletions src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,91 +1,106 @@
use clap::{crate_authors, crate_description, crate_version, App, AppSettings, Arg, SubCommand};
use clap::{crate_authors, crate_description, crate_version, Arg, Command};
use clap_complete::Shell;

pub fn build_cli() -> App<'static, 'static> {
let arg_cache_directory: Arg = Arg::with_name("cache_directory")
.short("C")
pub fn build_cli() -> Command<'static> {
let arg_cache_directory: Arg = Arg::new("cache_directory")
.short('C')
.long("cache")
.takes_value(true)
.env("PLANTUML_GENERATOR_OUTPUT_CACHE")
.help("The cache directory.");

let arg_plantuml_version: Arg = Arg::with_name("plantuml_version")
let arg_plantuml_version: Arg = Arg::new("plantuml_version")
.conflicts_with("plantuml_jar")
.short("V")
.short('V')
.long("plantuml-version")
.takes_value(true)
.env("PLANTUML_GENERATOR_PLANTUML_VERSION")
.help("The PlantUML version.");

let arg_plantuml_jar: Arg = Arg::with_name("plantuml_jar")
let arg_plantuml_jar: Arg = Arg::new("plantuml_jar")
.conflicts_with("plantuml_version")
.short("P")
.short('P')
.long("plantuml")
.takes_value(true)
.env("PLANTUML_GENERATOR_PLANTUML_JAR")
.help("The PlantUML version.");

let arg_java_binary: Arg = Arg::with_name("java_binary")
.short("J")
let arg_java_binary: Arg = Arg::new("java_binary")
.short('J')
.long("java")
.takes_value(true)
.env("PLANTUML_GENERATOR_JAVA_BINARY")
.help("The java binary path or command line.");

let arg_inkscape_binary: Arg = Arg::with_name("inkscape_binary")
.short("I")
let arg_inkscape_binary: Arg = Arg::new("inkscape_binary")
.short('I')
.long("inkscape")
.takes_value(true)
.env("PLANTUML_GENERATOR_INKSCAPE_BINARY")
.help("The inkscape binary path or command line.");

App::new("plantuml-generator")
Command::new("plantuml-generator")
.version(crate_version!())
.author(crate_authors!())
.about(crate_description!())
.setting(AppSettings::SubcommandRequiredElseHelp)
.subcommand_required(true)
.arg_required_else_help(true)
.arg(
Arg::with_name("log_level")
.short("l")
Arg::new("log_level")
.short('l')
.long("log-level")
.takes_value(true)
.default_value("Info")
.possible_values(&["Off", "Trace", "Debug", "Info", "Warn", "Error"])
.help("Set the verbosity of the logs."),
)
.subcommand(
SubCommand::with_name("library")
Command::new("library")
.about("Manage libraries")
.setting(AppSettings::SubcommandRequiredElseHelp)
.subcommand_required(true)
.arg_required_else_help(true)
.subcommand(
SubCommand::with_name("generate")
Command::new("generate")
.about("Generate a library from a manifest.")
.arg(Arg::with_name("MANIFEST")
.arg(Arg::new("MANIFEST")
.index(1)
.required(true)
.takes_value(true)
.help("The manifest of the library."))
.arg(Arg::with_name("output_directory")
.short("O")
.help("The manifest of the library.")
)
.arg(Arg::new("output_directory")
.short('O')
.long("output")
.env("PLANTUML_GENERATOR_OUTPUT_DIRECTORY")
.help("The output directory."))
.arg(Arg::with_name("urns")
.short("u")
.takes_value(true)
.help("The output directory.")
)
.arg(Arg::new("urns")
.help("Handle only artifacts included in the URN.")
.short('u')
.long("urn")
.takes_value(true)
.multiple(true)
.help("Handle only artifacts included in the URN."))
.arg(Arg::with_name("do_clean_cache")
.multiple_occurrences(true)
.allow_invalid_utf8(false)
)
.arg(Arg::new("do_clean_cache")
.long("clean-cache")
.help("Delete the cache directory before the generation-"))
.arg(Arg::with_name("urns_to_clean")
.arg(Arg::new("urns_to_clean")
.help("Delete the given URN in the output directory before the generation.")
.long("clean-urn")
.takes_value(true)
.multiple(true))
.arg(Arg::with_name("cleanup_scopes")
.multiple_occurrences(true)
.allow_invalid_utf8(false)
)
.arg(Arg::new("cleanup_scopes")
.help("The scopes to cleanup before the generation.")
.long_help("By default, artifacts which are already generated won't be generated again. The cleanup-scope option helps to target artifacts which will be re-generated.")
.short("c")
.short('c')
.long("cleanup-scope")
.takes_value(true)
.multiple(true)
.possible_values(&[
.multiple_occurrences(true)
.possible_values([
"All",
"Example",
"Item",
Expand All @@ -97,7 +112,8 @@ pub fn build_cli() -> App<'static, 'static> {
"Sprite",
"SpriteIcon",
"SpriteValue",
]))
])
)
.arg(&arg_cache_directory)
.arg(&arg_plantuml_version)
.arg(&arg_plantuml_jar)
Expand All @@ -106,20 +122,22 @@ pub fn build_cli() -> App<'static, 'static> {
),
)
.subcommand(
SubCommand::with_name("diagram")
Command::new("diagram")
.about("Manage diagrams")
.setting(AppSettings::SubcommandRequiredElseHelp)
.subcommand_required(true)
.arg_required_else_help(true)
.subcommand(
SubCommand::with_name("generate")
Command::new("generate")
.about("Generate discovered .puml files which has been mutated since the last generation.")
.arg(Arg::with_name("source_directory")
.short("s")
.arg(Arg::new("source_directory")
.short('s')
.long("source")
.default_value(".")
.takes_value(true)
.env("PLANTUML_GENERATOR_SOURCE_DIRECTORY")
.help("The directory where the .puml will be discovered."))
.arg(Arg::with_name("do_force_generation")
.short("f")
.arg(Arg::new("do_force_generation")
.short('f')
.long("force")
.help("Force the rendering of discovered .puml file."))
.arg(&arg_cache_directory)
Expand All @@ -128,4 +146,16 @@ pub fn build_cli() -> App<'static, 'static> {
.arg(&arg_java_binary)
),
)
.subcommand(Command::new("completion")
.about("Generate resources for autocompletion")
.arg_required_else_help(true)
.arg(
Arg::new("SHELL")
.help("set the shell")
.index(1)
.takes_value(true)
.required(true)
.possible_values(Shell::possible_values())
)
)
}
4 changes: 2 additions & 2 deletions src/cmd/library/generate/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ pub fn execute_library_generate(arg_matches: &ArgMatches) -> Result<()> {

// clean the targeted output directories
for urn_as_string in arg_matches
.values_of_lossy("urns_to_clean")
.values_of_t::<String>("urns_to_clean")
.unwrap_or_default()
{
let path_to_delete = Path::new(&config.output_directory).join(&urn_as_string);
Expand Down Expand Up @@ -87,7 +87,7 @@ pub fn execute_library_generate(arg_matches: &ArgMatches) -> Result<()> {
};

// fetch the targeted URNs
let urns = &values_t!(arg_matches, "urns", Urn).unwrap_or_default();
let urns = &arg_matches.values_of_t::<Urn>("urns").unwrap_or_default();
log::info!(
"targeted urns: {}",
urns.iter().map(|u| u.value.clone()).collect::<String>()
Expand Down
1 change: 0 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#[macro_use]
extern crate clap;

use crate::app::start_app;
Expand Down
5 changes: 2 additions & 3 deletions src/urn.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use std::fmt;
use std::result;
use std::str::FromStr;

use heck::TitleCase;
Expand Down Expand Up @@ -63,7 +62,7 @@ impl Serialize for Urn {
}

impl<'de> Deserialize<'de> for Urn {
fn deserialize<D>(deserializer: D) -> result::Result<Self, D::Error>
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
Expand All @@ -90,7 +89,7 @@ impl<'de> Deserialize<'de> for Urn {
impl FromStr for Urn {
type Err = crate::error::Error;

fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Urn::from(s))
}
}
Expand Down

0 comments on commit f0a9549

Please sign in to comment.