| 1 | use std::path::PathBuf; |
| 2 | |
| 3 | use clap::error::ErrorKind; |
| 4 | use clap::{arg, command, value_parser, ArgAction}; |
| 5 | |
| 6 | fn main() { |
| 7 | // Create application like normal |
| 8 | let mut cmd = command!() // requires `cargo` feature |
| 9 | // Add the version arguments |
| 10 | .arg(arg!(--"set-ver" <VER> "set version manually" )) |
| 11 | .arg(arg!(--major "auto inc major" ).action(ArgAction::SetTrue)) |
| 12 | .arg(arg!(--minor "auto inc minor" ).action(ArgAction::SetTrue)) |
| 13 | .arg(arg!(--patch "auto inc patch" ).action(ArgAction::SetTrue)) |
| 14 | // Arguments can also be added to a group individually, these two arguments |
| 15 | // are part of the "input" group which is not required |
| 16 | .arg(arg!([INPUT_FILE] "some regular input" ).value_parser(value_parser!(PathBuf))) |
| 17 | .arg( |
| 18 | arg!(--"spec-in" <SPEC_IN> "some special input argument" ) |
| 19 | .value_parser(value_parser!(PathBuf)), |
| 20 | ) |
| 21 | // Now let's assume we have a -c [config] argument which requires one of |
| 22 | // (but **not** both) the "input" arguments |
| 23 | .arg(arg!(config: -c <CONFIG>).value_parser(value_parser!(PathBuf))); |
| 24 | let matches = cmd.get_matches_mut(); |
| 25 | |
| 26 | // Let's assume the old version 1.2.3 |
| 27 | let mut major = 1; |
| 28 | let mut minor = 2; |
| 29 | let mut patch = 3; |
| 30 | |
| 31 | // See if --set-ver was used to set the version manually |
| 32 | let version = if let Some(ver) = matches.get_one::<String>("set-ver" ) { |
| 33 | if matches.get_flag("major" ) || matches.get_flag("minor" ) || matches.get_flag("patch" ) { |
| 34 | cmd.error( |
| 35 | ErrorKind::ArgumentConflict, |
| 36 | "Can't do relative and absolute version change" , |
| 37 | ) |
| 38 | .exit(); |
| 39 | } |
| 40 | ver.to_string() |
| 41 | } else { |
| 42 | // Increment the one requested (in a real program, we'd reset the lower numbers) |
| 43 | let (maj, min, pat) = ( |
| 44 | matches.get_flag("major" ), |
| 45 | matches.get_flag("minor" ), |
| 46 | matches.get_flag("patch" ), |
| 47 | ); |
| 48 | match (maj, min, pat) { |
| 49 | (true, false, false) => major += 1, |
| 50 | (false, true, false) => minor += 1, |
| 51 | (false, false, true) => patch += 1, |
| 52 | _ => { |
| 53 | cmd.error( |
| 54 | ErrorKind::ArgumentConflict, |
| 55 | "Can only modify one version field" , |
| 56 | ) |
| 57 | .exit(); |
| 58 | } |
| 59 | }; |
| 60 | format!("{major}.{minor}.{patch}" ) |
| 61 | }; |
| 62 | |
| 63 | println!("Version: {version}" ); |
| 64 | |
| 65 | // Check for usage of -c |
| 66 | if matches.contains_id("config" ) { |
| 67 | let input = matches |
| 68 | .get_one::<PathBuf>("INPUT_FILE" ) |
| 69 | .or_else(|| matches.get_one::<PathBuf>("spec-in" )) |
| 70 | .unwrap_or_else(|| { |
| 71 | cmd.error( |
| 72 | ErrorKind::MissingRequiredArgument, |
| 73 | "INPUT_FILE or --spec-in is required when using --config" , |
| 74 | ) |
| 75 | .exit() |
| 76 | }) |
| 77 | .display(); |
| 78 | println!( |
| 79 | "Doing work using input {} and config {}" , |
| 80 | input, |
| 81 | matches.get_one::<PathBuf>("config" ).unwrap().display() |
| 82 | ); |
| 83 | } |
| 84 | } |
| 85 | |