summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/flags.rs22
-rw-r--r--cli/lib.rs8
-rw-r--r--cli/tests/integration_tests.rs31
-rw-r--r--cli/upgrade.rs76
4 files changed, 106 insertions, 31 deletions
diff --git a/cli/flags.rs b/cli/flags.rs
index bb81f0d01..216fcd474 100644
--- a/cli/flags.rs
+++ b/cli/flags.rs
@@ -65,6 +65,7 @@ pub enum DenoSubcommand {
Upgrade {
dry_run: bool,
force: bool,
+ version: Option<String>,
},
}
@@ -563,7 +564,12 @@ fn test_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
fn upgrade_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
let dry_run = matches.is_present("dry-run");
let force = matches.is_present("force");
- flags.subcommand = DenoSubcommand::Upgrade { dry_run, force };
+ let version = matches.value_of("version").map(|s| s.to_string());
+ flags.subcommand = DenoSubcommand::Upgrade {
+ dry_run,
+ force,
+ version,
+ };
}
fn doc_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
@@ -811,15 +817,22 @@ Future runs of this module will trigger no downloads or compilation unless
fn upgrade_subcommand<'a, 'b>() -> App<'a, 'b> {
SubCommand::with_name("upgrade")
- .about("Upgrade deno executable to newest version")
+ .about("Upgrade deno executable to given version")
.long_about(
- "Upgrade deno executable to newest available version.
+ "Upgrade deno executable to the given version.
+Defaults to latest.
-The latest version is downloaded from
+The version is downloaded from
https://github.com/denoland/deno/releases
and is used to replace the current executable.",
)
.arg(
+ Arg::with_name("version")
+ .long("version")
+ .help("The version to upgrade to")
+ .takes_value(true),
+ )
+ .arg(
Arg::with_name("dry-run")
.long("dry-run")
.help("Perform all checks without replacing old exe"),
@@ -1354,6 +1367,7 @@ mod tests {
subcommand: DenoSubcommand::Upgrade {
force: true,
dry_run: true,
+ version: None
},
..Flags::default()
}
diff --git a/cli/lib.rs b/cli/lib.rs
index 060c86b55..957637719 100644
--- a/cli/lib.rs
+++ b/cli/lib.rs
@@ -616,9 +616,11 @@ pub fn main() {
}
return;
}
- DenoSubcommand::Upgrade { force, dry_run } => {
- upgrade_command(dry_run, force).boxed_local()
- }
+ DenoSubcommand::Upgrade {
+ force,
+ dry_run,
+ version,
+ } => upgrade_command(dry_run, force, version).boxed_local(),
_ => unreachable!(),
};
diff --git a/cli/tests/integration_tests.rs b/cli/tests/integration_tests.rs
index 28df47250..7ad7781de 100644
--- a/cli/tests/integration_tests.rs
+++ b/cli/tests/integration_tests.rs
@@ -224,6 +224,37 @@ fn upgrade_in_tmpdir() {
// TODO(ry) assert!(mtime1 < mtime2);
}
+// Warning: this test requires internet access.
+#[test]
+fn upgrade_with_version_in_tmpdir() {
+ let temp_dir = TempDir::new().unwrap();
+ let exe_path = if cfg!(windows) {
+ temp_dir.path().join("deno")
+ } else {
+ temp_dir.path().join("deno.exe")
+ };
+ let _ = std::fs::copy(util::deno_exe_path(), &exe_path).unwrap();
+ assert!(exe_path.exists());
+ let _mtime1 = std::fs::metadata(&exe_path).unwrap().modified().unwrap();
+ let status = Command::new(&exe_path)
+ .arg("upgrade")
+ .arg("--force")
+ .arg("--version")
+ .arg("0.42.0")
+ .spawn()
+ .unwrap()
+ .wait()
+ .unwrap();
+ assert!(status.success());
+ let upgraded_deno_version = String::from_utf8(
+ Command::new(&exe_path).arg("-V").output().unwrap().stdout,
+ )
+ .unwrap();
+ assert!(upgraded_deno_version.contains("0.42.0"));
+ let _mtime2 = std::fs::metadata(&exe_path).unwrap().modified().unwrap();
+ // TODO(ry) assert!(mtime1 < mtime2);
+}
+
#[test]
fn installer_test_local_module_run() {
let temp_dir = TempDir::new().expect("tempdir fail");
diff --git a/cli/upgrade.rs b/cli/upgrade.rs
index 519f8d6bc..b4f207643 100644
--- a/cli/upgrade.rs
+++ b/cli/upgrade.rs
@@ -52,36 +52,64 @@ async fn get_latest_version(client: &Client) -> Result<Version, ErrBox> {
/// Asynchronously updates deno executable to greatest version
/// if greatest version is available.
-pub async fn upgrade_command(dry_run: bool, force: bool) -> Result<(), ErrBox> {
+pub async fn upgrade_command(
+ dry_run: bool,
+ force: bool,
+ version: Option<String>,
+) -> Result<(), ErrBox> {
let client = Client::builder().redirect(Policy::none()).build()?;
- let latest_version = get_latest_version(&client).await?;
let current_version = semver_parse(crate::version::DENO).unwrap();
- if !force && current_version >= latest_version {
- println!(
- "Local deno version {} is the most recent release",
- &crate::version::DENO
- );
- } else {
- println!(
- "New version has been found\nDeno is upgrading to version {}",
- &latest_version
- );
- let archive_data =
- download_package(&compose_url_to_exec(&latest_version)?, client).await?;
-
- let old_exe_path = std::env::current_exe()?;
- let new_exe_path = unpack(archive_data)?;
- let permissions = fs::metadata(&old_exe_path)?.permissions();
- fs::set_permissions(&new_exe_path, permissions)?;
- check_exe(&new_exe_path, &latest_version)?;
-
- if !dry_run {
- replace_exe(&new_exe_path, &old_exe_path)?;
+ let install_version = match version {
+ Some(passed_version) => match semver_parse(&passed_version) {
+ Ok(ver) => {
+ if !force && current_version == ver {
+ println!("Version {} is already installed", &ver);
+ std::process::exit(1)
+ } else {
+ ver
+ }
+ }
+ Err(_) => {
+ eprintln!("Invalid semver passed");
+ std::process::exit(1)
+ }
+ },
+ None => {
+ let latest_version = get_latest_version(&client).await?;
+
+ if !force && current_version >= latest_version {
+ println!(
+ "Local deno version {} is the most recent release",
+ &crate::version::DENO
+ );
+ std::process::exit(1)
+ } else {
+ latest_version
+ }
}
+ };
- println!("Upgrade done successfully")
+ println!(
+ "Version has been found\nDeno is upgrading to version {}",
+ &install_version
+ );
+
+ let archive_data =
+ download_package(&compose_url_to_exec(&install_version)?, client).await?;
+
+ let old_exe_path = std::env::current_exe()?;
+ let new_exe_path = unpack(archive_data)?;
+ let permissions = fs::metadata(&old_exe_path)?.permissions();
+ fs::set_permissions(&new_exe_path, permissions)?;
+ check_exe(&new_exe_path, &install_version)?;
+
+ if !dry_run {
+ replace_exe(&new_exe_path, &old_exe_path)?;
}
+
+ println!("Upgrade done successfully");
+
Ok(())
}