summary refs log tree commit diff
path: root/pkgs/development/ruby-modules
diff options
context:
space:
mode:
authortalyz <kim.lindberger@gmail.com>2020-03-03 20:07:32 +0100
committerMilan <me@pbb.lc>2020-03-03 21:19:01 +0100
commitaffcf9ba1ef419cb366af6f7482734b23b885c6b (patch)
tree4644d8a1aff00c4464e7a6bab8df0cd5107bf4e3 /pkgs/development/ruby-modules
parent17721d3b33cea3250f83068f517fbb465e29ca3d (diff)
downloadnixpkgs-affcf9ba1ef419cb366af6f7482734b23b885c6b.tar
nixpkgs-affcf9ba1ef419cb366af6f7482734b23b885c6b.tar.gz
nixpkgs-affcf9ba1ef419cb366af6f7482734b23b885c6b.tar.bz2
nixpkgs-affcf9ba1ef419cb366af6f7482734b23b885c6b.tar.lz
nixpkgs-affcf9ba1ef419cb366af6f7482734b23b885c6b.tar.xz
nixpkgs-affcf9ba1ef419cb366af6f7482734b23b885c6b.tar.zst
nixpkgs-affcf9ba1ef419cb366af6f7482734b23b885c6b.zip
bundlerEnv: Add option to copy gem files instead of symlinking
The way ruby loads gems and keeps track of their paths seems to not
always work very well when the gems are accessed through
symlinks. Ruby will then complain that the same files are loaded
multiple times; it relies on the file's full path to determine whether
the file is loaded or not.

This adds an option to simply copy all gem files into the environment
instead, which gets rid of this issue, but may instead result in major
file duplication.
Diffstat (limited to 'pkgs/development/ruby-modules')
-rw-r--r--pkgs/development/ruby-modules/bundled-common/default.nix18
-rw-r--r--pkgs/development/ruby-modules/bundler-env/default.nix57
2 files changed, 52 insertions, 23 deletions
diff --git a/pkgs/development/ruby-modules/bundled-common/default.nix b/pkgs/development/ruby-modules/bundled-common/default.nix
index 0812ff590a5..66f33f6e31f 100644
--- a/pkgs/development/ruby-modules/bundled-common/default.nix
+++ b/pkgs/development/ruby-modules/bundled-common/default.nix
@@ -1,4 +1,4 @@
-{ stdenv, runCommand, ruby, lib
+{ stdenv, runCommand, ruby, lib, rsync
 , defaultGemConfig, buildRubyGem, buildEnv
 , makeWrapper
 , bundler
@@ -13,6 +13,7 @@
 , lockfile ? null
 , gemset ? null
 , ruby ? defs.ruby
+, copyGemFiles ? false # Copy gem files instead of symlinking
 , gemConfig ? defaultGemConfig
 , postBuild ? null
 , document ? []
@@ -96,7 +97,8 @@ let
 
   envPaths = lib.attrValues gems ++ lib.optional (!hasBundler) bundler;
 
-  basicEnv = buildEnv {
+
+  basicEnvArgs = {
     inherit buildInputs ignoreCollisions;
 
     name = name';
@@ -154,5 +156,17 @@ let
         };
     };
   };
+
+  basicEnv =
+    if copyGemFiles then
+      runCommand name' basicEnvArgs ''
+        mkdir -p $out
+        for i in $paths; do
+          ${rsync}/bin/rsync -a $i/lib $out/
+        done
+        eval "$postBuild"
+      ''
+    else
+      buildEnv basicEnvArgs;
 in
   basicEnv
diff --git a/pkgs/development/ruby-modules/bundler-env/default.nix b/pkgs/development/ruby-modules/bundler-env/default.nix
index 9e9ccb128cf..d412d10102f 100644
--- a/pkgs/development/ruby-modules/bundler-env/default.nix
+++ b/pkgs/development/ruby-modules/bundler-env/default.nix
@@ -1,4 +1,6 @@
-{ ruby, lib, callPackage, defaultGemConfig, buildEnv, bundler }@defs:
+{ ruby, lib, callPackage, defaultGemConfig, buildEnv, runCommand
+, bundler, rsync
+}@defs:
 
 { name ? null
 , pname ? null
@@ -8,6 +10,7 @@
 , gemset ? null
 , groups ? ["default"]
 , ruby ? defs.ruby
+, copyGemFiles ? false # Copy gem files instead of symlinking
 , gemConfig ? defaultGemConfig
 , postBuild ? null
 , document ? []
@@ -38,23 +41,35 @@ in
   if pname == null then
     basicEnv // { inherit name basicEnv; }
   else
-    (buildEnv {
-      inherit ignoreCollisions;
-
-      name = basicEnv.name;
-
-      paths = envPaths;
-      pathsToLink = [ "/lib" ];
-
-      postBuild = genStubsScript {
-        inherit lib ruby bundler groups;
-        confFiles = basicEnv.confFiles;
-        binPaths = [ basicEnv.gems.${pname} ];
-      } + lib.optionalString (postBuild != null) postBuild;
-
-      meta = { platforms = ruby.meta.platforms; } // meta;
-      passthru = basicEnv.passthru // {
-        inherit basicEnv;
-        inherit (basicEnv) env;
-      } // passthru;
-    })
+    let
+      bundlerEnvArgs = {
+        inherit ignoreCollisions;
+
+        name = basicEnv.name;
+
+        paths = envPaths;
+        pathsToLink = [ "/lib" ];
+
+        postBuild = genStubsScript {
+          inherit lib ruby bundler groups;
+          confFiles = basicEnv.confFiles;
+          binPaths = [ basicEnv.gems.${pname} ];
+        } + lib.optionalString (postBuild != null) postBuild;
+
+        meta = { platforms = ruby.meta.platforms; } // meta;
+        passthru = basicEnv.passthru // {
+          inherit basicEnv;
+          inherit (basicEnv) env;
+        } // passthru;
+      };
+    in
+      if copyGemFiles then
+        runCommand basicEnv.name bundlerEnvArgs ''
+          mkdir -p $out
+          for i in $paths; do
+            ${rsync}/bin/rsync -a $i/lib $out/
+          done
+          eval "$postBuild"
+        ''
+      else
+        buildEnv bundlerEnvArgs