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 | |