From aeb3ae5008cb75134f90031d6ca9b973a2ba150d Mon Sep 17 00:00:00 2001 From: Andrew Childs Date: Fri, 25 Feb 2022 16:40:52 +0900 Subject: [PATCH 1/4] ruby: separate rails express patches and source location These are unnecessarily composed. Disabling useRailsExpress changes to using a tarball instead of fetching directly from git, which will have unexpected effects. In come cases (Ruby 2.7) it will cause the build to fail due to en error rubygems/installer.rb. It also changes the set of gems that are available, since the bundled gems[1] are only included in the tarball. [1]: https://stdgems.org/ --- pkgs/development/interpreters/ruby/default.nix | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pkgs/development/interpreters/ruby/default.nix b/pkgs/development/interpreters/ruby/default.nix index ea31f354d0d7..e2f225fa8d05 100644 --- a/pkgs/development/interpreters/ruby/default.nix +++ b/pkgs/development/interpreters/ruby/default.nix @@ -49,17 +49,19 @@ let , libiconv, libobjc, libunwind, Foundation , makeWrapper, buildRubyGem, defaultGemConfig , baseRuby ? buildPackages.ruby.override { + buildFromGit = false; useRailsExpress = false; docSupport = false; rubygemsSupport = false; } - , useBaseRuby ? stdenv.hostPlatform != stdenv.buildPlatform || useRailsExpress + , buildFromGit ? true + , useBaseRuby ? stdenv.hostPlatform != stdenv.buildPlatform || useRailsExpress || buildFromGit }: stdenv.mkDerivation rec { pname = "ruby"; inherit version; - src = if useRailsExpress then fetchFromGitHub { + src = if buildFromGit then fetchFromGitHub { owner = "ruby"; repo = "ruby"; rev = tag; @@ -100,7 +102,7 @@ let patchLevel = ver.patchLevel; }).${ver.majMinTiny} ++ op (lib.versionOlder ver.majMin "3.1") ./do-not-regenerate-revision.h.patch - ++ op (atLeast30 && useRailsExpress) ./do-not-update-gems-baseruby.patch + ++ op (atLeast30 && useBaseRuby) ./do-not-update-gems-baseruby.patch # Ruby prior to 3.0 has a bug the installer (tools/rbinstall.rb) but # the resulting error was swallowed. Newer rubygems no longer swallows # this error. We upgrade rubygems when rubygemsSupport is enabled, so From fa6f87a8aefa8c9d00b69b8de96fed2f869f8cbb Mon Sep 17 00:00:00 2001 From: Andrew Childs Date: Fri, 25 Feb 2022 16:48:47 +0900 Subject: [PATCH 2/4] ruby: fix default value of RUBY_REVISION when building from git The revision.h header is normally pregenerated and included in the tarball. When building from a git export the value defaults to "HEAD". --- pkgs/development/interpreters/ruby/default.nix | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/pkgs/development/interpreters/ruby/default.nix b/pkgs/development/interpreters/ruby/default.nix index e2f225fa8d05..806ba251b688 100644 --- a/pkgs/development/interpreters/ruby/default.nix +++ b/pkgs/development/interpreters/ruby/default.nix @@ -17,7 +17,7 @@ let # Contains the ruby version heuristics rubyVersion = import ./ruby-version.nix { inherit lib; }; - generic = { version, sha256 }: let + generic = { version, revision, sha256 }: let ver = version; tag = ver.gitTag; atLeast30 = lib.versionAtLeast ver.majMin "3.0"; @@ -118,6 +118,11 @@ let rm -rf $sourceRoot/{lib,test}/rubygems* cp -r ${rubygems}/lib/rubygems* $sourceRoot/lib cp -r ${rubygems}/test/rubygems $sourceRoot/test + '' + opString buildFromGit '' + cat < $sourceRoot/revision.h + #define RUBY_REVISION "${lib.substring 0 8 revision}" + #define RUBY_FULL_REVISION "${revision}" + EOF ''; postPatch = '' @@ -255,6 +260,7 @@ let in { ruby_2_7 = generic { version = rubyVersion "2" "7" "5" ""; + revision = "f69aeb83146be640995753667fdd6c6f157527f5"; sha256 = { src = "1wc1hwmz4m6iqlmqag8liyld917p6a8dvnhnpd1v8d8jl80bjm97"; git = "16565fyl7141hr6q6d74myhsz46lvgam8ifnacshi68vzibwjbbh"; @@ -263,6 +269,7 @@ in { ruby_3_0 = generic { version = rubyVersion "3" "0" "3" ""; + revision = "3fb7d2cadc18472ec107b14234933b017a33c14d"; sha256 = { src = "1b4j39zyyvdkf1ax2c6qfa40b4mxfkr87zghhw19fmnzn8f8d1im"; git = "1q19w5i1jkfxn7qq6f9v9ngax9h52gxwijk7hp312dx6amwrkaim"; @@ -271,6 +278,7 @@ in { ruby_3_1 = generic { version = rubyVersion "3" "1" "1" ""; + revision = "53f5fc4236a754ddf94b20dbb70ab63bd5109b18"; sha256 = { src = "sha256-/m5Hgt6XRDl43bqLpL440iKqJNw+PwKmqOdwHA7rYZ0="; git = "sha256-76t/tGyK5nz7nvcRdHJTjjckU+Kv+/kbTMiNWJ93jU8="; From 9634895022ef33cc4b02c8b483771050c68750ce Mon Sep 17 00:00:00 2001 From: Andrew Childs Date: Mon, 14 Mar 2022 16:31:14 +0900 Subject: [PATCH 3/4] ruby: fix build with bundled gems --- .../development/interpreters/ruby/default.nix | 24 +++-- .../ruby/rbinstall-new-rubygems-compat.patch | 87 +++++++++++++++++++ 2 files changed, 104 insertions(+), 7 deletions(-) create mode 100644 pkgs/development/interpreters/ruby/rbinstall-new-rubygems-compat.patch diff --git a/pkgs/development/interpreters/ruby/default.nix b/pkgs/development/interpreters/ruby/default.nix index 806ba251b688..39410fbebc36 100644 --- a/pkgs/development/interpreters/ruby/default.nix +++ b/pkgs/development/interpreters/ruby/default.nix @@ -103,16 +103,21 @@ let }).${ver.majMinTiny} ++ op (lib.versionOlder ver.majMin "3.1") ./do-not-regenerate-revision.h.patch ++ op (atLeast30 && useBaseRuby) ./do-not-update-gems-baseruby.patch - # Ruby prior to 3.0 has a bug the installer (tools/rbinstall.rb) but - # the resulting error was swallowed. Newer rubygems no longer swallows - # this error. We upgrade rubygems when rubygemsSupport is enabled, so - # we have to fix this bug to prevent the install step from failing. - # See https://github.com/ruby/ruby/pull/2930 - ++ op (!atLeast30 && rubygemsSupport) + ++ ops (!atLeast30 && rubygemsSupport) [ + # We upgrade rubygems to a version that isn't compatible with the + # ruby 2.7 installer. Backport the upstream fix. + ./rbinstall-new-rubygems-compat.patch + + # Ruby prior to 3.0 has a bug the installer (tools/rbinstall.rb) but + # the resulting error was swallowed. Newer rubygems no longer swallows + # this error. We upgrade rubygems when rubygemsSupport is enabled, so + # we have to fix this bug to prevent the install step from failing. + # See https://github.com/ruby/ruby/pull/2930 (fetchpatch { url = "https://github.com/ruby/ruby/commit/261d8dd20afd26feb05f00a560abd99227269c1c.patch"; sha256 = "0wrii25cxcz2v8bgkrf7ibcanjlxwclzhayin578bf0qydxdm9qy"; - }); + }) + ]; postUnpack = opString rubygemsSupport '' rm -rf $sourceRoot/{lib,test}/rubygems* @@ -189,6 +194,11 @@ let sed -i '/CC_VERSION_MESSAGE/d' $rbConfig '' } + # Remove unnecessary external intermediate files created by gems + extMakefiles=$(find $out/lib/ruby/gems -name Makefile) + for makefile in $extMakefiles; do + make -C "$(dirname "$makefile")" distclean + done # Bundler tries to create this directory mkdir -p $out/nix-support cat > $out/nix-support/setup-hook < +Date: Tue, 1 Oct 2019 12:03:33 +0200 +Subject: [PATCH] Use `Gem::Package` like object instead of monkey patching. + +1. This is similar to what RubyGems does and it is less magic [[1]]. +2. It avoids deprecated code paths in RubyGems [[2]]. + +[1]: https://github.com/rubygems/rubygems/blob/92892bbc3adba86a90756c385433835f6761b8da/lib/rubygems/installer.rb#L151 +[2]: https://github.com/rubygems/rubygems/blob/92892bbc3adba86a90756c385433835f6761b8da/lib/rubygems/installer.rb#L187 + +(cherry picked from commit e960ef6f18a25c637c54f00c75bb6c24f8ab55d0) +--- + tool/rbinstall.rb | 47 +++++++++++++++++++++++++++-------------------- + 1 file changed, 27 insertions(+), 20 deletions(-) + +diff --git a/tool/rbinstall.rb b/tool/rbinstall.rb +index 060390626f..28ae8c409a 100755 +--- a/tool/rbinstall.rb ++++ b/tool/rbinstall.rb +@@ -710,28 +710,34 @@ def remove_prefix(prefix, string) + end + end + +- class UnpackedInstaller < Gem::Installer +- module DirPackage +- def extract_files(destination_dir, pattern = "*") +- path = File.dirname(@gem.path) +- return if path == destination_dir +- File.chmod(0700, destination_dir) +- mode = pattern == "bin/*" ? $script_mode : $data_mode +- spec.files.each do |f| +- src = File.join(path, f) +- dest = File.join(without_destdir(destination_dir), f) +- makedirs(dest[/.*(?=\/)/m]) +- install src, dest, :mode => mode +- end +- File.chmod($dir_mode, destination_dir) ++ class DirPackage ++ attr_reader :spec ++ ++ attr_accessor :dir_mode ++ attr_accessor :prog_mode ++ attr_accessor :data_mode ++ ++ def initialize(spec) ++ @spec = spec ++ @src_dir = File.dirname(@spec.loaded_from) ++ end ++ ++ def extract_files(destination_dir, pattern = "*") ++ path = @src_dir ++ return if path == destination_dir ++ File.chmod(0700, destination_dir) ++ mode = pattern == "bin/*" ? $script_mode : $data_mode ++ spec.files.each do |f| ++ src = File.join(path, f) ++ dest = File.join(without_destdir(destination_dir), f) ++ makedirs(dest[/.*(?=\/)/m]) ++ install src, dest, :mode => mode + end ++ File.chmod($dir_mode, destination_dir) + end ++ end + +- def initialize(spec, *options) +- super(spec.loaded_from, *options) +- @package.extend(DirPackage).spec = spec +- end +- ++ class UnpackedInstaller < Gem::Installer + def write_cache_file + end + +@@ -890,7 +896,8 @@ def install_default_gem(dir, srcdir) + if File.directory?(ext = "#{gem_ext_dir}/#{spec.full_name}") + spec.extensions[0] ||= "-" + end +- ins = RbInstall::UnpackedInstaller.new(spec, options) ++ package = RbInstall::DirPackage.new spec ++ ins = RbInstall::UnpackedInstaller.new(package, options) + puts "#{INDENT}#{spec.name} #{spec.version}" + ins.install + File.chmod($data_mode, File.join(install_dir, "specifications", "#{spec.full_name}.gemspec")) +-- +2.35.1 + From 6e859afe34879a29b9389aa47f1fb022fc0f4f98 Mon Sep 17 00:00:00 2001 From: Andrew Childs Date: Fri, 11 Mar 2022 11:53:36 +0900 Subject: [PATCH 4/4] ruby: always build from the tarball, drop support for git builds --- .../development/interpreters/ruby/default.nix | 38 ++++--------------- 1 file changed, 7 insertions(+), 31 deletions(-) diff --git a/pkgs/development/interpreters/ruby/default.nix b/pkgs/development/interpreters/ruby/default.nix index 39410fbebc36..37d70d4719a4 100644 --- a/pkgs/development/interpreters/ruby/default.nix +++ b/pkgs/development/interpreters/ruby/default.nix @@ -17,7 +17,7 @@ let # Contains the ruby version heuristics rubyVersion = import ./ruby-version.nix { inherit lib; }; - generic = { version, revision, sha256 }: let + generic = { version, sha256 }: let ver = version; tag = ver.gitTag; atLeast30 = lib.versionAtLeast ver.majMin "3.0"; @@ -49,26 +49,19 @@ let , libiconv, libobjc, libunwind, Foundation , makeWrapper, buildRubyGem, defaultGemConfig , baseRuby ? buildPackages.ruby.override { - buildFromGit = false; useRailsExpress = false; docSupport = false; rubygemsSupport = false; } - , buildFromGit ? true - , useBaseRuby ? stdenv.hostPlatform != stdenv.buildPlatform || useRailsExpress || buildFromGit + , useBaseRuby ? stdenv.hostPlatform != stdenv.buildPlatform || useRailsExpress }: stdenv.mkDerivation rec { pname = "ruby"; inherit version; - src = if buildFromGit then fetchFromGitHub { - owner = "ruby"; - repo = "ruby"; - rev = tag; - sha256 = sha256.git; - } else fetchurl { + src = fetchurl { url = "https://cache.ruby-lang.org/pub/ruby/${ver.majMin}/ruby-${ver}.tar.gz"; - sha256 = sha256.src; + inherit sha256; }; # Have `configure' avoid `/usr/bin/nroff' in non-chroot builds. @@ -123,11 +116,6 @@ let rm -rf $sourceRoot/{lib,test}/rubygems* cp -r ${rubygems}/lib/rubygems* $sourceRoot/lib cp -r ${rubygems}/test/rubygems $sourceRoot/test - '' + opString buildFromGit '' - cat < $sourceRoot/revision.h - #define RUBY_REVISION "${lib.substring 0 8 revision}" - #define RUBY_FULL_REVISION "${revision}" - EOF ''; postPatch = '' @@ -270,28 +258,16 @@ let in { ruby_2_7 = generic { version = rubyVersion "2" "7" "5" ""; - revision = "f69aeb83146be640995753667fdd6c6f157527f5"; - sha256 = { - src = "1wc1hwmz4m6iqlmqag8liyld917p6a8dvnhnpd1v8d8jl80bjm97"; - git = "16565fyl7141hr6q6d74myhsz46lvgam8ifnacshi68vzibwjbbh"; - }; + sha256 = "1wc1hwmz4m6iqlmqag8liyld917p6a8dvnhnpd1v8d8jl80bjm97"; }; ruby_3_0 = generic { version = rubyVersion "3" "0" "3" ""; - revision = "3fb7d2cadc18472ec107b14234933b017a33c14d"; - sha256 = { - src = "1b4j39zyyvdkf1ax2c6qfa40b4mxfkr87zghhw19fmnzn8f8d1im"; - git = "1q19w5i1jkfxn7qq6f9v9ngax9h52gxwijk7hp312dx6amwrkaim"; - }; + sha256 = "1b4j39zyyvdkf1ax2c6qfa40b4mxfkr87zghhw19fmnzn8f8d1im"; }; ruby_3_1 = generic { version = rubyVersion "3" "1" "1" ""; - revision = "53f5fc4236a754ddf94b20dbb70ab63bd5109b18"; - sha256 = { - src = "sha256-/m5Hgt6XRDl43bqLpL440iKqJNw+PwKmqOdwHA7rYZ0="; - git = "sha256-76t/tGyK5nz7nvcRdHJTjjckU+Kv+/kbTMiNWJ93jU8="; - }; + sha256 = "sha256-/m5Hgt6XRDl43bqLpL440iKqJNw+PwKmqOdwHA7rYZ0="; }; }