install: add --force flag and remove yes/no prompt (#3917)

This commit is contained in:
Kevin (Kun) "Kassimo" Qian 2020-02-08 00:49:55 -08:00 committed by GitHub
parent f650c3edb3
commit 619a24390f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 101 additions and 27 deletions

View file

@ -4,7 +4,6 @@ use regex::{Regex, RegexBuilder};
use std::env;
use std::fs;
use std::fs::File;
use std::io;
use std::io::Error;
use std::io::ErrorKind;
use std::io::Write;
@ -23,15 +22,6 @@ lazy_static! {
).case_insensitive(true).build().unwrap();
}
fn yes_no_prompt(msg: &str) -> bool {
println!("{} [yN]", msg);
let mut buffer = String::new();
io::stdin()
.read_line(&mut buffer)
.expect("Couldn't read from stdin");
buffer.starts_with('y') | buffer.starts_with('Y')
}
fn is_remote_url(module_url: &str) -> bool {
module_url.starts_with("http://") || module_url.starts_with("https://")
}
@ -60,7 +50,6 @@ fn generate_executable_file(
"% generated by deno install %\ndeno.exe {} %*\n",
args.join(" ")
);
let file_path = file_path.with_extension(".cmd");
let mut file = File::create(&file_path)?;
file.write_all(template.as_bytes())?;
Ok(())
@ -71,9 +60,6 @@ fn generate_executable_file(
file_path: PathBuf,
args: Vec<String>,
) -> Result<(), Error> {
// On Windows if user is using Powershell .cmd extension is need to run the
// installed module.
// Generate batch script to satisfy that.
let args: Vec<String> = args.iter().map(|c| format!("\"{}\"", c)).collect();
let template = format!(
r#"#!/bin/sh
@ -119,6 +105,7 @@ pub fn install(
exec_name: &str,
module_url: &str,
args: Vec<String>,
force: bool,
) -> Result<(), Error> {
let installation_dir = if let Some(dir) = installation_dir {
PathBuf::from(dir).canonicalize()?
@ -131,7 +118,7 @@ pub fn install(
if !metadata.is_dir() {
return Err(Error::new(
ErrorKind::Other,
"Insallation path is not a directory",
"Installation path is not a directory",
));
}
} else {
@ -153,16 +140,17 @@ pub fn install(
};
validate_exec_name(exec_name)?;
let file_path = installation_dir.join(exec_name);
let mut file_path = installation_dir.join(exec_name);
if file_path.exists() {
let msg = format!(
"⚠️ {} is already installed, do you want to overwrite it?",
exec_name
);
if !yes_no_prompt(&msg) {
return Ok(());
};
if cfg!(windows) {
file_path = file_path.with_extension(".cmd");
}
if file_path.exists() && !force {
return Err(Error::new(
ErrorKind::Other,
"Existing installation found. Aborting (Use -f to overwrite)",
));
};
let mut executable_args = vec!["run".to_string()];
@ -227,6 +215,7 @@ mod tests {
"echo_test",
"http://localhost:4545/cli/tests/echo_server.ts",
vec![],
false,
)
.expect("Install failed");
@ -260,6 +249,7 @@ mod tests {
"echo_test",
"http://localhost:4545/cli/tests/echo_server.ts",
vec![],
false,
)
.expect("Install failed");
@ -288,6 +278,7 @@ mod tests {
"echo_test",
"http://localhost:4545/cli/tests/echo_server.ts",
vec!["--foobar".to_string()],
false,
)
.expect("Install failed");
@ -314,6 +305,7 @@ mod tests {
"echo_test",
&local_module_str,
vec![],
false,
)
.expect("Install failed");
@ -326,4 +318,69 @@ mod tests {
let content = fs::read_to_string(file_path).unwrap();
assert!(content.contains(&local_module_url.to_string()));
}
#[test]
fn install_force() {
let temp_dir = TempDir::new().expect("tempdir fail");
let temp_dir_str = temp_dir.path().to_string_lossy().to_string();
let original_home = env::var_os("HOME");
let original_user_profile = env::var_os("HOME");
env::set_var("HOME", &temp_dir_str);
env::set_var("USERPROFILE", &temp_dir_str);
install(
DenoFlags::default(),
None,
"echo_test",
"http://localhost:4545/cli/tests/echo_server.ts",
vec![],
false,
)
.expect("Install failed");
let mut file_path = temp_dir.path().join(".deno/bin/echo_test");
if cfg!(windows) {
file_path = file_path.with_extension(".cmd");
}
assert!(file_path.exists());
// No force. Install failed.
let no_force_result = install(
DenoFlags::default(),
None,
"echo_test",
"http://localhost:4545/cli/tests/cat.ts", // using a different URL
vec![],
false,
);
assert!(no_force_result.is_err());
assert!(no_force_result
.unwrap_err()
.to_string()
.contains("Existing installation found"));
// Assert not modified
let file_content = fs::read_to_string(&file_path).unwrap();
assert!(file_content.contains("echo_server.ts"));
// Force. Install success.
let force_result = install(
DenoFlags::default(),
None,
"echo_test",
"http://localhost:4545/cli/tests/cat.ts", // using a different URL
vec![],
true,
);
assert!(force_result.is_ok());
// Assert modified
let file_content_2 = fs::read_to_string(&file_path).unwrap();
assert!(file_content_2.contains("cat.ts"));
if let Some(home) = original_home {
env::set_var("HOME", home);
}
if let Some(user_profile) = original_user_profile {
env::set_var("USERPROFILE", user_profile);
}
}
}