Repository: railwayapp/nixpacks
Pull request #195 (2022-06-08 21:19:11)

Canvas provider
This PR adds required libraries and variables for [canvas](https://www.npmjs.com/package/canvas) projects.


Patch:
diff --git a/Cargo.lock b/Cargo.lock
index d9f750c..088596c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -260,7 +260,7 @@ checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
 
 [[package]]
 name = "nixpacks"
-version = "0.0.21"
+version = "0.0.22"
 dependencies = [
  "anyhow",
  "clap",
diff --git a/Cargo.toml b/Cargo.toml
index ab6565e..4944c01 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "nixpacks"
-version = "0.0.21"
+version = "0.0.22"
 edition = "2021"
 license = "MIT"
 authors = ["Railway <contact@railway.app>"]
diff --git a/examples/node-no-lockfile-canvas/index.js b/examples/node-no-lockfile-canvas/index.js
new file mode 100644
index 0000000..e8e31fe
--- /dev/null
+++ b/examples/node-no-lockfile-canvas/index.js
@@ -0,0 +1,2 @@
+require("canvas");
+console.log("Hello from Node canvas");
diff --git a/examples/node-no-lockfile/package.json b/examples/node-no-lockfile-canvas/package.json
similarity index 70%
rename from examples/node-no-lockfile/package.json
rename to examples/node-no-lockfile-canvas/package.json
index 2f12d8f..0953c6f 100644
--- a/examples/node-no-lockfile/package.json
+++ b/examples/node-no-lockfile-canvas/package.json
@@ -4,5 +4,8 @@
   "main": "index.js",
   "scripts": {
     "start": "node index.js"
+  },
+  "dependencies": {
+    "canvas": "^2.9.1"
   }
 }
diff --git a/examples/node-no-lockfile/index.js b/examples/node-no-lockfile/index.js
deleted file mode 100644
index bc8aaff..0000000
--- a/examples/node-no-lockfile/index.js
+++ /dev/null
@@ -1,1 +0,0 @@
-console.log("Hello from Node");
diff --git a/src/nixpacks/images.rs b/src/nixpacks/images.rs
index 4a354e9..b1a6816 100644
--- a/src/nixpacks/images.rs
+++ b/src/nixpacks/images.rs
@@ -1,3 +1,3 @@
-pub static DEFAULT_BASE_IMAGE: &str = "ghcr.io/railwayapp/nixpacks:debian-1654798583";
+pub static DEFAULT_BASE_IMAGE: &str = "ghcr.io/railwayapp/nixpacks:debian-1654800960";
 
 pub static DEBIAN_SLIM_IMAGE: &str = "debian:bullseye-slim";
diff --git a/src/providers/node.rs b/src/providers/node.rs
index 9d3ef8a..6d4ffe4 100644
--- a/src/providers/node.rs
+++ b/src/providers/node.rs
@@ -36,7 +36,12 @@ impl Provider for NodeProvider {
 
     fn setup(&self, app: &App, env: &Environment) -> Result<Option<SetupPhase>> {
         let packages = NodeProvider::get_nix_packages(app, env)?;
-        Ok(Some(SetupPhase::new(packages)))
+        let mut setup_phase = SetupPhase::new(packages);
+        if NodeProvider::uses_canvas(app) {
+            setup_phase.add_library("libuuid".to_string());
+            setup_phase.add_library("libGL".to_string());
+        }
+        Ok(Some(setup_phase))
     }
 
     fn install(&self, app: &App, _env: &Environment) -> Result<Option<InstallPhase>> {
@@ -177,24 +182,34 @@ impl NodeProvider {
     pub fn get_nix_packages(app: &App, env: &Environment) -> Result<Vec<Pkg>> {
         let package_json: PackageJson = app.read_json("package.json")?;
         let node_pkg = NodeProvider::get_nix_node_pkg(&package_json, env)?;
-
+        let mut pkgs = vec![node_pkg.clone()];
         if NodeProvider::get_package_manager(app) == "pnpm" {
             let mut pnpm_pkg = Pkg::new("nodePackages.pnpm");
             // Only override the node package if not the default one
             if node_pkg.name != *DEFAULT_NODE_PKG_NAME {
                 pnpm_pkg = pnpm_pkg.set_override("nodejs", node_pkg.name.as_str());
             }
-            Ok(vec![node_pkg, pnpm_pkg])
+            pkgs.push(pnpm_pkg);
         } else if NodeProvider::get_package_manager(app) == "yarn" {
             let mut yarn_pkg = Pkg::new("yarn");
             // Only override the node package if not the default one
             if node_pkg.name != *DEFAULT_NODE_PKG_NAME {
                 yarn_pkg = yarn_pkg.set_override("nodejs", node_pkg.name.as_str());
             }
-            Ok(vec![node_pkg, yarn_pkg])
-        } else {
-            Ok(vec![node_pkg])
+            pkgs.push(yarn_pkg);
         }
+        Ok(pkgs)
+    }
+
+    pub fn uses_canvas(app: &App) -> bool {
+        let package_json = app.read_file("package.json").unwrap_or_default();
+        let lock_json = app.read_file("package-lock.json").unwrap_or_default();
+        let yarn_lock = app.read_file("yarn.lock").unwrap_or_default();
+        let pnpm_yaml = app.read_file("pnpm-lock.yaml").unwrap_or_default();
+        package_json.contains("\"canvas\"")
+            || lock_json.contains("/canvas/")
+            || yarn_lock.contains("/canvas/")
+            || pnpm_yaml.contains("/canvas/")
     }
 }
 


Test patch:
diff --git a/tests/docker_run_tests.rs b/tests/docker_run_tests.rs
index 31f91ad..203c4a8 100644
--- a/tests/docker_run_tests.rs
+++ b/tests/docker_run_tests.rs
@@ -238,9 +238,9 @@ fn test_node_custom_version() {
 
 #[test]
 fn test_node_no_lockfile() {
-    let name = simple_build("./examples/node-no-lockfile");
+    let name = simple_build("./examples/node-no-lockfile-canvas");
     let output = run_image(name, None);
-    assert!(output.contains("Hello from Node"));
+    assert!(output.contains("Hello from Node canvas"));
 }
 
 #[test]
diff --git a/tests/generate_plan_tests.rs b/tests/generate_plan_tests.rs
index 394eb1b..7d492bf 100644
--- a/tests/generate_plan_tests.rs
+++ b/tests/generate_plan_tests.rs
@@ -23,7 +23,7 @@ fn test_node() -> Result<()> {
 
 #[test]
 fn test_node_no_lockfile() -> Result<()> {
-    let plan = simple_gen_plan("./examples/node-no-lockfile");
+    let plan = simple_gen_plan("./examples/node-no-lockfile-canvas");
     assert_eq!(plan.install.unwrap().cmd, Some("npm i".to_string()));
     assert_eq!(plan.build.unwrap().cmd, None);
     assert_eq!(plan.start.unwrap().cmd, Some("npm run start".to_string()));