{ lib, gemConfig, ... }:
let
inherit (lib)
attrValues
concatMap
converge
filterAttrs
getAttrs
intersectLists
;
in
rec {
bundlerFiles =
{
gemfile ? null,
lockfile ? null,
gemset ? null,
gemdir ? null,
...
}:
inherit gemdir;
gemfile =
if gemfile == null then
assert gemdir != null;
gemdir + "/Gemfile"
else
gemfile;
lockfile =
if lockfile == null then
gemdir + "/Gemfile.lock"
lockfile;
gemset =
if gemset == null then
gemdir + "/gemset.nix"
gemset;
};
filterGemset =
{ ruby, groups, ... }:
gemset:
platformGems = filterAttrs (_: platformMatches ruby) gemset;
directlyMatchingGems = filterAttrs (_: groupMatches groups) platformGems;
expandDependencies =
gems:
depNames = concatMap (gem: gem.dependencies or [ ]) (attrValues gems);
deps = getAttrs depNames platformGems;
gems // deps;
converge expandDependencies directlyMatchingGems;
platformMatches =
{ rubyEngine, version, ... }:
attrs:
(
!(attrs ? platforms)
|| builtins.length attrs.platforms == 0
|| builtins.any (
platform:
platform.engine == rubyEngine && (!(platform ? version) || platform.version == version.majMin)
) attrs.platforms
);
groupMatches =
groups: attrs:
groups == null
|| !(attrs ? groups)
|| (intersectLists (groups ++ [ "default" ]) attrs.groups) != [ ];
applyGemConfigs =
attrs: (if gemConfig ? ${attrs.gemName} then attrs // gemConfig.${attrs.gemName} attrs else attrs);
genStubsScript =
lib,
runCommand,
ruby,
confFiles,
bundler,
groups,
binPaths,
runCommand "gen-bin-stubs"
strictDeps = true;
nativeBuildInputs = [ ruby ];
}
''
cp ${./gen-bin-stubs.rb} $out
chmod +x $out
patchShebangs --build $out
'';
${genStubsScript} \
"${ruby}/bin/ruby" \
"${confFiles}/Gemfile" \
"$out/${ruby.gemPath}" \
"${bundler}/${ruby.gemPath}/gems/bundler-${bundler.version}" \
${lib.escapeShellArg binPaths} \
${lib.escapeShellArg groups}
pathDerivation =
gemName,
version,
path,
res = {
type = "derivation";
bundledByPath = true;
name = gemName;
version = version;
outPath = "${path}";
outputs = [ "out" ];
out = res;
outputName = "out";
suffix = version;
gemType = "path";
res;
composeGemAttrs =
ruby: gems: name: attrs:
(removeAttrs attrs [ "platforms" ])
// {
inherit ruby;
inherit (attrs.source) type;
source = removeAttrs attrs.source [ "type" ];
gemName = name;
gemPath = map (gemName: gems.${gemName}) (attrs.dependencies or [ ]);