diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index a3ab431b3..ed3c009c8 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -17,6 +17,16 @@ jobs: - name: cargo fmt run: cargo fmt -- --check + clippy: + runs-on: ubuntu-latest + steps: + - uses: hecrj/setup-rust-action@v1 + with: + rust-version: stable + - uses: actions/checkout@v2 + - name: cargo clippy + run: cargo clippy -- -D warnings + unit_tests: runs-on: ${{ matrix.os }} strategy: @@ -67,7 +77,7 @@ jobs: path: target/release/fnm.exe build_macos_release: - runs-on: macOS-latest + runs-on: macos-latest name: "Release build for macOS" steps: - uses: hecrj/setup-rust-action@v1 @@ -91,17 +101,23 @@ jobs: name: "Build static Linux binary" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Build static binary + - uses: hecrj/setup-rust-action@v1 + with: + rust-version: stable + targets: x86_64-unknown-linux-musl + - name: Install musl tools run: | - sudo chown -R 1000:1000 . - docker run --rm -v "$(pwd)":/home/rust/src ekidd/rust-musl-builder:stable \ - cargo build --target x86_64-unknown-linux-gnu --release - sudo chown -R $(whoami):$(whoami) . + sudo apt-get update + sudo apt-get install -y --no-install-recommends musl-tools + - uses: actions/checkout@v2 + - name: Build release binary + run: cargo build --release --target x86_64-unknown-linux-musl + - name: Strip binary from debug symbols + run: strip target/x86_64-unknown-linux-musl/release/fnm - uses: actions/upload-artifact@v2 with: name: fnm-linux - path: target/x86_64-unknown-linux-gnu/release/fnm + path: target/x86_64-unknown-linux-musl/release/fnm build_static_arm_binary: name: "Build ARM binary" diff --git a/src/alias.rs b/src/alias.rs index 0b2e9bdaa..14b1f6415 100644 --- a/src/alias.rs +++ b/src/alias.rs @@ -28,7 +28,7 @@ pub fn create_alias( pub fn list_aliases(config: &FnmConfig) -> std::io::Result> { let vec: Vec<_> = std::fs::read_dir(&config.aliases_dir())? - .filter_map(|item| item.ok()) + .filter_map(Result::ok) .filter_map(|x| TryInto::::try_into(x.path().as_path()).ok()) .collect(); Ok(vec) diff --git a/src/arch.rs b/src/arch.rs index ac0e56345..64f5f6775 100644 --- a/src/arch.rs +++ b/src/arch.rs @@ -18,7 +18,7 @@ pub fn get_safe_arch<'a>(arch: &'a Arch, version: &Version) -> &'a Arch { return match (platform_name(), platform_arch(), version) { ("darwin", "arm64", Version::Semver(v)) if v.major < 16 => &Arch::X64, - _ => &arch, + _ => arch, }; } @@ -83,7 +83,7 @@ impl ArchError { } impl std::fmt::Display for ArchError { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.details) } } diff --git a/src/archive/zip.rs b/src/archive/zip.rs index 502e8e768..efa0d1d47 100644 --- a/src/archive/zip.rs +++ b/src/archive/zip.rs @@ -33,7 +33,7 @@ impl Extract for Zip { for i in 0..archive.len() { let mut file = archive.by_index(i)?; - let outpath = path.join(file.sanitized_name()); + let outpath = path.join(file.mangled_name()); { let comment = file.comment(); diff --git a/src/choose_version_for_user_input.rs b/src/choose_version_for_user_input.rs index 39a2c2e33..f213fdcbf 100644 --- a/src/choose_version_for_user_input.rs +++ b/src/choose_version_for_user_input.rs @@ -50,7 +50,7 @@ pub fn choose_version_for_user_input<'a>( version: Version::Alias(alias_name), }) } else { - let current_version = requested_version.to_version(&all_versions, &config); + let current_version = requested_version.to_version(&all_versions, config); current_version.map(|version| { info!("Using Node {}", version.to_string().cyan()); let path = config diff --git a/src/commands/alias.rs b/src/commands/alias.rs index 506ef8839..8d8ed59a2 100644 --- a/src/commands/alias.rs +++ b/src/commands/alias.rs @@ -25,7 +25,7 @@ impl Command for Alias { version: self.to_version, })?; - create_alias(&config, &self.name, applicable_version.version()) + create_alias(config, &self.name, applicable_version.version()) .context(CantCreateSymlink)?; Ok(()) diff --git a/src/commands/current.rs b/src/commands/current.rs index 7d2b4a065..74cb7e1fe 100644 --- a/src/commands/current.rs +++ b/src/commands/current.rs @@ -10,7 +10,7 @@ impl Command for Current { type Error = Error; fn apply(self, config: &FnmConfig) -> Result<(), Self::Error> { - let version_string = match current_version(&config)? { + let version_string = match current_version(config)? { Some(ver) => ver.v_str(), None => "none".into(), }; diff --git a/src/commands/default.rs b/src/commands/default.rs index 603302d8f..a24d20837 100644 --- a/src/commands/default.rs +++ b/src/commands/default.rs @@ -11,6 +11,7 @@ pub struct Default { impl Command for Default { type Error = super::alias::Error; + fn apply(self, config: &FnmConfig) -> Result<(), Self::Error> { Alias { name: "default".into(), @@ -18,7 +19,8 @@ impl Command for Default { } .apply(config) } + fn handle_error(err: Self::Error, config: &FnmConfig) { - Alias::handle_error(err, config) + Alias::handle_error(err, config); } } diff --git a/src/commands/env.rs b/src/commands/env.rs index 5173646a9..a14b15df7 100644 --- a/src/commands/env.rs +++ b/src/commands/env.rs @@ -54,7 +54,7 @@ impl Command for Env { } let shell: Box = self.shell.or_else(&infer_shell).context(CantInferShell)?; - let multishell_path = make_symlink(&config); + let multishell_path = make_symlink(config); let binary_path = if cfg!(windows) { multishell_path.clone() } else { @@ -82,7 +82,7 @@ impl Command for Env { shell.set_env_var("FNM_ARCH", &config.arch.to_string()) ); if self.use_on_cd { - println!("{}", shell.use_on_cd(&config)); + println!("{}", shell.use_on_cd(config)); } Ok(()) } diff --git a/src/commands/exec.rs b/src/commands/exec.rs index 6f1aa08e3..b07a01b81 100644 --- a/src/commands/exec.rs +++ b/src/commands/exec.rs @@ -40,10 +40,10 @@ impl Cmd for Exec { let current_dir = std::env::current_dir().unwrap(); UserVersionReader::Path(current_dir) }) - .to_user_version() + .into_user_version() .context(CantInferVersion)?; - let applicable_version = choose_version_for_user_input(&version, &config) + let applicable_version = choose_version_for_user_input(&version, config) .context(ApplicableVersionError)? .context(VersionNotFound { version })?; diff --git a/src/commands/install.rs b/src/commands/install.rs index 2a670a46a..519c4a0d5 100644 --- a/src/commands/install.rs +++ b/src/commands/install.rs @@ -55,7 +55,7 @@ impl super::command::Command for Install { let version = match current_version.clone() { UserVersion::Full(Version::Semver(actual_version)) => Version::Semver(actual_version), - UserVersion::Full(v @ Version::Bypassed) | UserVersion::Full(v @ Version::Alias(_)) => { + UserVersion::Full(v @ (Version::Bypassed | Version::Alias(_))) => { ensure!(false, UninstallableVersion { version: v }); unreachable!(); } @@ -84,7 +84,7 @@ impl super::command::Command for Install { .collect(); current_version - .to_version(&available_versions, &config) + .to_version(&available_versions, config) .context(CantFindNodeVersion { requested_version: current_version, })? @@ -117,12 +117,12 @@ impl super::command::Command for Install { alias_name.cyan(), version.v_str().cyan() ); - create_alias(&config, &alias_name, &version).context(IoError)?; + create_alias(config, &alias_name, &version).context(IoError)?; } if !config.default_version_dir().exists() { debug!("Tagging {} as the default version", version.v_str().cyan()); - create_alias(&config, "default", &version).context(IoError)?; + create_alias(config, "default", &version).context(IoError)?; } Ok(()) diff --git a/src/commands/ls_local.rs b/src/commands/ls_local.rs index 673865fce..bdbb1d125 100644 --- a/src/commands/ls_local.rs +++ b/src/commands/ls_local.rs @@ -2,7 +2,7 @@ use crate::alias::{list_aliases, StoredAlias}; use crate::config::FnmConfig; use crate::current_version::current_version; use crate::version::Version; -use colored::*; +use colored::Colorize; use snafu::{ResultExt, Snafu}; use std::collections::HashMap; use structopt::StructOpt; @@ -19,8 +19,8 @@ impl super::command::Command for LsLocal { crate::installed_versions::list(base_dir).context(CantListLocallyInstalledVersion)?; versions.insert(0, Version::Bypassed); versions.sort(); - let aliases_hash = generate_aliases_hash(&config).context(CantReadAliases)?; - let curr_version = current_version(&config).ok().flatten(); + let aliases_hash = generate_aliases_hash(config).context(CantReadAliases)?; + let curr_version = current_version(config).ok().flatten(); for version in versions { let version_aliases = match aliases_hash.get(&version.v_str()) { @@ -28,7 +28,7 @@ impl super::command::Command for LsLocal { Some(versions) => { let version_string = versions .iter() - .map(|x| x.name()) + .map(StoredAlias::name) .collect::>() .join(", "); format!(" {}", version_string.dimmed()) @@ -48,7 +48,7 @@ impl super::command::Command for LsLocal { } fn generate_aliases_hash(config: &FnmConfig) -> std::io::Result>> { - let mut aliases = list_aliases(&config)?; + let mut aliases = list_aliases(config)?; let mut hashmap: HashMap> = HashMap::with_capacity(aliases.len()); for alias in aliases.drain(..) { if let Some(value) = hashmap.get_mut(alias.s_ver()) { diff --git a/src/commands/ls_remote.rs b/src/commands/ls_remote.rs index 2c4d9f360..0cad39296 100644 --- a/src/commands/ls_remote.rs +++ b/src/commands/ls_remote.rs @@ -10,9 +10,7 @@ impl super::command::Command for LsRemote { type Error = Error; fn apply(self, config: &FnmConfig) -> Result<(), Self::Error> { - let mut all_versions = - remote_node_index::list(&config.node_dist_mirror).context(HttpError)?; - all_versions.sort(); + let all_versions = remote_node_index::list(&config.node_dist_mirror).context(HttpError)?; for version in all_versions { print!("{}", version.version); diff --git a/src/commands/uninstall.rs b/src/commands/uninstall.rs index 9a5abb7f6..a31c86fe2 100644 --- a/src/commands/uninstall.rs +++ b/src/commands/uninstall.rs @@ -37,7 +37,7 @@ impl Command for Uninstall { let available_versions: Vec<&Version> = all_versions .iter() - .filter(|v| requested_version.matches(v, &config)) + .filter(|v| requested_version.matches(v, config)) .collect(); ensure!( @@ -51,12 +51,12 @@ impl Command for Uninstall { ); let version = requested_version - .to_version(&all_versions, &config) + .to_version(&all_versions, config) .context(CantFindVersion)?; - let matching_aliases = version.find_aliases(&config).context(IoError)?; + let matching_aliases = version.find_aliases(config).context(IoError)?; let root_path = version - .root_path(&config) + .root_path(config) .with_context(|| RootPathNotFound { version: version.clone(), })?; diff --git a/src/commands/use.rs b/src/commands/use.rs index 5ded73ad3..f8f2049a4 100644 --- a/src/commands/use.rs +++ b/src/commands/use.rs @@ -24,7 +24,7 @@ impl Command for Use { fn apply(self, config: &FnmConfig) -> Result<(), Self::Error> { let multishell_path = config.multishell_path().context(FnmEnvWasNotSourced)?; - warn_if_multishell_path_not_in_path_env_var(&multishell_path, &config); + warn_if_multishell_path_not_in_path_env_var(multishell_path, config); let all_versions = installed_versions::list(config.installations_dir()).context(VersionListingError)?; @@ -34,7 +34,7 @@ impl Command for Use { let current_dir = std::env::current_dir().unwrap(); UserVersionReader::Path(current_dir) }) - .to_user_version() + .into_user_version() .context(CantInferVersion)?; let version_path = if let UserVersion::Full(Version::Bypassed) = requested_version { @@ -50,23 +50,20 @@ impl Command for Use { return Ok(()); } } else { - let current_version = requested_version.to_version(&all_versions, &config); - match current_version { - Some(version) => { - outln!(config#Info, "Using Node {}", version.to_string().cyan()); - config - .installations_dir() - .join(version.to_string()) - .join("installation") - } - None => { - install_new_version(requested_version, config, self.install_if_missing)?; - return Ok(()); - } + let current_version = requested_version.to_version(&all_versions, config); + if let Some(version) = current_version { + outln!(config#Info, "Using Node {}", version.to_string().cyan()); + config + .installations_dir() + .join(version.to_string()) + .join("installation") + } else { + install_new_version(requested_version, config, self.install_if_missing)?; + return Ok(()); } }; - replace_symlink(&version_path, &multishell_path).context(SymlinkingCreationIssue)?; + replace_symlink(&version_path, multishell_path).context(SymlinkingCreationIssue)?; Ok(()) } @@ -86,7 +83,7 @@ fn install_new_version( Install { version: Some(requested_version.clone()), - ..Default::default() + ..Install::default() } .apply(config) .context(InstallError)?; @@ -97,7 +94,7 @@ fn install_new_version( } .apply(config)?; - return Ok(()); + Ok(()) } /// Tries to delete `from`, and then tries to symlink `from` to `to` anyway. @@ -115,11 +112,12 @@ fn replace_symlink(from: &std::path::Path, to: &std::path::Path) -> std::io::Res } fn should_install_interactively(requested_version: &UserVersion) -> bool { + use std::io::Write; + if !(atty::is(atty::Stream::Stdout) && atty::is(atty::Stream::Stdin)) { return false; } - use std::io::Write; let error_message = format!( "Can't find an installed Node version matching {}.", requested_version.to_string().italic() @@ -146,7 +144,7 @@ fn warn_if_multishell_path_not_in_path_env_var( multishell_path.to_path_buf() }; - for path in std::env::split_paths(&std::env::var("PATH").unwrap_or(String::new())) { + for path in std::env::split_paths(&std::env::var("PATH").unwrap_or_default()) { if bin_path == path { return; } diff --git a/src/config.rs b/src/config.rs index e680cc9b9..f23619eea 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,4 +1,4 @@ -use crate::arch; +use crate::arch::Arch; use crate::log_level::LogLevel; use crate::path_ext::PathExt; use dirs::home_dir; @@ -57,7 +57,7 @@ pub struct FnmConfig { global = true, hide_env_values = true )] - pub arch: arch::Arch, + pub arch: Arch, } impl Default for FnmConfig { @@ -67,7 +67,7 @@ impl Default for FnmConfig { base_dir: None, multishell_path: None, log_level: LogLevel::Info, - arch: Default::default(), + arch: Arch::default(), } } } @@ -112,10 +112,4 @@ impl FnmConfig { self.base_dir = base_dir; self } - - pub fn multishell_base_dir(&self) -> std::path::PathBuf { - std::env::temp_dir() - .join("fnm_multishell") - .ensure_exists_silently() - } } diff --git a/src/directory_portal.rs b/src/directory_portal.rs index 458a732aa..a55879547 100644 --- a/src/directory_portal.rs +++ b/src/directory_portal.rs @@ -1,4 +1,4 @@ -use log::*; +use log::debug; use std::path::Path; use tempfile::TempDir; @@ -19,7 +19,7 @@ impl> DirectoryPortal

{ pub fn new_in(parent_dir: impl AsRef, target: P) -> Self { let temp_dir = TempDir::new_in(parent_dir).expect("Can't generate a temp directory"); debug!("Created a temp directory in {:?}", temp_dir.path()); - Self { target, temp_dir } + Self { temp_dir, target } } pub fn teleport(self) -> std::io::Result

{ diff --git a/src/installed_versions.rs b/src/installed_versions.rs index cb2ca43b3..4d875c355 100644 --- a/src/installed_versions.rs +++ b/src/installed_versions.rs @@ -9,8 +9,7 @@ pub fn list>(installations_dir: P) -> Result, Error> if entry .file_name() .to_str() - .map(|s| s.starts_with(".")) - .unwrap_or(false) + .map_or(false, |s| s.starts_with('.')) { continue; } diff --git a/src/log_level.rs b/src/log_level.rs index ad27e0de2..8580deb37 100644 --- a/src/log_level.rs +++ b/src/log_level.rs @@ -8,10 +8,7 @@ pub enum LogLevel { impl LogLevel { pub fn is_writable(&self, logging: &Self) -> bool { use std::cmp::Ordering; - match self.cmp(logging) { - Ordering::Greater | Ordering::Equal => true, - _ => false, - } + matches!(self.cmp(logging), Ordering::Greater | Ordering::Equal) } pub fn writer_for(&self, logging: &Self) -> Box { @@ -30,12 +27,12 @@ impl LogLevel { } } -impl Into<&'static str> for LogLevel { - fn into(self) -> &'static str { - match self { - Self::Quiet => "quiet", - Self::Info => "info", - Self::Error => "error", +impl From for &'static str { + fn from(level: LogLevel) -> Self { + match level { + LogLevel::Quiet => "quiet", + LogLevel::Info => "info", + LogLevel::Error => "error", } } } diff --git a/src/main.rs b/src/main.rs index 78470bb4f..9af4badd5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,11 @@ +#![warn(rust_2018_idioms, clippy::all, clippy::pedantic)] +#![allow( + clippy::enum_variant_names, + clippy::large_enum_variant, + clippy::module_name_repetitions, + clippy::similar_names +)] + mod alias; mod arch; mod archive; diff --git a/src/remote_node_index.rs b/src/remote_node_index.rs index c60dfba7f..e4e083aec 100644 --- a/src/remote_node_index.rs +++ b/src/remote_node_index.rs @@ -15,11 +15,11 @@ mod lts_status { Yes(String), } - impl Into> for LtsStatus { - fn into(self) -> Option { - match self { - Self::Nope(_) => None, - Self::Yes(x) => Some(x), + impl From for Option { + fn from(status: LtsStatus) -> Self { + match status { + LtsStatus::Nope(_) => None, + LtsStatus::Yes(x) => Some(x), } } } @@ -60,7 +60,7 @@ mod lts_status { } } -#[derive(Deserialize, Debug, Eq, Ord)] +#[derive(Deserialize, Debug)] pub struct IndexedNodeVersion { pub version: Version, #[serde(with = "lts_status")] @@ -69,18 +69,6 @@ pub struct IndexedNodeVersion { pub files: Vec, } -impl PartialEq for IndexedNodeVersion { - fn eq(&self, other: &Self) -> bool { - self.version.eq(&other.version) - } -} - -impl PartialOrd for IndexedNodeVersion { - fn partial_cmp(&self, other: &Self) -> Option { - self.version.partial_cmp(&other.version) - } -} - /// Prints /// /// ```rust @@ -111,7 +99,7 @@ pub fn list(base_url: &Url) -> Result, ureq::Error> { ) })?; - value.sort(); + value.sort_by(|a, b| a.version.cmp(&b.version)); Ok(value) } diff --git a/src/shell/bash.rs b/src/shell/bash.rs index 427c6846a..9589e5ac0 100644 --- a/src/shell/bash.rs +++ b/src/shell/bash.rs @@ -1,16 +1,16 @@ use super::shell::Shell; use indoc::indoc; -use std::path::PathBuf; +use std::path::Path; #[derive(Debug)] pub struct Bash; impl Shell for Bash { - fn into_structopt_shell(&self) -> structopt::clap::Shell { + fn to_structopt_shell(&self) -> structopt::clap::Shell { structopt::clap::Shell::Bash } - fn path(&self, path: &PathBuf) -> String { + fn path(&self, path: &Path) -> String { format!("export PATH={:?}:$PATH", path.to_str().unwrap()) } diff --git a/src/shell/fish.rs b/src/shell/fish.rs index 7c5e41dd4..0d08af2e1 100644 --- a/src/shell/fish.rs +++ b/src/shell/fish.rs @@ -1,16 +1,16 @@ use super::shell::Shell; use indoc::indoc; -use std::path::PathBuf; +use std::path::Path; #[derive(Debug)] pub struct Fish; impl Shell for Fish { - fn into_structopt_shell(&self) -> structopt::clap::Shell { + fn to_structopt_shell(&self) -> structopt::clap::Shell { structopt::clap::Shell::Fish } - fn path(&self, path: &PathBuf) -> String { + fn path(&self, path: &Path) -> String { format!("set -gx PATH {:?} $PATH;", path.to_str().unwrap()) } diff --git a/src/shell/infer/unix.rs b/src/shell/infer/unix.rs index 5463d6a7e..323a03e7c 100644 --- a/src/shell/infer/unix.rs +++ b/src/shell/infer/unix.rs @@ -73,7 +73,7 @@ fn get_process_info(pid: u32) -> std::io::Result { .expect("Can't read the command from ps, should be the second item in the table"); Ok(ProcessInfo { - parent_pid: u32::from_str_radix(ppid, 10).ok(), + parent_pid: ppid.parse().ok(), command: command.into(), }) } diff --git a/src/shell/powershell.rs b/src/shell/powershell.rs index dfe44cb4f..9603e6fa4 100644 --- a/src/shell/powershell.rs +++ b/src/shell/powershell.rs @@ -1,11 +1,12 @@ use super::Shell; use indoc::indoc; +use std::path::Path; #[derive(Debug)] pub struct PowerShell; impl Shell for PowerShell { - fn path(&self, path: &std::path::PathBuf) -> String { + fn path(&self, path: &Path) -> String { let current_path = std::env::var_os("PATH").expect("Can't read PATH env var"); let mut split_paths: Vec<_> = std::env::split_paths(¤t_path).collect(); split_paths.insert(0, path.to_path_buf()); @@ -27,7 +28,7 @@ impl Shell for PowerShell { Set-FnmOnLoad "#).into() } - fn into_structopt_shell(&self) -> clap::Shell { + fn to_structopt_shell(&self) -> clap::Shell { clap::Shell::PowerShell } } diff --git a/src/shell/shell.rs b/src/shell/shell.rs index 7239e5f13..f1071ae74 100644 --- a/src/shell/shell.rs +++ b/src/shell/shell.rs @@ -1,11 +1,11 @@ use std::fmt::Debug; -use std::path::PathBuf; +use std::path::Path; pub trait Shell: Debug { - fn path(&self, path: &PathBuf) -> String; + fn path(&self, path: &Path) -> String; fn set_env_var(&self, name: &str, value: &str) -> String; fn use_on_cd(&self, config: &crate::config::FnmConfig) -> String; - fn into_structopt_shell(&self) -> structopt::clap::Shell; + fn to_structopt_shell(&self) -> structopt::clap::Shell; } #[cfg(windows)] @@ -29,8 +29,8 @@ impl std::str::FromStr for Box { } } -impl Into for Box { - fn into(self) -> structopt::clap::Shell { - self.into_structopt_shell() +impl From> for structopt::clap::Shell { + fn from(shell: Box) -> Self { + shell.to_structopt_shell() } } diff --git a/src/shell/windows_cmd/mod.rs b/src/shell/windows_cmd/mod.rs index 9377d5862..f1f6d4c44 100644 --- a/src/shell/windows_cmd/mod.rs +++ b/src/shell/windows_cmd/mod.rs @@ -1,15 +1,15 @@ use super::shell::Shell; -use std::path::PathBuf; +use std::path::Path; #[derive(Debug)] pub struct WindowsCmd; impl Shell for WindowsCmd { - fn into_structopt_shell(&self) -> structopt::clap::Shell { + fn to_structopt_shell(&self) -> structopt::clap::Shell { panic!("Shell completion is not supported for Windows Command Prompt. Maybe try using PowerShell for a better experience?"); } - fn path(&self, path: &PathBuf) -> String { + fn path(&self, path: &Path) -> String { let current_path = std::env::var_os("path").expect("Can't read PATH env var"); let mut split_paths: Vec<_> = std::env::split_paths(¤t_path).collect(); split_paths.insert(0, path.to_path_buf()); diff --git a/src/shell/zsh.rs b/src/shell/zsh.rs index c79a89a02..679be1f40 100644 --- a/src/shell/zsh.rs +++ b/src/shell/zsh.rs @@ -1,16 +1,16 @@ use super::shell::Shell; use indoc::indoc; -use std::path::PathBuf; +use std::path::Path; #[derive(Debug)] pub struct Zsh; impl Shell for Zsh { - fn into_structopt_shell(&self) -> structopt::clap::Shell { + fn to_structopt_shell(&self) -> structopt::clap::Shell { structopt::clap::Shell::Zsh } - fn path(&self, path: &PathBuf) -> String { + fn path(&self, path: &Path) -> String { format!("export PATH={:?}:$PATH", path.to_str().unwrap()) } diff --git a/src/user_version.rs b/src/user_version.rs index 5e0a220cd..1e08618da 100644 --- a/src/user_version.rs +++ b/src/user_version.rs @@ -34,17 +34,14 @@ impl UserVersion { match (self, version) { (Self::Full(a), b) if a == b => true, (Self::Full(user_version), maybe_alias) => { - match (user_version.alias_name(), maybe_alias.find_aliases(&config)) { + match (user_version.alias_name(), maybe_alias.find_aliases(config)) { (None, _) | (_, Err(_)) => false, - (Some(user_alias), Ok(aliases)) => aliases - .iter() - .find(|alias| alias.name() == user_alias) - .is_some(), + (Some(user_alias), Ok(aliases)) => { + aliases.iter().any(|alias| alias.name() == user_alias) + } } } - (_, Version::Bypassed) => false, - (_, Version::Lts(_)) => false, - (_, Version::Alias(_)) => false, + (_, Version::Bypassed | Version::Lts(_) | Version::Alias(_)) => false, (Self::OnlyMajor(major), Version::Semver(other)) => *major == other.major, (Self::MajorMinor(major, minor), Version::Semver(other)) => { *major == other.major && *minor == other.minor @@ -69,11 +66,7 @@ impl std::fmt::Display for UserVersion { } fn skip_first_v(str: &str) -> &str { - if str.starts_with('v') { - &str[1..] - } else { - str - } + str.strip_prefix('v').unwrap_or(str) } impl FromStr for UserVersion { @@ -96,12 +89,10 @@ impl FromStr for UserVersion { #[cfg(test)] impl PartialEq for UserVersion { fn eq(&self, other: &Self) -> bool { - use UserVersion::*; - match (self, other) { - (OnlyMajor(a), OnlyMajor(b)) if a == b => true, - (MajorMinor(a1, a2), MajorMinor(b1, b2)) if (a1, a2) == (b1, b2) => true, - (Full(v1), Full(v2)) if v1 == v2 => true, + (Self::OnlyMajor(a), Self::OnlyMajor(b)) if a == b => true, + (Self::MajorMinor(a1, a2), Self::MajorMinor(b1, b2)) if (a1, a2) == (b1, b2) => true, + (Self::Full(v1), Self::Full(v2)) if v1 == v2 => true, (_, _) => false, } } @@ -109,6 +100,8 @@ impl PartialEq for UserVersion { #[cfg(test)] mod tests { + use crate::config::FnmConfig; + use super::*; #[test] @@ -138,7 +131,7 @@ mod tests { expected.clone(), Version::parse("7.0.1").unwrap(), ]; - let result = UserVersion::OnlyMajor(6).to_version(&versions, &Default::default()); + let result = UserVersion::OnlyMajor(6).to_version(&versions, &FnmConfig::default()); assert_eq!(result, Some(&expected)); } @@ -152,7 +145,7 @@ mod tests { expected.clone(), Version::parse("7.0.1").unwrap(), ]; - let result = UserVersion::MajorMinor(6, 0).to_version(&versions, &Default::default()); + let result = UserVersion::MajorMinor(6, 0).to_version(&versions, &FnmConfig::default()); assert_eq!(result, Some(&expected)); } @@ -166,7 +159,8 @@ mod tests { Version::parse("6.0.1").unwrap(), Version::parse("7.0.1").unwrap(), ]; - let result = UserVersion::Full(expected.clone()).to_version(&versions, &Default::default()); + let result = + UserVersion::Full(expected.clone()).to_version(&versions, &FnmConfig::default()); assert_eq!(result, Some(&expected)); } diff --git a/src/user_version_reader.rs b/src/user_version_reader.rs index 7a1cc5366..78ab0ee36 100644 --- a/src/user_version_reader.rs +++ b/src/user_version_reader.rs @@ -10,7 +10,7 @@ pub enum UserVersionReader { } impl UserVersionReader { - pub fn to_user_version(self) -> Option { + pub fn into_user_version(self) -> Option { match self { Self::Direct(uv) => Some(uv), Self::Path(pathbuf) if pathbuf.is_file() => get_user_version_for_file(&pathbuf), @@ -23,8 +23,8 @@ impl FromStr for UserVersionReader { type Err = semver::Error; fn from_str(s: &str) -> Result { - let pathbuf = PathBuf::from_str(&s); - let user_version = UserVersion::from_str(&s); + let pathbuf = PathBuf::from_str(s); + let user_version = UserVersion::from_str(s); match (user_version, pathbuf) { (_, Ok(pathbuf)) if pathbuf.exists() => Ok(Self::Path(pathbuf)), (Ok(user_version), _) => Ok(Self::Direct(user_version)), @@ -47,7 +47,7 @@ mod tests { write!(file, "14").unwrap(); let pathbuf = file.path().to_path_buf(); - let user_version = UserVersionReader::Path(pathbuf).to_user_version(); + let user_version = UserVersionReader::Path(pathbuf).into_user_version(); assert_eq!(user_version, Some(UserVersion::OnlyMajor(14))); } @@ -58,13 +58,14 @@ mod tests { std::fs::write(node_version_path, "14").unwrap(); let pathbuf = directory.path().to_path_buf(); - let user_version = UserVersionReader::Path(pathbuf).to_user_version(); + let user_version = UserVersionReader::Path(pathbuf).into_user_version(); assert_eq!(user_version, Some(UserVersion::OnlyMajor(14))); } #[test] fn test_direct_to_version() { - let user_version = UserVersionReader::Direct(UserVersion::OnlyMajor(14)).to_user_version(); + let user_version = + UserVersionReader::Direct(UserVersion::OnlyMajor(14)).into_user_version(); assert_eq!(user_version, Some(UserVersion::OnlyMajor(14))); } diff --git a/src/version.rs b/src/version.rs index 4a1da232b..da86bb031 100644 --- a/src/version.rs +++ b/src/version.rs @@ -12,7 +12,7 @@ pub enum Version { } fn first_letter_is_number(s: &str) -> bool { - s.chars().next().map(|x| x.is_digit(10)).unwrap_or(false) + s.chars().next().map_or(false, |x| x.is_digit(10)) } impl Version { @@ -25,7 +25,7 @@ impl Version { Ok(Self::Lts(lts_type)) } else if first_letter_is_number(lowercased.trim_start_matches('v')) { let version_plain = lowercased.trim_start_matches('v'); - let sver = semver::Version::parse(&version_plain)?; + let sver = semver::Version::parse(version_plain)?; Ok(Self::Semver(sver)) } else { Ok(Self::Alias(lowercased)) @@ -34,8 +34,7 @@ impl Version { pub fn alias_name(&self) -> Option { match self { - l @ Self::Lts(_) => Some(l.v_str()), - l @ Self::Alias(_) => Some(l.v_str()), + l @ (Self::Lts(_) | Self::Alias(_)) => Some(l.v_str()), _ => None, } } @@ -44,7 +43,7 @@ impl Version { &self, config: &config::FnmConfig, ) -> std::io::Result> { - let aliases = alias::list_aliases(&config)? + let aliases = alias::list_aliases(config)? .drain(..) .filter(|alias| alias.s_ver() == self.v_str()) .collect(); @@ -58,7 +57,7 @@ impl Version { pub fn installation_path(&self, config: &config::FnmConfig) -> Option { match self { Self::Bypassed => None, - v @ Self::Lts(_) | v @ Self::Alias(_) => { + v @ (Self::Lts(_) | Self::Alias(_)) => { Some(config.aliases_dir().join(v.alias_name().unwrap())) } v @ Self::Semver(_) => Some( @@ -71,7 +70,7 @@ impl Version { } pub fn root_path(&self, config: &config::FnmConfig) -> Option { - match self.installation_path(&config) { + match self.installation_path(config) { None => None, Some(path) => { let mut canon_path = path.canonicalize().ok()?; diff --git a/src/version_files.rs b/src/version_files.rs index c5bf3084b..4d0bbea76 100644 --- a/src/version_files.rs +++ b/src/version_files.rs @@ -10,7 +10,7 @@ const PATH_PARTS: [&str; 2] = [".nvmrc", ".node-version"]; pub fn get_user_version_for_directory(path: impl AsRef) -> Option { let path = path.as_ref(); - for path_part in PATH_PARTS.iter() { + for path_part in &PATH_PARTS { let new_path = path.join(path_part); info!( "Looking for version file in {}. exists? {}", diff --git a/tests/shellcode/call.rs b/tests/shellcode/call.rs index abe5b1235..2f45b792a 100644 --- a/tests/shellcode/call.rs +++ b/tests/shellcode/call.rs @@ -4,16 +4,13 @@ use std::fmt::Write; #[derive(Debug)] pub(crate) struct Call { - binary: Box<&'static str>, + binary: &'static str, args: Vec<&'static str>, } impl Call { pub(crate) fn new(binary: &'static str, args: Vec<&'static str>) -> Self { - Self { - binary: Box::from(binary), - args, - } + Self { binary, args } } } diff --git a/tests/shellcode/line_separated_expressions.rs b/tests/shellcode/line_separated_expressions.rs index 6ef1cc154..b944cfdbf 100644 --- a/tests/shellcode/line_separated_expressions.rs +++ b/tests/shellcode/line_separated_expressions.rs @@ -38,7 +38,7 @@ impl, B: Expression> Expression { fn write_shell(&self, writer: &mut impl Write) -> std::fmt::Result { self.a.write_shell(writer)?; - write!(writer, "\n")?; + writeln!(writer)?; self.b.write_shell(writer) } } diff --git a/tests/shellcode/mod.rs b/tests/shellcode/mod.rs index d55540d4d..c6ab55ffe 100644 --- a/tests/shellcode/mod.rs +++ b/tests/shellcode/mod.rs @@ -81,7 +81,7 @@ macro_rules! test_shell { $( #[test] #[serial_test::serial] - #[allow(non_snake_case)] + #[allow(non_snake_case, clippy::redundant_closure_call)] fn $shell() { use super::*; #[allow(unused)]