diff options
author | crowlKats <13135287+crowlKats@users.noreply.github.com> | 2020-11-29 20:00:35 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-29 20:00:35 +0100 |
commit | 973af61d8bb03c1709f61e456581d58386ed4952 (patch) | |
tree | 1176ac2827ec79b8ff6bfd17d92dcdd0866a8210 | |
parent | 47a16d21186bfcd7c03f81af6aa30be6620f640a (diff) |
feat(cli/tools/upgrade): canary support (#8476)
-rw-r--r-- | cli/flags.rs | 10 | ||||
-rw-r--r-- | cli/main.rs | 9 | ||||
-rw-r--r-- | cli/tests/integration_tests.rs | 29 | ||||
-rw-r--r-- | cli/tools/upgrade.rs | 96 | ||||
-rw-r--r-- | cli/version.rs | 4 |
5 files changed, 118 insertions, 30 deletions
diff --git a/cli/flags.rs b/cli/flags.rs index 5219471f2..740cec790 100644 --- a/cli/flags.rs +++ b/cli/flags.rs @@ -77,6 +77,7 @@ pub enum DenoSubcommand { Upgrade { dry_run: bool, force: bool, + canary: bool, version: Option<String>, output: Option<PathBuf>, ca_file: Option<String>, @@ -625,6 +626,7 @@ fn upgrade_parse(flags: &mut Flags, matches: &clap::ArgMatches) { let dry_run = matches.is_present("dry-run"); let force = matches.is_present("force"); + let canary = matches.is_present("canary"); let version = matches.value_of("version").map(|s| s.to_string()); let output = if matches.is_present("output") { let install_root = matches.value_of("output").unwrap(); @@ -636,6 +638,7 @@ fn upgrade_parse(flags: &mut Flags, matches: &clap::ArgMatches) { flags.subcommand = DenoSubcommand::Upgrade { dry_run, force, + canary, version, output, ca_file, @@ -951,6 +954,11 @@ update to a different location, use the --output flag .short("f") .help("Replace current exe even if not out-of-date"), ) + .arg( + Arg::with_name("canary") + .long("canary") + .help("Upgrade to canary builds"), + ) .arg(ca_file_arg()) } @@ -1589,6 +1597,7 @@ mod tests { subcommand: DenoSubcommand::Upgrade { force: true, dry_run: true, + canary: false, version: None, output: None, ca_file: None, @@ -2991,6 +3000,7 @@ mod tests { subcommand: DenoSubcommand::Upgrade { force: false, dry_run: false, + canary: false, version: None, output: None, ca_file: Some("example.crt".to_owned()), diff --git a/cli/main.rs b/cli/main.rs index de2e1b402..6c48a75f6 100644 --- a/cli/main.rs +++ b/cli/main.rs @@ -952,13 +952,14 @@ fn get_subcommand( DenoSubcommand::Upgrade { force, dry_run, + canary, version, output, ca_file, - } => { - tools::upgrade::upgrade_command(dry_run, force, version, output, ca_file) - .boxed_local() - } + } => tools::upgrade::upgrade_command( + dry_run, force, canary, version, output, ca_file, + ) + .boxed_local(), } } diff --git a/cli/tests/integration_tests.rs b/cli/tests/integration_tests.rs index 430bd53cd..8ad4ea5ed 100644 --- a/cli/tests/integration_tests.rs +++ b/cli/tests/integration_tests.rs @@ -634,6 +634,35 @@ fn upgrade_with_version_in_tmpdir() { // TODO(#7412): reenable. test is flaky #[test] #[ignore] +fn upgrade_with_canary_in_tmpdir() { + let temp_dir = TempDir::new().unwrap(); + let exe_path = temp_dir.path().join("deno"); + 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("--canary") + .arg("--version") + .arg("e6685f0f01b8a11a5eaff020f5babcfde76b3038") + .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("e6685f0")); + let _mtime2 = std::fs::metadata(&exe_path).unwrap().modified().unwrap(); + // TODO(ry) assert!(mtime1 < mtime2); +} + +// Warning: this test requires internet access. +// TODO(#7412): reenable. test is flaky +#[test] +#[ignore] fn upgrade_with_out_in_tmpdir() { let temp_dir = TempDir::new().unwrap(); let exe_path = temp_dir.path().join("deno"); diff --git a/cli/tools/upgrade.rs b/cli/tools/upgrade.rs index 3344ca2d5..b76850dde 100644 --- a/cli/tools/upgrade.rs +++ b/cli/tools/upgrade.rs @@ -21,6 +21,7 @@ const RELEASE_URL: &str = "https://github.com/denoland/deno/releases"; pub async fn upgrade_command( dry_run: bool, force: bool, + canary: bool, version: Option<String>, output: Option<PathBuf>, ca_file: Option<String>, @@ -38,27 +39,49 @@ pub async fn upgrade_command( let install_version = match version { Some(passed_version) => { - if !force && output.is_none() && crate::version::deno() == passed_version - { - println!("Version {} is already installed", passed_version); + let current_is_passed = if canary { + let mut passed_hash = passed_version.clone(); + passed_hash.truncate(7); + crate::version::GIT_COMMIT_HASH == passed_hash + } else if !crate::version::is_canary() { + crate::version::deno() == passed_version + } else { + false + }; + + if !force && output.is_none() && current_is_passed { + println!("Version {} is already installed", crate::version::deno()); return Ok(()); } else { passed_version } } None => { - let latest_version = get_latest_version(&client).await?; - - let current = semver_parse(&*crate::version::deno()).unwrap(); - let latest = match semver_parse(&latest_version) { - Ok(v) => v, - Err(_) => { - eprintln!("Invalid semver passed"); - std::process::exit(1) - } + let latest_version = if canary { + get_latest_canary_version(&client).await? + } else { + get_latest_release_version(&client).await? + }; + + let current_is_most_recent = if canary { + let mut latest_hash = latest_version.clone(); + latest_hash.truncate(7); + crate::version::GIT_COMMIT_HASH == latest_hash + } else if !crate::version::is_canary() { + let current = semver_parse(&*crate::version::deno()).unwrap(); + let latest = match semver_parse(&latest_version) { + Ok(v) => v, + Err(_) => { + eprintln!("Invalid semver passed"); + std::process::exit(1) + } + }; + current >= latest + } else { + false }; - if !force && output.is_none() && current >= latest { + if !force && output.is_none() && current_is_most_recent { println!( "Local deno version {} is the most recent release", crate::version::deno() @@ -71,7 +94,19 @@ pub async fn upgrade_command( } }; - let archive_data = download_package(client, &install_version).await?; + let download_url = if canary { + format!( + "https://dl.deno.land/canary/{}/{}", + install_version, *ARCHIVE_NAME + ) + } else { + format!( + "{}/download/v{}/{}", + RELEASE_URL, install_version, *ARCHIVE_NAME + ) + }; + + let archive_data = download_package(client, &*download_url).await?; println!("Deno is upgrading to version {}", &install_version); @@ -79,7 +114,7 @@ pub async fn upgrade_command( 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)?; + check_exe(&new_exe_path)?; if !dry_run { match output { @@ -96,7 +131,9 @@ pub async fn upgrade_command( Ok(()) } -async fn get_latest_version(client: &Client) -> Result<String, AnyError> { +async fn get_latest_release_version( + client: &Client, +) -> Result<String, AnyError> { println!("Looking up latest version"); let res = client @@ -108,18 +145,27 @@ async fn get_latest_version(client: &Client) -> Result<String, AnyError> { Ok(version.replace("v", "")) } +async fn get_latest_canary_version( + client: &Client, +) -> Result<String, AnyError> { + println!("Looking up latest version"); + + let res = client + .get("https://dl.deno.land/canary-latest.txt") + .send() + .await?; + let version = res.text().await?.trim().to_string(); + + Ok(version) +} + async fn download_package( client: Client, - install_version: &str, + download_url: &str, ) -> Result<Vec<u8>, AnyError> { - let download_url = format!( - "{}/download/v{}/{}", - RELEASE_URL, install_version, *ARCHIVE_NAME - ); - println!("Checking {}", &download_url); - let res = client.get(&download_url).send().await?; + let res = client.get(download_url).send().await?; if res.status().is_success() { println!("Download has been found"); @@ -200,13 +246,11 @@ fn replace_exe(new: &Path, old: &Path) -> Result<(), std::io::Error> { Ok(()) } -fn check_exe(exe_path: &Path, expected_version: &str) -> Result<(), AnyError> { +fn check_exe(exe_path: &Path) -> Result<(), AnyError> { let output = Command::new(exe_path) .arg("-V") .stderr(std::process::Stdio::inherit()) .output()?; - let stdout = String::from_utf8(output.stdout)?; assert!(output.status.success()); - assert_eq!(stdout.trim(), format!("deno {}", expected_version)); Ok(()) } diff --git a/cli/version.rs b/cli/version.rs index eb1b3a003..694ffc44b 100644 --- a/cli/version.rs +++ b/cli/version.rs @@ -10,6 +10,10 @@ pub fn deno() -> String { }) } +pub fn is_canary() -> bool { + option_env!("DENO_CANARY").is_some() +} + pub fn v8() -> &'static str { deno_core::v8_version() } |