diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 41e30e3e..9fb1a848 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -13,7 +13,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: - toolchain: 1.53.0 + toolchain: 1.57.0 profile: minimal override: true components: rustfmt, clippy diff --git a/.github/workflows/release-cross.yml b/.github/workflows/release-cross.yml index 13b2b0cf..7d3d4ef0 100644 --- a/.github/workflows/release-cross.yml +++ b/.github/workflows/release-cross.yml @@ -15,7 +15,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: - toolchain: 1.53.0 + toolchain: 1.57.0 profile: minimal default: true override: true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 345a44cc..ed30643f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,7 +15,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: - toolchain: 1.53.0 + toolchain: 1.57.0 profile: minimal override: true components: rustfmt, clippy diff --git a/Cargo.lock b/Cargo.lock index cffaed3b..60e05edf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -23,15 +23,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "ansi_term" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi", -] - [[package]] name = "anyhow" version = "1.0.56" @@ -216,17 +207,41 @@ dependencies = [ [[package]] name = "clap" -version = "2.34.0" +version = "3.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +checksum = "6aad2534fad53df1cc12519c5cda696dd3e20e6118a027e24054aea14a0bdcbe" dependencies = [ - "ansi_term", "atty", "bitflags", + "clap_derive", + "clap_lex", + "indexmap", + "lazy_static", "strsim", + "termcolor", "textwrap", - "unicode-width", - "vec_map", +] + +[[package]] +name = "clap_derive" +version = "3.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3aab4734e083b809aaf5794e14e756d1c798d2c69c7f7de7a09a2f5214993c1" +dependencies = [ + "heck 0.4.0", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "189ddd3b5d32a70b35e7686054371742a937b0d99128e76dde6340210e966669" +dependencies = [ + "os_str_bytes", ] [[package]] @@ -634,6 +649,12 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -1081,6 +1102,12 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "os_str_bytes" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" + [[package]] name = "parking" version = "2.0.0" @@ -1555,33 +1582,9 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "strsim" -version = "0.8.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" - -[[package]] -name = "structopt" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" -dependencies = [ - "clap", - "lazy_static", - "structopt-derive", -] - -[[package]] -name = "structopt-derive" -version = "0.4.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" -dependencies = [ - "heck", - "proc-macro-error", - "proc-macro2", - "quote", - "syn", -] +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "strum" @@ -1607,7 +1610,7 @@ version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "339f799d8b549e3744c7ac7feb216383e4005d94bdb22561b3ab8f3b808ae9fb" dependencies = [ - "heck", + "heck 0.3.3", "proc-macro2", "quote", "syn", @@ -1619,7 +1622,7 @@ version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5bb0dc7ee9c15cea6199cde9a127fa16a4c5819af85395457ad72d68edc85a38" dependencies = [ - "heck", + "heck 0.3.3", "proc-macro2", "quote", "rustversion", @@ -1693,12 +1696,9 @@ dependencies = [ [[package]] name = "textwrap" -version = "0.11.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -dependencies = [ - "unicode-width", -] +checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" [[package]] name = "thiserror" @@ -1814,6 +1814,7 @@ dependencies = [ "anyhow", "cfg-if", "chrono", + "clap", "console", "directories", "futures", @@ -1830,7 +1831,6 @@ dependencies = [ "self_update", "serde", "shellexpand", - "structopt", "strum 0.23.0", "sys-info", "tempfile", @@ -1931,12 +1931,6 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" -[[package]] -name = "vec_map" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" - [[package]] name = "version_check" version = "0.9.4" diff --git a/Cargo.toml b/Cargo.toml index 3a80a096..1a9a8775 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ serde = { version = "1.0.125", features = ["derive"] } toml = "0.5.8" which_crate = { version = "4.1.0", package = "which" } shellexpand = "2.1.0" -structopt = "0.3.21" +clap = { version = "3.1", features = ["cargo", "derive"] } log = "0.4.14" walkdir = "2.3.2" console = "0.15.0" diff --git a/src/config.rs b/src/config.rs index 5b61e45a..80e95f63 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,3 +1,4 @@ +#![allow(dead_code)] use std::collections::BTreeMap; use std::fs::write; use std::path::PathBuf; @@ -5,12 +6,12 @@ use std::process::Command; use std::{env, fs}; use anyhow::Result; +use clap::{ArgEnum, Parser}; use directories::BaseDirs; use log::debug; use regex::Regex; use serde::Deserialize; -use structopt::StructOpt; -use strum::{EnumIter, EnumString, EnumVariantNames, IntoEnumIterator, VariantNames}; +use strum::{EnumIter, EnumString, EnumVariantNames, IntoEnumIterator}; use sys_info::hostname; use which_crate::which; @@ -61,7 +62,8 @@ macro_rules! get_deprecated { type Commands = BTreeMap; -#[derive(EnumString, EnumVariantNames, Debug, Clone, PartialEq, Deserialize, EnumIter, Copy)] +#[derive(ArgEnum, EnumString, EnumVariantNames, Debug, Clone, PartialEq, Deserialize, EnumIter, Copy)] +#[clap(rename_all = "snake_case")] #[serde(rename_all = "snake_case")] #[strum(serialize_all = "snake_case")] pub enum Step { @@ -358,68 +360,68 @@ impl ConfigFile { } } -#[derive(StructOpt, Debug)] -#[structopt(name = "Topgrade", setting = structopt::clap::AppSettings::ColoredHelp)] -/// Command line arguments +// Command line arguments +#[derive(Parser, Debug)] +#[clap(name = "Topgrade", version)] pub struct CommandLineArgs { /// Edit the configuration file - #[structopt(long = "edit-config")] + #[clap(long = "edit-config")] edit_config: bool, /// Show config reference - #[structopt(long = "config-reference")] + #[clap(long = "config-reference")] show_config_reference: bool, /// Run inside tmux - #[structopt(short = "t", long = "tmux")] + #[clap(short = 't', long = "tmux")] run_in_tmux: bool, /// Cleanup temporary or old files - #[structopt(short = "c", long = "cleanup")] + #[clap(short = 'c', long = "cleanup")] cleanup: bool, /// Print what would be done - #[structopt(short = "n", long = "dry-run")] + #[clap(short = 'n', long = "dry-run")] dry_run: bool, /// Do not ask to retry failed steps - #[structopt(long = "no-retry")] + #[clap(long = "no-retry")] no_retry: bool, /// Do not perform upgrades for the given steps - #[structopt(long = "disable", possible_values = &Step::VARIANTS)] + #[clap(long = "disable", arg_enum)] disable: Vec, /// Perform only the specified steps (experimental) - #[structopt(long = "only", possible_values = &Step::VARIANTS)] + #[clap(long = "only", arg_enum)] only: Vec, /// Output logs - #[structopt(short = "v", long = "verbose")] + #[clap(short = 'v', long = "verbose")] pub verbose: bool, /// Prompt for a key before exiting - #[structopt(short = "k", long = "keep")] + #[clap(short = 'k', long = "keep")] keep_at_end: bool, /// Say yes to package manager's prompt - #[structopt(short = "y", long = "yes")] + #[clap(short = 'y', long = "yes", arg_enum)] yes: Option>, /// Don't pull the predefined git repos - #[structopt(long = "disable-predefined-git-repos")] + #[clap(long = "disable-predefined-git-repos")] disable_predefined_git_repos: bool, /// Alternative configuration file - #[structopt(long = "config")] + #[clap(long = "config")] config: Option, /// A regular expression for restricting remote host execution - #[structopt(long = "remote-host-limit", parse(try_from_str))] + #[clap(long = "remote-host-limit")] remote_host_limit: Option, /// Show the reason for skipped steps - #[structopt(long = "show-skipped")] + #[clap(long = "show-skipped")] show_skipped: bool, } @@ -499,7 +501,7 @@ impl Config { /// The list of additional git repositories to pull. pub fn git_repos(&self) -> &Option> { - get_deprecated!(&self.config_file, git_repos, git, repos) + get_deprecated!(self.config_file, git_repos, git, repos) } /// Tell whether the specified step should run. @@ -569,11 +571,11 @@ impl Config { /// Extra Git arguments pub fn git_arguments(&self) -> &Option { - get_deprecated!(&self.config_file, git_arguments, git, arguments) + get_deprecated!(self.config_file, git_arguments, git, arguments) } /// Extra Tmux arguments - #[allow(dead_code)] + pub fn tmux_arguments(&self) -> &Option { &self.config_file.tmux_arguments } @@ -589,7 +591,6 @@ impl Config { } /// Whether to say yes to package managers - #[allow(dead_code)] pub fn yes(&self, step: Step) -> bool { if let Some(yes) = self.config_file.assume_yes { return yes; @@ -607,13 +608,11 @@ impl Config { } /// Bash-it branch - #[allow(dead_code)] pub fn bashit_branch(&self) -> &str { self.config_file.bashit_branch.as_deref().unwrap_or("stable") } /// Whether to accept all Windows updates - #[allow(dead_code)] pub fn accept_all_windows_updates(&self) -> bool { get_deprecated!( self.config_file, @@ -625,7 +624,6 @@ impl Config { } /// Whether to self rename the Topgrade executable during the run - #[allow(dead_code)] pub fn self_rename(&self) -> bool { self.config_file .windows @@ -635,7 +633,6 @@ impl Config { } /// Whether Brew cask should be greedy - #[allow(dead_code)] pub fn brew_cask_greedy(&self) -> bool { self.config_file .brew @@ -663,13 +660,11 @@ impl Config { } /// Whether to send a desktop notification at the beginning of every step - #[allow(dead_code)] pub fn notify_each_step(&self) -> bool { self.config_file.notify_each_step.unwrap_or(false) } /// Extra trizen arguments - #[allow(dead_code)] pub fn trizen_arguments(&self) -> &str { self.config_file .linux @@ -689,7 +684,6 @@ impl Config { } /// Show news on Arch Linux - #[allow(dead_code)] pub fn show_arch_news(&self) -> bool { self.config_file .linux @@ -699,7 +693,6 @@ impl Config { } /// Extra yay arguments - #[allow(dead_code)] pub fn arch_package_manager(&self) -> ArchPackageManager { self.config_file .linux @@ -709,7 +702,6 @@ impl Config { } /// Extra yay arguments - #[allow(dead_code)] pub fn yay_arguments(&self) -> &str { get_deprecated!(self.config_file, yay_arguments, linux, yay_arguments) .as_deref() @@ -717,7 +709,6 @@ impl Config { } /// Extra apt arguments - #[allow(dead_code)] pub fn apt_arguments(&self) -> Option<&str> { self.config_file .linux @@ -726,7 +717,6 @@ impl Config { } /// Extra dnf arguments - #[allow(dead_code)] pub fn dnf_arguments(&self) -> Option<&str> { self.config_file .linux @@ -761,7 +751,6 @@ impl Config { } /// Enable tlmgr on Linux - #[allow(dead_code)] pub fn enable_tlmgr_linux(&self) -> bool { self.config_file .linux @@ -771,7 +760,6 @@ impl Config { } /// Use distro-sync in Red Hat based distrbutions - #[allow(dead_code)] pub fn redhat_distro_sync(&self) -> bool { self.config_file .linux @@ -781,7 +769,6 @@ impl Config { } /// Use rpm-ostree in *when rpm-ostree is detected* (default: true) - #[allow(dead_code)] pub fn rpm_ostree(&self) -> bool { self.config_file .linux @@ -801,7 +788,7 @@ impl Config { pub fn use_predefined_git_repos(&self) -> bool { !self.opt.disable_predefined_git_repos - && get_deprecated!(&self.config_file, predefined_git_repos, git, pull_predefined).unwrap_or(true) + && get_deprecated!(self.config_file, predefined_git_repos, git, pull_predefined).unwrap_or(true) } pub fn verbose(&self) -> bool { diff --git a/src/main.rs b/src/main.rs index 65d9584f..a61cd2be 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,12 +5,11 @@ use std::io; use std::process::exit; use anyhow::{anyhow, Result}; +use clap::{crate_version, Parser}; use console::Key; use log::debug; use log::LevelFilter; use pretty_env_logger::formatted_timed_builder; -use structopt::clap::crate_version; -use structopt::StructOpt; use self::config::{CommandLineArgs, Config, Step}; use self::error::StepFailed; @@ -39,7 +38,7 @@ fn run() -> Result<()> { let base_dirs = directories::BaseDirs::new().ok_or_else(|| anyhow!("No base directories"))?; - let opt = CommandLineArgs::from_args(); + let opt = CommandLineArgs::parse(); let mut builder = formatted_timed_builder(); if opt.verbose {