Skip to content

Commit a0a1629

Browse files
authored
fix: distinguish latest and lts versions (#236)
1 parent 7c6da8e commit a0a1629

8 files changed

Lines changed: 198 additions & 64 deletions

File tree

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,10 @@ Options:
5353
EXAMPLE:
5454
dvm install 1.3.2 Install v1.3.2 release
5555
dvm install Install the latest available version
56+
dvm install lts Install the latest LTS version
5657
dvm use 1.0.0 Use v1.0.0 release
5758
dvm use latest Use the latest alias that comes with dvm, equivalent to *
59+
dvm use lts Use the latest LTS version
5860
dvm use canary Use the canary version of the Deno
5961

6062
NOTE:

README_zh-cn.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,10 @@ Options:
5454
EXAMPLE:
5555
dvm install 1.3.2 Install v1.3.2 release
5656
dvm install Install the latest available version
57+
dvm install lts Install the latest LTS version
5758
dvm use 1.0.0 Use v1.0.0 release
5859
dvm use latest Use the latest alias that comes with dvm, equivalent to *
60+
dvm use lts Use the latest LTS version
5961
dvm use canary Use the canary version of the Deno
6062

6163
NOTE:

src/commands/exec.rs

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
use std::process::Stdio;
22

33
use crate::{
4-
consts::DVM_VERSION_LATEST,
4+
consts::{DVM_VERSION_LATEST, DVM_VERSION_LTS},
55
meta::DvmMeta,
66
utils::{best_version, deno_version_path, is_exact_version, prompt_request},
7-
version::{remote_versions, VersionArg},
7+
version::{get_latest_lts_version, remote_versions, VersionArg},
88
};
99
use anyhow::Result;
1010
use colored::Colorize;
@@ -17,23 +17,34 @@ pub fn exec(meta: &mut DvmMeta, version: Option<String>, args: Vec<String>) -> R
1717
let version = version.unwrap_or_else(|| DVM_VERSION_LATEST.to_string());
1818
let v = version.clone();
1919

20-
let Some(version) = is_exact_version(&version).then_some(version).or_else(|| {
21-
meta.has_alias(&v).then(|| {
22-
let version_req = meta.resolve_version_req(&v);
23-
match version_req {
24-
VersionArg::Exact(v) => v.to_string(),
25-
VersionArg::Range(r) => {
26-
let best = best_version(versions.iter().map(AsRef::as_ref), r.clone());
27-
if let Some(best) = best {
28-
best.to_string()
29-
} else {
30-
eprintln!("No version found for {} in {:?}", r, versions);
31-
std::process::exit(1);
32-
}
20+
let version = if is_exact_version(&version) {
21+
version
22+
} else if version == DVM_VERSION_LTS {
23+
println!("Checking for latest LTS version");
24+
let version = get_latest_lts_version()?;
25+
println!("The latest LTS version is v{}", version);
26+
version.to_string()
27+
} else if meta.has_alias(&v) {
28+
let version_req = meta.resolve_version_req(&v);
29+
match version_req {
30+
VersionArg::Exact(v) => v.to_string(),
31+
VersionArg::Lts => {
32+
println!("Checking for latest LTS version");
33+
let version = get_latest_lts_version()?;
34+
println!("The latest LTS version is v{}", version);
35+
version.to_string()
36+
}
37+
VersionArg::Range(r) => {
38+
let best = best_version(versions.iter().map(AsRef::as_ref), r.clone());
39+
if let Some(best) = best {
40+
best.to_string()
41+
} else {
42+
eprintln!("No version found for {} in {:?}", r, versions);
43+
std::process::exit(1);
3344
}
3445
}
35-
})
36-
}) else {
46+
}
47+
} else {
3748
eprintln!("{}", "No such alias or version found.".red());
3849
std::process::exit(1);
3950
};

src/commands/install.rs

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
use super::use_version;
44
use crate::configrc::rc_get_with_fix;
55
use crate::consts::{
6-
DVM_CACHE_PATH_PREFIX, DVM_CANARY_PATH_PREFIX, DVM_CONFIGRC_KEY_REGISTRY_BINARY, DVM_VERSION_CANARY,
7-
DVM_VERSION_LATEST, REGISTRY_OFFICIAL,
6+
DVM_CACHE_PATH_PREFIX, DVM_CANARY_PATH_PREFIX, DVM_CONFIGRC_KEY_REGISTRY_BINARY, DVM_CONFIGRC_KEY_REGISTRY_VERSION,
7+
DVM_VERSION_CANARY, DVM_VERSION_LATEST, DVM_VERSION_LTS, REGISTRY_LIST_OFFICIAL, REGISTRY_OFFICIAL,
88
};
99
use crate::meta::DvmMeta;
1010
use crate::utils::{deno_canary_path, deno_version_path, dvm_root};
11-
use crate::version::get_latest_canary;
11+
use crate::version::{get_latest_canary, get_latest_lts_version, get_latest_remote_version};
1212
use anyhow::Result;
1313
use cfg_if::cfg_if;
1414
use semver::Version;
@@ -34,6 +34,8 @@ cfg_if! {
3434
pub fn exec(_: &DvmMeta, no_use: bool, version: Option<String>) -> Result<()> {
3535
let binary_registry_url =
3636
rc_get_with_fix(DVM_CONFIGRC_KEY_REGISTRY_BINARY).unwrap_or_else(|_| REGISTRY_OFFICIAL.to_string());
37+
let version_registry_url =
38+
rc_get_with_fix(DVM_CONFIGRC_KEY_REGISTRY_VERSION).unwrap_or_else(|_| REGISTRY_LIST_OFFICIAL.to_string());
3739

3840
if let Some(version) = version.clone() {
3941
if version == *DVM_VERSION_CANARY {
@@ -52,10 +54,27 @@ pub fn exec(_: &DvmMeta, no_use: bool, version: Option<String>) -> Result<()> {
5254
}
5355

5456
let install_version = match version {
57+
Some(ref passed_version) if passed_version == DVM_VERSION_LATEST => {
58+
println!("Checking for latest version");
59+
let version = get_latest_remote_version(&version_registry_url)?;
60+
println!("The latest version is v{}", version);
61+
version
62+
}
63+
Some(ref passed_version) if passed_version == DVM_VERSION_LTS => {
64+
println!("Checking for latest LTS version");
65+
let version = get_latest_lts_version()?;
66+
println!("The latest LTS version is v{}", version);
67+
version
68+
}
5569
Some(ref passed_version) => {
5670
Version::parse(passed_version).map_err(|_| anyhow::format_err!("Invalid semver {}", passed_version))?
5771
}
58-
None => get_latest_version(&binary_registry_url)?,
72+
None => {
73+
println!("Checking for latest version");
74+
let version = get_latest_remote_version(&version_registry_url)?;
75+
println!("The latest version is v{}", version);
76+
version
77+
}
5978
};
6079

6180
let exe_path = deno_version_path(&install_version);
@@ -82,17 +101,6 @@ pub fn exec(_: &DvmMeta, no_use: bool, version: Option<String>) -> Result<()> {
82101
Ok(())
83102
}
84103

85-
fn get_latest_version(registry: &str) -> Result<Version> {
86-
println!("Checking for latest version");
87-
88-
let response = tinyget::get(format!("{}release-latest.txt", registry)).send()?;
89-
90-
let body = response.as_str()?;
91-
let v = body.trim().replace('v', "");
92-
println!("The latest version is v{}", &v);
93-
Ok(Version::parse(&v).unwrap())
94-
}
95-
96104
fn download_package(url: &str, version: &Version) -> Result<Vec<u8>> {
97105
println!("downloading {}", &url);
98106

src/commands/upgrade.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::{
22
commands::install,
33
consts::{DVM_VERSION_CANARY, DVM_VERSION_INVALID, DVM_VERSION_SELF},
44
utils::best_version,
5-
version::{remote_versions, VersionArg},
5+
version::{get_latest_lts_version, remote_versions, VersionArg},
66
DvmMeta,
77
};
88
use anyhow::{Ok, Result};
@@ -46,6 +46,11 @@ pub fn exec(meta: &mut DvmMeta, alias: Option<String>) -> Result<()> {
4646
install::exec(meta, true, Some(v.to_string())).expect("Install failed");
4747
}
4848
}
49+
VersionArg::Lts => {
50+
let version = get_latest_lts_version()?;
51+
install::exec(meta, true, Some(version.to_string())).expect("Install failed");
52+
meta.set_version_mapping(alias, version.to_string());
53+
}
4954
VersionArg::Range(r) => {
5055
let version = best_version(versions.iter().map(AsRef::as_ref), r).unwrap();
5156
install::exec(meta, true, Some(version.to_string())).expect("Install failed");
@@ -60,6 +65,7 @@ pub fn exec(meta: &mut DvmMeta, alias: Option<String>) -> Result<()> {
6065

6166
let latest = match VersionArg::from_str(alias.required.clone().as_str()).unwrap() {
6267
VersionArg::Exact(v) => v.to_string(),
68+
VersionArg::Lts => get_latest_lts_version()?.to_string(),
6369
VersionArg::Range(v) => best_version(versions.iter().map(AsRef::as_ref), v).unwrap().to_string(),
6470
};
6571

src/commands/use_version.rs

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,27 @@
11
use crate::commands::install;
22
use crate::configrc::{rc_get_with_fix, rc_update};
33
use crate::consts::{
4-
DVM_CONFIGRC_KEY_DENO_VERSION, DVM_CONFIGRC_KEY_REGISTRY_BINARY, DVM_VERSION_CANARY, DVM_VERSION_LATEST,
5-
DVM_VERSION_SYSTEM, REGISTRY_OFFICIAL,
4+
DVM_CONFIGRC_KEY_DENO_VERSION, DVM_CONFIGRC_KEY_REGISTRY_VERSION, DVM_VERSION_CANARY, DVM_VERSION_LATEST,
5+
DVM_VERSION_LTS, DVM_VERSION_SYSTEM, REGISTRY_LIST_OFFICIAL,
66
};
77
use crate::deno_bin_path;
88
use crate::meta::DvmMeta;
99
use crate::utils::{best_version, deno_canary_path, deno_version_path, prompt_request, run_with_spinner, update_stub};
1010
use crate::utils::{is_exact_version, load_dvmrc};
1111
use crate::version::remote_versions;
12-
use crate::version::{get_latest_version, VersionArg};
12+
use crate::version::{get_latest_lts_version, get_latest_remote_version, VersionArg};
1313
use anyhow::Result;
14-
use semver::Version;
14+
use semver::{Version, VersionReq};
1515
use std::fs;
1616
use std::path::Path;
1717
use std::process::Command;
1818

1919
/// using a tag or a specific version
2020
pub fn exec(meta: &mut DvmMeta, version: Option<String>, write_local: bool) -> Result<()> {
21-
let rc_binary_url =
22-
rc_get_with_fix(DVM_CONFIGRC_KEY_REGISTRY_BINARY).unwrap_or_else(|_| REGISTRY_OFFICIAL.to_string());
21+
let rc_version_url =
22+
rc_get_with_fix(DVM_CONFIGRC_KEY_REGISTRY_VERSION).unwrap_or_else(|_| REGISTRY_LIST_OFFICIAL.to_string());
2323

24-
let version_req: VersionArg;
25-
if let Some(ref version) = version {
24+
let version_req = if let Some(ref version) = version {
2625
if version == &DVM_VERSION_CANARY.to_string() {
2726
let canary_path = deno_canary_path();
2827
if !canary_path.exists() {
@@ -40,12 +39,14 @@ pub fn exec(meta: &mut DvmMeta, version: Option<String>, write_local: bool) -> R
4039
std::fs::remove_file(deno_bin_path()).unwrap();
4140
println!("Deno that was previously installed on your system will be activated now.");
4241
return Ok(());
43-
}
44-
45-
if is_exact_version(version) {
46-
version_req = VersionArg::Exact(Version::parse(version).unwrap());
42+
} else if version == DVM_VERSION_LTS {
43+
VersionArg::Lts
44+
} else if version == DVM_VERSION_LATEST {
45+
VersionArg::Range(VersionReq::parse("*").unwrap())
46+
} else if is_exact_version(version) {
47+
VersionArg::Exact(Version::parse(version).unwrap())
4748
} else if meta.has_alias(version) {
48-
version_req = meta.resolve_version_req(version);
49+
meta.resolve_version_req(version)
4950
} else {
5051
// dvm will reject for using semver range directly now.
5152
eprintln!(
@@ -56,23 +57,29 @@ pub fn exec(meta: &mut DvmMeta, version: Option<String>, write_local: bool) -> R
5657
}
5758
} else {
5859
println!("No version input detect, try to use version in .dvmrc file");
59-
version_req = load_dvmrc();
60+
let version_req = load_dvmrc();
6061
println!("Using semver range: {}", version_req);
61-
}
62+
version_req
63+
};
6264

63-
let used_version = if version_req.to_string() == "*" {
64-
println!("Checking for latest version");
65-
let version = get_latest_version(&rc_binary_url).expect("Get latest version failed");
66-
println!("The latest version is v{}", version);
67-
version
68-
} else {
69-
match version_req {
70-
VersionArg::Exact(ref v) => v.clone(),
71-
VersionArg::Range(ref r) => {
72-
println!("Fetching version list");
73-
let versions = remote_versions().expect("Fetching version list failed.");
74-
best_version(versions.iter().map(AsRef::as_ref), r.clone()).unwrap()
75-
}
65+
let used_version = match &version_req {
66+
VersionArg::Lts => {
67+
println!("Checking for latest LTS version");
68+
let version = get_latest_lts_version()?;
69+
println!("The latest LTS version is v{}", version);
70+
version
71+
}
72+
VersionArg::Range(r) if r.to_string() == "*" => {
73+
println!("Checking for latest version");
74+
let version = get_latest_remote_version(&rc_version_url)?;
75+
println!("The latest version is v{}", version);
76+
version
77+
}
78+
VersionArg::Exact(v) => v.clone(),
79+
VersionArg::Range(r) => {
80+
println!("Fetching version list");
81+
let versions = remote_versions().expect("Fetching version list failed.");
82+
best_version(versions.iter().map(AsRef::as_ref), r.clone()).unwrap()
7683
}
7784
};
7885

src/consts.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ pub const DVM_CONFIGRC_KEY_REGISTRY_BINARY: &str = "registry_binary";
2121
pub const DVM_VERSION_SELF: &str = "self";
2222
pub const DVM_VERSION_CANARY: &str = "canary";
2323
pub const DVM_VERSION_LATEST: &str = "latest";
24+
pub const DVM_VERSION_LTS: &str = "lts";
2425
pub const DVM_VERSION_SYSTEM: &str = "system";
2526
pub const DVM_VERSION_INVALID: &str = "N/A";
2627

@@ -35,8 +36,10 @@ cfg_if::cfg_if! {
3536
pub const AFTER_HELP: &str = "\x1b[33mEXAMPLE:\x1b[39m
3637
dvm install 1.3.2 Install v1.3.2 release
3738
dvm install Install the latest available version
39+
dvm install lts Install the latest LTS version
3840
dvm use 1.0.0 Use v1.0.0 release
3941
dvm use latest Use the latest alias that comes with dvm, equivalent to *
42+
dvm use lts Use the latest LTS version
4043
dvm use canary Use the canary version of the Deno
4144
4245
\x1b[33mNOTE:\x1b[39m

0 commit comments

Comments
 (0)