Skip to content

Commit ae02ae4

Browse files
Merge pull request #114 from notriddle/master
Bump to clap 3
2 parents ed86e91 + b3a4b38 commit ae02ae4

File tree

9 files changed

+92
-273
lines changed

9 files changed

+92
-273
lines changed

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ num_cpus = "1"
2020
remove_dir_all = "0.5"
2121

2222
[dependencies.clap]
23-
features = ["yaml"]
24-
version = "2.19.0"
23+
features = ["derive"]
24+
version = "3.1"
2525

2626
[target."cfg(windows)".dependencies]
2727
lazy_static = "1"

src/combiner.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,34 +13,44 @@ actor! {
1313
#[derive(Debug)]
1414
pub struct Combiner {
1515
/// The name of the product, for display.
16+
#[clap(value_name = "NAME")]
1617
product_name: String = "Product",
1718

1819
/// The name of the package tarball.
20+
#[clap(value_name = "NAME")]
1921
package_name: String = "package",
2022

2123
/// The directory under lib/ where the manifest lives.
24+
#[clap(value_name = "DIR")]
2225
rel_manifest_dir: String = "packagelib",
2326

2427
/// The string to print after successful installation.
28+
#[clap(value_name = "MESSAGE")]
2529
success_message: String = "Installed.",
2630

2731
/// Places to look for legacy manifests to uninstall.
32+
#[clap(value_name = "DIRS")]
2833
legacy_manifest_dirs: String = "",
2934

3035
/// Installers to combine.
36+
#[clap(value_name = "FILE,FILE")]
3137
input_tarballs: String = "",
3238

3339
/// Directory containing files that should not be installed.
40+
#[clap(value_name = "DIR")]
3441
non_installed_overlay: String = "",
3542

3643
/// The directory to do temporary work.
44+
#[clap(value_name = "DIR")]
3745
work_dir: String = "./workdir",
3846

3947
/// The location to put the final image and tarball.
48+
#[clap(value_name = "DIR")]
4049
output_dir: String = "./dist",
4150

4251
/// The formats used to compress the tarball
43-
compression_formats: CompressionFormats = CompressionFormats::default(),
52+
#[clap(value_name = "FORMAT", default_value_t)]
53+
compression_formats: CompressionFormats,
4454
}
4555
}
4656

src/compression.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use anyhow::{Context, Error};
22
use flate2::{read::GzDecoder, write::GzEncoder};
33
use rayon::prelude::*;
4-
use std::{convert::TryFrom, io::Read, io::Write, path::Path};
4+
use std::{convert::TryFrom, fmt, io::Read, io::Write, path::Path, str::FromStr};
55
use xz2::{read::XzDecoder, write::XzEncoder};
66

77
#[derive(Debug, Copy, Clone)]
@@ -80,6 +80,29 @@ impl TryFrom<&'_ str> for CompressionFormats {
8080
}
8181
}
8282

