Repository: railwayapp/nixpacks
Pull request #477 (2022-08-30 22:17:10)

Support installing Ruby local deps
This PR copies over all files before running `bundle install` so that local deps can be installed



Patch:
diff --git a/examples/ruby-local-deps/Gemfile b/examples/ruby-local-deps/Gemfile
new file mode 100644
index 0000000..37c7e89
--- /dev/null
+++ b/examples/ruby-local-deps/Gemfile
@@ -0,0 +1,3 @@
+source 'https://rubygems.org'
+
+gem "local", path: "libs/local"
diff --git a/examples/ruby-local-deps/Gemfile.lock b/examples/ruby-local-deps/Gemfile.lock
new file mode 100644
index 0000000..f877fbe
--- /dev/null
+++ b/examples/ruby-local-deps/Gemfile.lock
@@ -0,0 +1,20 @@
+PATH
+  remote: libs/local
+  specs:
+    local (0.1.0)
+
+GEM
+  remote: https://rubygems.org/
+  specs:
+
+PLATFORMS
+  arm64-darwin-21
+
+DEPENDENCIES
+  local!
+
+RUBY VERSION
+   ruby 3.1.2p20
+
+BUNDLED WITH
+   2.3.7
diff --git a/examples/ruby-local-deps/Procfile b/examples/ruby-local-deps/Procfile
new file mode 100644
index 0000000..4a7f07b
--- /dev/null
+++ b/examples/ruby-local-deps/Procfile
@@ -0,0 +1,1 @@
+web: bundle exec ruby app.rb
diff --git a/examples/ruby-local-deps/app.rb b/examples/ruby-local-deps/app.rb
new file mode 100644
index 0000000..984bf84
--- /dev/null
+++ b/examples/ruby-local-deps/app.rb
@@ -0,0 +1,3 @@
+require "local"
+
+Local.hi
diff --git a/examples/ruby-local-deps/libs/local/Gemfile b/examples/ruby-local-deps/libs/local/Gemfile
new file mode 100644
index 0000000..2d1f73e
--- /dev/null
+++ b/examples/ruby-local-deps/libs/local/Gemfile
@@ -0,0 +1,4 @@
+source "https://rubygems.org"
+git_source(:github) { |repo| "https://github.com/#{repo}.git" }
+
+gemspec
diff --git a/examples/ruby-local-deps/libs/local/lib/local.rb b/examples/ruby-local-deps/libs/local/lib/local.rb
new file mode 100644
index 0000000..510cedc
--- /dev/null
+++ b/examples/ruby-local-deps/libs/local/lib/local.rb
@@ -0,0 +1,5 @@
+class Local
+  def self.hi
+    puts "Hello world from Local lib"
+  end
+end
diff --git a/examples/ruby-local-deps/libs/local/local.gemspec b/examples/ruby-local-deps/libs/local/local.gemspec
new file mode 100644
index 0000000..06d31de
--- /dev/null
+++ b/examples/ruby-local-deps/libs/local/local.gemspec
@@ -0,0 +1,11 @@
+# Describe your gem and declare its dependencies:
+Gem::Specification.new do |s|
+  s.name = "local"
+  s.version = "0.1.0"
+  s.authors = ["Nixpacks"]
+  s.homepage = ""
+  s.summary = ""
+  s.description = ""
+  s.license = "MIT"
+  s.files = ["lib/local.rb"]
+end
diff --git a/examples/ruby-with-node/app.rb b/examples/ruby-with-node/app.rb
index 0bbb7fd..8c0da45 100644
--- a/examples/ruby-with-node/app.rb
+++ b/examples/ruby-with-node/app.rb
@@ -1,1 +1,1 @@
-puts "Hello from Ruby"
+puts "Hello from Ruby with Node"
diff --git a/src/nixpacks/builder/docker/docker_image_builder.rs b/src/nixpacks/builder/docker/docker_image_builder.rs
index 429c12b..739fd47 100644
--- a/src/nixpacks/builder/docker/docker_image_builder.rs
+++ b/src/nixpacks/builder/docker/docker_image_builder.rs
@@ -6,7 +6,7 @@ use crate::nixpacks::{
 use anyhow::{bail, Context, Ok, Result};
 
 use std::{
-    fs::{self, File},
+    fs::{self, remove_dir_all, File},
     process::Command,
 };
 use tempdir::TempDir;
@@ -29,7 +29,7 @@ impl ImageBuilder for DockerImageBuilder {
             }
         };
         let name = self.options.name.clone().unwrap_or_else(|| id.to_string());
