Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow version specification for deno #970

Merged
merged 6 commits into from
Oct 29, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
79 changes: 76 additions & 3 deletions src/steps/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,79 @@ 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" => {}
sehnryr marked this conversation as resolved.
Show resolved Hide resolved
"rc" => {
return Err(SkipStep("Deno v1.x cannot be upgraded to a release candidate".to_string()).into());
sehnryr marked this conversation as resolved.
Show resolved Hide resolved
}
"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 v1.x 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(())
}

fn version(&self) -> Result<Version> {
let version_str = Command::new(&self.command)
sehnryr marked this conversation as resolved.
Show resolved Hide resolved
.args(["-V"])
.output_checked_utf8()
.map(|s| s.stdout.trim().to_owned().split_off(5));
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 +339,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