Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ edition = "2018"
anyhow = "1.0.36"
clap = "3.0.0-beta.2"
clap_generate = "3.0.0-beta.2"
colored = "2.0.0"
dirs-next = "2.0.0"
indoc = "1.0.3"
semver = "0.11.0"
Expand Down
17 changes: 7 additions & 10 deletions src/cmd/alias.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,14 @@ impl super::Command for Alias {
fn init(&self, config: Config) -> anyhow::Result<Self::InitResult> {
let dir = config.release_dir();
let versions = NodeVersion::list_versions(&dir)?;
let found = self.version.to_node_version(&versions);
let version = self.version.to_node_version(&versions)?;

if let Some(version) = found {
symlink_to(
dir.join(version.version_str()),
config.alias_dir().join(&self.alias),
)?;
println!("Version {} is aliased to {}", version, &self.alias);
} else {
println!("Version {} not found locally", self.version);
}
symlink_to(
dir.join(version.version_str()),
config.alias_dir().join(&self.alias),
)?;

println!("Version {} is aliased to {}", version, &self.alias);

Ok(())
}
Expand Down
6 changes: 4 additions & 2 deletions src/cmd/exec.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use crate::config::Config;
use crate::pretty_error_msg;
use crate::version::{NodeVersion, Version};
use clap::Clap;
use colored::*;
use std::env;
use std::process::{self, Command, Stdio};

Expand All @@ -18,7 +20,7 @@ impl super::Command for Exec {
let path = {
let dir = config.release_dir();
let versions = NodeVersion::list_versions(&dir)?;
let version = self.version.to_node_version(&versions).unwrap();
let version = self.version.to_node_version(&versions)?;
let bin_path = dir.join(version.version_str()).join("bin");
let path_env = env::var("PATH")?;
let mut splits: Vec<_> = env::split_paths(&path_env).collect();
Expand All @@ -33,7 +35,7 @@ impl super::Command for Exec {
.stderr(Stdio::inherit())
.env("PATH", &path)
.spawn()
.map_err(|_| anyhow::Error::msg("Can't spawn program"))?
.map_err(|_| pretty_error_msg!("Can't spawn program {}", &self.binary.bold()))?
.wait()
.map_err(|_| anyhow::Error::msg("Failed to grab exit code"))?;

Expand Down
27 changes: 17 additions & 10 deletions src/cmd/install.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use crate::config::Config;
use crate::downloader::download;
use crate::fetcher::Fetcher;
use crate::pretty_error;
use crate::version::{NodeVersion, Version};
use clap::Clap;
use colored::*;

#[derive(Debug, Clap, PartialEq, Eq)]
pub struct Install {
Expand All @@ -21,18 +23,23 @@ impl super::Command for Install {
};

if !can_install {
println!("Requested version ({}) is not installable", &self.version);
} else {
let release = Fetcher::fetch(&config.dist_mirror)?.find_release(&self.version);
return pretty_error!(
"Unable to install the version {}",
&self.version.to_string().bold()
);
}

let release = Fetcher::fetch(&config.dist_mirror)?.find_release(&self.version);

match release {
Some(r) => {
download(&r, &config)?;
}
_ => println!("No release found with the version {}", &self.version),
match release {
Some(r) => {
download(&r, &config)?;
Ok(())
}
_ => pretty_error!(
"No release found with the version {}",
&self.version.to_string().bold()
),
}

Ok(())
}
}
8 changes: 6 additions & 2 deletions src/cmd/ls_remote.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use crate::config::Config;
use crate::fetcher::Fetcher;
use crate::pretty_error;
use crate::version::Version;
use clap::Clap;
use colored::*;

#[derive(Debug, Clap, PartialEq, Eq)]
pub struct LsRemote {
Expand Down Expand Up @@ -33,8 +35,10 @@ impl super::Command for LsRemote {
};

if releases.is_empty() {
println!("No releases found with the version {}", version.unwrap());
return Ok(());
return pretty_error!(
"No releases found with the version {}",
version.unwrap().to_string().bold()
);
}

let releases = releases.into_iter();
Expand Down
5 changes: 3 additions & 2 deletions src/cmd/prune.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use crate::alias::Alias;
use crate::config::Config;
use crate::pretty_error;
use crate::version::NodeVersion;
use clap::Clap;
use colored::*;
use std::fs;

#[derive(Debug, Clap, PartialEq, Eq)]
Expand All @@ -14,8 +16,7 @@ impl super::Command for Prune {
let default_alias = config.alias_default();

if !default_alias.exists() {
println!("No installation found.");
return Ok(());
return pretty_error!("Unable to prune. No {} alias found", "default".bold());
}

// Removing aliases except the `default` alias
Expand Down
18 changes: 12 additions & 6 deletions src/cmd/uninstall.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use crate::alias::Alias;
use crate::config::Config;
use crate::pretty_error;
use crate::version::{NodeVersion, Version};
use clap::Clap;
use colored::*;

#[derive(Debug, Clap, PartialEq, Eq)]
pub struct UnInstall {
Expand All @@ -22,14 +24,16 @@ impl super::Command for UnInstall {
let matches = self.version.match_node_versions(&downloaded);

if matches.is_empty() {
println!("No downloaded version found.");
return Ok(());
return pretty_error!(
"No downloads found with version {}",
&self.version.to_string().bold()
);
}

if matches.len() > 1 {
println!("Multiple versions found, expected 1. Please be a little more specific.");
eprintln!("Multiple versions found, expected 1. Please be a little more specific.");
for m in matches {
println!("- {}", m);
eprintln!("- {}", m);
}
} else {
let found_ver = matches.get(0).unwrap();
Expand All @@ -38,8 +42,10 @@ impl super::Command for UnInstall {

for alias in found_alias {
if alias.name() == "default" && self.no_used {
println!("{} is currently used. Aborting...", found_ver);
return Ok(());
return Err(anyhow::Error::msg(format!(
"Unable to uninstall. Version {} is currently used",
found_ver.to_string().bold()
)));
}

alias.remove_alias()?;
Expand Down
7 changes: 2 additions & 5 deletions src/cmd/use.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,9 @@ impl super::Command for Use {

fn init(&self, config: Config) -> anyhow::Result<Self::InitResult> {
let dir = config.release_dir();
let downloads = NodeVersion::list_versions(&dir)?;
let versions = NodeVersion::list_versions(&dir)?;

let version = self
.version
.to_node_version(&downloads)
.ok_or(anyhow::Error::msg("Unable to find the version to use."))?;
let version = self.version.to_node_version(&versions)?;

symlink_to(dir.join(version.version_str()), config.alias_default())?;

Expand Down
3 changes: 2 additions & 1 deletion src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ impl Config {

pub fn snm_home(&self) -> PathBuf {
self.ensure_create(
(self.snm_dir.clone())
self.snm_dir
.clone()
.unwrap_or_else(|| home_dir().expect("Can't get home directory.").join(".snm")),
)
}
Expand Down
10 changes: 6 additions & 4 deletions src/downloader.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use crate::archive::Archive;
use crate::config::Config;
use crate::fetcher::Release;
use crate::pretty_error;
use crate::symlink::symlink_to;
use crate::url;
use colored::*;
use std::path::PathBuf;
use ureq;

Expand All @@ -11,10 +13,10 @@ pub fn download(r: &Release, config: &Config) -> anyhow::Result<PathBuf> {
let dest = release_dir.join(&r.version.to_string());

if dest.exists() {
return Err(anyhow::Error::msg(format!(
"Version {} is already exists.",
&r.version
)));
return pretty_error!(
"Version {} is already exists locally",
&r.version.to_string().bold()
);
}

let dist = url::release(&config.dist_mirror, &r.version);
Expand Down
13 changes: 13 additions & 0 deletions src/errors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#[macro_export]
macro_rules! pretty_error_msg {
($($l:expr),*) => {
anyhow::Error::msg(format!($($l,)*));
};
}

#[macro_export]
macro_rules! pretty_error {
($($l:expr),*) => {
Err(anyhow::Error::msg(format!($($l,)*)));
};
}
9 changes: 7 additions & 2 deletions src/fetcher.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use crate::pretty_error_msg;
use crate::version::{NodeVersion, Version};
use colored::*;
use serde::Deserialize;
use url::Url;

Expand Down Expand Up @@ -37,7 +39,7 @@ impl Fetcher {
Lts::Yes(_) => true,
_ => false,
})
.ok_or(anyhow::Error::msg("Unable to find release"))
.ok_or(pretty_error_msg!("Unable to find {} release", "lts".bold()))
}

pub fn latest(&self) -> anyhow::Result<&Release> {
Expand All @@ -47,7 +49,10 @@ impl Fetcher {
Lts::No(_) => true,
_ => false,
})
.ok_or(anyhow::Error::msg("Unable to find release."))
.ok_or(pretty_error_msg!(
"Unable to find {} release",
"latest".bold()
))
}

pub fn find_releases(self, version: &Version) -> Vec<Release> {
Expand Down
13 changes: 11 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,24 @@ mod cli;
mod cmd;
mod config;
mod downloader;
mod errors;
mod fetcher;
mod shell;
mod symlink;
mod sysinfo;
mod url;
mod version;

fn main() -> anyhow::Result<()> {
use colored::*;

fn main() {
let app = cli::parse();

app.cmd.exec(app.options)
if let Err(e) = app.cmd.exec(app.options) {
eprintln!(
"{} :: {}",
"ERROR".bright_blue(),
e.to_string().bright_red()
)
}
}
2 changes: 1 addition & 1 deletion src/symlink.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub fn remove_symlink<P: AsRef<Path>>(path: P) -> io::Result<()> {
/// Win -- Create a symlink from destination path to the given path
#[cfg(windows)]
pub fn symlink<P: AsRef<Path>>(from: P, to: P) -> io::Result<()> {
self.remove_symlink(&to)?;
remove_symlink(&to)?;
std::os::windows::fs::symlink_dir(from, to)
}

Expand Down
12 changes: 6 additions & 6 deletions src/url.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,25 @@ pub struct Dist {
}

#[cfg(unix)]
pub fn release(base_url: &Url, v: &NodeVersion) -> Dist {
pub fn release(base_url: &Url, version: &NodeVersion) -> Dist {
use crate::sysinfo::{platform_arch, platform_name};

let name = format!("node-{}-{}-{}", v, platform_name(), platform_arch());
let name = format!("node-{}-{}-{}", version, platform_name(), platform_arch());

Dist {
url: format!("{}/{}/{}.tar.xz", base_url, v, &name),
url: format!("{}/{}/{}.tar.xz", base_url, version, &name),
name,
}
}

#[cfg(windows)]
pub fn release(base_url: &Url, v: &NodeVersion) -> Binary {
pub fn release(base_url: &Url, version: &NodeVersion) -> Dist {
use crate::sysinfo::platform_arch;

let name = format!("node-{}-win-{}", v, platform_arch());

Binary {
url: format!("{}/{}/{}.zip", base_url, v, &name),
Dist {
url: format!("{}/{}/{}.zip", base_url, version, &name),
name,
}
}
Loading