Browse Source

Fix clippy & use musl target on Rust compiler for static compilation (#554)

remotes/origin/add-with-shims
Dominik Nakamura 3 years ago committed by GitHub
parent
commit
74c9b37895
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 32
      .github/workflows/rust.yml
  2. 2
      src/alias.rs
  3. 4
      src/arch.rs
  4. 2
      src/archive/zip.rs
  5. 2
      src/choose_version_for_user_input.rs
  6. 2
      src/commands/alias.rs
  7. 2
      src/commands/current.rs
  8. 4
      src/commands/default.rs
  9. 4
      src/commands/env.rs
  10. 4
      src/commands/exec.rs
  11. 8
      src/commands/install.rs
  12. 10
      src/commands/ls_local.rs
  13. 4
      src/commands/ls_remote.rs
  14. 8
      src/commands/uninstall.rs
  15. 38
      src/commands/use.rs
  16. 12
      src/config.rs
  17. 4
      src/directory_portal.rs
  18. 3
      src/installed_versions.rs
  19. 17
      src/log_level.rs
  20. 8
      src/main.rs
  21. 26
      src/remote_node_index.rs
  22. 6
      src/shell/bash.rs
  23. 6
      src/shell/fish.rs
  24. 2
      src/shell/infer/unix.rs
  25. 5
      src/shell/powershell.rs
  26. 12
      src/shell/shell.rs
  27. 6
      src/shell/windows_cmd/mod.rs
  28. 6
      src/shell/zsh.rs
  29. 36
      src/user_version.rs
  30. 13
      src/user_version_reader.rs
  31. 13
      src/version.rs
  32. 2
      src/version_files.rs
  33. 7
      tests/shellcode/call.rs
  34. 2
      tests/shellcode/line_separated_expressions.rs
  35. 2
      tests/shellcode/mod.rs

32
.github/workflows/rust.yml

@ -17,6 +17,16 @@ jobs: @@ -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: @@ -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: @@ -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"

2
src/alias.rs

@ -28,7 +28,7 @@ pub fn create_alias( @@ -28,7 +28,7 @@ pub fn create_alias(
pub fn list_aliases(config: &FnmConfig) -> std::io::Result<Vec<StoredAlias>> {
let vec: Vec<_> = std::fs::read_dir(&config.aliases_dir())?
.filter_map(|item| item.ok())
.filter_map(Result::ok)
.filter_map(|x| TryInto::<StoredAlias>::try_into(x.path().as_path()).ok())
.collect();
Ok(vec)

4
src/arch.rs

@ -18,7 +18,7 @@ pub fn get_safe_arch<'a>(arch: &'a Arch, version: &Version) -> &'a Arch { @@ -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 { @@ -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)
}
}

2
src/archive/zip.rs

@ -33,7 +33,7 @@ impl<R: Read> Extract for Zip<R> { @@ -33,7 +33,7 @@ impl<R: Read> Extract for Zip<R> {
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();

2
src/choose_version_for_user_input.rs

@ -50,7 +50,7 @@ pub fn choose_version_for_user_input<'a>( @@ -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

2
src/commands/alias.rs

@ -25,7 +25,7 @@ impl Command for Alias { @@ -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(())

2
src/commands/current.rs

@ -10,7 +10,7 @@ impl Command for Current { @@ -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(),
};

4
src/commands/default.rs

@ -11,6 +11,7 @@ pub struct Default { @@ -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 { @@ -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);
}
}

4
src/commands/env.rs

@ -54,7 +54,7 @@ impl Command for Env { @@ -54,7 +54,7 @@ impl Command for Env {
}
let shell: Box<dyn Shell> = 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 { @@ -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(())
}

4
src/commands/exec.rs

@ -40,10 +40,10 @@ impl Cmd for Exec { @@ -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 })?;

8
src/commands/install.rs

@ -55,7 +55,7 @@ impl super::command::Command for Install { @@ -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 { @@ -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 { @@ -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(())

10
src/commands/ls_local.rs

@ -2,7 +2,7 @@ use crate::alias::{list_aliases, StoredAlias}; @@ -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 { @@ -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 { @@ -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::<Vec<_>>()
.join(", ");
format!(" {}", version_string.dimmed())
@ -48,7 +48,7 @@ impl super::command::Command for LsLocal { @@ -48,7 +48,7 @@ impl super::command::Command for LsLocal {
}
fn generate_aliases_hash(config: &FnmConfig) -> std::io::Result<HashMap<String, Vec<StoredAlias>>> {
let mut aliases = list_aliases(&config)?;
let mut aliases = list_aliases(config)?;
let mut hashmap: HashMap<String, Vec<StoredAlias>> = HashMap::with_capacity(aliases.len());
for alias in aliases.drain(..) {
if let Some(value) = hashmap.get_mut(alias.s_ver()) {

4
src/commands/ls_remote.rs

@ -10,9 +10,7 @@ impl super::command::Command for LsRemote { @@ -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);

8
src/commands/uninstall.rs

@ -37,7 +37,7 @@ impl Command for Uninstall { @@ -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 { @@ -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(),
})?;

38
src/commands/use.rs

@ -24,7 +24,7 @@ impl Command for Use { @@ -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 { @@ -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 { @@ -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( @@ -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( @@ -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 @@ -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( @@ -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;
}

12
src/config.rs

@ -1,4 +1,4 @@ @@ -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 { @@ -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 { @@ -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 { @@ -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()
}
}

4
src/directory_portal.rs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
use log::*;
use log::debug;
use std::path::Path;
use tempfile::TempDir;
@ -19,7 +19,7 @@ impl<P: AsRef<Path>> DirectoryPortal<P> { @@ -19,7 +19,7 @@ impl<P: AsRef<Path>> DirectoryPortal<P> {
pub fn new_in(parent_dir: impl AsRef<Path>, 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<P> {

3
src/installed_versions.rs

@ -9,8 +9,7 @@ pub fn list<P: AsRef<Path>>(installations_dir: P) -> Result<Vec<Version>, Error> @@ -9,8 +9,7 @@ pub fn list<P: AsRef<Path>>(installations_dir: P) -> Result<Vec<Version>, Error>
if entry
.file_name()
.to_str()
.map(|s| s.starts_with("."))
.unwrap_or(false)
.map_or(false, |s| s.starts_with('.'))
{
continue;
}

17
src/log_level.rs

@ -8,10 +8,7 @@ pub enum LogLevel { @@ -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<dyn std::io::Write> {
@ -30,12 +27,12 @@ impl LogLevel { @@ -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<LogLevel> for &'static str {
fn from(level: LogLevel) -> Self {
match level {
LogLevel::Quiet => "quiet",
LogLevel::Info => "info",
LogLevel::Error => "error",
}
}
}

8
src/main.rs

@ -1,3 +1,11 @@ @@ -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;

26
src/remote_node_index.rs

@ -15,11 +15,11 @@ mod lts_status { @@ -15,11 +15,11 @@ mod lts_status {
Yes(String),
}
impl Into<Option<String>> for LtsStatus {
fn into(self) -> Option<String> {
match self {
Self::Nope(_) => None,
Self::Yes(x) => Some(x),
impl From<LtsStatus> for Option<String> {
fn from(status: LtsStatus) -> Self {
match status {
LtsStatus::Nope(_) => None,
LtsStatus::Yes(x) => Some(x),
}
}
}
@ -60,7 +60,7 @@ mod lts_status { @@ -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 { @@ -69,18 +69,6 @@ pub struct IndexedNodeVersion {
pub files: Vec<String>,
}
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<std::cmp::Ordering> {
self.version.partial_cmp(&other.version)
}
}
/// Prints
///
/// ```rust
@ -111,7 +99,7 @@ pub fn list(base_url: &Url) -> Result<Vec<IndexedNodeVersion>, ureq::Error> { @@ -111,7 +99,7 @@ pub fn list(base_url: &Url) -> Result<Vec<IndexedNodeVersion>, ureq::Error> {
)
})?;
value.sort();
value.sort_by(|a, b| a.version.cmp(&b.version));
Ok(value)
}

6
src/shell/bash.rs

@ -1,16 +1,16 @@ @@ -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())
}

6
src/shell/fish.rs

@ -1,16 +1,16 @@ @@ -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())
}

2
src/shell/infer/unix.rs

@ -73,7 +73,7 @@ fn get_process_info(pid: u32) -> std::io::Result<ProcessInfo> { @@ -73,7 +73,7 @@ fn get_process_info(pid: u32) -> std::io::Result<ProcessInfo> {
.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(),
})
}

5
src/shell/powershell.rs

@ -1,11 +1,12 @@ @@ -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(&current_path).collect();
split_paths.insert(0, path.to_path_buf());
@ -27,7 +28,7 @@ impl Shell for PowerShell { @@ -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
}
}

12
src/shell/shell.rs

@ -1,11 +1,11 @@ @@ -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<dyn Shell> { @@ -29,8 +29,8 @@ impl std::str::FromStr for Box<dyn Shell> {
}
}
impl Into<structopt::clap::Shell> for Box<dyn Shell> {
fn into(self) -> structopt::clap::Shell {
self.into_structopt_shell()
impl From<Box<dyn Shell>> for structopt::clap::Shell {
fn from(shell: Box<dyn Shell>) -> Self {
shell.to_structopt_shell()
}
}

6
src/shell/windows_cmd/mod.rs

@ -1,15 +1,15 @@ @@ -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(&current_path).collect();
split_paths.insert(0, path.to_path_buf());

6
src/shell/zsh.rs

@ -1,16 +1,16 @@ @@ -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())
}

36
src/user_version.rs

@ -34,17 +34,14 @@ impl UserVersion { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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));
}

13
src/user_version_reader.rs

@ -10,7 +10,7 @@ pub enum UserVersionReader { @@ -10,7 +10,7 @@ pub enum UserVersionReader {
}
impl UserVersionReader {
pub fn to_user_version(self) -> Option<UserVersion> {
pub fn into_user_version(self) -> Option<UserVersion> {
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 { @@ -23,8 +23,8 @@ impl FromStr for UserVersionReader {
type Err = semver::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
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 { @@ -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 { @@ -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)));
}

13
src/version.rs

@ -12,7 +12,7 @@ pub enum Version { @@ -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 { @@ -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 { @@ -34,8 +34,7 @@ impl Version {
pub fn alias_name(&self) -> Option<String> {
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 { @@ -44,7 +43,7 @@ impl Version {
&self,
config: &config::FnmConfig,
) -> std::io::Result<Vec<alias::StoredAlias>> {
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 { @@ -58,7 +57,7 @@ impl Version {
pub fn installation_path(&self, config: &config::FnmConfig) -> Option<std::path::PathBuf> {
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 { @@ -71,7 +70,7 @@ impl Version {
}
pub fn root_path(&self, config: &config::FnmConfig) -> Option<std::path::PathBuf> {
match self.installation_path(&config) {
match self.installation_path(config) {
None => None,
Some(path) => {
let mut canon_path = path.canonicalize().ok()?;

2
src/version_files.rs

@ -10,7 +10,7 @@ const PATH_PARTS: [&str; 2] = [".nvmrc", ".node-version"]; @@ -10,7 +10,7 @@ const PATH_PARTS: [&str; 2] = [".nvmrc", ".node-version"];
pub fn get_user_version_for_directory(path: impl AsRef<Path>) -> Option<UserVersion> {
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? {}",

7
tests/shellcode/call.rs

@ -4,16 +4,13 @@ use std::fmt::Write; @@ -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 }
}
}

2
tests/shellcode/line_separated_expressions.rs

@ -38,7 +38,7 @@ impl<S: Shell, A: Expression<S>, B: Expression<S>> Expression<S> @@ -38,7 +38,7 @@ impl<S: Shell, A: Expression<S>, B: Expression<S>> Expression<S>
{
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)
}
}

2
tests/shellcode/mod.rs

@ -81,7 +81,7 @@ macro_rules! test_shell { @@ -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)]

Loading…
Cancel
Save