Skip to content

Commit

Permalink
feat: added support for lts/* syntax in nvmrc (#1230)
Browse files Browse the repository at this point in the history
* feat(test): added to_json tests

* feat(nvm): added support for  syntax in nvmrc

* feat(tests): added tests for  support of nvmrc

* fix(clippy): corrected clippy suggestions

* feat(docs): added nvmrc in node docs

---------

Co-authored-by: Jake Runzer <[email protected]>
  • Loading branch information
shubhexists and coffee-cup authored Dec 5, 2024
1 parent fddbf66 commit 90443a4
Show file tree
Hide file tree
Showing 11 changed files with 152 additions and 1 deletion.
1 change: 1 addition & 0 deletions docs/pages/docs/providers/node.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ The version can be overridden by

- Setting the `NIXPACKS_NODE_VERSION` environment variable
- Specifying the `engines.node` field in `package.json`
- Creating a `.nvmrc` file in your project and specify the version or alias (`lts/*`)

Only a major version can be specified. For example, `18.x` or `20`.

Expand Down
1 change: 1 addition & 0 deletions examples/node-nvmrc-invalid-lts/.nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
some_invalid_version
1 change: 1 addition & 0 deletions examples/node-nvmrc-invalid-lts/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log("Oops this version is invalid. Using default 18");
13 changes: 13 additions & 0 deletions examples/node-nvmrc-invalid-lts/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions examples/node-nvmrc-invalid-lts/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "node",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"start": "node index.js"
}
}
1 change: 1 addition & 0 deletions examples/node-nvmrc-lts/.nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
lts/iron
1 change: 1 addition & 0 deletions examples/node-nvmrc-lts/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log("Hello from the NVM test");
13 changes: 13 additions & 0 deletions examples/node-nvmrc-lts/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions examples/node-nvmrc-lts/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "node",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"start": "node index.js"
}
}
41 changes: 41 additions & 0 deletions src/nixpacks/plan/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,47 @@ mod test {
assert_eq!(result, env_plan);
}

#[test]
fn test_to_json_and_from_json() {
let original_plan = BuildPlan::from_toml(
r#"
[phases.setup]
nixPkgs = ["nodejs", "yarn"]
aptPkgs = ["git"]
[phases.install]
cmds = ["yarn install"]
cacheDirectories = ["node_modules"]
dependsOn = ["setup"]
[phases.build]
cmds = ["yarn build"]
dependsOn = ["install"]
[start]
cmd = "yarn start"
"#,
)
.unwrap();

let json_str = original_plan.to_json().unwrap();
let deserialized_plan = BuildPlan::from_json(json_str).unwrap();

assert_eq!(original_plan, deserialized_plan);
assert_eq!(
deserialized_plan.get_phase("setup").unwrap().nix_pkgs,
Some(vec!["nodejs".to_string(), "yarn".to_string()])
);
assert_eq!(
deserialized_plan.get_phase("setup").unwrap().apt_pkgs,
Some(vec!["git".to_string()])
);
assert_eq!(
deserialized_plan.start_phase.unwrap().cmd.unwrap(),
"yarn start".to_string()
);
}

#[test]
fn test_get_phases_with_dependencies() {
let setup = Phase::new("setup");
Expand Down
65 changes: 64 additions & 1 deletion src/providers/node/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ impl NodeProvider {

let nvmrc_node_version = if app.includes_file(".nvmrc") {
let nvmrc = app.read_file(".nvmrc")?;
Some(nvmrc.trim().replace('v', ""))
Some(parse_nvmrc(&nvmrc))
} else {
None
};
Expand Down Expand Up @@ -636,6 +636,35 @@ fn parse_node_version_into_pkg(node_version: &str) -> String {
default_node_pkg_name
}

fn parse_nvmrc(nvmrc_content: &str) -> String {
let lts_versions: HashMap<&str, u32> = {
let mut nvm_map = HashMap::new();
nvm_map.insert("lts/*", 22);
nvm_map.insert("lts/jod", 22);
nvm_map.insert("lts/argon", 4);
nvm_map.insert("lts/boron", 6);
nvm_map.insert("lts/carbon", 8);
nvm_map.insert("lts/dubnium", 10);
nvm_map.insert("lts/erbium", 12);
nvm_map.insert("lts/fermium", 14);
nvm_map.insert("lts/gallium", 16);
nvm_map.insert("lts/hydrogen", 18);
nvm_map.insert("lts/iron", 20);
nvm_map
};

let trimmed_version = nvmrc_content.trim();
if let Some(&version) = lts_versions.get(trimmed_version) {
return version.to_string();
}

// Only remove v if it is in the starting character, lts/ will never have that in starting
trimmed_version
.strip_prefix('v')
.unwrap_or(trimmed_version)
.to_string()
}

#[cfg(test)]
mod test {
use std::collections::BTreeMap;
Expand Down Expand Up @@ -932,6 +961,40 @@ mod test {
Ok(())
}

#[test]
fn test_version_from_nvmrc_lts() -> Result<()> {
assert_eq!(
NodeProvider::get_nix_node_pkg(
&PackageJson {
name: Some(String::default()),
..Default::default()
},
&App::new("examples/node-nvmrc-lts")?,
&Environment::default()
)?,
Pkg::new("nodejs_20")
);

Ok(())
}

#[test]
fn test_invalid_version_from_nvmrc_lts() -> Result<()> {
assert_eq!(
NodeProvider::get_nix_node_pkg(
&PackageJson {
name: Some(String::default()),
..Default::default()
},
&App::new("examples/node-nvmrc-invalid-lts")?,
&Environment::default()
)?,
Pkg::new("nodejs_18")
);

Ok(())
}

#[test]
fn test_engine_invalid_version() -> Result<()> {
// this test now defaults to lts
Expand Down

0 comments on commit 90443a4

Please sign in to comment.