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: added support for lts/* syntax in nvmrc #1230

Merged
merged 6 commits into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
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() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good test 🙂

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
Loading