83+
impl FromStr for CompressionFormats {
84+
type Err = Error;
85+
86+
fn from_str(value: &str) -> Result<Self, Self::Err> {
87+
Self::try_from(value)
88+
}
89+
}
90+
91+
impl fmt::Display for CompressionFormats {
92+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
93+
for (i, format) in self.iter().enumerate() {
94+
if i != 0 {
95+
write!(f, ",")?;
96+
}
97+
fmt::Display::fmt(match format {
98+
CompressionFormat::Xz => "xz",
99+
CompressionFormat::Gz => "gz",
100+
}, f)?;
101+
}
102+
Ok(())
103+
}
104+
}
105+
83106
impl Default for CompressionFormats {
84107
fn default() -> Self {
85108
Self(vec![CompressionFormat::Gz, CompressionFormat::Xz])

src/generator.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,40 +10,52 @@ actor! {
1010
#[derive(Debug)]
1111
pub struct Generator {
1212
/// The name of the product, for display
13+
#[clap(value_name = "NAME")]
1314
product_name: String = "Product",
1415

1516
/// The name of the component, distinct from other installed components
17+
#[clap(value_name = "NAME")]
1618
component_name: String = "component",
1719

1820
/// The name of the package, tarball
21+
#[clap(value_name = "NAME")]
1922
package_name: String = "package",
2023

2124
/// The directory under lib/ where the manifest lives
25+
#[clap(value_name = "DIR")]
2226
rel_manifest_dir: String = "packagelib",
2327

2428
/// The string to print after successful installation
29+
#[clap(value_name = "MESSAGE")]
2530
success_message: String = "Installed.",
2631

2732
/// Places to look for legacy manifests to uninstall
33+
#[clap(value_name = "DIRS")]
2834
legacy_manifest_dirs: String = "",
2935

3036
/// Directory containing files that should not be installed
37+
#[clap(value_name = "DIR")]
3138
non_installed_overlay: String = "",
3239

3340
/// Path prefixes of directories that should be installed/uninstalled in bulk
41+
#[clap(value_name = "DIRS")]
3442
bulk_dirs: String = "",
3543

3644
/// The directory containing the installation medium
45+
#[clap(value_name = "DIR")]
3746
image_dir: String = "./install_image",
3847

3948
/// The directory to do temporary work
49+
#[clap(value_name = "DIR")]
4050
work_dir: String = "./workdir",
4151

4252
/// The location to put the final image and tarball
53+
#[clap(value_name = "DIR")]
4354
output_dir: String = "./dist",
4455

4556
/// The formats used to compress the tarball
46-
compression_formats: CompressionFormats = CompressionFormats::default(),
57+
#[clap(value_name = "FORMAT", default_value_t)]
58+
compression_formats: CompressionFormats,
4759
}
4860
}
4961

src/main.rs

Lines changed: 19 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,96 +1,28 @@
11
use anyhow::{Context, Result};
2-
use clap::{App, ArgMatches};
2+
use clap::{self, Command, Parser};
33
use std::convert::TryInto;
44

5-
fn main() -> Result<()> {
6-
let yaml = clap::load_yaml!("main.yml");
7-
let matches = App::from_yaml(yaml).get_matches();
8-
9-
match matches.subcommand() {
10-
("combine", Some(matches)) => combine(matches),
11-
("generate", Some(matches)) => generate(matches),
12-
("script", Some(matches)) => script(matches),
13-
("tarball", Some(matches)) => tarball(matches),
14-
_ => unreachable!(),
15-
}
16-
}
17-
18-
/// Parse clap arguements into the type constructor.
19-
macro_rules! parse(
20-
($matches:expr => $type:ty { $( $option:tt => $setter:ident, )* }) => {
21-
{
22-
let mut command: $type = Default::default();
23-
$(
24-
if let Some(val) = $matches.value_of($option) {
25-
command.$setter(val.try_into()?);
26-
}
27-
)*
28-
command
29-
}
30-
}
31-
);
32-
33-
fn combine(matches: &ArgMatches<'_>) -> Result<()> {
34-
let combiner = parse!(matches => installer::Combiner {
35-
"product-name" => product_name,
36-
"package-name" => package_name,
37-
"rel-manifest-dir" => rel_manifest_dir,
38-
"success-message" => success_message,
39-
"legacy-manifest-dirs" => legacy_manifest_dirs,
40-
"input-tarballs" => input_tarballs,
41-
"non-installed-overlay" => non_installed_overlay,
42-
"work-dir" => work_dir,
43-
"output-dir" => output_dir,
44-
"compression-formats" => compression_formats,
45-
});
46-
47-
combiner.run().context("failed to combine installers")?;
48-
Ok(())
5+
#[derive(Parser)]
6+
struct CommandLine {
7+
#[clap(subcommand)]
8+
command: Subcommand,
499
}
5010

51-
fn generate(matches: &ArgMatches<'_>) -> Result<()> {
52-
let generator = parse!(matches => installer::Generator {
53-
"product-name" => product_name,
54-
"component-name" => component_name,
55-
"package-name" => package_name,
56-
"rel-manifest-dir" => rel_manifest_dir,
57-
"success-message" => success_message,
58-
"legacy-manifest-dirs" => legacy_manifest_dirs,
59-
"non-installed-overlay" => non_installed_overlay,
60-
"bulk-dirs" => bulk_dirs,
61-
"image-dir" => image_dir,
62-
"work-dir" => work_dir,
63-
"output-dir" => output_dir,
64-
"compression-formats" => compression_formats,
65-
});
66-
67-
generator.run().context("failed to generate installer")?;
68-
Ok(())
11+
#[derive(clap::Subcommand)]
12+
enum Subcommand {
13+
Generate(installer::Generator),
14+
Combine(installer::Combiner),
15+
Script(installer::Scripter),
16+
Tarball(installer::Tarballer),
6917
}
7018

71-
fn script(matches: &ArgMatches<'_>) -> Result<()> {
72-
let scripter = parse!(matches => installer::Scripter {
73-
"product-name" => product_name,
74-
"rel-manifest-dir" => rel_manifest_dir,
75-
"success-message" => success_message,
76-
"legacy-manifest-dirs" => legacy_manifest_dirs,
77-
"output-script" => output_script,
78-
});
79-
80-
scripter
81-
.run()
82-
.context("failed to generate installation script")?;
83-
Ok(())
84-
}
85-
86-
fn tarball(matches: &ArgMatches<'_>) -> Result<()> {
87-
let tarballer = parse!(matches => installer::Tarballer {
88-
"input" => input,
89-
"output" => output,
90-
"work-dir" => work_dir,
91-
"compression-formats" => compression_formats,
92-
});
93-
94-
tarballer.run().context("failed to generate tarballs")?;
19+
fn main() -> Result<()> {
20+
let command_line = CommandLine::parse();
21+
match command_line.command {
22+
Subcommand::Combine(combiner) => combiner.run().context("failed to combine installers")?,
23+
Subcommand::Generate(generator) => generator.run().context("failed to generate installer")?,
24+
Subcommand::Script(scripter) => scripter.run().context("failed to generate installation script")?,
25+
Subcommand::Tarball(tarballer) => tarballer.run().context("failed to generate tarballs")?,
26+
}
9527
Ok(())
9628
}

0 commit comments

Comments
 (0)