1{ ruby, lib, callPackage, gemFixes, fetchurl, fetchgit, buildRubyGem }@defs:
2
3# This function builds a set of gems. You first convert your Gemfile to an attrset
4# called a "gemset", and then use this function to build the gemset.
5#
6# A gemset looks like the following:
7#
8# {
9# libv8 = {
10# version = "3.16.14.7";
11# src = {
12# type = "gem";
13# sha256 = "...";
14# };
15# };
16# therubyracer = {
17# version = "0.12.1";
18# dependencies = [ "libv8" ];
19# src = {
20# type = "gem";
21# sha256 = "...";
22# };
23# };
24# }
25#
26# If you use these gems as build inputs, the GEM_PATH will be updated
27# appropriately, and command like `bundle exec` should work out of the box.
28
29{ gemset, ruby ? defs.ruby, fixes ? gemFixes }@args:
30
31let
32 const = x: y: x;
33
34 fetchers.path = attrs: attrs.src.path;
35 fetchers.gem = attrs: fetchurl {
36 url = "${attrs.src.source or "https://rubygems.org"}/downloads/${attrs.name}-${attrs.version}.gem";
37 inherit (attrs.src) sha256;
38 };
39 fetchers.git = attrs: fetchgit {
40 inherit (attrs.src) url rev sha256 fetchSubmodules;
41 leaveDotGit = true;
42 };
43
44 instantiate = (attrs:
45 let
46 defaultAttrs = {
47 name = "${attrs.name}-${attrs.version}";
48 inherit ruby gemPath;
49 };
50 gemPath = map (name: gemset''."${name}") (attrs.dependencies or []);
51 fixedAttrs = attrs // (fixes."${attrs.name}" or (const {})) attrs;
52 withSource = fixedAttrs //
53 (if (lib.isDerivation fixedAttrs.src || builtins.isString fixedAttrs.src)
54 then {}
55 else { src = (fetchers."${fixedAttrs.src.type}" fixedAttrs); });
56
57 in
58 buildRubyGem (withSource // defaultAttrs)
59 );
60
61 gemset' = if builtins.isAttrs gemset then gemset else import gemset;
62
63 gemset'' = lib.flip lib.mapAttrs gemset' (name: attrs:
64 if (lib.isDerivation attrs)
65 then attrs
66 else instantiate (attrs // { inherit name; })
67 );
68
69in gemset''