Skip to content

Commit

Permalink
feat: allow version specification for deno (#970)
Browse files Browse the repository at this point in the history
* feat: allow version specification for deno

* fix: missing quotes for string in toml file

Co-authored-by: SteveLauC <[email protected]>

* 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 <[email protected]>

---------

Co-authored-by: SteveLauC <[email protected]>
  • Loading branch information
sehnryr and SteveLauC authored Oct 29, 2024
1 parent 98ec13f commit 444689c
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 3 deletions.
5 changes: 5 additions & 0 deletions config.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,11 @@
# use_sudo = true


[deno]
# Upgrade deno executable to the given version.
# version = "stable"


[vim]
# For `vim-plug`, execute `PlugUpdate!` instead of `PlugUpdate`
# force_plug_update = true
Expand Down
14 changes: 14 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,13 @@ pub struct NPM {
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)]
#[serde(deny_unknown_fields)]
#[allow(clippy::upper_case_acronyms)]
Expand Down Expand Up @@ -491,6 +498,9 @@ pub struct ConfigFile {
#[merge(strategy = crate::utils::merge_strategies::inner_merge_opt)]
yarn: Option<Yarn>,

#[merge(strategy = crate::utils::merge_strategies::inner_merge_opt)]
deno: Option<Deno>,

#[merge(strategy = crate::utils::merge_strategies::inner_merge_opt)]
vim: Option<Vim>,

Expand Down Expand Up @@ -1526,6 +1536,10 @@ impl Config {
.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")]
pub fn firmware_upgrade(&self) -> bool {
self.config_file
Expand Down
92 changes: 89 additions & 3 deletions src/steps/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
fn should_use_sudo(npm: &NPM, ctx: &ExecutionContext) -> Result<bool> {
if npm.should_use_sudo()? {
Expand Down Expand Up @@ -266,16 +352,16 @@ pub fn run_yarn_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");

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());
return Err(skip_reason.into());
}

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
Expand Down

0 comments on commit 444689c

Please sign in to comment.