-        let output = OutputDir::new(dir)?;
+        let output = OutputDir::new(dir.clone())?;
         output.ensure_output_exists()?;
 
         let dockerfile = plan
@@ -63,6 +63,8 @@ impl ImageBuilder for DockerImageBuilder {
             self.logger.log_section("Successfully Built!");
             println!("\nRun:");
             println!("  docker run -it {}", name);
+
+            remove_dir_all(dir)?;
         } else {
             println!("\nSaved output to:");
             println!("  {}", output.root.to_str().unwrap());
diff --git a/src/providers/node/mod.rs b/src/providers/node/mod.rs
index 68322e0..4d346ec 100644
--- a/src/providers/node/mod.rs
+++ b/src/providers/node/mod.rs
@@ -65,11 +65,9 @@ impl Provider for NodeProvider {
     fn get_build_plan(&self, app: &App, env: &Environment) -> Result<Option<BuildPlan>> {
         // Setup
         let mut setup = Phase::setup(Some(NodeProvider::get_nix_packages(app, env)?));
-        if NodeProvider::uses_node_dependency(app, "canvas") {
-            setup.add_pkgs_libs(vec!["libuuid".to_string(), "libGL".to_string()]);
-        }
 
         if NodeProvider::uses_node_dependency(app, "puppeteer") {
+            // https://gist.github.com/winuxue/cfef08e2f5fe9dfc16a1d67a4ad38a01
             setup.add_apt_pkgs(vec![
                 "libnss3".to_string(),
                 "libatk1.0-0".to_string(),
@@ -83,6 +81,8 @@ impl Provider for NodeProvider {
                 "libxshmfence1".to_string(),
                 "libglu1".to_string(),
             ]);
+        } else if NodeProvider::uses_node_dependency(app, "canvas") {
+            setup.add_pkgs_libs(vec!["libuuid".to_string(), "libGL".to_string()]);
         }
 
         // Install
diff --git a/src/providers/ruby.rs b/src/providers/ruby.rs
index cd54f6d..c06ef5a 100644
--- a/src/providers/ruby.rs
+++ b/src/providers/ruby.rs
@@ -81,7 +81,6 @@ impl RubyProvider {
 
     fn get_install(&self, app: &App) -> Result<Option<Phase>> {
         let mut install = Phase::install(None);
-        install.add_file_dependency("Gemfile*".to_string());
         install.add_cache_directory(BUNDLE_CACHE_DIR.to_string());
 
         install.add_cmd("bundle install".to_string());


Test patch:
diff --git a/tests/docker_run_tests.rs b/tests/docker_run_tests.rs
index 06b23f1..60860b4 100644
--- a/tests/docker_run_tests.rs
+++ b/tests/docker_run_tests.rs
@@ -645,6 +645,20 @@ fn test_ruby_sinatra() {
     assert!(output.contains("Hello from Sinatra"));
 }
 
+#[test]
+fn test_ruby_node() {
+    let name = simple_build("./examples/ruby-with-node/");
+    let output = run_image(&name, None);
+    assert!(output.contains("Hello from Ruby with Node"));
+}
+
+#[test]
+fn test_ruby_local_deps() {
+    let name = simple_build("./examples/ruby-local-deps/");
+    let output = run_image(&name, None);
+    assert!(output.contains("Hello world from Local lib"));
+}
+
 #[test]
 fn test_ruby_rails() {
     // Create the network
diff --git a/tests/snapshots/generate_plan_tests__ruby.snap b/tests/snapshots/generate_plan_tests__ruby.snap
index 55195b0..788cccf 100644
--- a/tests/snapshots/generate_plan_tests__ruby.snap
+++ b/tests/snapshots/generate_plan_tests__ruby.snap
@@ -32,9 +32,6 @@ expression: plan
       "commands": [
         "bundle install"
       ],
-      "onlyIncludeFiles": [
-        "Gemfile*"
-      ],
       "cacheDirectories": [
         "/root/.bundle/cache"
       ],
diff --git a/tests/snapshots/generate_plan_tests__ruby_local_deps.snap b/tests/snapshots/generate_plan_tests__ruby_local_deps.snap
new file mode 100644
index 0000000..20ad7e7
--- /dev/null
+++ b/tests/snapshots/generate_plan_tests__ruby_local_deps.snap
@@ -0,0 +1,54 @@
+---
+source: tests/generate_plan_tests.rs
+expression: plan
+---
+{
+  "nixpacksVersion": "[version]",
+  "buildImage": "[build_image]",
+  "variables": {
+    "BUNDLE_GEMFILE": "/app/Gemfile",
+    "GEM_HOME": "/usr/local/rvm/gems/ruby-3.1.2",
+    "GEM_PATH": "/usr/local/rvm/gems/ruby-3.1.2:/usr/local/rvm/gems/ruby-3.1.2@global"
+  },
+  "phases": [
+    {
+      "name": "setup",
+      "aptPackages": [
+        "procps"
+      ],
+      "commands": [
+        "curl -sSL https://get.rvm.io | bash -s stable && . /etc/profile.d/rvm.sh",
+        "rvm install ruby-3.1.2",
+        "rvm --default use ruby-3.1.2",
+        "gem install bundler:2.3.7",
+        "echo 'source /usr/local/rvm/scripts/rvm' >> /root/.profile"
+      ]
+    },
+    {
+      "name": "install",
+      "dependsOn": [
+        "setup"
+      ],
+      "commands": [
+        "bundle install"
+      ],
+      "cacheDirectories": [
+        "/root/.bundle/cache"
+      ],
+      "paths": [
+        "/usr/local/rvm/rubies/ruby-3.1.2/bin",
+        "/usr/local/rvm/gems/ruby-3.1.2/bin",
+        "/usr/local/rvm/gems/ruby-3.1.2@global/bin"
+      ]
+    },
+    {
+      "name": "build",
+      "dependsOn": [
+        "install"
+      ]
+    }
+  ],
+  "startPhase": {
+    "cmd": "bundle exec ruby app.rb"
+  }
+}
diff --git a/tests/snapshots/generate_plan_tests__ruby_rails_postgres.snap b/tests/snapshots/generate_plan_tests__ruby_rails_postgres.snap
index 04c5848..2f3f6f1 100644
--- a/tests/snapshots/generate_plan_tests__ruby_rails_postgres.snap
+++ b/tests/snapshots/generate_plan_tests__ruby_rails_postgres.snap
@@ -19,9 +19,6 @@ expression: plan
       "commands": [
         "bundle install"
       ],
-      "onlyIncludeFiles": [
-        "Gemfile*"
-      ],
       "cacheDirectories": [
         "/root/.bundle/cache"
       ],
diff --git a/tests/snapshots/generate_plan_tests__ruby_sinatra.snap b/tests/snapshots/generate_plan_tests__ruby_sinatra.snap
index 4d662d3..cd70545 100644
--- a/tests/snapshots/generate_plan_tests__ruby_sinatra.snap
+++ b/tests/snapshots/generate_plan_tests__ruby_sinatra.snap
@@ -32,9 +32,6 @@ expression: plan
       "commands": [
         "bundle install"
       ],
-      "onlyIncludeFiles": [
-        "Gemfile*"
-      ],
       "cacheDirectories": [
         "/root/.bundle/cache"
       ],
diff --git a/tests/snapshots/generate_plan_tests__ruby_with_node.snap b/tests/snapshots/generate_plan_tests__ruby_with_node.snap
index debca78..5ee43fa 100644
--- a/tests/snapshots/generate_plan_tests__ruby_with_node.snap
+++ b/tests/snapshots/generate_plan_tests__ruby_with_node.snap
@@ -59,9 +59,6 @@ expression: plan
       "commands": [
         "bundle install"
       ],
-      "onlyIncludeFiles": [
-        "Gemfile*"
-      ],
       "cacheDirectories": [
         "/root/.bundle/cache"
       ],