![gal@spitfire.co.il](/assets/img/avatar_default.png)
![GitHub](/assets/img/avatar_default.png)
17 changed files with 279 additions and 41 deletions
@ -0,0 +1,100 @@ |
|||||||
|
use super::command::Command; |
||||||
|
use crate::config::FnmConfig; |
||||||
|
use crate::fs::remove_symlink_dir; |
||||||
|
use crate::installed_versions; |
||||||
|
use crate::outln; |
||||||
|
use crate::user_version::UserVersion; |
||||||
|
use crate::version::Version; |
||||||
|
use crate::version_files::get_user_version_from_file; |
||||||
|
use colored::Colorize; |
||||||
|
use log::debug; |
||||||
|
use snafu::{ensure, OptionExt, ResultExt, Snafu}; |
||||||
|
use structopt::StructOpt; |
||||||
|
|
||||||
|
#[derive(StructOpt, Debug)] |
||||||
|
pub struct Uninstall { |
||||||
|
version: Option<UserVersion>, |
||||||
|
} |
||||||
|
|
||||||
|
impl Command for Uninstall { |
||||||
|
type Error = Error; |
||||||
|
|
||||||
|
fn apply(self, config: &FnmConfig) -> Result<(), Self::Error> { |
||||||
|
let all_versions = |
||||||
|
installed_versions::list(config.installations_dir()).context(VersionListingError)?; |
||||||
|
let requested_version = self |
||||||
|
.version |
||||||
|
.or_else(|| { |
||||||
|
let current_dir = std::env::current_dir().unwrap(); |
||||||
|
get_user_version_from_file(current_dir) |
||||||
|
}) |
||||||
|
.context(CantInferVersion)?; |
||||||
|
|
||||||
|
ensure!( |
||||||
|
!matches!(requested_version, UserVersion::Full(Version::Bypassed)), |
||||||
|
CantUninstallSystemVersion |
||||||
|
); |
||||||
|
|
||||||
|
let available_versions: Vec<&Version> = all_versions |
||||||
|
.iter() |
||||||
|
.filter(|v| requested_version.matches(v, &config)) |
||||||
|
.collect(); |
||||||
|
|
||||||
|
ensure!( |
||||||
|
available_versions.len() < 2, |
||||||
|
PleaseBeMoreSpecificToDelete { |
||||||
|
matched_versions: available_versions |
||||||
|
.iter() |
||||||
|
.map(|x| x.v_str()) |
||||||
|
.collect::<Vec<_>>() |
||||||
|
} |
||||||
|
); |
||||||
|
|
||||||
|
let version = requested_version |
||||||
|
.to_version(&all_versions, &config) |
||||||
|
.context(CantFindVersion)?; |
||||||
|
|
||||||
|
let matching_aliases = version.find_aliases(&config).context(IoError)?; |
||||||
|
let root_path = version |
||||||
|
.root_path(&config) |
||||||
|
.with_context(|| RootPathNotFound { |
||||||
|
version: version.clone(), |
||||||
|
})?; |
||||||
|
|
||||||
|
debug!("Removing Node version from {:?}", root_path); |
||||||
|
std::fs::remove_dir_all(root_path).context(CantDeleteNodeVersion)?; |
||||||
|
outln!(config#Info, "Node version {} was removed successfuly", version.v_str().cyan()); |
||||||
|
|
||||||
|
for alias in matching_aliases { |
||||||
|
debug!("Removing alias from {:?}", alias.path()); |
||||||
|
remove_symlink_dir(alias.path()).context(CantDeleteSymlink)?; |
||||||
|
outln!(config#Info, "Alias {} was removed successfuly", alias.name().cyan()); |
||||||
|
} |
||||||
|
|
||||||
|
Ok(()) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#[derive(Debug, Snafu)] |
||||||
|
pub enum Error { |
||||||
|
#[snafu(display("Can't get locally installed versions: {}", source))] |
||||||
|
VersionListingError { source: installed_versions::Error }, |
||||||
|
#[snafu(display(
|
||||||
|
"Can't find version in dotfiles. Please provide a version manually to the command." |
||||||
|
))] |
||||||
|
CantInferVersion, |
||||||
|
#[snafu(display("Can't uninstall system version"))] |
||||||
|
CantUninstallSystemVersion, |
||||||
|
#[snafu(display("Too many versions had matched, please be more specific.\nFound {} matching versions, expected 1:\n{}", matched_versions.len(), matched_versions.iter().map(|v| format!("* {}", v)).collect::<Vec<_>>().join("\n")))] |
||||||
|
PleaseBeMoreSpecificToDelete { matched_versions: Vec<String> }, |
||||||
|
#[snafu(display("Can't find a matching version"))] |
||||||
|
CantFindVersion, |
||||||
|
#[snafu(display("Root path not found for version {}", version))] |
||||||
|
RootPathNotFound { version: Version }, |
||||||
|
#[snafu(display("io error: {}", source))] |
||||||
|
IoError { source: std::io::Error }, |
||||||
|
#[snafu(display("Can't delete Node.js version: {}", source))] |
||||||
|
CantDeleteNodeVersion { source: std::io::Error }, |
||||||
|
#[snafu(display("Can't delete symlink: {}", source))] |
||||||
|
CantDeleteSymlink { source: std::io::Error }, |
||||||
|
} |
@ -0,0 +1,14 @@ |
|||||||
|
#[allow(unused_imports)] |
||||||
|
use crate::shellcode::*; |
||||||
|
|
||||||
|
test_shell!(Bash, Zsh, Fish, PowerShell; { |
||||||
|
EvalFnmEnv::default() |
||||||
|
.then(Call::new("fnm", vec!["install", "12.0.0"])) |
||||||
|
.then(Call::new("fnm", vec!["alias", "12.0.0", "hello"])) |
||||||
|
.then(OutputContains::new( |
||||||
|
OutputContains::new(Call::new("fnm", vec!["ls"]), "v12.0.0"), |
||||||
|
"hello", |
||||||
|
)) |
||||||
|
.then(Call::new("fnm", vec!["uninstall", "hello"])) |
||||||
|
.then(ExpectCommandOutput::new(Call::new("fnm", vec!["ls"]), "* system", "fnm ls")) |
||||||
|
}); |
@ -0,0 +1,16 @@ |
|||||||
|
--- |
||||||
|
source: tests/e2e.rs |
||||||
|
expression: "&source.trim()" |
||||||
|
--- |
||||||
|
set -e |
||||||
|
shopt -s expand_aliases |
||||||
|
|
||||||
|
eval "$(fnm env)" |
||||||
|
fnm install 12.0.0 |
||||||
|
fnm alias 12.0.0 hello |
||||||
|
fnm ls | grep v12.0.0 | grep hello |
||||||
|
fnm uninstall hello |
||||||
|
if [ "$(fnm ls)" != "* system" ]; then |
||||||
|
echo 'Expected fnm ls to be "* system", Got: '"$(fnm ls)" |
||||||
|
exit 1 |
||||||
|
fi |
@ -0,0 +1,13 @@ |
|||||||
|
--- |
||||||
|
source: tests/e2e.rs |
||||||
|
expression: "&source.trim()" |
||||||
|
--- |
||||||
|
fnm env | source |
||||||
|
fnm install 12.0.0 |
||||||
|
fnm alias 12.0.0 hello |
||||||
|
fnm ls | grep v12.0.0 | grep hello |
||||||
|
fnm uninstall hello |
||||||
|
if test (fnm ls) != "* system" |
||||||
|
echo 'Expected fnm ls to be "* system", Got: '(fnm ls) |
||||||
|
exit 1 |
||||||
|
end |
@ -0,0 +1,14 @@ |
|||||||
|
--- |
||||||
|
source: tests/e2e.rs |
||||||
|
expression: "&source.trim()" |
||||||
|
--- |
||||||
|
$ErrorActionPreference = "Stop" |
||||||
|
fnm env | Out-String | Invoke-Expression |
||||||
|
fnm install 12.0.0 |
||||||
|
fnm alias 12.0.0 hello |
||||||
|
$($__out__ = $($($__out__ = $(fnm ls | Select-String 'v12.0.0'); echo $__out__; if ($__out__ -eq $null){ exit 1 } else { $__out__ }) | Select-String 'hello'); echo $__out__; if ($__out__ -eq $null){ exit 1 } else { $__out__ }) |
||||||
|
fnm uninstall hello |
||||||
|
If ("$(fnm ls)" -ne "* system") { |
||||||
|
Write-Output ('Expected fnm ls to be "* system", Got: ' + $(fnm ls)) |
||||||
|
exit 1 |
||||||
|
} |
@ -0,0 +1,14 @@ |
|||||||
|
--- |
||||||
|
source: tests/e2e.rs |
||||||
|
expression: "&source.trim()" |
||||||
|
--- |
||||||
|
set -e |
||||||
|
eval "$(fnm env)" |
||||||
|
fnm install 12.0.0 |
||||||
|
fnm alias 12.0.0 hello |
||||||
|
fnm ls | grep v12.0.0 | grep hello |
||||||
|
fnm uninstall hello |
||||||
|
if [ "$(fnm ls)" != "* system" ]; then |
||||||
|
echo 'Expected fnm ls to be "* system", Got: '"$(fnm ls)" |
||||||
|
exit 1 |
||||||
|
fi |
Loading…
Reference in new issue