Skip to content

Commit

Permalink
feat(upgrade): allow specifying a version (denoland#5156)
Browse files Browse the repository at this point in the history
  • Loading branch information
crowlKats committed May 9, 2020
1 parent 7d3728e commit abbf033
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 31 deletions.
22 changes: 18 additions & 4 deletions cli/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ pub enum DenoSubcommand {
Upgrade {
dry_run: bool,
force: bool,
version: Option<String>,
},
}

Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -811,14 +817,21 @@ 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")
Expand Down Expand Up @@ -1354,6 +1367,7 @@ mod tests {
subcommand: DenoSubcommand::Upgrade {
force: true,
dry_run: true,
version: None
},
..Flags::default()
}
Expand Down
8 changes: 5 additions & 3 deletions cli/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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!(),
};

Expand Down
31 changes: 31 additions & 0 deletions cli/tests/integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
76 changes: 52 additions & 24 deletions cli/upgrade.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(())
}

Expand Down

0 comments on commit abbf033

Please sign in to comment.