From bf506841119f9a2b831e78476c4fd95d29f5e119 Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 10 Dec 2022 17:35:24 +0100 Subject: [PATCH 1/8] add `is-installed` command --- src/main.rs | 6 ++-- src/subcommand/is_installed.rs | 63 ++++++++++++++++++++++++++++++++++ src/subcommand/mod.rs | 3 +- 3 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 src/subcommand/is_installed.rs diff --git a/src/main.rs b/src/main.rs index 230e18b..4ba655c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,8 +9,8 @@ use anyhow::{bail, Result}; use clap::{Parser, ValueHint}; use crate::subcommand::{ - install::InstallCommand, list::ListCommand, parse_version::ParseVersionCommand, - switch::SwitchCommand, uninstall::UninstallCommand, Action, + install::InstallCommand, is_installed::IsInstalledCommand, list::ListCommand, + parse_version::ParseVersionCommand, switch::SwitchCommand, uninstall::UninstallCommand, Action, }; mod archives; @@ -21,6 +21,7 @@ mod subcommand; #[derive(Parser, Clone, Debug)] enum Subcommands { List(ListCommand), + IsInstalled(IsInstalledCommand), Install(InstallCommand), Uninstall(UninstallCommand), Use(SwitchCommand), @@ -143,6 +144,7 @@ fn main() -> Result<()> { match config.command { Subcommands::List(ref options) => ListCommand::run(&config, options), + Subcommands::IsInstalled(ref options) => IsInstalledCommand::run(&config, options), Subcommands::Install(ref options) => InstallCommand::run(&config, options), Subcommands::Uninstall(ref options) => UninstallCommand::run(&config, options), Subcommands::Use(ref options) => SwitchCommand::run(&config, options), diff --git a/src/subcommand/is_installed.rs b/src/subcommand/is_installed.rs new file mode 100644 index 0000000..fbb68f0 --- /dev/null +++ b/src/subcommand/is_installed.rs @@ -0,0 +1,63 @@ +use anyhow::Result; +use clap::Parser; +use node_semver::Range; + +use crate::{ + files, + node_version::{parse_range, InstalledNodeVersion, NodeVersion}, + subcommand::Action, + Config, +}; + +#[derive(Parser, Clone, Debug)] +#[command( + about = "Check if a version is installed", + alias = "isi", + alias = "installed" +)] +pub struct IsInstalledCommand { + /// A semver range. Will be matched against installed all installed versions. + #[arg(value_parser = parse_range)] + pub version: Option, + /// Which exit code to use when a version is not installed. + #[arg(short = 'e', default_value = "1")] + pub exit_code: i32, + /// Silence output. + #[arg(short = 'q')] + pub quiet: bool, +} + +impl Action for IsInstalledCommand { + fn run(config: &Config, options: &IsInstalledCommand) -> Result<()> { + let version_filter = options + .version + .clone() + .or_else(|| files::get_version_file().map(|version_file| version_file.range())); + + if version_filter.is_none() { + anyhow::bail!("You did not pass a version and we did not find any version files (package.json#engines, .nvmrc) in the current directory."); + } + let version_filter = version_filter.unwrap(); + + let installed_versions = InstalledNodeVersion::list(config); + for installed_version in installed_versions { + if !version_filter.satisfies(installed_version.version()) { + continue; + } + + if !options.quiet { + println!( + "✅ A version matching {version_filter} is installed ({})!", + installed_version.to_string() + ); + } + return Ok(()); + } + + if !options.quiet { + println!("❌ A version matching {version_filter} is not installed."); + } + + std::process::exit(options.exit_code) + } +} diff --git a/src/subcommand/mod.rs b/src/subcommand/mod.rs index 263aa7d..f449c7a 100644 --- a/src/subcommand/mod.rs +++ b/src/subcommand/mod.rs @@ -2,8 +2,9 @@ use anyhow::Result; use crate::Config; -pub mod install; pub mod list; +pub mod is_installed; +pub mod install; pub mod parse_version; pub mod switch; pub mod uninstall; From 9987333192b41870ebae98ae6764a12ae33818f0 Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 10 Dec 2022 17:36:51 +0100 Subject: [PATCH 2/8] rename `dir` flag to `install-dir` --- src/main.rs | 14 ++++++++++---- tests/utils.rs | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/main.rs b/src/main.rs index 4ba655c..3312b6a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -37,10 +37,16 @@ enum Subcommands { )] pub struct Config { /// Installation directory - #[clap(global(true), long, value_hint(ValueHint::DirPath), env("NVM_DIR"))] + #[arg( + id("install-dir"), + global(true), + long, + value_hint(ValueHint::DirPath), + env("NVM_DIR") + )] dir: Option, /// bin directory - #[clap( + #[arg( global(true), long, value_hint(ValueHint::DirPath), @@ -48,10 +54,10 @@ pub struct Config { )] shims_dir: Option, /// Accept any prompts needed for the command to complete - #[clap(global(true), short, long)] + #[arg(global(true), short, long)] force: bool, - #[clap(subcommand)] + #[command(subcommand)] command: Subcommands, } diff --git a/tests/utils.rs b/tests/utils.rs index 90ffb80..8c305d3 100644 --- a/tests/utils.rs +++ b/tests/utils.rs @@ -30,7 +30,7 @@ pub fn setup_integration_test() -> Result<(TempDir, Command)> { let temp_dir = integration_dir(); let mut cmd = Command::cargo_bin("nvm").expect("Could not create Command"); - cmd.args(["--dir", &temp_dir.to_string_lossy()]); + cmd.args(["--install-dir", &temp_dir.to_string_lossy()]); Ok((temp_dir, cmd)) } From 6bbcd06c214ff0f23466be86fc8ff82a3a0e8fb1 Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 10 Dec 2022 19:36:43 +0100 Subject: [PATCH 3/8] add missed long variants of isi option --- src/subcommand/is_installed.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/subcommand/is_installed.rs b/src/subcommand/is_installed.rs index fbb68f0..a6d6091 100644 --- a/src/subcommand/is_installed.rs +++ b/src/subcommand/is_installed.rs @@ -20,10 +20,10 @@ pub struct IsInstalledCommand { #[arg(value_parser = parse_range)] pub version: Option, /// Which exit code to use when a version is not installed. - #[arg(short = 'e', default_value = "1")] + #[arg(long, short = 'e', default_value = "1")] pub exit_code: i32, /// Silence output. - #[arg(short = 'q')] + #[arg(long, short = 'q')] pub quiet: bool, } From d64bdda36665ec4b1ed97cd468dbdddf3083190f Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 10 Dec 2022 19:55:10 +0100 Subject: [PATCH 4/8] automatically enable corepack in newly installed versions --- src/main.rs | 1 + src/node_version.rs | 29 ++++++++++++----------------- src/subcommand/install.rs | 26 ++++++++++++++++++-------- src/utils.rs | 7 +++++++ 4 files changed, 38 insertions(+), 25 deletions(-) create mode 100644 src/utils.rs diff --git a/src/main.rs b/src/main.rs index 3312b6a..787b815 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,6 +17,7 @@ mod archives; mod files; mod node_version; mod subcommand; +mod utils; #[derive(Parser, Clone, Debug)] enum Subcommands { diff --git a/src/node_version.rs b/src/node_version.rs index 260f334..18c46b2 100644 --- a/src/node_version.rs +++ b/src/node_version.rs @@ -11,7 +11,7 @@ use node_semver::{Range, Version}; use reqwest::Url; use serde::Deserialize; -use crate::Config; +use crate::{utils, Config}; pub trait NodeVersion { fn version(&self) -> &Version; @@ -95,8 +95,12 @@ impl OnlineNodeVersion { serde_json::from_str(&body).context("Failed to parse versions list from nodejs.org") } - pub fn get_download_url(&self) -> Result { - let file_name = self.get_file(); + pub fn install_path(&self, config: &Config) -> PathBuf { + config.get_versions_dir().join(self.to_string()) + } + + pub fn download_url(&self) -> Result { + let file_name = self.file(); let url = format!("https://nodejs.org/dist/v{}/{}", self.version, file_name); @@ -104,7 +108,7 @@ impl OnlineNodeVersion { } #[cfg(target_os = "windows")] - fn get_file(&self) -> String { + fn file(&self) -> String { format!( "node-v{version}-win-{arch}.zip", version = self.version(), @@ -117,7 +121,7 @@ impl OnlineNodeVersion { } #[cfg(target_os = "macos")] - fn get_file(&self) -> String { + fn file(&self) -> String { format!( "node-v{version}-darwin-x64.tar.gz", version = self.version() @@ -125,7 +129,7 @@ impl OnlineNodeVersion { } #[cfg(target_os = "linux")] - fn get_file(&self) -> String { + fn file(&self) -> String { format!("node-v{version}-linux-x64.tar.gz", version = self.version()) } } @@ -174,15 +178,6 @@ impl InstalledNodeVersion { .contains(&self.version().to_string()) } - #[allow(dead_code)] - fn exec_ext() -> &'static str { - if cfg!(windows) { - ".cmd" - } else { - "" - } - } - // Functions pub fn uninstall(self, config: &Config) -> Result<()> { @@ -199,8 +194,8 @@ impl InstalledNodeVersion { read_link(config.get_shims_dir()).expect("Could not read installation dir"); let mut required_files = vec![version_dir; 2]; - required_files[0].set_file_name(format!("node{}", Self::exec_ext())); - required_files[1].set_file_name(format!("npm{}", Self::exec_ext())); + required_files[0].set_file_name(format!("node{}", utils::exec_ext())); + required_files[1].set_file_name(format!("npm{}", utils::exec_ext())); if let Some(missing_file) = required_files.iter().find(|file| !file.exists()) { anyhow::bail!( diff --git a/src/subcommand/install.rs b/src/subcommand/install.rs index 0e68c3a..ad2d893 100644 --- a/src/subcommand/install.rs +++ b/src/subcommand/install.rs @@ -10,7 +10,7 @@ use crate::{ filter_version_req, parse_range, InstalledNodeVersion, NodeVersion, OnlineNodeVersion, }, subcommand::{switch::SwitchCommand, Action}, - Config, + utils, Config, }; #[derive(Parser, Clone, Debug)] @@ -22,6 +22,9 @@ pub struct InstallCommand { /// Switch to the new version after installing it #[arg(long, short, default_value("false"))] pub switch: bool, + /// Enable corepack after installing the new version + #[arg(long, default_value("true"), hide(true), env("NVM_ENABLE_COREPACK"))] + pub enable_corepack: bool, } impl Action for InstallCommand { @@ -54,12 +57,8 @@ impl Action for InstallCommand { return Ok(()); } - download_and_extract_to( - version_to_install.borrow(), - &config - .get_versions_dir() - .join(version_to_install.to_string()), - )?; + let install_path = version_to_install.install_path(config); + download_and_extract_to(version_to_install.borrow(), &install_path)?; if config.force || (options.switch @@ -76,12 +75,23 @@ impl Action for InstallCommand { )?; } + if options.enable_corepack { + if let Err(e) = std::process::Command::new( + install_path.join(format!("corepack{}", utils::exec_ext())), + ) + .arg("enable") + .output() + { + println!("⚠️ Failed to automatically enable corepack!\n{e}",) + } + } + Ok(()) } } fn download_and_extract_to(version: &OnlineNodeVersion, path: &Path) -> Result<()> { - let url = version.get_download_url().unwrap(); + let url = version.download_url().unwrap(); println!("Downloading from {url}..."); let response = reqwest::blocking::get(url) diff --git a/src/utils.rs b/src/utils.rs new file mode 100644 index 0000000..3ffa1b8 --- /dev/null +++ b/src/utils.rs @@ -0,0 +1,7 @@ +pub fn exec_ext() -> &'static str { + if cfg!(windows) { + ".cmd" + } else { + "" + } +} From 3cec1a5af12ded189c3e0a4f1760b95f2eedfa08 Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 10 Dec 2022 19:55:27 +0100 Subject: [PATCH 5/8] use new rust actions --- .github/workflows/ci.yml | 36 +++++------------------------------- 1 file changed, 5 insertions(+), 31 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7a545e5..3627992 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,23 +30,11 @@ jobs: with: repo-token: ${{ secrets.CUSTOM_GITHUB_TOKEN }} - - uses: actions-rs/toolchain@v1 + - uses: dtolnay/rust-toolchain@master with: - profile: minimal toolchain: nightly - default: true - - uses: actions/cache@v3 - with: - path: | - ~/.cargo/bin - ~/.cargo/registry/index - ~/.cargo/registry/cache - ~/.cargo/git/db - ./target - key: ${{ runner.os }}-cargo-build-${{ hashFiles('**/Cargo.lock') }} - restore-keys: | - ${{ runner.os }}-cargo-build- + - uses: Swatinem/rust-cache@v2 - run: task build:release @@ -72,23 +60,11 @@ jobs: with: repo-token: ${{ secrets.CUSTOM_GITHUB_TOKEN }} - - uses: actions-rs/toolchain@v1 + - uses: dtolnay/rust-toolchain@master with: - profile: minimal toolchain: nightly - default: true - - uses: actions/cache@v3 - with: - path: | - ~/.cargo/bin - ~/.cargo/registry/index - ~/.cargo/registry/cache - ~/.cargo/git/db - ./target - key: ${{ runner.os }}-cargo-test-${{ hashFiles('**/Cargo.lock') }} - restore-keys: | - ${{ runner.os }}-cargo-test- + - uses: Swatinem/rust-cache@v2 - run: task test @@ -102,11 +78,9 @@ jobs: with: repo-token: ${{ secrets.CUSTOM_GITHUB_TOKEN }} - - uses: actions-rs/toolchain@v1 + - uses: dtolnay/rust-toolchain@master with: - profile: minimal toolchain: nightly - override: true components: rustfmt, clippy - run: task format -- --check From 47adaab4b8b44a711a5896c8d768f836ce406213 Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 10 Dec 2022 19:59:03 +0100 Subject: [PATCH 6/8] rust fmt --all --- src/subcommand/mod.rs | 4 ++-- src/utils.rs | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/subcommand/mod.rs b/src/subcommand/mod.rs index f449c7a..171f713 100644 --- a/src/subcommand/mod.rs +++ b/src/subcommand/mod.rs @@ -2,9 +2,9 @@ use anyhow::Result; use crate::Config; -pub mod list; -pub mod is_installed; pub mod install; +pub mod is_installed; +pub mod list; pub mod parse_version; pub mod switch; pub mod uninstall; diff --git a/src/utils.rs b/src/utils.rs index 3ffa1b8..8fc43f4 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,7 +1,7 @@ -pub fn exec_ext() -> &'static str { - if cfg!(windows) { - ".cmd" - } else { - "" - } -} +pub fn exec_ext() -> &'static str { + if cfg!(windows) { + ".cmd" + } else { + "" + } +} From 84be33e4c1f41dbd69c48ab6c5c3021f4a422e01 Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 10 Dec 2022 20:32:40 +0100 Subject: [PATCH 7/8] replace reqwest with ureq --- Cargo.lock | 609 +++++--------------------------------- Cargo.toml | 2 +- Taskfile.yml | 2 + src/archives.rs | 5 +- src/node_version.rs | 15 +- src/subcommand/install.rs | 20 +- 6 files changed, 109 insertions(+), 544 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f400abc..f65b3be 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -135,12 +135,6 @@ version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" -[[package]] -name = "bytes" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" - [[package]] name = "bzip2" version = "0.4.3" @@ -177,6 +171,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chunked_transfer" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fff857943da45f546682664a79488be82e69e43c1a7a2307679ab9afb3a66d2e" + [[package]] name = "cipher" version = "0.3.0" @@ -244,22 +244,6 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" -[[package]] -name = "core-foundation" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a89e2ae426ea83155dccf10c0fa6b1463ef6d5fcb44cee0b224a408fa640a62" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b" - [[package]] name = "cpufeatures" version = "0.2.2" @@ -364,15 +348,6 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" -[[package]] -name = "encoding_rs" -version = "0.8.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80df024fbc5ac80f87dfef0d9f5209a252f2a497f7f42944cff24d8253cac065" -dependencies = [ - "cfg-if", -] - [[package]] name = "errno" version = "0.2.8" @@ -431,21 +406,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - [[package]] name = "form_urlencoded" version = "1.0.1" @@ -456,55 +416,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "futures-channel" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5da6ba8c3bb3c165d3c7319fc1cc8304facf1fb8db99c5de877183c08a273888" -dependencies = [ - "futures-core", -] - -[[package]] -name = "futures-core" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d1c26957f23603395cd326b0ffe64124b818f4449552f960d815cfba83a53d" - -[[package]] -name = "futures-io" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377" - -[[package]] -name = "futures-sink" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36ea153c13024fe480590b3e3d4cad89a0cfacecc24577b68f86c6ced9c2bc11" - -[[package]] -name = "futures-task" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d3d00f4eddb73e498a54394f228cd55853bdf059259e8e7bc6e69d408892e99" - -[[package]] -name = "futures-util" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36568465210a3a6ee45e1f165136d68671471a501e632e9a98d96872222b5481" -dependencies = [ - "autocfg", - "futures-core", - "futures-io", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - [[package]] name = "generic-array" version = "0.14.5" @@ -550,46 +461,12 @@ dependencies = [ "walkdir", ] -[[package]] -name = "h2" -version = "0.3.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c9de88456263e249e241fcd211d3954e2c9b0ef7ccfc235a444eb367cae3689" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hashbrown" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" - [[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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - [[package]] name = "hermit-abi" version = "0.2.6" @@ -608,77 +485,6 @@ dependencies = [ "digest", ] -[[package]] -name = "http" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1323096b05d41827dadeaee54c9981958c0f94e670bc94ed80037d1a7b8b186b" -dependencies = [ - "bytes", - "fnv", - "itoa 0.4.8", -] - -[[package]] -name = "http-body" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "399c583b2979440c60be0821a6199eca73bc3c8dcd9d070d75ac726e2c6186e5" -dependencies = [ - "bytes", - "http", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c" - -[[package]] -name = "httpdate" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6456b8a6c8f33fee7d958fcd1b60d55b11940a79e63ae87013e6d22e26034440" - -[[package]] -name = "hyper" -version = "0.14.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42dc3c131584288d375f2d07f822b0cb012d8c6fb899a5b9fdb3cb7eb9b6004f" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "httparse", - "httpdate", - "itoa 1.0.1", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", - "want", -] - -[[package]] -name = "hyper-tls" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" -dependencies = [ - "bytes", - "hyper", - "native-tls", - "tokio", - "tokio-native-tls", -] - [[package]] name = "idna" version = "0.2.3" @@ -708,16 +514,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "indexmap" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" -dependencies = [ - "autocfg", - "hashbrown", -] - [[package]] name = "io-lifetimes" version = "1.0.3" @@ -728,19 +524,13 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "ipnet" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f2d64f2edebec4ce84ad108148e67e1064789bee435edc5b60ad398714a3a9" - [[package]] name = "is-terminal" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "927609f78c2913a6f6ac3c27a4fe87f43e2a35367c0c4b0f8265e8f49a104330" dependencies = [ - "hermit-abi 0.2.6", + "hermit-abi", "io-lifetimes", "rustix", "windows-sys", @@ -755,12 +545,6 @@ dependencies = [ "either", ] -[[package]] -name = "itoa" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" - [[package]] name = "itoa" version = "1.0.1" @@ -847,12 +631,6 @@ dependencies = [ "syn", ] -[[package]] -name = "mime" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" - [[package]] name = "minimal-lexical" version = "0.2.1" @@ -868,46 +646,6 @@ dependencies = [ "adler", ] -[[package]] -name = "mio" -version = "0.7.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c2bdb6314ec10835cd3293dd268473a835c02b7b352e788be788b3c6ca6bb16" -dependencies = [ - "libc", - "log", - "miow", - "ntapi", - "winapi", -] - -[[package]] -name = "miow" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" -dependencies = [ - "winapi", -] - -[[package]] -name = "native-tls" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" -dependencies = [ - "lazy_static", - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - [[package]] name = "node-semver" version = "2.1.0" @@ -937,15 +675,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" -[[package]] -name = "ntapi" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" -dependencies = [ - "winapi", -] - [[package]] name = "num-traits" version = "0.2.14" @@ -955,16 +684,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "num_cpus" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" -dependencies = [ - "hermit-abi 0.1.19", - "libc", -] - [[package]] name = "num_threads" version = "0.1.6" @@ -988,10 +707,10 @@ dependencies = [ "itertools", "node-semver", "predicates", - "reqwest", "serde", "serde_json", "tar", + "ureq", "zip", ] @@ -1007,39 +726,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" -[[package]] -name = "openssl" -version = "0.10.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d9facdb76fec0b73c406f125d44d86fdad818d66fef0531eec9233ca425ff4a" -dependencies = [ - "bitflags", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-sys", -] - -[[package]] -name = "openssl-probe" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a" - -[[package]] -name = "openssl-sys" -version = "0.9.67" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69df2d8dfc6ce3aaf44b40dec6f487d5a886516cf6879c49e98e0710f310a058" -dependencies = [ - "autocfg", - "cc", - "libc", - "pkg-config", - "vcpkg", -] - [[package]] name = "os_str_bytes" version = "6.1.0" @@ -1075,18 +761,6 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" -[[package]] -name = "pin-project-lite" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - [[package]] name = "pkg-config" version = "0.3.20" @@ -1263,40 +937,18 @@ dependencies = [ ] [[package]] -name = "reqwest" -version = "0.11.13" +name = "ring" +version = "0.16.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68cc60575865c7831548863cc02356512e3f1dc2f3f82cb837d7fc4cc8f3c97c" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" dependencies = [ - "base64", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-tls", - "ipnet", - "js-sys", - "log", - "mime", - "native-tls", + "cc", + "libc", "once_cell", - "percent-encoding", - "pin-project-lite", - "serde", - "serde_json", - "serde_urlencoded", - "tokio", - "tokio-native-tls", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", + "spin", + "untrusted", "web-sys", - "winreg", + "winapi", ] [[package]] @@ -1313,6 +965,18 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "rustls" +version = "0.20.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "539a2bfe908f471bfa933876bd1eb6a19cf2176d375f82ef7f99530a40e48c2c" +dependencies = [ + "log", + "ring", + "sct", + "webpki", +] + [[package]] name = "ryu" version = "1.0.5" @@ -1329,36 +993,13 @@ dependencies = [ ] [[package]] -name = "schannel" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" -dependencies = [ - "lazy_static", - "winapi", -] - -[[package]] -name = "security-framework" -version = "2.4.2" +name = "sct" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525bc1abfda2e1998d152c45cf13e696f76d0a4972310b22fac1658b05df7c87" +checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" dependencies = [ - "bitflags", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9dd14d83160b528b7bfd66439110573efcfbe281b17fc2ca9f39f550d619c7e" -dependencies = [ - "core-foundation-sys", - "libc", + "ring", + "untrusted", ] [[package]] @@ -1387,19 +1028,7 @@ version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" dependencies = [ - "itoa 1.0.1", - "ryu", - "serde", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa 1.0.1", + "itoa", "ryu", "serde", ] @@ -1427,20 +1056,10 @@ dependencies = [ ] [[package]] -name = "slab" -version = "0.4.4" +name = "spin" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590" - -[[package]] -name = "socket2" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dc90fe6c7be1a323296982db1836d1ea9e47b6839496dde9a541bc496df3516" -dependencies = [ - "libc", - "winapi", -] +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] name = "strsim" @@ -1550,7 +1169,7 @@ version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82501a4c1c0330d640a6e176a3d6a204f5ec5237aca029029d21864a902e27b0" dependencies = [ - "itoa 1.0.1", + "itoa", "libc", "num_threads", "time-macros", @@ -1577,77 +1196,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" -[[package]] -name = "tokio" -version = "1.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c27a64b625de6d309e8c57716ba93021dccf1b3b5c97edd6d3dd2d2135afc0a" -dependencies = [ - "bytes", - "libc", - "memchr", - "mio", - "num_cpus", - "pin-project-lite", - "winapi", -] - -[[package]] -name = "tokio-native-tls" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" -dependencies = [ - "native-tls", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d3725d3efa29485e87311c5b699de63cde14b00ed4d256b8318aa30ca452cd" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "log", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tower-service" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" - -[[package]] -name = "tracing" -version = "0.1.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105" -dependencies = [ - "cfg-if", - "pin-project-lite", - "tracing-core", -] - -[[package]] -name = "tracing-core" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f4ed65637b8390770814083d20756f87bfa2c21bf2f110babdc5438351746e4" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "try-lock" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" - [[package]] name = "typenum" version = "1.15.0" @@ -1681,6 +1229,31 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "ureq" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97acb4c28a254fd7a4aeec976c46a7fa404eac4d7c134b30c75144846d7cb8f" +dependencies = [ + "base64", + "chunked_transfer", + "flate2", + "log", + "once_cell", + "rustls", + "serde", + "serde_json", + "url", + "webpki", + "webpki-roots", +] + [[package]] name = "url" version = "2.2.2" @@ -1693,12 +1266,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - [[package]] name = "version_check" version = "0.9.3" @@ -1725,16 +1292,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "want" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" -dependencies = [ - "log", - "try-lock", -] - [[package]] name = "wasi" version = "0.10.2+wasi-snapshot-preview1" @@ -1766,18 +1323,6 @@ dependencies = [ "wasm-bindgen-shared", ] -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8d7523cb1f2a4c96c1317ca690031b714a51cc14e05f712446691f413f5d39" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - [[package]] name = "wasm-bindgen-macro" version = "0.2.78" @@ -1817,6 +1362,25 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "webpki-roots" +version = "0.22.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" +dependencies = [ + "webpki", +] + [[package]] name = "winapi" version = "0.3.9" @@ -1905,15 +1469,6 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" -[[package]] -name = "winreg" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" -dependencies = [ - "winapi", -] - [[package]] name = "xattr" version = "0.2.2" diff --git a/Cargo.toml b/Cargo.toml index 94448b7..b6fb1a5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,9 +34,9 @@ dialoguer = "0.10.2" dirs = "4.0.0" itertools = "0.10.5" node-semver = "2.1.0" -reqwest = { version = "0.11.13", features = ["blocking"] } serde = { version = "1.0.149", features = ["derive"] } serde_json = "1.0.89" +ureq = { version = "2.5.0", features = ["json"] } [target.'cfg(unix)'.dependencies] flate2 = "1.0.25" diff --git a/Taskfile.yml b/Taskfile.yml index b2468b0..9e52d9e 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -5,10 +5,12 @@ tasks: desc: Lint code cmds: - cargo clippy {{.CLI_ARGS}} + - cargo fmt --check --all lint:fix: desc: Lint code and fix problems with autofixes cmds: - cargo clippy --fix --allow-staged --allow-dirty + - task: format format: desc: Format code diff --git a/src/archives.rs b/src/archives.rs index 1fae724..76bcd72 100644 --- a/src/archives.rs +++ b/src/archives.rs @@ -11,15 +11,14 @@ use std::{fs::create_dir_all, io::Cursor, path::Path}; use anyhow::Result; #[cfg(unix)] use flate2::read::GzDecoder; -use reqwest::blocking::Response; #[cfg(unix)] use tar::{Archive, Unpacked}; #[cfg(target_os = "windows")] use zip::ZipArchive; #[cfg(target_os = "windows")] -pub fn extract_archive(bytes: Response, path: &Path) -> Result<()> { - let reader = Cursor::new(bytes.bytes().unwrap()); +pub fn extract_archive(bytes: Vec, path: &Path) -> Result<()> { + let reader = Cursor::new(bytes); let mut archive = ZipArchive::new(reader).unwrap(); println!("Extracting..."); diff --git a/src/node_version.rs b/src/node_version.rs index 18c46b2..98a1e21 100644 --- a/src/node_version.rs +++ b/src/node_version.rs @@ -8,7 +8,6 @@ use std::{ use anyhow::{Context, Result}; use node_semver::{Range, Version}; -use reqwest::Url; use serde::Deserialize; use crate::{utils, Config}; @@ -88,23 +87,21 @@ pub struct OnlineNodeVersion { impl OnlineNodeVersion { pub fn fetch_all() -> Result> { - let response = reqwest::blocking::get("https://nodejs.org/dist/index.json")?; + let response = ureq::get("https://nodejs.org/dist/index.json").call()?; - let body = response.text().unwrap(); - - serde_json::from_str(&body).context("Failed to parse versions list from nodejs.org") + response + .into_json() + .context("Failed to parse versions list from nodejs.org") } pub fn install_path(&self, config: &Config) -> PathBuf { config.get_versions_dir().join(self.to_string()) } - pub fn download_url(&self) -> Result { + pub fn download_url(&self) -> String { let file_name = self.file(); - let url = format!("https://nodejs.org/dist/v{}/{}", self.version, file_name); - - Url::parse(&url).context(format!("Could not create a valid download url. [{url}]")) + format!("https://nodejs.org/dist/v{}/{}", self.version, file_name) } #[cfg(target_os = "windows")] diff --git a/src/subcommand/install.rs b/src/subcommand/install.rs index ad2d893..6597a77 100644 --- a/src/subcommand/install.rs +++ b/src/subcommand/install.rs @@ -1,8 +1,9 @@ -use std::{borrow::Borrow, path::Path}; +use std::{borrow::Borrow, path::Path, time::Duration}; use anyhow::{Context, Result}; use clap::Parser; use node_semver::Range; +use ureq; use crate::{ archives, files, @@ -91,11 +92,22 @@ impl Action for InstallCommand { } fn download_and_extract_to(version: &OnlineNodeVersion, path: &Path) -> Result<()> { - let url = version.download_url().unwrap(); + let url = version.download_url(); + let agent = ureq::AgentBuilder::new() + .timeout_connect(Duration::from_secs(30)) + .timeout_read(Duration::from_secs(120)) + .timeout_write(Duration::from_secs(120)) + .build(); println!("Downloading from {url}..."); - let response = reqwest::blocking::get(url) + let response = agent + .get(&url) + .call() .context(format!("Failed to download version: {}", version.version()))?; - archives::extract_archive(response, path) + let length: usize = response.header("Content-Length").unwrap().parse()?; + let mut bytes: Vec = Vec::with_capacity(length); + response.into_reader().read_to_end(&mut bytes)?; + + archives::extract_archive(bytes, path) } From 20d5b4ca64912ce8bb0a932997e47c89d552f6f0 Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 10 Dec 2022 20:38:52 +0100 Subject: [PATCH 8/8] try to fix unix builds --- src/archives.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/archives.rs b/src/archives.rs index 76bcd72..b1e0aca 100644 --- a/src/archives.rs +++ b/src/archives.rs @@ -57,8 +57,8 @@ pub fn extract_archive(bytes: Vec, path: &Path) -> Result<()> { } #[cfg(unix)] -pub fn extract_archive(bytes: Response, path: &Path) -> Result<()> { - let reader = Cursor::new(bytes.bytes().unwrap()); +pub fn extract_archive(bytes: Vec, path: &Path) -> Result<()> { + let reader = Cursor::new(bytes); let tar = GzDecoder::new(reader); let mut archive = Archive::new(tar);