mirror of
https://github.com/denoland/deno.git
synced 2024-12-26 00:59:24 -05:00
feat(cli/tools/upgrade): canary support (#8476)
This commit is contained in:
parent
47a16d2118
commit
973af61d8b
5 changed files with 118 additions and 30 deletions
10
cli/flags.rs
10
cli/flags.rs
|
@ -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()),
|
||||||
|
|
|
@ -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(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue