ruby: refactoring, and package bundix
This commit is contained in:
parent
bf16d03075
commit
221509b0a6
4
pkgs/development/interpreters/ruby/bundix/Gemfile
Normal file
4
pkgs/development/interpreters/ruby/bundix/Gemfile
Normal file
|
@ -0,0 +1,4 @@
|
|||
source "http://rubygems.org"
|
||||
gem "bundix",
|
||||
:git => "https://github.com/cstrahan/bundix.git",
|
||||
:ref => "5df25b11b5b86e636754d54c2a8859c7c6ec78c7"
|
19
pkgs/development/interpreters/ruby/bundix/Gemfile.lock
Normal file
19
pkgs/development/interpreters/ruby/bundix/Gemfile.lock
Normal file
|
@ -0,0 +1,19 @@
|
|||
GIT
|
||||
remote: https://github.com/cstrahan/bundix.git
|
||||
revision: 5df25b11b5b86e636754d54c2a8859c7c6ec78c7
|
||||
ref: 5df25b11b5b86e636754d54c2a8859c7c6ec78c7
|
||||
specs:
|
||||
bundix (0.1.0)
|
||||
bundler (~> 1.7.9)
|
||||
thor (~> 0.19.1)
|
||||
|
||||
GEM
|
||||
remote: http://rubygems.org/
|
||||
specs:
|
||||
thor (0.19.1)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
bundix!
|
9
pkgs/development/interpreters/ruby/bundix/default.nix
Normal file
9
pkgs/development/interpreters/ruby/bundix/default.nix
Normal file
|
@ -0,0 +1,9 @@
|
|||
{ ruby, bundlerEnv }:
|
||||
|
||||
bundlerEnv {
|
||||
name = "bundix";
|
||||
inherit ruby;
|
||||
gemset = ./gemset.nix;
|
||||
gemfile = ./Gemfile;
|
||||
lockfile = ./Gemfile.lock;
|
||||
}
|
22
pkgs/development/interpreters/ruby/bundix/gemset.nix
Normal file
22
pkgs/development/interpreters/ruby/bundix/gemset.nix
Normal file
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"bundix" = {
|
||||
version = "0.1.0";
|
||||
source = {
|
||||
type = "git";
|
||||
url = "https://github.com/cstrahan/bundix.git";
|
||||
rev = "5df25b11b5b86e636754d54c2a8859c7c6ec78c7";
|
||||
fetchSubmodules = false;
|
||||
sha256 = "0334jsavpzkikcs7wrx7a3r0ilvr5vsnqd34lhc58b8cgvgll47p";
|
||||
};
|
||||
dependencies = [
|
||||
"thor"
|
||||
];
|
||||
};
|
||||
"thor" = {
|
||||
version = "0.19.1";
|
||||
source = {
|
||||
type = "gem";
|
||||
sha256 = "08p5gx18yrbnwc6xc0mxvsfaxzgy2y9i78xq7ds0qmdm67q39y4z";
|
||||
};
|
||||
};
|
||||
}
|
|
@ -12,53 +12,103 @@
|
|||
|
||||
let
|
||||
const = x: y: x;
|
||||
#bundler = bundler_PATCHED;
|
||||
bundler = bundler_HEAD.override { inherit ruby; };
|
||||
inherit (builtins) attrValues;
|
||||
|
||||
fetchers.path = attrs: attrs.src.path;
|
||||
fetchers.gem = attrs:
|
||||
let fname = "${attrs.name}-${attrs.version}.gem";
|
||||
in toString (runCommand fname {
|
||||
gem = fetchurl {
|
||||
url = "${attrs.src.source or "https://rubygems.org"}/downloads/${fname}";
|
||||
inherit (attrs.src) sha256;
|
||||
};
|
||||
} ''
|
||||
mkdir $out
|
||||
cp $gem $out/${fname}
|
||||
'') + "/${fname}";
|
||||
gemName = attrs: "${attrs.name}-${attrs.version}.gem";
|
||||
|
||||
fetchers.path = attrs: attrs.source.path;
|
||||
fetchers.gem = attrs: fetchurl {
|
||||
url = "${attrs.source.source or "https://rubygems.org"}/downloads/${gemName attrs}";
|
||||
inherit (attrs.source) sha256;
|
||||
};
|
||||
fetchers.git = attrs: fetchgit {
|
||||
inherit (attrs.src) url rev sha256 fetchSubmodules;
|
||||
inherit (attrs.source) url rev sha256 fetchSubmodules;
|
||||
leaveDotGit = true;
|
||||
};
|
||||
|
||||
fixSpec = attrs:
|
||||
attrs // (fixes."${attrs.name}" or (const {})) attrs;
|
||||
applySrc = attrs:
|
||||
attrs // {
|
||||
src = (fetchers."${attrs.source.type}" attrs);
|
||||
};
|
||||
|
||||
applyFixes = attrs:
|
||||
if fixes ? "${attrs.name}"
|
||||
then attrs // fixes."${attrs.name}" attrs
|
||||
else attrs;
|
||||
|
||||
# patch a gem or source tree.
|
||||
# for gems, the gem is unpacked, patched, and then repacked.
|
||||
# see: https://github.com/fedora-ruby/gem-patch/blob/master/lib/rubygems/patcher.rb
|
||||
applyPatches = { attrs }:
|
||||
if (!(attrs ? patches))
|
||||
then attrs
|
||||
else attrs // { src =
|
||||
stdenv.mkDerivation {
|
||||
name = gemName attrs;
|
||||
phases = [ "unpackPhase" "patchPhase" "installPhase" ];
|
||||
buildInputs = [ ruby ];
|
||||
inherit (attrs) patches;
|
||||
unpackPhase = ''
|
||||
runHook preUnpack
|
||||
|
||||
if [[ -f ${attrs.src} ]]; then
|
||||
isGem=1
|
||||
gem unpack ${attrs.src} --target=contents
|
||||
else
|
||||
cp -r ${attrs.src} contents
|
||||
chmod -R +w contents
|
||||
fi
|
||||
|
||||
cd contents
|
||||
runHook postUnpack
|
||||
'';
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
|
||||
mkdir build
|
||||
if [[ -n "$isGem" ]]; then
|
||||
${writeScript "repack.rb" ''
|
||||
#!${ruby}/bin/ruby
|
||||
require 'rubygems'
|
||||
require 'fileutils'
|
||||
|
||||
out = ENV['out']
|
||||
files = Dir['**/{.[^\.]*,*}']
|
||||
package = Gem::Package.new("${attrs.src}")
|
||||
patched_package = Gem::Package.new(package.spec.file_name)
|
||||
patched_package.spec = package.spec.clone
|
||||
patched_package.spec.files = files
|
||||
|
||||
# Change dir and build the patched gem
|
||||
Dir.chdir("../build") do
|
||||
patched_package.build false
|
||||
end
|
||||
FileUtils.cp "../build/#{package.file_name}" out
|
||||
''}
|
||||
else
|
||||
cp -r . out
|
||||
fi
|
||||
|
||||
runHook postInstall
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
instantiate = (attrs:
|
||||
let
|
||||
withFixes = fixSpec attrs;
|
||||
withSource = withFixes //
|
||||
(if (lib.isDerivation withFixes.src || builtins.isString withFixes.src)
|
||||
then { source = attrs.src; }
|
||||
else { source = attrs.src; src = (fetchers."${attrs.src.type}" attrs); });
|
||||
|
||||
in
|
||||
withSource
|
||||
applyFixes (applySrc attrs)
|
||||
);
|
||||
|
||||
instantiated = lib.flip lib.mapAttrs (import gemset) (name: attrs:
|
||||
instantiate (attrs // { inherit name; })
|
||||
);
|
||||
|
||||
# only the *.gem files.
|
||||
gems = lib.fold (next: acc:
|
||||
# copy *.gem to ./gems
|
||||
copyGems = lib.fold (next: acc:
|
||||
if next.source.type == "gem"
|
||||
then acc ++ [next.src]
|
||||
then acc + "cp ${next.src} gems/${gemName next}\n"
|
||||
else acc
|
||||
) [] (attrValues instantiated);
|
||||
) "" (attrValues instantiated);
|
||||
|
||||
runRuby = name: env: command:
|
||||
runCommand name env ''
|
||||
|
@ -68,7 +118,7 @@ let
|
|||
# TODO: include json_pure, so the version of ruby doesn't matter.
|
||||
# not all rubies have support for JSON built-in,
|
||||
# so we'll convert JSON to ruby expressions.
|
||||
json2rb = writeScriptBin "json2rb" ''
|
||||
json2rb = writeScript "json2rb" ''
|
||||
#!${ruby}/bin/ruby
|
||||
begin
|
||||
require 'json'
|
||||
|
@ -81,7 +131,7 @@ let
|
|||
|
||||
# dump the instantiated gemset as a ruby expression.
|
||||
serializedGemset = runCommand "gemset.rb" { json = builtins.toJSON instantiated; } ''
|
||||
printf '%s' "$json" | ${json2rb}/bin/json2rb > $out
|
||||
printf '%s' "$json" | ${json2rb} > $out
|
||||
'';
|
||||
|
||||
# this is a mapping from a source type and identifier (uri/path/etc)
|
||||
|
@ -122,20 +172,22 @@ let
|
|||
'';
|
||||
|
||||
# rewrite PATH sources to point into the nix store.
|
||||
purifyLockfile = writeScript "purifyLockfile" ''
|
||||
purifiedLockfile = runRuby "purifiedLockfile" {} ''
|
||||
#!${ruby}/bin/ruby
|
||||
|
||||
out = ENV['out']
|
||||
sources = eval(File.read("${sources}"))
|
||||
paths = sources["path"]
|
||||
|
||||
lockfile = STDIN.read
|
||||
lockfile = File.read("${lockfile}")
|
||||
|
||||
paths.each_pair do |impure, pure|
|
||||
lockfile.gsub!(/^ remote: #{Regexp.escape(impure)}/, " remote: #{pure}")
|
||||
end
|
||||
|
||||
print lockfile
|
||||
File.open(out, "wb") do |f|
|
||||
f.print lockfile
|
||||
end
|
||||
'';
|
||||
|
||||
in
|
||||
|
@ -149,15 +201,15 @@ stdenv.mkDerivation {
|
|||
];
|
||||
phases = [ "installPhase" "fixupPhase" ];
|
||||
outputs = [
|
||||
"out" # the installed libs/bins
|
||||
"bundler" # supporting files for bundler
|
||||
"out" # the installed libs/bins
|
||||
"bundle" # supporting files for bundler
|
||||
];
|
||||
installPhase = ''
|
||||
# Copy the Gemfile and Gemfile.lock
|
||||
mkdir -p $bundler
|
||||
export BUNDLE_GEMFILE=$bundler/Gemfile
|
||||
mkdir -p $bundle
|
||||
export BUNDLE_GEMFILE=$bundle/Gemfile
|
||||
cp ${gemfile} $BUNDLE_GEMFILE
|
||||
cat ${lockfile} | ${purifyLockfile} > $BUNDLE_GEMFILE.lock
|
||||
cp ${purifiedLockfile} $BUNDLE_GEMFILE.lock
|
||||
|
||||
export NIX_GEM_SOURCES=${sources}
|
||||
export NIX_BUNDLER_GEMPATH=${bundler}/${ruby.gemPath}
|
||||
|
@ -167,15 +219,15 @@ stdenv.mkDerivation {
|
|||
mkdir -p $GEM_HOME
|
||||
|
||||
mkdir gems
|
||||
for gem in ${toString gems}; do
|
||||
ln -s $gem gems
|
||||
done
|
||||
${copyGems}
|
||||
|
||||
mkdir $out/bin
|
||||
cp ${./monkey_patches.rb} monkey_patches.rb
|
||||
export RUBYOPT="-rmonkey_patches.rb -I $(pwd -P)"
|
||||
bundler install --frozen
|
||||
bundler install --frozen --binstubs
|
||||
'';
|
||||
passthru = {
|
||||
inherit ruby;
|
||||
inherit bundler;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -95,6 +95,46 @@ Bundler::Source::Rubygems.class_eval do
|
|||
end
|
||||
end
|
||||
|
||||
Bundler::Installer.class_eval do
|
||||
def generate_bundler_executable_stubs(spec, options = {})
|
||||
return if spec.executables.empty?
|
||||
|
||||
out = ENV['out']
|
||||
|
||||
spec.executables.each do |executable|
|
||||
next if executable == "bundle" || executable == "bundler"
|
||||
|
||||
binstub_path = "#{out}/bin/#{executable}"
|
||||
|
||||
File.open(binstub_path, 'w', 0777 & ~File.umask) do |f|
|
||||
f.print <<-TEXT
|
||||
#!/usr/bin/env #{RbConfig::CONFIG['ruby_install_name']}
|
||||
|
||||
old_gemfile = ENV["BUNDLE_GEMFILE"]
|
||||
old_gem_home = ENV["GEM_HOME"]
|
||||
old_gem_path = ENV["GEM_PATH"]
|
||||
|
||||
ENV["BUNDLE_GEMFILE"] =
|
||||
"#{ENV["BUNDLE_GEMFILE"]}"
|
||||
ENV["GEM_HOME"] =
|
||||
"#{ENV["GEM_HOME"]}"
|
||||
ENV["GEM_PATH"] =
|
||||
"#{ENV["NIX_BUNDLER_GEMPATH"]}:#{ENV["GEM_HOME"]}\#{old_gem_path ? ":\#{old_gem_path}" : ""}}"
|
||||
|
||||
require 'rubygems'
|
||||
require 'bundler/setup'
|
||||
|
||||
ENV["BUNDLE_GEMFILE"] = old_gemfile
|
||||
ENV["GEM_HOME"] = old_gem_home
|
||||
ENV["GEM_PATH"] = old_gem_path
|
||||
|
||||
load Gem.bin_path('#{spec.name}', '#{executable}')
|
||||
TEXT
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Gem::Installer.class_eval do
|
||||
# Make the wrappers automagically use bundler.
|
||||
#
|
||||
|
@ -122,7 +162,7 @@ Gem::Installer.class_eval do
|
|||
# this file is here to facilitate running it.
|
||||
#
|
||||
|
||||
old_gemfile = ENV["BUNDLE_GEMFILE"]
|
||||
old_gemfile = ENV["BUNDLE_GEMFILE"]
|
||||
old_gem_home = ENV["GEM_HOME"]
|
||||
old_gem_path = ENV["GEM_PATH"]
|
||||
|
||||
|
|
|
@ -4188,6 +4188,9 @@ let
|
|||
wrapPython = pythonPackages.wrapPython;
|
||||
};
|
||||
|
||||
bundix = callPackage ../development/interpreters/ruby/bundix {
|
||||
ruby = ruby_2_1_3;
|
||||
};
|
||||
bundler = callPackage ../development/interpreters/ruby/bundler.nix { };
|
||||
bundler_HEAD = import ../development/interpreters/ruby/bundler-head.nix {
|
||||
inherit buildRubyGem coreutils fetchgit;
|
||||
|
|
Loading…
Reference in a new issue