feat: allow version specification for deno (#970)
* feat: allow version specification for deno * fix: missing quotes for string in toml file Co-authored-by: SteveLauC <stevelauc@outlook.com> * fix: deno upgrade for different executable versions * fix: tell apart the two cases for v1.x in SkipStep reason * docs: add comments and documentation on version method for deno * chore: add explanatory comment on stable channel that does nothing Co-authored-by: SteveLauC <stevelauc@outlook.com> --------- Co-authored-by: SteveLauC <stevelauc@outlook.com>
This commit is contained in:
@@ -223,6 +223,11 @@
|
|||||||
# use_sudo = true
|
# use_sudo = true
|
||||||
|
|
||||||
|
|
||||||
|
[deno]
|
||||||
|
# Upgrade deno executable to the given version.
|
||||||
|
# version = "stable"
|
||||||
|
|
||||||
|
|
||||||
[vim]
|
[vim]
|
||||||
# For `vim-plug`, execute `PlugUpdate!` instead of `PlugUpdate`
|
# For `vim-plug`, execute `PlugUpdate!` instead of `PlugUpdate`
|
||||||
# force_plug_update = true
|
# force_plug_update = true
|
||||||
|
|||||||
@@ -255,6 +255,13 @@ pub struct NPM {
|
|||||||
use_sudo: Option<bool>,
|
use_sudo: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Default, Debug, Merge)]
|
||||||
|
#[serde(deny_unknown_fields)]
|
||||||
|
#[allow(clippy::upper_case_acronyms)]
|
||||||
|
pub struct Deno {
|
||||||
|
version: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Default, Debug, Merge)]
|
#[derive(Deserialize, Default, Debug, Merge)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
#[allow(clippy::upper_case_acronyms)]
|
#[allow(clippy::upper_case_acronyms)]
|
||||||
@@ -491,6 +498,9 @@ pub struct ConfigFile {
|
|||||||
#[merge(strategy = crate::utils::merge_strategies::inner_merge_opt)]
|
#[merge(strategy = crate::utils::merge_strategies::inner_merge_opt)]
|
||||||
yarn: Option<Yarn>,
|
yarn: Option<Yarn>,
|
||||||
|
|
||||||
|
#[merge(strategy = crate::utils::merge_strategies::inner_merge_opt)]
|
||||||
|
deno: Option<Deno>,
|
||||||
|
|
||||||
#[merge(strategy = crate::utils::merge_strategies::inner_merge_opt)]
|
#[merge(strategy = crate::utils::merge_strategies::inner_merge_opt)]
|
||||||
vim: Option<Vim>,
|
vim: Option<Vim>,
|
||||||
|
|
||||||
@@ -1526,6 +1536,10 @@ impl Config {
|
|||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn deno_version(&self) -> Option<&str> {
|
||||||
|
self.config_file.deno.as_ref().and_then(|deno| deno.version.as_deref())
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
pub fn firmware_upgrade(&self) -> bool {
|
pub fn firmware_upgrade(&self) -> bool {
|
||||||
self.config_file
|
self.config_file
|
||||||
|
|||||||
@@ -184,6 +184,92 @@ impl Yarn {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Deno {
|
||||||
|
command: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deno {
|
||||||
|
fn new(command: PathBuf) -> Self {
|
||||||
|
Self { command }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn upgrade(&self, ctx: &ExecutionContext) -> Result<()> {
|
||||||
|
let mut args = vec![];
|
||||||
|
|
||||||
|
let version = ctx.config().deno_version();
|
||||||
|
if let Some(version) = version {
|
||||||
|
let bin_version = self.version()?;
|
||||||
|
|
||||||
|
if bin_version >= Version::new(2, 0, 0) {
|
||||||
|
args.push(version);
|
||||||
|
} else if bin_version >= Version::new(1, 6, 0) {
|
||||||
|
match version {
|
||||||
|
"stable" => { /* do nothing, as stable is the default channel to upgrade */ }
|
||||||
|
"rc" => {
|
||||||
|
return Err(SkipStep(
|
||||||
|
"Deno (1.6.0-2.0.0) cannot be upgraded to a release candidate".to_string(),
|
||||||
|
)
|
||||||
|
.into());
|
||||||
|
}
|
||||||
|
"canary" => args.push("--canary"),
|
||||||
|
_ => {
|
||||||
|
if Version::parse(version).is_err() {
|
||||||
|
return Err(SkipStep("Invalid Deno version".to_string()).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
args.push("--version");
|
||||||
|
args.push(version);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if bin_version >= Version::new(1, 0, 0) {
|
||||||
|
match version {
|
||||||
|
"stable" | "rc" | "canary" => {
|
||||||
|
// Prior to v1.6.0, `deno upgrade` is not able fetch the latest tag version.
|
||||||
|
return Err(
|
||||||
|
SkipStep("Deno (1.0.0-1.6.0) cannot be upgraded to a named channel".to_string()).into(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
if Version::parse(version).is_err() {
|
||||||
|
return Err(SkipStep("Invalid Deno version".to_string()).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
args.push("--version");
|
||||||
|
args.push(version);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// v0.x cannot be upgraded with `deno upgrade` to v1.x or v2.x
|
||||||
|
// nor can be upgraded to a specific version.
|
||||||
|
return Err(SkipStep("Unsupported Deno version".to_string()).into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.run_type()
|
||||||
|
.execute(&self.command)
|
||||||
|
.arg("upgrade")
|
||||||
|
.args(args)
|
||||||
|
.status_checked()?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the version of Deno.
|
||||||
|
///
|
||||||
|
/// This function will return the version of Deno installed on the system.
|
||||||
|
/// The version is parsed from the output of `deno -V`.
|
||||||
|
///
|
||||||
|
/// ```sh
|
||||||
|
/// deno -V # deno 1.6.0
|
||||||
|
/// ```
|
||||||
|
fn version(&self) -> Result<Version> {
|
||||||
|
let version_str = Command::new(&self.command)
|
||||||
|
.args(["-V"])
|
||||||
|
.output_checked_utf8()
|
||||||
|
.map(|s| s.stdout.trim().to_owned().split_off(5)); // remove "deno " prefix
|
||||||
|
Version::parse(&version_str?).map_err(|err| err.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
fn should_use_sudo(npm: &NPM, ctx: &ExecutionContext) -> Result<bool> {
|
fn should_use_sudo(npm: &NPM, ctx: &ExecutionContext) -> Result<bool> {
|
||||||
if npm.should_use_sudo()? {
|
if npm.should_use_sudo()? {
|
||||||
@@ -266,16 +352,16 @@ pub fn run_yarn_upgrade(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn deno_upgrade(ctx: &ExecutionContext) -> Result<()> {
|
pub fn deno_upgrade(ctx: &ExecutionContext) -> Result<()> {
|
||||||
let deno = require("deno")?;
|
let deno = require("deno").map(Deno::new)?;
|
||||||
let deno_dir = HOME_DIR.join(".deno");
|
let deno_dir = HOME_DIR.join(".deno");
|
||||||
|
|
||||||
if !deno.canonicalize()?.is_descendant_of(&deno_dir) {
|
if !deno.command.canonicalize()?.is_descendant_of(&deno_dir) {
|
||||||
let skip_reason = SkipStep(t!("Deno installed outside of .deno directory").to_string());
|
let skip_reason = SkipStep(t!("Deno installed outside of .deno directory").to_string());
|
||||||
return Err(skip_reason.into());
|
return Err(skip_reason.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
print_separator("Deno");
|
print_separator("Deno");
|
||||||
ctx.run_type().execute(&deno).arg("upgrade").status_checked()
|
deno.upgrade(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// There is no `volta upgrade` command, so we need to upgrade each package
|
/// There is no `volta upgrade` command, so we need to upgrade each package
|
||||||
|
|||||||
Reference in New Issue
Block a user