1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-25 16:49:18 -05:00

feat(cli/tools/upgrade): canary support (#8476)

This commit is contained in:
crowlKats 2020-11-29 20:00:35 +01:00 committed by GitHub
parent 47a16d2118
commit 973af61d8b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 118 additions and 30 deletions

View file

@ -77,6 +77,7 @@ pub enum DenoSubcommand {
Upgrade { Upgrade {
dry_run: bool, dry_run: bool,
force: bool, force: bool,
canary: bool,
version: Option<String>, version: Option<String>,
output: Option<PathBuf>, output: Option<PathBuf>,
ca_file: Option<String>, 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 dry_run = matches.is_present("dry-run");
let force = matches.is_present("force"); let force = matches.is_present("force");
let canary = matches.is_present("canary");
let version = matches.value_of("version").map(|s| s.to_string()); let version = matches.value_of("version").map(|s| s.to_string());
let output = if matches.is_present("output") { let output = if matches.is_present("output") {
let install_root = matches.value_of("output").unwrap(); 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 { flags.subcommand = DenoSubcommand::Upgrade {
dry_run, dry_run,
force, force,
canary,
version, version,
output, output,
ca_file, ca_file,
@ -951,6 +954,11 @@ update to a different location, use the --output flag
.short("f") .short("f")
.help("Replace current exe even if not out-of-date"), .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()) .arg(ca_file_arg())
} }
@ -1589,6 +1597,7 @@ mod tests {
subcommand: DenoSubcommand::Upgrade { subcommand: DenoSubcommand::Upgrade {
force: true, force: true,
dry_run: true, dry_run: true,
canary: false,
version: None, version: None,
output: None, output: None,
ca_file: None, ca_file: None,
@ -2991,6 +3000,7 @@ mod tests {
subcommand: DenoSubcommand::Upgrade { subcommand: DenoSubcommand::Upgrade {
force: false, force: false,
dry_run: false, dry_run: false,
canary: false,
version: None, version: None,
output: None, output: None,
ca_file: Some("example.crt".to_owned()), ca_file: Some("example.crt".to_owned()),

View file

@ -952,13 +952,14 @@ fn get_subcommand(
DenoSubcommand::Upgrade { DenoSubcommand::Upgrade {
force, force,
dry_run, dry_run,
canary,
version, version,
output, output,
ca_file, ca_file,
} => { } => tools::upgrade::upgrade_command(
tools::upgrade::upgrade_command(dry_run, force, version, output, ca_file) dry_run, force, canary, version, output, ca_file,
.boxed_local() )
} .boxed_local(),
} }
} }

View file

@ -630,6 +630,35 @@ fn upgrade_with_version_in_tmpdir() {
// TODO(ry) assert!(mtime1 < mtime2); // TODO(ry) assert!(mtime1 < mtime2);
} }
// Warning: this test requires internet access.
// 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. // Warning: this test requires internet access.
// TODO(#7412): reenable. test is flaky // TODO(#7412): reenable. test is flaky
#[test] #[test]

View file

@ -21,6 +21,7 @@ const RELEASE_URL: &str = "https://github.com/denoland/deno/releases";
pub async fn upgrade_command( pub async fn upgrade_command(
dry_run: bool, dry_run: bool,
force: bool, force: bool,
canary: bool,
version: Option<String>, version: Option<String>,
output: Option<PathBuf>, output: Option<PathBuf>,
ca_file: Option<String>, ca_file: Option<String>,
@ -38,17 +39,35 @@ pub async fn upgrade_command(
let install_version = match version { let install_version = match version {
Some(passed_version) => { Some(passed_version) => {
if !force && output.is_none() && crate::version::deno() == passed_version let current_is_passed = if canary {
{ let mut passed_hash = passed_version.clone();
println!("Version {} is already installed", passed_version); 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(()); return Ok(());
} else { } else {
passed_version passed_version
} }
} }
None => { None => {
let latest_version = get_latest_version(&client).await?; 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 current = semver_parse(&*crate::version::deno()).unwrap();
let latest = match semver_parse(&latest_version) { let latest = match semver_parse(&latest_version) {
Ok(v) => v, Ok(v) => v,
@ -57,8 +76,12 @@ pub async fn upgrade_command(
std::process::exit(1) 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!( println!(
"Local deno version {} is the most recent release", "Local deno version {} is the most recent release",
crate::version::deno() 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); 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 new_exe_path = unpack(archive_data)?;
let permissions = fs::metadata(&old_exe_path)?.permissions(); let permissions = fs::metadata(&old_exe_path)?.permissions();
fs::set_permissions(&new_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 { if !dry_run {
match output { match output {
@ -96,7 +131,9 @@ pub async fn upgrade_command(
Ok(()) 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"); println!("Looking up latest version");
let res = client let res = client
@ -108,18 +145,27 @@ async fn get_latest_version(client: &Client) -> Result<String, AnyError> {
Ok(version.replace("v", "")) 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( async fn download_package(
client: Client, client: Client,
install_version: &str, download_url: &str,
) -> Result<Vec<u8>, AnyError> { ) -> Result<Vec<u8>, AnyError> {
let download_url = format!(
"{}/download/v{}/{}",
RELEASE_URL, install_version, *ARCHIVE_NAME
);
println!("Checking {}", &download_url); 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() { if res.status().is_success() {
println!("Download has been found"); println!("Download has been found");
@ -200,13 +246,11 @@ fn replace_exe(new: &Path, old: &Path) -> Result<(), std::io::Error> {
Ok(()) 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) let output = Command::new(exe_path)
.arg("-V") .arg("-V")
.stderr(std::process::Stdio::inherit()) .stderr(std::process::Stdio::inherit())
.output()?; .output()?;
let stdout = String::from_utf8(output.stdout)?;
assert!(output.status.success()); assert!(output.status.success());
assert_eq!(stdout.trim(), format!("deno {}", expected_version));
Ok(()) Ok(())
} }

View file

@ -10,6 +10,10 @@ pub fn deno() -> String {
}) })
} }
pub fn is_canary() -> bool {
option_env!("DENO_CANARY").is_some()
}
pub fn v8() -> &'static str { pub fn v8() -> &'static str {
deno_core::v8_version() deno_core::v8_version()
} }