1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-24 15:19:26 -05:00

refactor: show release channel in deno --version (#25061)

Also simplifies handling of various release channels in `deno upgrade`
subcommand.
This commit is contained in:
Bartek Iwańczuk 2024-08-16 21:42:19 +01:00 committed by GitHub
parent ff4226a3cd
commit db75462bd6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 30 additions and 181 deletions

View file

@ -36,7 +36,6 @@ use std::path::PathBuf;
use std::str::FromStr; use std::str::FromStr;
use crate::args::resolve_no_prompt; use crate::args::resolve_no_prompt;
use crate::shared::ReleaseChannel;
use crate::util::fs::canonicalize_path; use crate::util::fs::canonicalize_path;
use super::flags_net; use super::flags_net;
@ -1333,27 +1332,10 @@ static UNSTABLE_HEADING: &str = "Unstable";
pub fn clap_root() -> Command { pub fn clap_root() -> Command {
let long_version = format!( let long_version = format!(
"{} ({}, {})\nv8 {}\ntypescript {}", "{} ({}, {}, {})\nv8 {}\ntypescript {}",
crate::version::DENO_VERSION_INFO.deno, crate::version::DENO_VERSION_INFO.deno,
// TODO(bartlomieju): alter what's printed here. crate::version::DENO_VERSION_INFO.release_channel.name(),
// I think it's best if we print as follows: env!("PROFILE"),
// <version>(+<short_git_hash>) (<release_channel>, <profile>, <target>)
// For stable it would be:
// v1.46.0 (stable, release, aarch64-apple-darwin)
// For rc it would be:
// v1.46.0-rc.2 (release candidate, release, aarch64-apple-darwin)
// For lts it would be:
// v2.1.13-lts (LTS (long term support), release, aarch64-apple-darwin)
// For canary it would be:
// v1.46.0+25bb59d (canary, release, aarch64-apple-darwin)
if matches!(
crate::version::DENO_VERSION_INFO.release_channel,
ReleaseChannel::Canary
) {
"canary"
} else {
env!("PROFILE")
},
env!("TARGET"), env!("TARGET"),
deno_core::v8_version(), deno_core::v8_version(),
crate::version::DENO_VERSION_INFO.typescript crate::version::DENO_VERSION_INFO.typescript

View file

@ -16,17 +16,17 @@ pub enum ReleaseChannel {
#[allow(unused)] #[allow(unused)]
Lts, Lts,
/// Release candidate, poiting to a git hash /// Release candidate, eg. 1.46.0-rc.0, 2.0.0-rc.1
Rc, Rc,
} }
impl ReleaseChannel { impl ReleaseChannel {
pub fn name(&self) -> &str { pub fn name(&self) -> &str {
match self { match self {
Self::Stable => "latest", Self::Stable => "stable",
Self::Canary => "canary", Self::Canary => "canary",
Self::Rc => "release candidate", Self::Rc => "release candidate",
Self::Lts => "LTS (long term support)", Self::Lts => "long term support",
} }
} }

View file

@ -101,10 +101,7 @@ trait VersionProvider: Clone {
/// and "lts" versions use semver. /// and "lts" versions use semver.
fn current_version(&self) -> Cow<str>; fn current_version(&self) -> Cow<str>;
// TODO(bartlomieju): update to handle `Lts` channel fn get_current_exe_release_channel(&self) -> ReleaseChannel;
async fn get_current_exe_release_channel(
&self,
) -> Result<ReleaseChannel, AnyError>;
} }
#[derive(Clone)] #[derive(Clone)]
@ -143,36 +140,8 @@ impl VersionProvider for RealVersionProvider {
Cow::Borrowed(version::DENO_VERSION_INFO.version_or_git_hash()) Cow::Borrowed(version::DENO_VERSION_INFO.version_or_git_hash())
} }
// TODO(bartlomieju): update to handle `Lts` channel fn get_current_exe_release_channel(&self) -> ReleaseChannel {
async fn get_current_exe_release_channel( version::DENO_VERSION_INFO.release_channel
&self,
) -> Result<ReleaseChannel, AnyError> {
// TODO(bartlomieju): remove hitting a remote server
if matches!(
version::DENO_VERSION_INFO.release_channel,
ReleaseChannel::Canary
) {
// If this fails for whatever reason, just return an empty vector.
// It's better to miss that than throw error here.
let rc_versions = get_rc_versions(
&self.http_client_provider.get_or_create()?,
self.check_kind,
)
.await
.unwrap_or_else(|_| vec![]);
let is_current_exe_an_rc = rc_versions
.iter()
.any(|(hash, _)| hash == version::DENO_VERSION_INFO.git_hash);
if is_current_exe_an_rc {
Ok(ReleaseChannel::Rc)
} else {
Ok(ReleaseChannel::Canary)
}
} else {
Ok(ReleaseChannel::Stable)
}
} }
} }
@ -389,8 +358,7 @@ pub async fn check_for_upgrades_for_lsp(
async fn check_for_upgrades_for_lsp_with_provider( async fn check_for_upgrades_for_lsp_with_provider(
version_provider: &impl VersionProvider, version_provider: &impl VersionProvider,
) -> Result<Option<LspVersionUpgradeInfo>, AnyError> { ) -> Result<Option<LspVersionUpgradeInfo>, AnyError> {
let release_channel = let release_channel = version_provider.get_current_exe_release_channel();
version_provider.get_current_exe_release_channel().await?;
let latest_version = version_provider.latest_version(release_channel).await?; let latest_version = version_provider.latest_version(release_channel).await?;
let current_version = version_provider.current_version(); let current_version = version_provider.current_version();
@ -400,7 +368,7 @@ async fn check_for_upgrades_for_lsp_with_provider(
} }
match release_channel { match release_channel {
ReleaseChannel::Stable => { ReleaseChannel::Stable | ReleaseChannel::Rc => {
if let Ok(current) = Version::parse_standard(&current_version) { if let Ok(current) = Version::parse_standard(&current_version) {
if let Ok(latest) = if let Ok(latest) =
Version::parse_standard(&latest_version.version_or_hash) Version::parse_standard(&latest_version.version_or_hash)
@ -421,11 +389,6 @@ async fn check_for_upgrades_for_lsp_with_provider(
is_canary: true, is_canary: true,
})), })),
ReleaseChannel::Rc => Ok(Some(LspVersionUpgradeInfo {
latest_version: latest_version.display,
is_canary: true,
})),
// TODO(bartlomieju) // TODO(bartlomieju)
ReleaseChannel::Lts => unreachable!(), ReleaseChannel::Lts => unreachable!(),
} }
@ -438,12 +401,7 @@ async fn fetch_and_store_latest_version<
env: &TEnvironment, env: &TEnvironment,
version_provider: &TVersionProvider, version_provider: &TVersionProvider,
) { ) {
// Fetch latest version or commit hash from server. let release_channel = version_provider.get_current_exe_release_channel();
let Ok(release_channel) =
version_provider.get_current_exe_release_channel().await
else {
return;
};
let Ok(latest_version) = let Ok(latest_version) =
version_provider.latest_version(release_channel).await version_provider.latest_version(release_channel).await
else { else {
@ -644,10 +602,9 @@ fn select_specific_version_for_upgrade(
) -> Result<Option<AvailableVersion>, AnyError> { ) -> Result<Option<AvailableVersion>, AnyError> {
match release_channel { match release_channel {
ReleaseChannel::Stable => { ReleaseChannel::Stable => {
let current_is_passed = if !matches!( let current_is_passed = if version::DENO_VERSION_INFO.release_channel
version::DENO_VERSION_INFO.release_channel, != ReleaseChannel::Canary
ReleaseChannel::Canary {
) {
version::DENO_VERSION_INFO.deno == version version::DENO_VERSION_INFO.deno == version
} else { } else {
false false
@ -708,10 +665,9 @@ async fn find_latest_version_to_upgrade(
let (maybe_newer_latest_version, current_version) = match release_channel { let (maybe_newer_latest_version, current_version) = match release_channel {
ReleaseChannel::Stable => { ReleaseChannel::Stable => {
let current_version = version::DENO_VERSION_INFO.deno; let current_version = version::DENO_VERSION_INFO.deno;
let current_is_most_recent = if !matches!( let current_is_most_recent = if version::DENO_VERSION_INFO.release_channel
version::DENO_VERSION_INFO.release_channel, != ReleaseChannel::Canary
ReleaseChannel::Canary {
) {
let current = Version::parse_standard(current_version).unwrap(); let current = Version::parse_standard(current_version).unwrap();
let latest = let latest =
Version::parse_standard(&latest_version_found.version_or_hash) Version::parse_standard(&latest_version_found.version_or_hash)
@ -771,46 +727,11 @@ async fn find_latest_version_to_upgrade(
Ok(maybe_newer_latest_version) Ok(maybe_newer_latest_version)
} }
// Return a list of available RC release in format of (<commit_hash>, <version_name>)
fn parse_rc_versions_text(
text: &str,
) -> Result<Vec<(String, String)>, AnyError> {
let lines: Vec<_> = text
.split("\n")
.map(|s| s.to_string())
.filter(|s| !s.is_empty())
.collect();
if lines.is_empty() {
bail!("No release candidates available");
}
let mut parsed = Vec::with_capacity(lines.len());
for line in lines {
let v = line.split(' ').collect::<Vec<_>>();
if v.len() != 2 {
bail!("Malformed list of RC releases");
}
parsed.push((v[0].to_string(), v[1].to_string()));
}
Ok(parsed)
}
async fn get_rc_versions(
client: &HttpClient,
check_kind: UpgradeCheckKind,
) -> Result<Vec<(String, String)>, AnyError> {
let url =
get_latest_version_url(ReleaseChannel::Rc, env!("TARGET"), check_kind);
let text = client.download_text(url.parse()?).await?;
parse_rc_versions_text(&text)
}
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
struct AvailableVersion { struct AvailableVersion {
version_or_hash: String, version_or_hash: String,
release_channel: ReleaseChannel, release_channel: ReleaseChannel,
// TODO(bartlomieju): remove this one
display: String, display: String,
} }
@ -842,7 +763,7 @@ fn normalize_version_from_server(
) -> Result<AvailableVersion, AnyError> { ) -> Result<AvailableVersion, AnyError> {
let text = text.trim(); let text = text.trim();
match release_channel { match release_channel {
ReleaseChannel::Stable => { ReleaseChannel::Stable | ReleaseChannel::Rc | ReleaseChannel::Lts => {
let v = text.trim_start_matches('v').to_string(); let v = text.trim_start_matches('v').to_string();
Ok(AvailableVersion { Ok(AvailableVersion {
version_or_hash: v.to_string(), version_or_hash: v.to_string(),
@ -855,16 +776,6 @@ fn normalize_version_from_server(
release_channel, release_channel,
display: text.to_string(), display: text.to_string(),
}), }),
ReleaseChannel::Rc => {
let lines = parse_rc_versions_text(text)?;
let latest = lines.last().unwrap();
Ok(AvailableVersion {
version_or_hash: latest.0.to_string(),
release_channel,
display: latest.1.to_string(),
})
}
_ => unreachable!(),
} }
} }
@ -1126,43 +1037,6 @@ mod test {
assert!(result.is_none()); assert!(result.is_none());
} }
#[test]
fn test_parse_rc_versions_text() {
let rc_versions = parse_rc_versions_text(
r#"qwerw3452gbxcvbarwett234 v1.46.0-rc.0
cvbnfhuertt23523452345 v1.46.0-rc.1
sdfq3452345egasdfgsdgf v2.0.0-rc.0
asdf456yegfncbvjwe4523 v2.0.0-rc.1
hjr6562w34rgzcvh56734a v2.0.0-rc.2
bdfgtd6wergsdg3243234v v2.0.0-rc.3
"#,
)
.unwrap();
assert_eq!(rc_versions.len(), 6);
assert_eq!(rc_versions[3].0, "asdf456yegfncbvjwe4523");
assert_eq!(rc_versions[3].1, "v2.0.0-rc.1");
let rc_versions = parse_rc_versions_text(
r#"qwerw3452gbxcvbarwett234 v1.46.0-rc.0
cvbnfhuertt23523452345 v1.46.0-rc.1
"#,
)
.unwrap();
assert_eq!(rc_versions.len(), 2);
assert_eq!(rc_versions[1].0, "cvbnfhuertt23523452345");
assert_eq!(rc_versions[1].1, "v1.46.0-rc.1");
let err =
parse_rc_versions_text(r#"qwerw3452gbxcvbarwett234 v1.46.0-rc.0"#)
.unwrap_err();
assert_eq!(err.to_string(), "Malformed list of RC releases");
let err = parse_rc_versions_text("").unwrap_err();
assert_eq!(err.to_string(), "No release candidates available");
}
#[test] #[test]
fn test_serialize_upgrade_check_file() { fn test_serialize_upgrade_check_file() {
let mut file = CheckVersionFile { let mut file = CheckVersionFile {
@ -1276,10 +1150,8 @@ cvbnfhuertt23523452345 v1.46.0-rc.1
Cow::Owned(self.current_version.borrow().clone()) Cow::Owned(self.current_version.borrow().clone())
} }
async fn get_current_exe_release_channel( fn get_current_exe_release_channel(&self) -> ReleaseChannel {
&self, *self.release_channel.borrow()
) -> Result<ReleaseChannel, AnyError> {
Ok(*self.release_channel.borrow())
} }
} }
@ -1575,15 +1447,12 @@ cvbnfhuertt23523452345 v1.46.0-rc.1
} }
); );
assert_eq!( assert_eq!(
normalize_version_from_server( normalize_version_from_server(ReleaseChannel::Rc, "v1.46.0-rc.0\n\n")
ReleaseChannel::Rc, .unwrap(),
"asdfq345wdfasdfasdf v1.46.0-rc.0\nasdfq345wdfasdfasdf v1.46.0-rc.1\n"
)
.unwrap(),
AvailableVersion { AvailableVersion {
version_or_hash: "asdfq345wdfasdfasdf".to_string(), version_or_hash: "1.46.0-rc.0".to_string(),
release_channel: ReleaseChannel::Rc, release_channel: ReleaseChannel::Rc,
display: "v1.46.0-rc.1".to_string(), display: "1.46.0-rc.0".to_string(),
}, },
); );
} }
@ -1668,7 +1537,7 @@ cvbnfhuertt23523452345 v1.46.0-rc.1
maybe_info, maybe_info,
Some(LspVersionUpgradeInfo { Some(LspVersionUpgradeInfo {
latest_version: "1.2.3-rc.1".to_string(), latest_version: "1.2.3-rc.1".to_string(),
is_canary: true, is_canary: false,
}) })
); );
} }

View file

@ -23,8 +23,7 @@ pub static DENO_VERSION_INFO: Lazy<DenoVersionInfo> = Lazy::new(|| {
}); });
DenoVersionInfo { DenoVersionInfo {
// TODO(bartlomieju): fix further for RC and LTS releases deno: if release_channel == ReleaseChannel::Canary {
deno: if IS_CANARY {
concat!( concat!(
env!("CARGO_PKG_VERSION"), env!("CARGO_PKG_VERSION"),
"+", "+",
@ -39,8 +38,7 @@ pub static DENO_VERSION_INFO: Lazy<DenoVersionInfo> = Lazy::new(|| {
git_hash: GIT_COMMIT_HASH, git_hash: GIT_COMMIT_HASH,
// Keep in sync with `deno` field. // Keep in sync with `deno` field.
// TODO(bartlomieju): fix further for RC and LTS releases user_agent: if release_channel == ReleaseChannel::Canary {
user_agent: if IS_CANARY {
concat!( concat!(
"Deno/", "Deno/",
env!("CARGO_PKG_VERSION"), env!("CARGO_PKG_VERSION"),
@ -77,7 +75,7 @@ impl DenoVersionInfo {
/// For stable release, a semver like, eg. `v1.46.2`. /// For stable release, a semver like, eg. `v1.46.2`.
/// For canary release a full git hash, eg. `9bdab6fb6b93eb43b1930f40987fa4997287f9c8`. /// For canary release a full git hash, eg. `9bdab6fb6b93eb43b1930f40987fa4997287f9c8`.
pub fn version_or_git_hash(&self) -> &'static str { pub fn version_or_git_hash(&self) -> &'static str {
if IS_CANARY { if self.release_channel == ReleaseChannel::Canary {
self.git_hash self.git_hash
} else { } else {
CARGO_PKG_VERSION CARGO_PKG_VERSION