mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-02-23 12:34:15 +00:00
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
|
let
|
||||||
const = x: y: x;
|
const = x: y: x;
|
||||||
#bundler = bundler_PATCHED;
|
|
||||||
bundler = bundler_HEAD.override { inherit ruby; };
|
bundler = bundler_HEAD.override { inherit ruby; };
|
||||||
inherit (builtins) attrValues;
|
inherit (builtins) attrValues;
|
||||||
|
|
||||||
fetchers.path = attrs: attrs.src.path;
|
gemName = attrs: "${attrs.name}-${attrs.version}.gem";
|
||||||
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}";
|
|
||||||
|
|
||||||
|
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 {
|
fetchers.git = attrs: fetchgit {
|
||||||
inherit (attrs.src) url rev sha256 fetchSubmodules;
|
inherit (attrs.source) url rev sha256 fetchSubmodules;
|
||||||
leaveDotGit = true;
|
leaveDotGit = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
fixSpec = attrs:
|
applySrc = attrs:
|
||||||
attrs // (fixes."${attrs.name}" or (const {})) 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:
|
instantiate = (attrs:
|
||||||
let
|
applyFixes (applySrc attrs)
|
||||||
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
|
|
||||||
);
|
);
|
||||||
|
|
||||||
instantiated = lib.flip lib.mapAttrs (import gemset) (name: attrs:
|
instantiated = lib.flip lib.mapAttrs (import gemset) (name: attrs:
|
||||||
instantiate (attrs // { inherit name; })
|
instantiate (attrs // { inherit name; })
|
||||||
);
|
);
|
||||||
|
|
||||||
# only the *.gem files.
|
# copy *.gem to ./gems
|
||||||
gems = lib.fold (next: acc:
|
copyGems = lib.fold (next: acc:
|
||||||
if next.source.type == "gem"
|
if next.source.type == "gem"
|
||||||
then acc ++ [next.src]
|
then acc + "cp ${next.src} gems/${gemName next}\n"
|
||||||
else acc
|
else acc
|
||||||
) [] (attrValues instantiated);
|
) "" (attrValues instantiated);
|
||||||
|
|
||||||
runRuby = name: env: command:
|
runRuby = name: env: command:
|
||||||
runCommand name env ''
|
runCommand name env ''
|
||||||
@ -68,7 +118,7 @@ let
|
|||||||
# TODO: include json_pure, so the version of ruby doesn't matter.
|
# TODO: include json_pure, so the version of ruby doesn't matter.
|
||||||
# not all rubies have support for JSON built-in,
|
# not all rubies have support for JSON built-in,
|
||||||
# so we'll convert JSON to ruby expressions.
|
# so we'll convert JSON to ruby expressions.
|
||||||
json2rb = writeScriptBin "json2rb" ''
|
json2rb = writeScript "json2rb" ''
|
||||||
#!${ruby}/bin/ruby
|
#!${ruby}/bin/ruby
|
||||||
begin
|
begin
|
||||||
require 'json'
|
require 'json'
|
||||||
@ -81,7 +131,7 @@ let
|
|||||||
|
|
||||||
# dump the instantiated gemset as a ruby expression.
|
# dump the instantiated gemset as a ruby expression.
|
||||||
serializedGemset = runCommand "gemset.rb" { json = builtins.toJSON instantiated; } ''
|
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)
|
# 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.
|
# rewrite PATH sources to point into the nix store.
|
||||||
purifyLockfile = writeScript "purifyLockfile" ''
|
purifiedLockfile = runRuby "purifiedLockfile" {} ''
|
||||||
#!${ruby}/bin/ruby
|
#!${ruby}/bin/ruby
|
||||||
|
|
||||||
out = ENV['out']
|
out = ENV['out']
|
||||||
sources = eval(File.read("${sources}"))
|
sources = eval(File.read("${sources}"))
|
||||||
paths = sources["path"]
|
paths = sources["path"]
|
||||||
|
|
||||||
lockfile = STDIN.read
|
lockfile = File.read("${lockfile}")
|
||||||
|
|
||||||
paths.each_pair do |impure, pure|
|
paths.each_pair do |impure, pure|
|
||||||
lockfile.gsub!(/^ remote: #{Regexp.escape(impure)}/, " remote: #{pure}")
|
lockfile.gsub!(/^ remote: #{Regexp.escape(impure)}/, " remote: #{pure}")
|
||||||
end
|
end
|
||||||
|
|
||||||
print lockfile
|
File.open(out, "wb") do |f|
|
||||||
|
f.print lockfile
|
||||||
|
end
|
||||||
'';
|
'';
|
||||||
|
|
||||||
in
|
in
|
||||||
@ -149,15 +201,15 @@ stdenv.mkDerivation {
|
|||||||
];
|
];
|
||||||
phases = [ "installPhase" "fixupPhase" ];
|
phases = [ "installPhase" "fixupPhase" ];
|
||||||
outputs = [
|
outputs = [
|
||||||
"out" # the installed libs/bins
|
"out" # the installed libs/bins
|
||||||
"bundler" # supporting files for bundler
|
"bundle" # supporting files for bundler
|
||||||
];
|
];
|
||||||
installPhase = ''
|
installPhase = ''
|
||||||
# Copy the Gemfile and Gemfile.lock
|
# Copy the Gemfile and Gemfile.lock
|
||||||
mkdir -p $bundler
|
mkdir -p $bundle
|
||||||
export BUNDLE_GEMFILE=$bundler/Gemfile
|
export BUNDLE_GEMFILE=$bundle/Gemfile
|
||||||
cp ${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_GEM_SOURCES=${sources}
|
||||||
export NIX_BUNDLER_GEMPATH=${bundler}/${ruby.gemPath}
|
export NIX_BUNDLER_GEMPATH=${bundler}/${ruby.gemPath}
|
||||||
@ -167,15 +219,15 @@ stdenv.mkDerivation {
|
|||||||
mkdir -p $GEM_HOME
|
mkdir -p $GEM_HOME
|
||||||
|
|
||||||
mkdir gems
|
mkdir gems
|
||||||
for gem in ${toString gems}; do
|
${copyGems}
|
||||||
ln -s $gem gems
|
|
||||||
done
|
|
||||||
|
|
||||||
|
mkdir $out/bin
|
||||||
cp ${./monkey_patches.rb} monkey_patches.rb
|
cp ${./monkey_patches.rb} monkey_patches.rb
|
||||||
export RUBYOPT="-rmonkey_patches.rb -I $(pwd -P)"
|
export RUBYOPT="-rmonkey_patches.rb -I $(pwd -P)"
|
||||||
bundler install --frozen
|
bundler install --frozen --binstubs
|
||||||
'';
|
'';
|
||||||
passthru = {
|
passthru = {
|
||||||
inherit ruby;
|
inherit ruby;
|
||||||
|
inherit bundler;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -95,6 +95,46 @@ Bundler::Source::Rubygems.class_eval do
|
|||||||
end
|
end
|
||||||
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
|
Gem::Installer.class_eval do
|
||||||
# Make the wrappers automagically use bundler.
|
# Make the wrappers automagically use bundler.
|
||||||
#
|
#
|
||||||
@ -122,7 +162,7 @@ Gem::Installer.class_eval do
|
|||||||
# this file is here to facilitate running it.
|
# 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_home = ENV["GEM_HOME"]
|
||||||
old_gem_path = ENV["GEM_PATH"]
|
old_gem_path = ENV["GEM_PATH"]
|
||||||
|
|
||||||
|
@ -4188,6 +4188,9 @@ let
|
|||||||
wrapPython = pythonPackages.wrapPython;
|
wrapPython = pythonPackages.wrapPython;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bundix = callPackage ../development/interpreters/ruby/bundix {
|
||||||
|
ruby = ruby_2_1_3;
|
||||||
|
};
|
||||||
bundler = callPackage ../development/interpreters/ruby/bundler.nix { };
|
bundler = callPackage ../development/interpreters/ruby/bundler.nix { };
|
||||||
bundler_HEAD = import ../development/interpreters/ruby/bundler-head.nix {
|
bundler_HEAD = import ../development/interpreters/ruby/bundler-head.nix {
|
||||||
inherit buildRubyGem coreutils fetchgit;
|
inherit buildRubyGem coreutils fetchgit;
|
||||||
|
Loading…
Reference in New Issue
Block a user