From c765f680e3675faff57e05f41072616bac56b67a Mon Sep 17 00:00:00 2001 From: Judson Date: Sun, 19 Feb 2017 10:18:54 -0800 Subject: Updates to bundlerEnv --- .../ruby-modules/bundler-env/default.nix | 66 +++++++++++++++++----- 1 file changed, 52 insertions(+), 14 deletions(-) diff --git a/pkgs/development/ruby-modules/bundler-env/default.nix b/pkgs/development/ruby-modules/bundler-env/default.nix index 57ca23d41436..e82a6af0085e 100644 --- a/pkgs/development/ruby-modules/bundler-env/default.nix +++ b/pkgs/development/ruby-modules/bundler-env/default.nix @@ -46,11 +46,20 @@ let importedGemset = import gemset'; - filteredGemset = (lib.filterAttrs (name: attrs: - if (builtins.hasAttr "groups" attrs) - then (builtins.any (gemGroup: builtins.any (group: group == gemGroup) groups) attrs.groups) - else true - ) importedGemset); + platformMatches = attrs: ( + !(attrs ? "platforms") || + builtins.any (platform: + platform.engine == ruby.rubyEngine && + (!(platform ? "version") || platform.version == ruby.version.majMin) + ) attrs.platforms + ); + + groupMatches = attrs: ( + !(attrs ? "groups") || + builtins.any (gemGroup: builtins.any (group: group == gemGroup) groups) attrs.groups + ); + + filteredGemset = lib.filterAttrs (name: attrs: platformMatches attrs && groupMatches attrs) importedGemset; applyGemConfigs = attrs: (if gemConfig ? "${attrs.gemName}" @@ -67,25 +76,54 @@ let if hasBundler then gems.bundler else defs.bundler.override (attrs: { inherit ruby; }); - gems = lib.flip lib.mapAttrs configuredGemset (name: attrs: - buildRubyGem ((removeAttrs attrs ["source"]) // attrs.source // { - inherit ruby; - gemName = name; - gemPath = map (gemName: gems."${gemName}") (attrs.dependencies or []); - })); + pathDerivation = { + usesGemspec ? false, ... + }@attrs: + let + res = { + inherit usesGemspec; + type = "derivation"; + name = attrs.gemName; + version = attrs.version; + outPath = attrs.path; + outputs = [ "out" ]; + out = res; + outputName = "out"; + }; + in res; + + buildGem = name: attrs: ( + let + gemAttrs = ((removeAttrs attrs ["source"]) // attrs.source // { + inherit ruby; + gemName = name; + gemPath = map (gemName: gems."${gemName}") (attrs.dependencies or []); + }); + in + if gemAttrs.type == "path" then pathDerivation gemAttrs + else buildRubyGem gemAttrs); + + gems = lib.flip lib.mapAttrs configuredGemset (name: attrs: buildGem name attrs); + + maybeCopyAll = { usesGemspec ? false, ...}@main: + (if usesGemspec then '' + cp -a ${gemdir}/* $out/ + '' else "" + ); # We have to normalize the Gemfile.lock, otherwise bundler tries to be # helpful by doing so at run time, causing executables to immediately bail # out. Yes, I'm serious. confFiles = runCommand "gemfile-and-lockfile" {} '' mkdir -p $out - cp ${gemfile'} $out/Gemfile - cp ${lockfile'} $out/Gemfile.lock + ${maybeCopyAll mainGem} + cp ${gemfile'} $out/Gemfile || ls -l $out/Gemfile + cp ${lockfile'} $out/Gemfile.lock || ls -l $out/Gemfile.lock ''; envPaths = lib.attrValues gems ++ lib.optional (!hasBundler) bundler; - binPaths = if mainGem != null then [ mainGem ] else envPaths; + binPaths = if mainGem != null then [ mainGem ] ++ envPaths else envPaths; bundlerEnv = buildEnv { inherit ignoreCollisions; -- cgit 1.4.1 From 3c9941114f1c1801c388fbd1fc31907b14625b72 Mon Sep 17 00:00:00 2001 From: Judson Date: Sun, 19 Feb 2017 10:51:35 -0800 Subject: Need to handle "null" mainGems Not every gem package uses pname, nor should it. --- pkgs/development/ruby-modules/bundler-env/default.nix | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkgs/development/ruby-modules/bundler-env/default.nix b/pkgs/development/ruby-modules/bundler-env/default.nix index e82a6af0085e..ba9ea5f3fa80 100644 --- a/pkgs/development/ruby-modules/bundler-env/default.nix +++ b/pkgs/development/ruby-modules/bundler-env/default.nix @@ -105,7 +105,9 @@ let gems = lib.flip lib.mapAttrs configuredGemset (name: attrs: buildGem name attrs); - maybeCopyAll = { usesGemspec ? false, ...}@main: + maybeCopyAll = main: if main == null then "" else copyIfUseGemspec main; + + copyIfUseGemspec = { usesGemspec ? false, ...}@main: (if usesGemspec then '' cp -a ${gemdir}/* $out/ '' else "" -- cgit 1.4.1 From 0481a33d214b3129970d0951e2fe82548c4d3d04 Mon Sep 17 00:00:00 2001 From: Judson Date: Mon, 20 Feb 2017 21:03:44 -0800 Subject: Simplifying interface on gemset.nix slightly. `usesGemspec` no longer required to trigger the "copy everything into gemfile-and-lock" behavior. If the mainGem is referred to by path, that's sufficient. --- pkgs/development/ruby-modules/bundler-env/default.nix | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/pkgs/development/ruby-modules/bundler-env/default.nix b/pkgs/development/ruby-modules/bundler-env/default.nix index ba9ea5f3fa80..794dd11665d1 100644 --- a/pkgs/development/ruby-modules/bundler-env/default.nix +++ b/pkgs/development/ruby-modules/bundler-env/default.nix @@ -76,16 +76,14 @@ let if hasBundler then gems.bundler else defs.bundler.override (attrs: { inherit ruby; }); - pathDerivation = { - usesGemspec ? false, ... - }@attrs: + pathDerivation = { gemName, version, path, ... }: let res = { - inherit usesGemspec; type = "derivation"; - name = attrs.gemName; - version = attrs.version; - outPath = attrs.path; + bundledByPath = true; + name = gemName; + version = version; + outPath = path; outputs = [ "out" ]; out = res; outputName = "out"; @@ -105,10 +103,10 @@ let gems = lib.flip lib.mapAttrs configuredGemset (name: attrs: buildGem name attrs); - maybeCopyAll = main: if main == null then "" else copyIfUseGemspec main; + maybeCopyAll = main: if main == null then "" else copyIfBundledByPath main; - copyIfUseGemspec = { usesGemspec ? false, ...}@main: - (if usesGemspec then '' + copyIfBundledByPath = { bundledByPath ? false, ...}@main: + (if bundledByPath then '' cp -a ${gemdir}/* $out/ '' else "" ); -- cgit 1.4.1 From 7f6e8a1cd5297d35e7cf431f682b1b1abfa26f16 Mon Sep 17 00:00:00 2001 From: Judson Date: Sun, 26 Mar 2017 17:32:30 -0700 Subject: Adding "allBins" flag on bundlerEnv The bin stubs need to be built where there's access to /nix/store - so it can't happen in a nix-shell run. Ergo, a shell.nix needs to be able to signal to the build that all bins need to be built. --- .../ruby-modules/bundler-env/default.nix | 25 ++++++++++++---------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/pkgs/development/ruby-modules/bundler-env/default.nix b/pkgs/development/ruby-modules/bundler-env/default.nix index 794dd11665d1..7d2f0efe0011 100644 --- a/pkgs/development/ruby-modules/bundler-env/default.nix +++ b/pkgs/development/ruby-modules/bundler-env/default.nix @@ -12,6 +12,7 @@ , gemfile ? null , lockfile ? null , gemset ? null +, allBins ? false , ruby ? defs.ruby , gemConfig ? defaultGemConfig , postBuild ? null @@ -123,7 +124,17 @@ let envPaths = lib.attrValues gems ++ lib.optional (!hasBundler) bundler; - binPaths = if mainGem != null then [ mainGem ] ++ envPaths else envPaths; + binPaths = if !allBins && mainGem != null then [ mainGem ] else envPaths; + + genStubs = binPaths: '' + ${ruby}/bin/ruby ${./gen-bin-stubs.rb} \ + "${ruby}/bin/ruby" \ + "${confFiles}/Gemfile" \ + "$out/${ruby.gemPath}" \ + "${bundler}/${ruby.gemPath}" \ + ${lib.escapeShellArg binPaths} \ + ${lib.escapeShellArg groups} + ''; bundlerEnv = buildEnv { inherit ignoreCollisions; @@ -133,15 +144,7 @@ let paths = envPaths; pathsToLink = [ "/lib" ]; - postBuild = '' - ${ruby}/bin/ruby ${./gen-bin-stubs.rb} \ - "${ruby}/bin/ruby" \ - "${confFiles}/Gemfile" \ - "$out/${ruby.gemPath}" \ - "${bundler}/${ruby.gemPath}" \ - ${lib.escapeShellArg binPaths} \ - ${lib.escapeShellArg groups} - '' + lib.optionalString (postBuild != null) postBuild; + postBuild = (genStubs binPaths) + lib.optionalString (postBuild != null) postBuild; meta = { platforms = ruby.meta.platforms; } // meta; @@ -173,7 +176,7 @@ let require 'bundler/setup' ''; in stdenv.mkDerivation { - name = "interactive-${drvName}-environment"; + name = "${drvName}-interactive-environment"; nativeBuildInputs = [ wrappedRuby bundlerEnv ]; shellHook = '' export OLD_IRBRC="$IRBRC" -- cgit 1.4.1 From 89fda10d31f2843c87aa2232d8d7f19adbccb3e8 Mon Sep 17 00:00:00 2001 From: Judson Date: Mon, 24 Apr 2017 18:45:00 -0700 Subject: Starting decomposition of bundlerEnv --- .../development/ruby-modules/bundler-env/basic.nix | 134 ++++++++++++++ .../ruby-modules/bundler-env/default.nix | 157 ++--------------- .../ruby-modules/bundler-env/functions.nix | 49 ++++++ .../ruby-modules/bundler-env/too-complicated.nix | 195 +++++++++++++++++++++ 4 files changed, 394 insertions(+), 141 deletions(-) create mode 100644 pkgs/development/ruby-modules/bundler-env/basic.nix create mode 100644 pkgs/development/ruby-modules/bundler-env/functions.nix create mode 100644 pkgs/development/ruby-modules/bundler-env/too-complicated.nix diff --git a/pkgs/development/ruby-modules/bundler-env/basic.nix b/pkgs/development/ruby-modules/bundler-env/basic.nix new file mode 100644 index 000000000000..705c8dabd63c --- /dev/null +++ b/pkgs/development/ruby-modules/bundler-env/basic.nix @@ -0,0 +1,134 @@ +{ stdenv, runCommand, ruby, lib +, defaultGemConfig, buildRubyGem, buildEnv +, makeWrapper +, bundler +}@defs: + +{ + drvName +, pname +, gemfile +, lockfile +, gemset +, ruby ? defs.ruby +, gemConfig ? defaultGemConfig +, postBuild ? null +, document ? [] +, meta ? {} +, groups ? ["default"] +, ignoreCollisions ? false +, ... +}@args: + +with (import ./functions.nix); + +let + mainGem = gems."${pname}" or (throw "bundlerEnv: gem ${pname} not found"); + + importedGemset = import gemset; + + filteredGemset = lib.filterAttrs (name: attrs: platformMatches attrs && groupMatches attrs) importedGemset; + + configuredGemset = lib.flip lib.mapAttrs filteredGemset (name: attrs: + applyGemConfigs (attrs // { inherit ruby; gemName = name; }) + ); + + hasBundler = builtins.hasAttr "bundler" filteredGemset; + + bundler = + if hasBundler then gems.bundler + else defs.bundler.override (attrs: { inherit ruby; }); + + gems = lib.flip lib.mapAttrs configuredGemset (name: attrs: buildGem name attrs); + + copyIfBundledByPath = { bundledByPath ? false, ...}@main: + (if bundledByPath then '' + cp -a ${gemdir}/* $out/ + '' else "" + ); + + maybeCopyAll = main: if main == null then "" else copyIfBundledByPath main; + + # We have to normalize the Gemfile.lock, otherwise bundler tries to be + # helpful by doing so at run time, causing executables to immediately bail + # out. Yes, I'm serious. + confFiles = runCommand "gemfile-and-lockfile" {} '' + mkdir -p $out + ${maybeCopyAll mainGem} + cp ${gemfile} $out/Gemfile || ls -l $out/Gemfile + cp ${lockfile} $out/Gemfile.lock || ls -l $out/Gemfile.lock + ''; + + buildGem = name: attrs: ( + let + gemAttrs = composeGemAttrs gems name attrs; + in + if gemAttrs.type == "path" then + pathDerivation gemAttrs + else + buildRubyGem gemAttrs + ); + + envPaths = lib.attrValues gems ++ lib.optional (!hasBundler) bundler; + + # binPaths = if mainGem != null then [ mainGem ] else envPaths; + +in + buildEnv { + inherit ignoreCollisions; + + name = drvName; + + paths = envPaths; + pathsToLink = [ "/lib" ]; + + postBuild = genStubsScript defs // args // { + inherit confFiles bundler; + binPaths = envPaths; + } + lib.optionalString (postBuild != null) postBuild; + + meta = { platforms = ruby.meta.platforms; } // meta; + + passthru = rec { + inherit ruby bundler gems; + + wrappedRuby = stdenv.mkDerivation { + name = "wrapped-ruby-${drvName}"; + nativeBuildInputs = [ makeWrapper ]; + buildCommand = '' + mkdir -p $out/bin + for i in ${ruby}/bin/*; do + makeWrapper "$i" $out/bin/$(basename "$i") \ + --set BUNDLE_GEMFILE ${confFiles}/Gemfile \ + --set BUNDLE_PATH ${bundlerEnv}/${ruby.gemPath} \ + --set BUNDLE_FROZEN 1 \ + --set GEM_HOME ${bundlerEnv}/${ruby.gemPath} \ + --set GEM_PATH ${bundlerEnv}/${ruby.gemPath} + done + ''; + }; + + env = let + irbrc = builtins.toFile "irbrc" '' + if !(ENV["OLD_IRBRC"].nil? || ENV["OLD_IRBRC"].empty?) + require ENV["OLD_IRBRC"] + end + require 'rubygems' + require 'bundler/setup' + ''; + in stdenv.mkDerivation { + name = "${drvName}-interactive-environment"; + nativeBuildInputs = [ wrappedRuby bundlerEnv ]; + shellHook = '' + export OLD_IRBRC="$IRBRC" + export IRBRC=${irbrc} + ''; + buildCommand = '' + echo >&2 "" + echo >&2 "*** Ruby 'env' attributes are intended for interactive nix-shell sessions, not for building! ***" + echo >&2 "" + exit 1 + ''; + }; + }; + } diff --git a/pkgs/development/ruby-modules/bundler-env/default.nix b/pkgs/development/ruby-modules/bundler-env/default.nix index 7d2f0efe0011..5218d7f0c4dd 100644 --- a/pkgs/development/ruby-modules/bundler-env/default.nix +++ b/pkgs/development/ruby-modules/bundler-env/default.nix @@ -1,5 +1,6 @@ { stdenv, runCommand, writeText, writeScript, writeScriptBin, ruby, lib , callPackage, defaultGemConfig, fetchurl, fetchgit, buildRubyGem, buildEnv +, linkFarm , git , makeWrapper , bundler @@ -12,7 +13,6 @@ , gemfile ? null , lockfile ? null , gemset ? null -, allBins ? false , ruby ? defs.ruby , gemConfig ? defaultGemConfig , postBuild ? null @@ -45,151 +45,26 @@ let if gemset == null then gemdir + "/gemset.nix" else gemset; - importedGemset = import gemset'; - - platformMatches = attrs: ( - !(attrs ? "platforms") || - builtins.any (platform: - platform.engine == ruby.rubyEngine && - (!(platform ? "version") || platform.version == ruby.version.majMin) - ) attrs.platforms - ); - - groupMatches = attrs: ( - !(attrs ? "groups") || - builtins.any (gemGroup: builtins.any (group: group == gemGroup) groups) attrs.groups - ); - - filteredGemset = lib.filterAttrs (name: attrs: platformMatches attrs && groupMatches attrs) importedGemset; - - applyGemConfigs = attrs: - (if gemConfig ? "${attrs.gemName}" - then attrs // gemConfig."${attrs.gemName}" attrs - else attrs); - - configuredGemset = lib.flip lib.mapAttrs filteredGemset (name: attrs: - applyGemConfigs (attrs // { inherit ruby; gemName = name; }) - ); - - hasBundler = builtins.hasAttr "bundler" filteredGemset; - - bundler = - if hasBundler then gems.bundler - else defs.bundler.override (attrs: { inherit ruby; }); - - pathDerivation = { gemName, version, path, ... }: - let - res = { - type = "derivation"; - bundledByPath = true; - name = gemName; - version = version; - outPath = path; - outputs = [ "out" ]; - out = res; - outputName = "out"; - }; - in res; - - buildGem = name: attrs: ( - let - gemAttrs = ((removeAttrs attrs ["source"]) // attrs.source // { - inherit ruby; - gemName = name; - gemPath = map (gemName: gems."${gemName}") (attrs.dependencies or []); - }); - in - if gemAttrs.type == "path" then pathDerivation gemAttrs - else buildRubyGem gemAttrs); - - gems = lib.flip lib.mapAttrs configuredGemset (name: attrs: buildGem name attrs); - - maybeCopyAll = main: if main == null then "" else copyIfBundledByPath main; - - copyIfBundledByPath = { bundledByPath ? false, ...}@main: - (if bundledByPath then '' - cp -a ${gemdir}/* $out/ - '' else "" - ); - - # We have to normalize the Gemfile.lock, otherwise bundler tries to be - # helpful by doing so at run time, causing executables to immediately bail - # out. Yes, I'm serious. - confFiles = runCommand "gemfile-and-lockfile" {} '' - mkdir -p $out - ${maybeCopyAll mainGem} - cp ${gemfile'} $out/Gemfile || ls -l $out/Gemfile - cp ${lockfile'} $out/Gemfile.lock || ls -l $out/Gemfile.lock - ''; - envPaths = lib.attrValues gems ++ lib.optional (!hasBundler) bundler; - binPaths = if !allBins && mainGem != null then [ mainGem ] else envPaths; - - genStubs = binPaths: '' - ${ruby}/bin/ruby ${./gen-bin-stubs.rb} \ - "${ruby}/bin/ruby" \ - "${confFiles}/Gemfile" \ - "$out/${ruby.gemPath}" \ - "${bundler}/${ruby.gemPath}" \ - ${lib.escapeShellArg binPaths} \ - ${lib.escapeShellArg groups} - ''; + binPaths = if mainGem != null then [ mainGem ] else envPaths; - bundlerEnv = buildEnv { - inherit ignoreCollisions; + basicEnv = import ./basic args // { inherit drvName pname gemfile lockfile gemset; }; - name = drvName; + # Idea here is a mkDerivation that gen-bin-stubs new stubs "as specified" - + # either specific executables or the bin/ for certain gem(s), but + # incorporates the basicEnv as a requirement so that its $out is in our path. - paths = envPaths; - pathsToLink = [ "/lib" ]; + # When stubbing the bins for a gem, we should use the gem expression + # directly, which means that basicEnv should somehow make it available. - postBuild = (genStubs binPaths) + lib.optionalString (postBuild != null) postBuild; + # Different use cases should use different variations on this file, rather + # than the expression trying to deduce a use case. - meta = { platforms = ruby.meta.platforms; } // meta; - - passthru = rec { - inherit ruby bundler gems; - - wrappedRuby = stdenv.mkDerivation { - name = "wrapped-ruby-${drvName}"; - nativeBuildInputs = [ makeWrapper ]; - buildCommand = '' - mkdir -p $out/bin - for i in ${ruby}/bin/*; do - makeWrapper "$i" $out/bin/$(basename "$i") \ - --set BUNDLE_GEMFILE ${confFiles}/Gemfile \ - --set BUNDLE_PATH ${bundlerEnv}/${ruby.gemPath} \ - --set BUNDLE_FROZEN 1 \ - --set GEM_HOME ${bundlerEnv}/${ruby.gemPath} \ - --set GEM_PATH ${bundlerEnv}/${ruby.gemPath} - done - ''; - }; - - env = let - irbrc = builtins.toFile "irbrc" '' - if !(ENV["OLD_IRBRC"].nil? || ENV["OLD_IRBRC"].empty?) - require ENV["OLD_IRBRC"] - end - require 'rubygems' - require 'bundler/setup' - ''; - in stdenv.mkDerivation { - name = "${drvName}-interactive-environment"; - nativeBuildInputs = [ wrappedRuby bundlerEnv ]; - shellHook = '' - export OLD_IRBRC="$IRBRC" - export IRBRC=${irbrc} - ''; - buildCommand = '' - echo >&2 "" - echo >&2 "*** Ruby 'env' attributes are intended for interactive nix-shell sessions, not for building! ***" - echo >&2 "" - exit 1 - ''; - }; - }; - }; + # The basicEnv should be put into passthru so that e.g. nix-shell can use it. in - bundlerEnv + (linkFarm drvName entries) // { + passthru = { + inherit basicEnv; + }; + } diff --git a/pkgs/development/ruby-modules/bundler-env/functions.nix b/pkgs/development/ruby-modules/bundler-env/functions.nix new file mode 100644 index 000000000000..a2d17be47011 --- /dev/null +++ b/pkgs/development/ruby-modules/bundler-env/functions.nix @@ -0,0 +1,49 @@ +rec { + platformMatches = attrs: ( + !(attrs ? "platforms") || + builtins.any (platform: + platform.engine == ruby.rubyEngine && + (!(platform ? "version") || platform.version == ruby.version.majMin) + ) attrs.platforms + ); + + groupMatches = attrs: ( + !(attrs ? "groups") || + builtins.any (gemGroup: builtins.any (group: group == gemGroup) groups) attrs.groups + ); + + applyGemConfigs = attrs: + (if gemConfig ? "${attrs.gemName}" + then attrs // gemConfig."${attrs.gemName}" attrs + else attrs); + + genStubsScript = { lib, ruby, confFile, bundler, groups, binPaths }@args: '' + ${ruby}/bin/ruby ${./gen-bin-stubs.rb} \ + "${ruby}/bin/ruby" \ + "${confFiles}/Gemfile" \ + "$out/${ruby.gemPath}" \ + "${bundler}/${ruby.gemPath}" \ + ${lib.escapeShellArg binPaths} \ + ${lib.escapeShellArg groups} + ''; + + pathDerivation = { gemName, version, path, ... }: + let + res = { + type = "derivation"; + bundledByPath = true; + name = gemName; + version = version; + outPath = path; + outputs = [ "out" ]; + out = res; + outputName = "out"; + }; + in res; + + composeGemAttrs = gems: name: attrs: ((removeAttrs attrs ["source"]) // attrs.source // { + inherit ruby; + gemName = name; + gemPath = map (gemName: gems."${gemName}") (attrs.dependencies or []); + }); +} diff --git a/pkgs/development/ruby-modules/bundler-env/too-complicated.nix b/pkgs/development/ruby-modules/bundler-env/too-complicated.nix new file mode 100644 index 000000000000..7d2f0efe0011 --- /dev/null +++ b/pkgs/development/ruby-modules/bundler-env/too-complicated.nix @@ -0,0 +1,195 @@ +{ stdenv, runCommand, writeText, writeScript, writeScriptBin, ruby, lib +, callPackage, defaultGemConfig, fetchurl, fetchgit, buildRubyGem, buildEnv +, git +, makeWrapper +, bundler +, tree +}@defs: + +{ name ? null +, pname ? null +, gemdir ? null +, gemfile ? null +, lockfile ? null +, gemset ? null +, allBins ? false +, ruby ? defs.ruby +, gemConfig ? defaultGemConfig +, postBuild ? null +, document ? [] +, meta ? {} +, groups ? ["default"] +, ignoreCollisions ? false +, ... +}@args: + +let + drvName = + if name != null then name + else if pname != null then "${toString pname}-${mainGem.version}" + else throw "bundlerEnv: either pname or name must be set"; + + mainGem = + if pname == null then null + else gems."${pname}" or (throw "bundlerEnv: gem ${pname} not found"); + + gemfile' = + if gemfile == null then gemdir + "/Gemfile" + else gemfile; + + lockfile' = + if lockfile == null then gemdir + "/Gemfile.lock" + else lockfile; + + gemset' = + if gemset == null then gemdir + "/gemset.nix" + else gemset; + + importedGemset = import gemset'; + + platformMatches = attrs: ( + !(attrs ? "platforms") || + builtins.any (platform: + platform.engine == ruby.rubyEngine && + (!(platform ? "version") || platform.version == ruby.version.majMin) + ) attrs.platforms + ); + + groupMatches = attrs: ( + !(attrs ? "groups") || + builtins.any (gemGroup: builtins.any (group: group == gemGroup) groups) attrs.groups + ); + + filteredGemset = lib.filterAttrs (name: attrs: platformMatches attrs && groupMatches attrs) importedGemset; + + applyGemConfigs = attrs: + (if gemConfig ? "${attrs.gemName}" + then attrs // gemConfig."${attrs.gemName}" attrs + else attrs); + + configuredGemset = lib.flip lib.mapAttrs filteredGemset (name: attrs: + applyGemConfigs (attrs // { inherit ruby; gemName = name; }) + ); + + hasBundler = builtins.hasAttr "bundler" filteredGemset; + + bundler = + if hasBundler then gems.bundler + else defs.bundler.override (attrs: { inherit ruby; }); + + pathDerivation = { gemName, version, path, ... }: + let + res = { + type = "derivation"; + bundledByPath = true; + name = gemName; + version = version; + outPath = path; + outputs = [ "out" ]; + out = res; + outputName = "out"; + }; + in res; + + buildGem = name: attrs: ( + let + gemAttrs = ((removeAttrs attrs ["source"]) // attrs.source // { + inherit ruby; + gemName = name; + gemPath = map (gemName: gems."${gemName}") (attrs.dependencies or []); + }); + in + if gemAttrs.type == "path" then pathDerivation gemAttrs + else buildRubyGem gemAttrs); + + gems = lib.flip lib.mapAttrs configuredGemset (name: attrs: buildGem name attrs); + + maybeCopyAll = main: if main == null then "" else copyIfBundledByPath main; + + copyIfBundledByPath = { bundledByPath ? false, ...}@main: + (if bundledByPath then '' + cp -a ${gemdir}/* $out/ + '' else "" + ); + + # We have to normalize the Gemfile.lock, otherwise bundler tries to be + # helpful by doing so at run time, causing executables to immediately bail + # out. Yes, I'm serious. + confFiles = runCommand "gemfile-and-lockfile" {} '' + mkdir -p $out + ${maybeCopyAll mainGem} + cp ${gemfile'} $out/Gemfile || ls -l $out/Gemfile + cp ${lockfile'} $out/Gemfile.lock || ls -l $out/Gemfile.lock + ''; + + envPaths = lib.attrValues gems ++ lib.optional (!hasBundler) bundler; + + binPaths = if !allBins && mainGem != null then [ mainGem ] else envPaths; + + genStubs = binPaths: '' + ${ruby}/bin/ruby ${./gen-bin-stubs.rb} \ + "${ruby}/bin/ruby" \ + "${confFiles}/Gemfile" \ + "$out/${ruby.gemPath}" \ + "${bundler}/${ruby.gemPath}" \ + ${lib.escapeShellArg binPaths} \ + ${lib.escapeShellArg groups} + ''; + + bundlerEnv = buildEnv { + inherit ignoreCollisions; + + name = drvName; + + paths = envPaths; + pathsToLink = [ "/lib" ]; + + postBuild = (genStubs binPaths) + lib.optionalString (postBuild != null) postBuild; + + meta = { platforms = ruby.meta.platforms; } // meta; + + passthru = rec { + inherit ruby bundler gems; + + wrappedRuby = stdenv.mkDerivation { + name = "wrapped-ruby-${drvName}"; + nativeBuildInputs = [ makeWrapper ]; + buildCommand = '' + mkdir -p $out/bin + for i in ${ruby}/bin/*; do + makeWrapper "$i" $out/bin/$(basename "$i") \ + --set BUNDLE_GEMFILE ${confFiles}/Gemfile \ + --set BUNDLE_PATH ${bundlerEnv}/${ruby.gemPath} \ + --set BUNDLE_FROZEN 1 \ + --set GEM_HOME ${bundlerEnv}/${ruby.gemPath} \ + --set GEM_PATH ${bundlerEnv}/${ruby.gemPath} + done + ''; + }; + + env = let + irbrc = builtins.toFile "irbrc" '' + if !(ENV["OLD_IRBRC"].nil? || ENV["OLD_IRBRC"].empty?) + require ENV["OLD_IRBRC"] + end + require 'rubygems' + require 'bundler/setup' + ''; + in stdenv.mkDerivation { + name = "${drvName}-interactive-environment"; + nativeBuildInputs = [ wrappedRuby bundlerEnv ]; + shellHook = '' + export OLD_IRBRC="$IRBRC" + export IRBRC=${irbrc} + ''; + buildCommand = '' + echo >&2 "" + echo >&2 "*** Ruby 'env' attributes are intended for interactive nix-shell sessions, not for building! ***" + echo >&2 "" + exit 1 + ''; + }; + }; + }; +in + bundlerEnv -- cgit 1.4.1 From 2b414e1c1553c1ff678d172f99da227670b8f68e Mon Sep 17 00:00:00 2001 From: Judson Date: Mon, 1 May 2017 09:07:42 -0700 Subject: Test harnesses --- .../development/ruby-modules/bundler-env/basic.nix | 42 ++++++++------- .../ruby-modules/bundler-env/default.nix | 47 ++++++++++------ .../ruby-modules/bundler-env/functions.nix | 5 +- .../ruby-modules/bundler-env/tap-support.nix | 20 +++++++ pkgs/development/ruby-modules/bundler-env/test.nix | 49 +++++++++++++++++ .../ruby-modules/bundler-env/testing.nix | 62 ++++++++++++++++++++++ 6 files changed, 189 insertions(+), 36 deletions(-) create mode 100644 pkgs/development/ruby-modules/bundler-env/tap-support.nix create mode 100644 pkgs/development/ruby-modules/bundler-env/test.nix create mode 100644 pkgs/development/ruby-modules/bundler-env/testing.nix diff --git a/pkgs/development/ruby-modules/bundler-env/basic.nix b/pkgs/development/ruby-modules/bundler-env/basic.nix index 705c8dabd63c..7f96a8ce0e73 100644 --- a/pkgs/development/ruby-modules/bundler-env/basic.nix +++ b/pkgs/development/ruby-modules/bundler-env/basic.nix @@ -5,11 +5,11 @@ }@defs: { - drvName -, pname + pname , gemfile , lockfile , gemset +, gemdir , ruby ? defs.ruby , gemConfig ? defaultGemConfig , postBuild ? null @@ -20,14 +20,13 @@ , ... }@args: -with (import ./functions.nix); +with (import ./functions.nix { inherit lib ruby gemConfig groups; }); let - mainGem = gems."${pname}" or (throw "bundlerEnv: gem ${pname} not found"); importedGemset = import gemset; - filteredGemset = lib.filterAttrs (name: attrs: platformMatches attrs && groupMatches attrs) importedGemset; + filteredGemset = filterGemset importedGemset; configuredGemset = lib.flip lib.mapAttrs filteredGemset (name: attrs: applyGemConfigs (attrs // { inherit ruby; gemName = name; }) @@ -47,14 +46,18 @@ let '' else "" ); - maybeCopyAll = main: if main == null then "" else copyIfBundledByPath main; + maybeCopyAll = pname: if pname == null then "" else + let + mainGem = gems."${pname}" or (throw "bundlerEnv: gem ${pname} not found"); + in + copyIfBundledByPath mainGem; # We have to normalize the Gemfile.lock, otherwise bundler tries to be # helpful by doing so at run time, causing executables to immediately bail # out. Yes, I'm serious. confFiles = runCommand "gemfile-and-lockfile" {} '' mkdir -p $out - ${maybeCopyAll mainGem} + ${maybeCopyAll pname} cp ${gemfile} $out/Gemfile || ls -l $out/Gemfile cp ${lockfile} $out/Gemfile.lock || ls -l $out/Gemfile.lock ''; @@ -71,13 +74,10 @@ let envPaths = lib.attrValues gems ++ lib.optional (!hasBundler) bundler; - # binPaths = if mainGem != null then [ mainGem ] else envPaths; - -in - buildEnv { + basicEnv = buildEnv { inherit ignoreCollisions; - name = drvName; + name = pname; paths = envPaths; pathsToLink = [ "/lib" ]; @@ -90,20 +90,20 @@ in meta = { platforms = ruby.meta.platforms; } // meta; passthru = rec { - inherit ruby bundler gems; + inherit ruby bundler gems; # drvName; wrappedRuby = stdenv.mkDerivation { - name = "wrapped-ruby-${drvName}"; + name = "wrapped-ruby-${pname}"; nativeBuildInputs = [ makeWrapper ]; buildCommand = '' mkdir -p $out/bin for i in ${ruby}/bin/*; do makeWrapper "$i" $out/bin/$(basename "$i") \ --set BUNDLE_GEMFILE ${confFiles}/Gemfile \ - --set BUNDLE_PATH ${bundlerEnv}/${ruby.gemPath} \ + --set BUNDLE_PATH ${basicEnv}/${ruby.gemPath} \ --set BUNDLE_FROZEN 1 \ - --set GEM_HOME ${bundlerEnv}/${ruby.gemPath} \ - --set GEM_PATH ${bundlerEnv}/${ruby.gemPath} + --set GEM_HOME ${basicEnv}/${ruby.gemPath} \ + --set GEM_PATH ${basicEnv}/${ruby.gemPath} done ''; }; @@ -117,8 +117,8 @@ in require 'bundler/setup' ''; in stdenv.mkDerivation { - name = "${drvName}-interactive-environment"; - nativeBuildInputs = [ wrappedRuby bundlerEnv ]; + name = "${pname}-interactive-environment"; + nativeBuildInputs = [ wrappedRuby basicEnv ]; shellHook = '' export OLD_IRBRC="$IRBRC" export IRBRC=${irbrc} @@ -131,4 +131,6 @@ in ''; }; }; - } + }; +in + basicEnv diff --git a/pkgs/development/ruby-modules/bundler-env/default.nix b/pkgs/development/ruby-modules/bundler-env/default.nix index 5218d7f0c4dd..d1fa4785c06c 100644 --- a/pkgs/development/ruby-modules/bundler-env/default.nix +++ b/pkgs/development/ruby-modules/bundler-env/default.nix @@ -24,15 +24,13 @@ }@args: let + inherit (import ./functions.nix (defs // args)) genStubsScript; + drvName = if name != null then name - else if pname != null then "${toString pname}-${mainGem.version}" + else if pname != null then "${toString pname}-${basicEnv.gems."${pname}".version}" else throw "bundlerEnv: either pname or name must be set"; - mainGem = - if pname == null then null - else gems."${pname}" or (throw "bundlerEnv: gem ${pname} not found"); - gemfile' = if gemfile == null then gemdir + "/Gemfile" else gemfile; @@ -45,12 +43,13 @@ let if gemset == null then gemdir + "/gemset.nix" else gemset; - envPaths = lib.attrValues gems ++ lib.optional (!hasBundler) bundler; - - binPaths = if mainGem != null then [ mainGem ] else envPaths; - - basicEnv = import ./basic args // { inherit drvName pname gemfile lockfile gemset; }; + basicEnv = (callPackage ./basic.nix {}) (args // { inherit pname gemdir; + gemfile = gemfile'; + lockfile = lockfile'; + gemset = gemset'; + }); + inherit (basicEnv) envPaths; # Idea here is a mkDerivation that gen-bin-stubs new stubs "as specified" - # either specific executables or the bin/ for certain gem(s), but # incorporates the basicEnv as a requirement so that its $out is in our path. @@ -63,8 +62,26 @@ let # The basicEnv should be put into passthru so that e.g. nix-shell can use it. in - (linkFarm drvName entries) // { - passthru = { - inherit basicEnv; - }; - } + if builtins.trace "pname: ${toString pname}" pname == null then + basicEnv // { inherit name; } + else + (buildEnv { + inherit ignoreCollisions; + + name = builtins.trace "name: ${toString drvName}" drvName; + + paths = envPaths; + pathsToLink = [ "/lib" ]; + + postBuild = genStubsScript defs // args // { + inherit bundler; + confFiles = basicEnv.confFiles; + binPaths = [ basicEnv.mainGem ]; + } + lib.optionalString (postBuild != null) postBuild; + + meta = { platforms = ruby.meta.platforms; } // meta; + passthru = basicEnv.passthru // { + inherit basicEnv; + inherit (basicEnv) env; + }; + }) diff --git a/pkgs/development/ruby-modules/bundler-env/functions.nix b/pkgs/development/ruby-modules/bundler-env/functions.nix index a2d17be47011..75dd276f663a 100644 --- a/pkgs/development/ruby-modules/bundler-env/functions.nix +++ b/pkgs/development/ruby-modules/bundler-env/functions.nix @@ -1,4 +1,7 @@ +{ lib, ruby, groups, gemConfig, ... }: rec { + filterGemset = gemset: lib.filterAttrs (name: attrs: platformMatches attrs && groupMatches attrs) gemset; + platformMatches = attrs: ( !(attrs ? "platforms") || builtins.any (platform: @@ -17,7 +20,7 @@ rec { then attrs // gemConfig."${attrs.gemName}" attrs else attrs); - genStubsScript = { lib, ruby, confFile, bundler, groups, binPaths }@args: '' + genStubsScript = { lib, ruby, confFiles, bundler, groups, binPaths }: '' ${ruby}/bin/ruby ${./gen-bin-stubs.rb} \ "${ruby}/bin/ruby" \ "${confFiles}/Gemfile" \ diff --git a/pkgs/development/ruby-modules/bundler-env/tap-support.nix b/pkgs/development/ruby-modules/bundler-env/tap-support.nix new file mode 100644 index 000000000000..ba576683d372 --- /dev/null +++ b/pkgs/development/ruby-modules/bundler-env/tap-support.nix @@ -0,0 +1,20 @@ +with builtins; +let + withIndexes = list: genList (idx: (elemAt list idx) // {index = idx;}) (length list); + + testLine = report: "${okStr report} ${toString report.index} ${report.description}" + testDirective report + testYaml report; + + testDirective = report: ""; + + testYaml = report: ""; + + okStr = { result, ...}: if result == "pass" then "ok" else "not ok"; +in + { + output = reports: '' + TAP version 13 + 1..${toString (length reports)}'' + (foldl' (l: r: l + "\n" + r) "" (map testLine (withIndexes reports))) + '' + + # Finished at ${toString currentTime} + ''; + } diff --git a/pkgs/development/ruby-modules/bundler-env/test.nix b/pkgs/development/ruby-modules/bundler-env/test.nix new file mode 100644 index 000000000000..3f77eb1fb43e --- /dev/null +++ b/pkgs/development/ruby-modules/bundler-env/test.nix @@ -0,0 +1,49 @@ +{ writeText, lib, ruby, defaultGemConfig, callPackage }: +let + test = import ./testing.nix; + tap = import ./tap-support.nix; + + bundlerEnv = callPackage ./default.nix {}; + + testConfigs = { + groups = ["default"]; + gemConfig = defaultGemConfig; + confFiles = "./testConfs"; + }; + functions = (import ./functions.nix ({ inherit lib ruby; } // testConfigs)); + + should = { + equal = expected: actual: + if actual == expected then + (test.passed "= ${toString expected}") else + (test.failed "'${toString actual}'(${builtins.typeOf actual}) != '${toString expected}'(${builtins.typeOf expected})"); + + beASet = actual: + if builtins.isAttrs actual then + (test.passed "is a set") else + (test.failed "is not a set, was ${builtins.typeOf actual}: ${toString actual}"); + }; + + justName = bundlerEnv { + name = "test"; + gemset = ./test/gemset.nix; + }; + + pnamed = bundlerEnv { + pname = "test"; + gemset = ./test/gemset.nix; + }; + + results = builtins.concatLists [ + (test.run "Filter empty gemset" {} (set: functions.filterGemset set == {})) + (test.run "bundlerEnv { name }" justName { + name = should.equal "test"; + }) + (test.run "bundlerEnv { pname }" pnamed + { + name = should.equal "test-0.1.2"; + env = should.beASet; + }) + ]; +in + writeText "test-results.tap" (tap.output results) diff --git a/pkgs/development/ruby-modules/bundler-env/testing.nix b/pkgs/development/ruby-modules/bundler-env/testing.nix new file mode 100644 index 000000000000..43d10fca0444 --- /dev/null +++ b/pkgs/development/ruby-modules/bundler-env/testing.nix @@ -0,0 +1,62 @@ +with builtins; +let + /* + underTest = { + x = { + a = 1; + b = "2"; + }; + }; + + tests = [ + (root: false) + { + x = [ + (set: true) + { + a = (a: a > 1); + b = (b: b == "3"); + } + ]; + } + ]; + + results = run "Examples" underTest tests; + */ + + passed = desc: { + result = "pass"; + description = desc; + }; + + failed = desc: { + result = "failed"; + description = desc; + }; + + prefixName = name: res: { + inherit (res) result; + description = "${name}: ${res.description}"; + }; + + run = name: under: tests: if isList tests then + (concatLists (map (run name under) tests)) + else if isAttrs tests then + (concatLists (map ( + subName: run (name + "." + subName) (if hasAttr subName under then getAttr subName under else "") (getAttr subName tests) + ) (attrNames tests))) + else if isFunction tests then + let + res = tests under; + in + if isBool res then + [ + (prefixName name (if tests under then passed "passed" else failed "failed")) + ] + else + [ (prefixName name res) ] + else [ + failed (name ": not a function, list or set") + ]; +in + { inherit run passed failed; } -- cgit 1.4.1 From 66fed6d28f70263f6a4105e6e8504742618932cb Mon Sep 17 00:00:00 2001 From: Judson Date: Wed, 3 May 2017 20:27:42 -0700 Subject: Basically working. Checking against actual use cases. --- .../development/ruby-modules/bundler-env/basic.nix | 8 ++--- .../ruby-modules/bundler-env/default.nix | 12 +++---- .../ruby-modules/bundler-env/functions.nix | 2 +- pkgs/development/ruby-modules/bundler-env/test.nix | 37 +++++++++++++++++++--- .../ruby-modules/bundler-env/test/Gemfile | 0 .../ruby-modules/bundler-env/test/Gemfile.lock | 0 6 files changed, 43 insertions(+), 16 deletions(-) create mode 100644 pkgs/development/ruby-modules/bundler-env/test/Gemfile create mode 100644 pkgs/development/ruby-modules/bundler-env/test/Gemfile.lock diff --git a/pkgs/development/ruby-modules/bundler-env/basic.nix b/pkgs/development/ruby-modules/bundler-env/basic.nix index 7f96a8ce0e73..4557a7500f6a 100644 --- a/pkgs/development/ruby-modules/bundler-env/basic.nix +++ b/pkgs/development/ruby-modules/bundler-env/basic.nix @@ -82,15 +82,15 @@ let paths = envPaths; pathsToLink = [ "/lib" ]; - postBuild = genStubsScript defs // args // { - inherit confFiles bundler; + postBuild = genStubsScript (defs // args // { + inherit confFiles bundler groups; binPaths = envPaths; - } + lib.optionalString (postBuild != null) postBuild; + }) + lib.optionalString (postBuild != null) postBuild; meta = { platforms = ruby.meta.platforms; } // meta; passthru = rec { - inherit ruby bundler gems; # drvName; + inherit ruby bundler gems mainGem confFiles; # drvName; wrappedRuby = stdenv.mkDerivation { name = "wrapped-ruby-${pname}"; diff --git a/pkgs/development/ruby-modules/bundler-env/default.nix b/pkgs/development/ruby-modules/bundler-env/default.nix index d1fa4785c06c..30896a598e42 100644 --- a/pkgs/development/ruby-modules/bundler-env/default.nix +++ b/pkgs/development/ruby-modules/bundler-env/default.nix @@ -24,7 +24,7 @@ }@args: let - inherit (import ./functions.nix (defs // args)) genStubsScript; + inherit (import ./functions.nix {inherit lib ruby gemConfig groups; }) genStubsScript; drvName = if name != null then name @@ -62,21 +62,21 @@ let # The basicEnv should be put into passthru so that e.g. nix-shell can use it. in - if builtins.trace "pname: ${toString pname}" pname == null then + if pname == null then basicEnv // { inherit name; } else (buildEnv { inherit ignoreCollisions; - name = builtins.trace "name: ${toString drvName}" drvName; + name = drvName; paths = envPaths; pathsToLink = [ "/lib" ]; - postBuild = genStubsScript defs // args // { - inherit bundler; + postBuild = genStubsScript { + inherit lib ruby bundler groups; confFiles = basicEnv.confFiles; - binPaths = [ basicEnv.mainGem ]; + binPaths = [ basicEnv.gems."${pname}" ]; } + lib.optionalString (postBuild != null) postBuild; meta = { platforms = ruby.meta.platforms; } // meta; diff --git a/pkgs/development/ruby-modules/bundler-env/functions.nix b/pkgs/development/ruby-modules/bundler-env/functions.nix index 75dd276f663a..21efcacff8a4 100644 --- a/pkgs/development/ruby-modules/bundler-env/functions.nix +++ b/pkgs/development/ruby-modules/bundler-env/functions.nix @@ -20,7 +20,7 @@ rec { then attrs // gemConfig."${attrs.gemName}" attrs else attrs); - genStubsScript = { lib, ruby, confFiles, bundler, groups, binPaths }: '' + genStubsScript = { lib, ruby, confFiles, bundler, groups, binPaths, ... }: '' ${ruby}/bin/ruby ${./gen-bin-stubs.rb} \ "${ruby}/bin/ruby" \ "${confFiles}/Gemfile" \ diff --git a/pkgs/development/ruby-modules/bundler-env/test.nix b/pkgs/development/ruby-modules/bundler-env/test.nix index 3f77eb1fb43e..cb06d1012d2a 100644 --- a/pkgs/development/ruby-modules/bundler-env/test.nix +++ b/pkgs/development/ruby-modules/bundler-env/test.nix @@ -1,9 +1,17 @@ +/* +Run with: +nix-build -E 'with import { }; callPackage ./test.nix {}' --show-trace; and cat result + +Confusingly, the ideal result ends with something like: +error: build of ‘/nix/store/3245f3dcl2wxjs4rci7n069zjlz8qg85-test-results.tap.drv’ failed +*/ { writeText, lib, ruby, defaultGemConfig, callPackage }: let test = import ./testing.nix; tap = import ./tap-support.nix; bundlerEnv = callPackage ./default.nix {}; + basicEnv = callPackage ./basic.nix {}; testConfigs = { groups = ["default"]; @@ -22,6 +30,18 @@ let if builtins.isAttrs actual then (test.passed "is a set") else (test.failed "is not a set, was ${builtins.typeOf actual}: ${toString actual}"); + + haveKeys = expected: actual: + if builtins.all + (ex: builtins.any (ac: ex == ac) (builtins.attrNames actual)) + expected then + (test.passed "has expected keys") else + (test.failed "keys differ: expected [${lib.concatStringsSep ";" expected}] have [${lib.concatStringsSep ";" (builtins.attrNames actual)}]"); + + havePrefix = expected: actual: + if lib.hasPrefix expected actual then + (test.passed "has prefix '${expected}'") else + (test.failed "prefix '${expected}' not found in '${actual}'"); }; justName = bundlerEnv { @@ -29,9 +49,12 @@ let gemset = ./test/gemset.nix; }; - pnamed = bundlerEnv { + pnamed = basicEnv { pname = "test"; + gemdir = ./test; gemset = ./test/gemset.nix; + gemfile = ./test/Gemfile; + lockfile = ./test/Gemfile.lock; }; results = builtins.concatLists [ @@ -40,10 +63,14 @@ let name = should.equal "test"; }) (test.run "bundlerEnv { pname }" pnamed - { - name = should.equal "test-0.1.2"; - env = should.beASet; - }) + [ + (should.haveKeys [ "name" "env" "postBuild" ]) + { + name = should.equal "test-0.1.2"; + env = should.beASet; + postBuild = should.havePrefix "nananana"; + } + ]) ]; in writeText "test-results.tap" (tap.output results) diff --git a/pkgs/development/ruby-modules/bundler-env/test/Gemfile b/pkgs/development/ruby-modules/bundler-env/test/Gemfile new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/pkgs/development/ruby-modules/bundler-env/test/Gemfile.lock b/pkgs/development/ruby-modules/bundler-env/test/Gemfile.lock new file mode 100644 index 000000000000..e69de29bb2d1 -- cgit 1.4.1 From 0145ec999c3a5e3d205e94221ce07f11e9fc3b35 Mon Sep 17 00:00:00 2001 From: Judson Date: Tue, 9 May 2017 09:39:20 -0700 Subject: Current round of tests pass, but filter function is failing to include when groups match in use. --- .../ruby-modules/bundler-env/assertions.nix | 24 +++++++++++++ .../development/ruby-modules/bundler-env/basic.nix | 7 ++-- .../ruby-modules/bundler-env/functions.nix | 3 +- .../development/ruby-modules/bundler-env/stubs.nix | 33 ++++++++++++++++++ pkgs/development/ruby-modules/bundler-env/test.nix | 40 ++++++---------------- pkgs/development/ruby-modules/gem/default.nix | 3 ++ 6 files changed, 77 insertions(+), 33 deletions(-) create mode 100644 pkgs/development/ruby-modules/bundler-env/assertions.nix create mode 100644 pkgs/development/ruby-modules/bundler-env/stubs.nix diff --git a/pkgs/development/ruby-modules/bundler-env/assertions.nix b/pkgs/development/ruby-modules/bundler-env/assertions.nix new file mode 100644 index 000000000000..3cf67d6f3eb6 --- /dev/null +++ b/pkgs/development/ruby-modules/bundler-env/assertions.nix @@ -0,0 +1,24 @@ +{ test, lib, ...}: +{ + equal = expected: actual: + if actual == expected then + (test.passed "= ${toString expected}") else + (test.failed "'${toString actual}'(${builtins.typeOf actual}) != '${toString expected}'(${builtins.typeOf expected})"); + + beASet = actual: + if builtins.isAttrs actual then + (test.passed "is a set") else + (test.failed "is not a set, was ${builtins.typeOf actual}: ${toString actual}"); + + haveKeys = expected: actual: + if builtins.all + (ex: builtins.any (ac: ex == ac) (builtins.attrNames actual)) + expected then + (test.passed "has expected keys") else + (test.failed "keys differ: expected [${lib.concatStringsSep ";" expected}] have [${lib.concatStringsSep ";" (builtins.attrNames actual)}]"); + + havePrefix = expected: actual: + if lib.hasPrefix expected actual then + (test.passed "has prefix '${expected}'") else + (test.failed "prefix '${expected}' not found in '${actual}'"); +} diff --git a/pkgs/development/ruby-modules/bundler-env/basic.nix b/pkgs/development/ruby-modules/bundler-env/basic.nix index 4557a7500f6a..75fe7342344e 100644 --- a/pkgs/development/ruby-modules/bundler-env/basic.nix +++ b/pkgs/development/ruby-modules/bundler-env/basic.nix @@ -20,7 +20,9 @@ , ... }@args: -with (import ./functions.nix { inherit lib ruby gemConfig groups; }); +with ( +builtins.trace "basic functions" +import ./functions.nix { inherit lib ruby gemConfig groups; }); let @@ -69,7 +71,8 @@ let if gemAttrs.type == "path" then pathDerivation gemAttrs else - buildRubyGem gemAttrs + builtins.trace (lib.showVal (gemAttrs.ruby or "def ruby")) + buildRubyGem gemAttrs ); envPaths = lib.attrValues gems ++ lib.optional (!hasBundler) bundler; diff --git a/pkgs/development/ruby-modules/bundler-env/functions.nix b/pkgs/development/ruby-modules/bundler-env/functions.nix index 21efcacff8a4..4c1f6deb55ba 100644 --- a/pkgs/development/ruby-modules/bundler-env/functions.nix +++ b/pkgs/development/ruby-modules/bundler-env/functions.nix @@ -1,4 +1,5 @@ { lib, ruby, groups, gemConfig, ... }: +builtins.trace (if ruby.stubbed or false then "functions has stubbed ruby" else "functions has live ruby") rec { filterGemset = gemset: lib.filterAttrs (name: attrs: platformMatches attrs && groupMatches attrs) gemset; @@ -44,7 +45,7 @@ rec { }; in res; - composeGemAttrs = gems: name: attrs: ((removeAttrs attrs ["source"]) // attrs.source // { + composeGemAttrs = gems: name: attrs: ((removeAttrs attrs ["source" "platforms"]) // attrs.source // { inherit ruby; gemName = name; gemPath = map (gemName: gems."${gemName}") (attrs.dependencies or []); diff --git a/pkgs/development/ruby-modules/bundler-env/stubs.nix b/pkgs/development/ruby-modules/bundler-env/stubs.nix new file mode 100644 index 000000000000..3585681478c8 --- /dev/null +++ b/pkgs/development/ruby-modules/bundler-env/stubs.nix @@ -0,0 +1,33 @@ +{ stdenv, lib, ruby, callPackage, ... }: +let + real = { + inherit (stdenv) mkDerivation; + }; + mkDerivation = {name, ...}@argSet: + derivation { + inherit name; + text = (builtins.toJSON (lib.filterAttrs ( n: v: builtins.any (x: x == n) ["name" "system"]) argSet)); + builder = stdenv.shell; + args = [ "-c" "echo $(<$textPath) > $out"]; + system = stdenv.system; + passAsFile = ["text"]; + }; + fetchurl = {url?"", urls ? [],...}: "fetchurl:${if urls == [] then url else builtins.head urls}"; + + stdenv' = stdenv // { + inherit mkDerivation; + stubbed = true; + }; + ruby' = ruby // { + stdenv = stdenv'; + stubbed = true; + }; +in + { + ruby = ruby'; + buildRubyGem = callPackage ../gem { + inherit fetchurl; + ruby = ruby'; + }; + stdenv = stdenv'; + } diff --git a/pkgs/development/ruby-modules/bundler-env/test.nix b/pkgs/development/ruby-modules/bundler-env/test.nix index cb06d1012d2a..28e5dbe318a2 100644 --- a/pkgs/development/ruby-modules/bundler-env/test.nix +++ b/pkgs/development/ruby-modules/bundler-env/test.nix @@ -5,44 +5,24 @@ nix-build -E 'with import { }; callPackage ./test.nix {}' --show-trace Confusingly, the ideal result ends with something like: error: build of ‘/nix/store/3245f3dcl2wxjs4rci7n069zjlz8qg85-test-results.tap.drv’ failed */ -{ writeText, lib, ruby, defaultGemConfig, callPackage }: +{ stdenv, writeText, lib, ruby, defaultGemConfig, callPackage }@defs: let test = import ./testing.nix; tap = import ./tap-support.nix; + stubs = import ./stubs.nix defs; + should = import ./assertions.nix { inherit test lib; }; - bundlerEnv = callPackage ./default.nix {}; - basicEnv = callPackage ./basic.nix {}; + basicEnv = callPackage ./basic.nix stubs; + bundlerEnv = callPackage ./default.nix stubs // { + inherit basicEnv; + }; testConfigs = { groups = ["default"]; gemConfig = defaultGemConfig; confFiles = "./testConfs"; }; - functions = (import ./functions.nix ({ inherit lib ruby; } // testConfigs)); - - should = { - equal = expected: actual: - if actual == expected then - (test.passed "= ${toString expected}") else - (test.failed "'${toString actual}'(${builtins.typeOf actual}) != '${toString expected}'(${builtins.typeOf expected})"); - - beASet = actual: - if builtins.isAttrs actual then - (test.passed "is a set") else - (test.failed "is not a set, was ${builtins.typeOf actual}: ${toString actual}"); - - haveKeys = expected: actual: - if builtins.all - (ex: builtins.any (ac: ex == ac) (builtins.attrNames actual)) - expected then - (test.passed "has expected keys") else - (test.failed "keys differ: expected [${lib.concatStringsSep ";" expected}] have [${lib.concatStringsSep ";" (builtins.attrNames actual)}]"); - - havePrefix = expected: actual: - if lib.hasPrefix expected actual then - (test.passed "has prefix '${expected}'") else - (test.failed "prefix '${expected}' not found in '${actual}'"); - }; + functions = (import ./functions.nix ({ inherit lib; ruby = stubs.ruby; } // testConfigs)); justName = bundlerEnv { name = "test"; @@ -66,9 +46,9 @@ let [ (should.haveKeys [ "name" "env" "postBuild" ]) { - name = should.equal "test-0.1.2"; + name = should.equal "test"; env = should.beASet; - postBuild = should.havePrefix "nananana"; + postBuild = should.havePrefix "/nix/store"; } ]) ]; diff --git a/pkgs/development/ruby-modules/gem/default.nix b/pkgs/development/ruby-modules/gem/default.nix index ade6659c400b..09dbc258876e 100644 --- a/pkgs/development/ruby-modules/gem/default.nix +++ b/pkgs/development/ruby-modules/gem/default.nix @@ -74,6 +74,8 @@ let in +builtins.trace (gemName) +builtins.trace (stdenv.stubbed or false) stdenv.mkDerivation (attrs // { inherit ruby; inherit doCheck; @@ -87,6 +89,7 @@ stdenv.mkDerivation (attrs // { ++ lib.optional stdenv.isDarwin darwin.libobjc ++ buildInputs; + #name = builtins.trace (attrs.name or "no attr.name" ) "${namePrefix}${gemName}-${version}"; name = attrs.name or "${namePrefix}${gemName}-${version}"; inherit src; -- cgit 1.4.1 From 07f781bd8d8b114985b47762bf0930729a5247ce Mon Sep 17 00:00:00 2001 From: Judson Date: Wed, 10 May 2017 10:00:21 -0700 Subject: Current round of tests pass, but filter function is failing to include when platform match in use. --- pkgs/development/ruby-modules/bundler-env/basic.nix | 11 ++++------- .../development/ruby-modules/bundler-env/functions.nix | 18 ++++++++++-------- pkgs/development/ruby-modules/bundler-env/runtests.sh | 2 ++ pkgs/development/ruby-modules/bundler-env/test.nix | 16 ++++++++++++---- pkgs/development/ruby-modules/gem/default.nix | 2 -- 5 files changed, 28 insertions(+), 21 deletions(-) create mode 100755 pkgs/development/ruby-modules/bundler-env/runtests.sh diff --git a/pkgs/development/ruby-modules/bundler-env/basic.nix b/pkgs/development/ruby-modules/bundler-env/basic.nix index 75fe7342344e..80f12c14bfe8 100644 --- a/pkgs/development/ruby-modules/bundler-env/basic.nix +++ b/pkgs/development/ruby-modules/bundler-env/basic.nix @@ -20,15 +20,13 @@ , ... }@args: -with ( -builtins.trace "basic functions" -import ./functions.nix { inherit lib ruby gemConfig groups; }); +with import ./functions.nix { inherit lib gemConfig; }; let importedGemset = import gemset; - filteredGemset = filterGemset importedGemset; + filteredGemset = filterGemset { inherit ruby groups; } importedGemset; configuredGemset = lib.flip lib.mapAttrs filteredGemset (name: attrs: applyGemConfigs (attrs // { inherit ruby; gemName = name; }) @@ -66,13 +64,12 @@ let buildGem = name: attrs: ( let - gemAttrs = composeGemAttrs gems name attrs; + gemAttrs = composeGemAttrs ruby gems name attrs; in if gemAttrs.type == "path" then pathDerivation gemAttrs else - builtins.trace (lib.showVal (gemAttrs.ruby or "def ruby")) - buildRubyGem gemAttrs + buildRubyGem gemAttrs ); envPaths = lib.attrValues gems ++ lib.optional (!hasBundler) bundler; diff --git a/pkgs/development/ruby-modules/bundler-env/functions.nix b/pkgs/development/ruby-modules/bundler-env/functions.nix index 4c1f6deb55ba..5a51f4d82081 100644 --- a/pkgs/development/ruby-modules/bundler-env/functions.nix +++ b/pkgs/development/ruby-modules/bundler-env/functions.nix @@ -1,17 +1,19 @@ -{ lib, ruby, groups, gemConfig, ... }: -builtins.trace (if ruby.stubbed or false then "functions has stubbed ruby" else "functions has live ruby") +{ lib, gemConfig, ... }: rec { - filterGemset = gemset: lib.filterAttrs (name: attrs: platformMatches attrs && groupMatches attrs) gemset; + filterGemset = {ruby, groups,...}@env: gemset: lib.filterAttrs (name: attrs: platformMatches ruby attrs && groupMatches groups attrs) gemset; - platformMatches = attrs: ( + platformMatches = {rubyEngine, version, ...}@ruby: attrs: ( !(attrs ? "platforms") || + builtins.trace "ruby engine: ${rubyEngine}" + builtins.trace "ruby version ${version.majMin}" builtins.any (platform: - platform.engine == ruby.rubyEngine && - (!(platform ? "version") || platform.version == ruby.version.majMin) + builtins.trace "checking: ${platform.engine}/${platform.version}" + platform.engine == rubyEngine && + (!(platform ? "version") || platform.version == version.majMin) ) attrs.platforms ); - groupMatches = attrs: ( + groupMatches = groups: attrs: ( !(attrs ? "groups") || builtins.any (gemGroup: builtins.any (group: group == gemGroup) groups) attrs.groups ); @@ -45,7 +47,7 @@ rec { }; in res; - composeGemAttrs = gems: name: attrs: ((removeAttrs attrs ["source" "platforms"]) // attrs.source // { + composeGemAttrs = ruby: gems: name: attrs: ((removeAttrs attrs ["source" "platforms"]) // attrs.source // { inherit ruby; gemName = name; gemPath = map (gemName: gems."${gemName}") (attrs.dependencies or []); diff --git a/pkgs/development/ruby-modules/bundler-env/runtests.sh b/pkgs/development/ruby-modules/bundler-env/runtests.sh new file mode 100755 index 000000000000..c3db8ed34afb --- /dev/null +++ b/pkgs/development/ruby-modules/bundler-env/runtests.sh @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +nix-build -E 'with import { }; callPackage ./test.nix {}' --show-trace && cat result diff --git a/pkgs/development/ruby-modules/bundler-env/test.nix b/pkgs/development/ruby-modules/bundler-env/test.nix index 28e5dbe318a2..af3d81d483d8 100644 --- a/pkgs/development/ruby-modules/bundler-env/test.nix +++ b/pkgs/development/ruby-modules/bundler-env/test.nix @@ -18,11 +18,10 @@ let }; testConfigs = { - groups = ["default"]; + inherit lib; gemConfig = defaultGemConfig; - confFiles = "./testConfs"; }; - functions = (import ./functions.nix ({ inherit lib; ruby = stubs.ruby; } // testConfigs)); + functions = (import ./functions.nix testConfigs); justName = bundlerEnv { name = "test"; @@ -38,7 +37,16 @@ let }; results = builtins.concatLists [ - (test.run "Filter empty gemset" {} (set: functions.filterGemset set == {})) + (test.run "Filter empty gemset" {} (set: functions.filterGemset {inherit ruby; groups = ["default"]; } set == {})) + ( let gemSet = { test = { groups = ["x" "y"]; }; }; + in + test.run "Filter matches a group" gemSet (set: functions.filterGemset {inherit ruby; groups = ["y" "z"];} set == gemSet)) + ( let gemSet = { test = { platforms = [{engine = ruby.rubyEngine; version = ruby.version;}]; }; }; + in + test.run "Filter matches on platform" gemSet (set: functions.filterGemset {inherit ruby; groups = [];} set == gemSet)) + ( let gemSet = { test = { groups = ["x" "y"]; }; }; + in + test.run "Filter excludes based on groups" gemSet (set: functions.filterGemset {inherit ruby; groups = ["a" "b"];} set == {})) (test.run "bundlerEnv { name }" justName { name = should.equal "test"; }) diff --git a/pkgs/development/ruby-modules/gem/default.nix b/pkgs/development/ruby-modules/gem/default.nix index 09dbc258876e..62a9d60686f3 100644 --- a/pkgs/development/ruby-modules/gem/default.nix +++ b/pkgs/development/ruby-modules/gem/default.nix @@ -74,8 +74,6 @@ let in -builtins.trace (gemName) -builtins.trace (stdenv.stubbed or false) stdenv.mkDerivation (attrs // { inherit ruby; inherit doCheck; -- cgit 1.4.1 From 56d214b0eaed1d9fe2b6e76d30dbb2cd279e3a5c Mon Sep 17 00:00:00 2001 From: Judson Date: Fri, 12 May 2017 09:44:39 -0700 Subject: Fixed platform filtering. --- pkgs/development/ruby-modules/bundler-env/functions.nix | 6 ++---- pkgs/development/ruby-modules/bundler-env/test.nix | 3 +++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/pkgs/development/ruby-modules/bundler-env/functions.nix b/pkgs/development/ruby-modules/bundler-env/functions.nix index 5a51f4d82081..d9f02324cc2d 100644 --- a/pkgs/development/ruby-modules/bundler-env/functions.nix +++ b/pkgs/development/ruby-modules/bundler-env/functions.nix @@ -4,12 +4,10 @@ rec { platformMatches = {rubyEngine, version, ...}@ruby: attrs: ( !(attrs ? "platforms") || - builtins.trace "ruby engine: ${rubyEngine}" - builtins.trace "ruby version ${version.majMin}" + builtins.length attrs.platforms == 0 || builtins.any (platform: - builtins.trace "checking: ${platform.engine}/${platform.version}" platform.engine == rubyEngine && - (!(platform ? "version") || platform.version == version.majMin) + (!(platform ? "version") || platform.version.majMin == version.majMin) ) attrs.platforms ); diff --git a/pkgs/development/ruby-modules/bundler-env/test.nix b/pkgs/development/ruby-modules/bundler-env/test.nix index af3d81d483d8..c3de862f1537 100644 --- a/pkgs/development/ruby-modules/bundler-env/test.nix +++ b/pkgs/development/ruby-modules/bundler-env/test.nix @@ -41,6 +41,9 @@ let ( let gemSet = { test = { groups = ["x" "y"]; }; }; in test.run "Filter matches a group" gemSet (set: functions.filterGemset {inherit ruby; groups = ["y" "z"];} set == gemSet)) + ( let gemSet = { test = { platforms = []; }; }; + in + test.run "Filter matches empty platforms list" gemSet (set: functions.filterGemset {inherit ruby; groups = [];} set == gemSet)) ( let gemSet = { test = { platforms = [{engine = ruby.rubyEngine; version = ruby.version;}]; }; }; in test.run "Filter matches on platform" gemSet (set: functions.filterGemset {inherit ruby; groups = [];} set == gemSet)) -- cgit 1.4.1 From c39508b2549ff1a2b27279b4fe1c003454c78fb8 Mon Sep 17 00:00:00 2001 From: Judson Date: Fri, 12 May 2017 09:47:00 -0700 Subject: Fixed platform test. --- pkgs/development/ruby-modules/bundler-env/functions.nix | 2 +- pkgs/development/ruby-modules/bundler-env/test.nix | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/development/ruby-modules/bundler-env/functions.nix b/pkgs/development/ruby-modules/bundler-env/functions.nix index d9f02324cc2d..ce8a1b69c749 100644 --- a/pkgs/development/ruby-modules/bundler-env/functions.nix +++ b/pkgs/development/ruby-modules/bundler-env/functions.nix @@ -7,7 +7,7 @@ rec { builtins.length attrs.platforms == 0 || builtins.any (platform: platform.engine == rubyEngine && - (!(platform ? "version") || platform.version.majMin == version.majMin) + (!(platform ? "version") || platform.version == version.majMin) ) attrs.platforms ); diff --git a/pkgs/development/ruby-modules/bundler-env/test.nix b/pkgs/development/ruby-modules/bundler-env/test.nix index c3de862f1537..164098e3f873 100644 --- a/pkgs/development/ruby-modules/bundler-env/test.nix +++ b/pkgs/development/ruby-modules/bundler-env/test.nix @@ -44,7 +44,7 @@ let ( let gemSet = { test = { platforms = []; }; }; in test.run "Filter matches empty platforms list" gemSet (set: functions.filterGemset {inherit ruby; groups = [];} set == gemSet)) - ( let gemSet = { test = { platforms = [{engine = ruby.rubyEngine; version = ruby.version;}]; }; }; + ( let gemSet = { test = { platforms = [{engine = ruby.rubyEngine; version = ruby.version.majMin;}]; }; }; in test.run "Filter matches on platform" gemSet (set: functions.filterGemset {inherit ruby; groups = [];} set == gemSet)) ( let gemSet = { test = { groups = ["x" "y"]; }; }; -- cgit 1.4.1 From ae84d19e651ddb09d22b31aae181fa6a500fdb65 Mon Sep 17 00:00:00 2001 From: Judson Date: Mon, 15 May 2017 09:36:30 -0700 Subject: Final testing --- pkgs/development/ruby-modules/bundler-env/basic.nix | 10 +++++++--- pkgs/development/ruby-modules/bundler-env/default.nix | 6 +++--- pkgs/development/ruby-modules/bundler-env/test.nix | 8 ++++---- pkgs/development/ruby-modules/bundler-env/test/gemset.nix | 10 ++++++++++ 4 files changed, 24 insertions(+), 10 deletions(-) create mode 100644 pkgs/development/ruby-modules/bundler-env/test/gemset.nix diff --git a/pkgs/development/ruby-modules/bundler-env/basic.nix b/pkgs/development/ruby-modules/bundler-env/basic.nix index 80f12c14bfe8..33a379c02759 100644 --- a/pkgs/development/ruby-modules/bundler-env/basic.nix +++ b/pkgs/development/ruby-modules/bundler-env/basic.nix @@ -5,7 +5,8 @@ }@defs: { - pname + name +, pname ? name , gemfile , lockfile , gemset @@ -77,7 +78,9 @@ let basicEnv = buildEnv { inherit ignoreCollisions; - name = pname; + name = if name == null then pname else name; + + #name = pname; paths = envPaths; pathsToLink = [ "/lib" ]; @@ -92,7 +95,8 @@ let passthru = rec { inherit ruby bundler gems mainGem confFiles; # drvName; - wrappedRuby = stdenv.mkDerivation { + wrappedRuby = + stdenv.mkDerivation { name = "wrapped-ruby-${pname}"; nativeBuildInputs = [ makeWrapper ]; buildCommand = '' diff --git a/pkgs/development/ruby-modules/bundler-env/default.nix b/pkgs/development/ruby-modules/bundler-env/default.nix index 30896a598e42..68267a4aead8 100644 --- a/pkgs/development/ruby-modules/bundler-env/default.nix +++ b/pkgs/development/ruby-modules/bundler-env/default.nix @@ -27,7 +27,7 @@ let inherit (import ./functions.nix {inherit lib ruby gemConfig groups; }) genStubsScript; drvName = - if name != null then name + if name != null then lib.traceVal name else if pname != null then "${toString pname}-${basicEnv.gems."${pname}".version}" else throw "bundlerEnv: either pname or name must be set"; @@ -43,7 +43,7 @@ let if gemset == null then gemdir + "/gemset.nix" else gemset; - basicEnv = (callPackage ./basic.nix {}) (args // { inherit pname gemdir; + basicEnv = (callPackage ./basic.nix {}) (args // { inherit pname name gemdir; gemfile = gemfile'; lockfile = lockfile'; gemset = gemset'; @@ -63,7 +63,7 @@ let # The basicEnv should be put into passthru so that e.g. nix-shell can use it. in if pname == null then - basicEnv // { inherit name; } + basicEnv // { inherit name basicEnv; } else (buildEnv { inherit ignoreCollisions; diff --git a/pkgs/development/ruby-modules/bundler-env/test.nix b/pkgs/development/ruby-modules/bundler-env/test.nix index 164098e3f873..e49c4fd93f2f 100644 --- a/pkgs/development/ruby-modules/bundler-env/test.nix +++ b/pkgs/development/ruby-modules/bundler-env/test.nix @@ -24,11 +24,11 @@ let functions = (import ./functions.nix testConfigs); justName = bundlerEnv { - name = "test"; + name = "test-0.1.2"; gemset = ./test/gemset.nix; }; - pnamed = basicEnv { + pnamed = bundlerEnv { pname = "test"; gemdir = ./test; gemset = ./test/gemset.nix; @@ -51,13 +51,13 @@ let in test.run "Filter excludes based on groups" gemSet (set: functions.filterGemset {inherit ruby; groups = ["a" "b"];} set == {})) (test.run "bundlerEnv { name }" justName { - name = should.equal "test"; + name = should.equal "test-0.1.2"; }) (test.run "bundlerEnv { pname }" pnamed [ (should.haveKeys [ "name" "env" "postBuild" ]) { - name = should.equal "test"; + name = should.equal "test-0.1.2"; env = should.beASet; postBuild = should.havePrefix "/nix/store"; } diff --git a/pkgs/development/ruby-modules/bundler-env/test/gemset.nix b/pkgs/development/ruby-modules/bundler-env/test/gemset.nix new file mode 100644 index 000000000000..53f15f96bc6d --- /dev/null +++ b/pkgs/development/ruby-modules/bundler-env/test/gemset.nix @@ -0,0 +1,10 @@ +{ + test = { + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1j5r0anj8m4qlf2psnldip4b8ha2bsscv11lpdgnfh4nnchzjnxw"; + type = "gem"; + }; + version = "0.1.2"; + }; +} -- cgit 1.4.1 From 998d011e426c2f8c51946ebbc4931a464f531db9 Mon Sep 17 00:00:00 2001 From: Judson Date: Sat, 27 May 2017 15:19:34 -0700 Subject: Restructuring files --- .../ruby-modules/bundled-common/default.nix | 140 +++++++++++++++++++++ .../ruby-modules/bundled-common/functions.nix | 53 ++++++++ .../ruby-modules/bundled-common/gen-bin-stubs.rb | 47 +++++++ .../ruby-modules/bundled-common/test.nix | 23 ++++ .../ruby-modules/bundler-env/assertions.nix | 24 ---- .../development/ruby-modules/bundler-env/basic.nix | 140 --------------------- .../ruby-modules/bundler-env/default.nix | 4 +- .../ruby-modules/bundler-env/functions.nix | 53 -------- .../ruby-modules/bundler-env/gen-bin-stubs.rb | 47 ------- .../ruby-modules/bundler-env/runtests.sh | 2 - .../development/ruby-modules/bundler-env/stubs.nix | 33 ----- .../ruby-modules/bundler-env/tap-support.nix | 20 --- pkgs/development/ruby-modules/bundler-env/test.nix | 44 +------ .../ruby-modules/bundler-env/testing.nix | 62 --------- pkgs/development/ruby-modules/runtests.sh | 6 + .../ruby-modules/testing/assertions.nix | 24 ++++ pkgs/development/ruby-modules/testing/driver.nix | 20 +++ pkgs/development/ruby-modules/testing/runtests.sh | 2 + pkgs/development/ruby-modules/testing/stubs.nix | 33 +++++ .../ruby-modules/testing/tap-support.nix | 20 +++ pkgs/development/ruby-modules/testing/testing.nix | 62 +++++++++ 21 files changed, 437 insertions(+), 422 deletions(-) create mode 100644 pkgs/development/ruby-modules/bundled-common/default.nix create mode 100644 pkgs/development/ruby-modules/bundled-common/functions.nix create mode 100644 pkgs/development/ruby-modules/bundled-common/gen-bin-stubs.rb create mode 100644 pkgs/development/ruby-modules/bundled-common/test.nix delete mode 100644 pkgs/development/ruby-modules/bundler-env/assertions.nix delete mode 100644 pkgs/development/ruby-modules/bundler-env/basic.nix delete mode 100644 pkgs/development/ruby-modules/bundler-env/functions.nix delete mode 100644 pkgs/development/ruby-modules/bundler-env/gen-bin-stubs.rb delete mode 100755 pkgs/development/ruby-modules/bundler-env/runtests.sh delete mode 100644 pkgs/development/ruby-modules/bundler-env/stubs.nix delete mode 100644 pkgs/development/ruby-modules/bundler-env/tap-support.nix delete mode 100644 pkgs/development/ruby-modules/bundler-env/testing.nix create mode 100755 pkgs/development/ruby-modules/runtests.sh create mode 100644 pkgs/development/ruby-modules/testing/assertions.nix create mode 100644 pkgs/development/ruby-modules/testing/driver.nix create mode 100755 pkgs/development/ruby-modules/testing/runtests.sh create mode 100644 pkgs/development/ruby-modules/testing/stubs.nix create mode 100644 pkgs/development/ruby-modules/testing/tap-support.nix create mode 100644 pkgs/development/ruby-modules/testing/testing.nix diff --git a/pkgs/development/ruby-modules/bundled-common/default.nix b/pkgs/development/ruby-modules/bundled-common/default.nix new file mode 100644 index 000000000000..33a379c02759 --- /dev/null +++ b/pkgs/development/ruby-modules/bundled-common/default.nix @@ -0,0 +1,140 @@ +{ stdenv, runCommand, ruby, lib +, defaultGemConfig, buildRubyGem, buildEnv +, makeWrapper +, bundler +}@defs: + +{ + name +, pname ? name +, gemfile +, lockfile +, gemset +, gemdir +, ruby ? defs.ruby +, gemConfig ? defaultGemConfig +, postBuild ? null +, document ? [] +, meta ? {} +, groups ? ["default"] +, ignoreCollisions ? false +, ... +}@args: + +with import ./functions.nix { inherit lib gemConfig; }; + +let + + importedGemset = import gemset; + + filteredGemset = filterGemset { inherit ruby groups; } importedGemset; + + configuredGemset = lib.flip lib.mapAttrs filteredGemset (name: attrs: + applyGemConfigs (attrs // { inherit ruby; gemName = name; }) + ); + + hasBundler = builtins.hasAttr "bundler" filteredGemset; + + bundler = + if hasBundler then gems.bundler + else defs.bundler.override (attrs: { inherit ruby; }); + + gems = lib.flip lib.mapAttrs configuredGemset (name: attrs: buildGem name attrs); + + copyIfBundledByPath = { bundledByPath ? false, ...}@main: + (if bundledByPath then '' + cp -a ${gemdir}/* $out/ + '' else "" + ); + + maybeCopyAll = pname: if pname == null then "" else + let + mainGem = gems."${pname}" or (throw "bundlerEnv: gem ${pname} not found"); + in + copyIfBundledByPath mainGem; + + # We have to normalize the Gemfile.lock, otherwise bundler tries to be + # helpful by doing so at run time, causing executables to immediately bail + # out. Yes, I'm serious. + confFiles = runCommand "gemfile-and-lockfile" {} '' + mkdir -p $out + ${maybeCopyAll pname} + cp ${gemfile} $out/Gemfile || ls -l $out/Gemfile + cp ${lockfile} $out/Gemfile.lock || ls -l $out/Gemfile.lock + ''; + + buildGem = name: attrs: ( + let + gemAttrs = composeGemAttrs ruby gems name attrs; + in + if gemAttrs.type == "path" then + pathDerivation gemAttrs + else + buildRubyGem gemAttrs + ); + + envPaths = lib.attrValues gems ++ lib.optional (!hasBundler) bundler; + + basicEnv = buildEnv { + inherit ignoreCollisions; + + name = if name == null then pname else name; + + #name = pname; + + paths = envPaths; + pathsToLink = [ "/lib" ]; + + postBuild = genStubsScript (defs // args // { + inherit confFiles bundler groups; + binPaths = envPaths; + }) + lib.optionalString (postBuild != null) postBuild; + + meta = { platforms = ruby.meta.platforms; } // meta; + + passthru = rec { + inherit ruby bundler gems mainGem confFiles; # drvName; + + wrappedRuby = + stdenv.mkDerivation { + name = "wrapped-ruby-${pname}"; + nativeBuildInputs = [ makeWrapper ]; + buildCommand = '' + mkdir -p $out/bin + for i in ${ruby}/bin/*; do + makeWrapper "$i" $out/bin/$(basename "$i") \ + --set BUNDLE_GEMFILE ${confFiles}/Gemfile \ + --set BUNDLE_PATH ${basicEnv}/${ruby.gemPath} \ + --set BUNDLE_FROZEN 1 \ + --set GEM_HOME ${basicEnv}/${ruby.gemPath} \ + --set GEM_PATH ${basicEnv}/${ruby.gemPath} + done + ''; + }; + + env = let + irbrc = builtins.toFile "irbrc" '' + if !(ENV["OLD_IRBRC"].nil? || ENV["OLD_IRBRC"].empty?) + require ENV["OLD_IRBRC"] + end + require 'rubygems' + require 'bundler/setup' + ''; + in stdenv.mkDerivation { + name = "${pname}-interactive-environment"; + nativeBuildInputs = [ wrappedRuby basicEnv ]; + shellHook = '' + export OLD_IRBRC="$IRBRC" + export IRBRC=${irbrc} + ''; + buildCommand = '' + echo >&2 "" + echo >&2 "*** Ruby 'env' attributes are intended for interactive nix-shell sessions, not for building! ***" + echo >&2 "" + exit 1 + ''; + }; + }; + }; +in + basicEnv diff --git a/pkgs/development/ruby-modules/bundled-common/functions.nix b/pkgs/development/ruby-modules/bundled-common/functions.nix new file mode 100644 index 000000000000..ce8a1b69c749 --- /dev/null +++ b/pkgs/development/ruby-modules/bundled-common/functions.nix @@ -0,0 +1,53 @@ +{ lib, gemConfig, ... }: +rec { + filterGemset = {ruby, groups,...}@env: gemset: lib.filterAttrs (name: attrs: platformMatches ruby attrs && groupMatches groups attrs) gemset; + + platformMatches = {rubyEngine, version, ...}@ruby: 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: ( + !(attrs ? "groups") || + builtins.any (gemGroup: builtins.any (group: group == gemGroup) groups) attrs.groups + ); + + applyGemConfigs = attrs: + (if gemConfig ? "${attrs.gemName}" + then attrs // gemConfig."${attrs.gemName}" attrs + else attrs); + + genStubsScript = { lib, ruby, confFiles, bundler, groups, binPaths, ... }: '' + ${ruby}/bin/ruby ${./gen-bin-stubs.rb} \ + "${ruby}/bin/ruby" \ + "${confFiles}/Gemfile" \ + "$out/${ruby.gemPath}" \ + "${bundler}/${ruby.gemPath}" \ + ${lib.escapeShellArg binPaths} \ + ${lib.escapeShellArg groups} + ''; + + pathDerivation = { gemName, version, path, ... }: + let + res = { + type = "derivation"; + bundledByPath = true; + name = gemName; + version = version; + outPath = path; + outputs = [ "out" ]; + out = res; + outputName = "out"; + }; + in res; + + composeGemAttrs = ruby: gems: name: attrs: ((removeAttrs attrs ["source" "platforms"]) // attrs.source // { + inherit ruby; + gemName = name; + gemPath = map (gemName: gems."${gemName}") (attrs.dependencies or []); + }); +} diff --git a/pkgs/development/ruby-modules/bundled-common/gen-bin-stubs.rb b/pkgs/development/ruby-modules/bundled-common/gen-bin-stubs.rb new file mode 100644 index 000000000000..92321d6427dc --- /dev/null +++ b/pkgs/development/ruby-modules/bundled-common/gen-bin-stubs.rb @@ -0,0 +1,47 @@ +require 'rbconfig' +require 'rubygems' +require 'rubygems/specification' +require 'fileutils' + +# args/settings +out = ENV["out"] +ruby = ARGV[0] +gemfile = ARGV[1] +bundle_path = ARGV[2] +bundler_gem_path = ARGV[3] +paths = ARGV[4].split +groups = ARGV[5].split + +# generate binstubs +FileUtils.mkdir_p("#{out}/bin") +paths.each do |path| + next unless File.directory?("#{path}/nix-support/gem-meta") + + name = File.read("#{path}/nix-support/gem-meta/name") + executables = File.read("#{path}/nix-support/gem-meta/executables").split + executables.each do |exe| + File.open("#{out}/bin/#{exe}", "w") do |f| + f.write(<<-EOF) +#!#{ruby} +# +# This file was generated by Nix. +# +# The application '#{exe}' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +ENV["BUNDLE_GEMFILE"] = #{gemfile.dump} +ENV["BUNDLE_PATH"] = #{bundle_path.dump} +ENV['BUNDLE_FROZEN'] = '1' + +Gem.use_paths(#{bundler_gem_path.dump}, ENV["GEM_PATH"]) + +require 'bundler' +Bundler.setup(#{groups.map(&:dump).join(', ')}) + +load Gem.bin_path(#{name.dump}, #{exe.dump}) +EOF + FileUtils.chmod("+x", "#{out}/bin/#{exe}") + end + end +end diff --git a/pkgs/development/ruby-modules/bundled-common/test.nix b/pkgs/development/ruby-modules/bundled-common/test.nix new file mode 100644 index 000000000000..b24a620ed507 --- /dev/null +++ b/pkgs/development/ruby-modules/bundled-common/test.nix @@ -0,0 +1,23 @@ +{ stdenv, writeText, lib, ruby, defaultGemConfig, callPackage, test, stubs, should }@defs: +let + testConfigs = { + inherit lib; + gemConfig = defaultGemConfig; + }; + functions = (import ./functions.nix testConfigs); +in + builtins.concatLists [ + (test.run "Filter empty gemset" {} (set: functions.filterGemset {inherit ruby; groups = ["default"]; } set == {})) + ( let gemSet = { test = { groups = ["x" "y"]; }; }; + in + test.run "Filter matches a group" gemSet (set: functions.filterGemset {inherit ruby; groups = ["y" "z"];} set == gemSet)) + ( let gemSet = { test = { platforms = []; }; }; + in + test.run "Filter matches empty platforms list" gemSet (set: functions.filterGemset {inherit ruby; groups = [];} set == gemSet)) + ( let gemSet = { test = { platforms = [{engine = ruby.rubyEngine; version = ruby.version.majMin;}]; }; }; + in + test.run "Filter matches on platform" gemSet (set: functions.filterGemset {inherit ruby; groups = [];} set == gemSet)) + ( let gemSet = { test = { groups = ["x" "y"]; }; }; + in + test.run "Filter excludes based on groups" gemSet (set: functions.filterGemset {inherit ruby; groups = ["a" "b"];} set == {})) + ] diff --git a/pkgs/development/ruby-modules/bundler-env/assertions.nix b/pkgs/development/ruby-modules/bundler-env/assertions.nix deleted file mode 100644 index 3cf67d6f3eb6..000000000000 --- a/pkgs/development/ruby-modules/bundler-env/assertions.nix +++ /dev/null @@ -1,24 +0,0 @@ -{ test, lib, ...}: -{ - equal = expected: actual: - if actual == expected then - (test.passed "= ${toString expected}") else - (test.failed "'${toString actual}'(${builtins.typeOf actual}) != '${toString expected}'(${builtins.typeOf expected})"); - - beASet = actual: - if builtins.isAttrs actual then - (test.passed "is a set") else - (test.failed "is not a set, was ${builtins.typeOf actual}: ${toString actual}"); - - haveKeys = expected: actual: - if builtins.all - (ex: builtins.any (ac: ex == ac) (builtins.attrNames actual)) - expected then - (test.passed "has expected keys") else - (test.failed "keys differ: expected [${lib.concatStringsSep ";" expected}] have [${lib.concatStringsSep ";" (builtins.attrNames actual)}]"); - - havePrefix = expected: actual: - if lib.hasPrefix expected actual then - (test.passed "has prefix '${expected}'") else - (test.failed "prefix '${expected}' not found in '${actual}'"); -} diff --git a/pkgs/development/ruby-modules/bundler-env/basic.nix b/pkgs/development/ruby-modules/bundler-env/basic.nix deleted file mode 100644 index 33a379c02759..000000000000 --- a/pkgs/development/ruby-modules/bundler-env/basic.nix +++ /dev/null @@ -1,140 +0,0 @@ -{ stdenv, runCommand, ruby, lib -, defaultGemConfig, buildRubyGem, buildEnv -, makeWrapper -, bundler -}@defs: - -{ - name -, pname ? name -, gemfile -, lockfile -, gemset -, gemdir -, ruby ? defs.ruby -, gemConfig ? defaultGemConfig -, postBuild ? null -, document ? [] -, meta ? {} -, groups ? ["default"] -, ignoreCollisions ? false -, ... -}@args: - -with import ./functions.nix { inherit lib gemConfig; }; - -let - - importedGemset = import gemset; - - filteredGemset = filterGemset { inherit ruby groups; } importedGemset; - - configuredGemset = lib.flip lib.mapAttrs filteredGemset (name: attrs: - applyGemConfigs (attrs // { inherit ruby; gemName = name; }) - ); - - hasBundler = builtins.hasAttr "bundler" filteredGemset; - - bundler = - if hasBundler then gems.bundler - else defs.bundler.override (attrs: { inherit ruby; }); - - gems = lib.flip lib.mapAttrs configuredGemset (name: attrs: buildGem name attrs); - - copyIfBundledByPath = { bundledByPath ? false, ...}@main: - (if bundledByPath then '' - cp -a ${gemdir}/* $out/ - '' else "" - ); - - maybeCopyAll = pname: if pname == null then "" else - let - mainGem = gems."${pname}" or (throw "bundlerEnv: gem ${pname} not found"); - in - copyIfBundledByPath mainGem; - - # We have to normalize the Gemfile.lock, otherwise bundler tries to be - # helpful by doing so at run time, causing executables to immediately bail - # out. Yes, I'm serious. - confFiles = runCommand "gemfile-and-lockfile" {} '' - mkdir -p $out - ${maybeCopyAll pname} - cp ${gemfile} $out/Gemfile || ls -l $out/Gemfile - cp ${lockfile} $out/Gemfile.lock || ls -l $out/Gemfile.lock - ''; - - buildGem = name: attrs: ( - let - gemAttrs = composeGemAttrs ruby gems name attrs; - in - if gemAttrs.type == "path" then - pathDerivation gemAttrs - else - buildRubyGem gemAttrs - ); - - envPaths = lib.attrValues gems ++ lib.optional (!hasBundler) bundler; - - basicEnv = buildEnv { - inherit ignoreCollisions; - - name = if name == null then pname else name; - - #name = pname; - - paths = envPaths; - pathsToLink = [ "/lib" ]; - - postBuild = genStubsScript (defs // args // { - inherit confFiles bundler groups; - binPaths = envPaths; - }) + lib.optionalString (postBuild != null) postBuild; - - meta = { platforms = ruby.meta.platforms; } // meta; - - passthru = rec { - inherit ruby bundler gems mainGem confFiles; # drvName; - - wrappedRuby = - stdenv.mkDerivation { - name = "wrapped-ruby-${pname}"; - nativeBuildInputs = [ makeWrapper ]; - buildCommand = '' - mkdir -p $out/bin - for i in ${ruby}/bin/*; do - makeWrapper "$i" $out/bin/$(basename "$i") \ - --set BUNDLE_GEMFILE ${confFiles}/Gemfile \ - --set BUNDLE_PATH ${basicEnv}/${ruby.gemPath} \ - --set BUNDLE_FROZEN 1 \ - --set GEM_HOME ${basicEnv}/${ruby.gemPath} \ - --set GEM_PATH ${basicEnv}/${ruby.gemPath} - done - ''; - }; - - env = let - irbrc = builtins.toFile "irbrc" '' - if !(ENV["OLD_IRBRC"].nil? || ENV["OLD_IRBRC"].empty?) - require ENV["OLD_IRBRC"] - end - require 'rubygems' - require 'bundler/setup' - ''; - in stdenv.mkDerivation { - name = "${pname}-interactive-environment"; - nativeBuildInputs = [ wrappedRuby basicEnv ]; - shellHook = '' - export OLD_IRBRC="$IRBRC" - export IRBRC=${irbrc} - ''; - buildCommand = '' - echo >&2 "" - echo >&2 "*** Ruby 'env' attributes are intended for interactive nix-shell sessions, not for building! ***" - echo >&2 "" - exit 1 - ''; - }; - }; - }; -in - basicEnv diff --git a/pkgs/development/ruby-modules/bundler-env/default.nix b/pkgs/development/ruby-modules/bundler-env/default.nix index 68267a4aead8..46d9e99f671e 100644 --- a/pkgs/development/ruby-modules/bundler-env/default.nix +++ b/pkgs/development/ruby-modules/bundler-env/default.nix @@ -24,7 +24,7 @@ }@args: let - inherit (import ./functions.nix {inherit lib ruby gemConfig groups; }) genStubsScript; + inherit (import ../bundled-common/functions.nix {inherit lib ruby gemConfig groups; }) genStubsScript; drvName = if name != null then lib.traceVal name @@ -43,7 +43,7 @@ let if gemset == null then gemdir + "/gemset.nix" else gemset; - basicEnv = (callPackage ./basic.nix {}) (args // { inherit pname name gemdir; + basicEnv = (callPackage ../bundled-common {}) (args // { inherit pname name gemdir; gemfile = gemfile'; lockfile = lockfile'; gemset = gemset'; diff --git a/pkgs/development/ruby-modules/bundler-env/functions.nix b/pkgs/development/ruby-modules/bundler-env/functions.nix deleted file mode 100644 index ce8a1b69c749..000000000000 --- a/pkgs/development/ruby-modules/bundler-env/functions.nix +++ /dev/null @@ -1,53 +0,0 @@ -{ lib, gemConfig, ... }: -rec { - filterGemset = {ruby, groups,...}@env: gemset: lib.filterAttrs (name: attrs: platformMatches ruby attrs && groupMatches groups attrs) gemset; - - platformMatches = {rubyEngine, version, ...}@ruby: 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: ( - !(attrs ? "groups") || - builtins.any (gemGroup: builtins.any (group: group == gemGroup) groups) attrs.groups - ); - - applyGemConfigs = attrs: - (if gemConfig ? "${attrs.gemName}" - then attrs // gemConfig."${attrs.gemName}" attrs - else attrs); - - genStubsScript = { lib, ruby, confFiles, bundler, groups, binPaths, ... }: '' - ${ruby}/bin/ruby ${./gen-bin-stubs.rb} \ - "${ruby}/bin/ruby" \ - "${confFiles}/Gemfile" \ - "$out/${ruby.gemPath}" \ - "${bundler}/${ruby.gemPath}" \ - ${lib.escapeShellArg binPaths} \ - ${lib.escapeShellArg groups} - ''; - - pathDerivation = { gemName, version, path, ... }: - let - res = { - type = "derivation"; - bundledByPath = true; - name = gemName; - version = version; - outPath = path; - outputs = [ "out" ]; - out = res; - outputName = "out"; - }; - in res; - - composeGemAttrs = ruby: gems: name: attrs: ((removeAttrs attrs ["source" "platforms"]) // attrs.source // { - inherit ruby; - gemName = name; - gemPath = map (gemName: gems."${gemName}") (attrs.dependencies or []); - }); -} diff --git a/pkgs/development/ruby-modules/bundler-env/gen-bin-stubs.rb b/pkgs/development/ruby-modules/bundler-env/gen-bin-stubs.rb deleted file mode 100644 index 92321d6427dc..000000000000 --- a/pkgs/development/ruby-modules/bundler-env/gen-bin-stubs.rb +++ /dev/null @@ -1,47 +0,0 @@ -require 'rbconfig' -require 'rubygems' -require 'rubygems/specification' -require 'fileutils' - -# args/settings -out = ENV["out"] -ruby = ARGV[0] -gemfile = ARGV[1] -bundle_path = ARGV[2] -bundler_gem_path = ARGV[3] -paths = ARGV[4].split -groups = ARGV[5].split - -# generate binstubs -FileUtils.mkdir_p("#{out}/bin") -paths.each do |path| - next unless File.directory?("#{path}/nix-support/gem-meta") - - name = File.read("#{path}/nix-support/gem-meta/name") - executables = File.read("#{path}/nix-support/gem-meta/executables").split - executables.each do |exe| - File.open("#{out}/bin/#{exe}", "w") do |f| - f.write(<<-EOF) -#!#{ruby} -# -# This file was generated by Nix. -# -# The application '#{exe}' is installed as part of a gem, and -# this file is here to facilitate running it. -# - -ENV["BUNDLE_GEMFILE"] = #{gemfile.dump} -ENV["BUNDLE_PATH"] = #{bundle_path.dump} -ENV['BUNDLE_FROZEN'] = '1' - -Gem.use_paths(#{bundler_gem_path.dump}, ENV["GEM_PATH"]) - -require 'bundler' -Bundler.setup(#{groups.map(&:dump).join(', ')}) - -load Gem.bin_path(#{name.dump}, #{exe.dump}) -EOF - FileUtils.chmod("+x", "#{out}/bin/#{exe}") - end - end -end diff --git a/pkgs/development/ruby-modules/bundler-env/runtests.sh b/pkgs/development/ruby-modules/bundler-env/runtests.sh deleted file mode 100755 index c3db8ed34afb..000000000000 --- a/pkgs/development/ruby-modules/bundler-env/runtests.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env bash -nix-build -E 'with import { }; callPackage ./test.nix {}' --show-trace && cat result diff --git a/pkgs/development/ruby-modules/bundler-env/stubs.nix b/pkgs/development/ruby-modules/bundler-env/stubs.nix deleted file mode 100644 index 3585681478c8..000000000000 --- a/pkgs/development/ruby-modules/bundler-env/stubs.nix +++ /dev/null @@ -1,33 +0,0 @@ -{ stdenv, lib, ruby, callPackage, ... }: -let - real = { - inherit (stdenv) mkDerivation; - }; - mkDerivation = {name, ...}@argSet: - derivation { - inherit name; - text = (builtins.toJSON (lib.filterAttrs ( n: v: builtins.any (x: x == n) ["name" "system"]) argSet)); - builder = stdenv.shell; - args = [ "-c" "echo $(<$textPath) > $out"]; - system = stdenv.system; - passAsFile = ["text"]; - }; - fetchurl = {url?"", urls ? [],...}: "fetchurl:${if urls == [] then url else builtins.head urls}"; - - stdenv' = stdenv // { - inherit mkDerivation; - stubbed = true; - }; - ruby' = ruby // { - stdenv = stdenv'; - stubbed = true; - }; -in - { - ruby = ruby'; - buildRubyGem = callPackage ../gem { - inherit fetchurl; - ruby = ruby'; - }; - stdenv = stdenv'; - } diff --git a/pkgs/development/ruby-modules/bundler-env/tap-support.nix b/pkgs/development/ruby-modules/bundler-env/tap-support.nix deleted file mode 100644 index ba576683d372..000000000000 --- a/pkgs/development/ruby-modules/bundler-env/tap-support.nix +++ /dev/null @@ -1,20 +0,0 @@ -with builtins; -let - withIndexes = list: genList (idx: (elemAt list idx) // {index = idx;}) (length list); - - testLine = report: "${okStr report} ${toString report.index} ${report.description}" + testDirective report + testYaml report; - - testDirective = report: ""; - - testYaml = report: ""; - - okStr = { result, ...}: if result == "pass" then "ok" else "not ok"; -in - { - output = reports: '' - TAP version 13 - 1..${toString (length reports)}'' + (foldl' (l: r: l + "\n" + r) "" (map testLine (withIndexes reports))) + '' - - # Finished at ${toString currentTime} - ''; - } diff --git a/pkgs/development/ruby-modules/bundler-env/test.nix b/pkgs/development/ruby-modules/bundler-env/test.nix index e49c4fd93f2f..63da7044c0cf 100644 --- a/pkgs/development/ruby-modules/bundler-env/test.nix +++ b/pkgs/development/ruby-modules/bundler-env/test.nix @@ -1,27 +1,8 @@ -/* -Run with: -nix-build -E 'with import { }; callPackage ./test.nix {}' --show-trace; and cat result - -Confusingly, the ideal result ends with something like: -error: build of ‘/nix/store/3245f3dcl2wxjs4rci7n069zjlz8qg85-test-results.tap.drv’ failed -*/ -{ stdenv, writeText, lib, ruby, defaultGemConfig, callPackage }@defs: +{ stdenv, writeText, lib, ruby, defaultGemConfig, callPackage, test, stubs, should}@defs: let - test = import ./testing.nix; - tap = import ./tap-support.nix; - stubs = import ./stubs.nix defs; - should = import ./assertions.nix { inherit test lib; }; - - basicEnv = callPackage ./basic.nix stubs; bundlerEnv = callPackage ./default.nix stubs // { - inherit basicEnv; - }; - - testConfigs = { - inherit lib; - gemConfig = defaultGemConfig; + basicEnv = callPackage ../bundled-common stubs; }; - functions = (import ./functions.nix testConfigs); justName = bundlerEnv { name = "test-0.1.2"; @@ -35,21 +16,8 @@ let gemfile = ./test/Gemfile; lockfile = ./test/Gemfile.lock; }; - - results = builtins.concatLists [ - (test.run "Filter empty gemset" {} (set: functions.filterGemset {inherit ruby; groups = ["default"]; } set == {})) - ( let gemSet = { test = { groups = ["x" "y"]; }; }; - in - test.run "Filter matches a group" gemSet (set: functions.filterGemset {inherit ruby; groups = ["y" "z"];} set == gemSet)) - ( let gemSet = { test = { platforms = []; }; }; - in - test.run "Filter matches empty platforms list" gemSet (set: functions.filterGemset {inherit ruby; groups = [];} set == gemSet)) - ( let gemSet = { test = { platforms = [{engine = ruby.rubyEngine; version = ruby.version.majMin;}]; }; }; - in - test.run "Filter matches on platform" gemSet (set: functions.filterGemset {inherit ruby; groups = [];} set == gemSet)) - ( let gemSet = { test = { groups = ["x" "y"]; }; }; - in - test.run "Filter excludes based on groups" gemSet (set: functions.filterGemset {inherit ruby; groups = ["a" "b"];} set == {})) +in + builtins.concatLists [ (test.run "bundlerEnv { name }" justName { name = should.equal "test-0.1.2"; }) @@ -62,6 +30,4 @@ let postBuild = should.havePrefix "/nix/store"; } ]) - ]; -in - writeText "test-results.tap" (tap.output results) + ] diff --git a/pkgs/development/ruby-modules/bundler-env/testing.nix b/pkgs/development/ruby-modules/bundler-env/testing.nix deleted file mode 100644 index 43d10fca0444..000000000000 --- a/pkgs/development/ruby-modules/bundler-env/testing.nix +++ /dev/null @@ -1,62 +0,0 @@ -with builtins; -let - /* - underTest = { - x = { - a = 1; - b = "2"; - }; - }; - - tests = [ - (root: false) - { - x = [ - (set: true) - { - a = (a: a > 1); - b = (b: b == "3"); - } - ]; - } - ]; - - results = run "Examples" underTest tests; - */ - - passed = desc: { - result = "pass"; - description = desc; - }; - - failed = desc: { - result = "failed"; - description = desc; - }; - - prefixName = name: res: { - inherit (res) result; - description = "${name}: ${res.description}"; - }; - - run = name: under: tests: if isList tests then - (concatLists (map (run name under) tests)) - else if isAttrs tests then - (concatLists (map ( - subName: run (name + "." + subName) (if hasAttr subName under then getAttr subName under else "") (getAttr subName tests) - ) (attrNames tests))) - else if isFunction tests then - let - res = tests under; - in - if isBool res then - [ - (prefixName name (if tests under then passed "passed" else failed "failed")) - ] - else - [ (prefixName name res) ] - else [ - failed (name ": not a function, list or set") - ]; -in - { inherit run passed failed; } diff --git a/pkgs/development/ruby-modules/runtests.sh b/pkgs/development/ruby-modules/runtests.sh new file mode 100755 index 000000000000..d0faaf971dba --- /dev/null +++ b/pkgs/development/ruby-modules/runtests.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +set -o xtrace +pwd +find . -name text.nix +testfiles=$(find . -name test.nix) +nix-build -E "with import {}; callPackage testing/driver.nix { testFiles = [ $testfiles ]; }" --show-trace && cat result diff --git a/pkgs/development/ruby-modules/testing/assertions.nix b/pkgs/development/ruby-modules/testing/assertions.nix new file mode 100644 index 000000000000..3cf67d6f3eb6 --- /dev/null +++ b/pkgs/development/ruby-modules/testing/assertions.nix @@ -0,0 +1,24 @@ +{ test, lib, ...}: +{ + equal = expected: actual: + if actual == expected then + (test.passed "= ${toString expected}") else + (test.failed "'${toString actual}'(${builtins.typeOf actual}) != '${toString expected}'(${builtins.typeOf expected})"); + + beASet = actual: + if builtins.isAttrs actual then + (test.passed "is a set") else + (test.failed "is not a set, was ${builtins.typeOf actual}: ${toString actual}"); + + haveKeys = expected: actual: + if builtins.all + (ex: builtins.any (ac: ex == ac) (builtins.attrNames actual)) + expected then + (test.passed "has expected keys") else + (test.failed "keys differ: expected [${lib.concatStringsSep ";" expected}] have [${lib.concatStringsSep ";" (builtins.attrNames actual)}]"); + + havePrefix = expected: actual: + if lib.hasPrefix expected actual then + (test.passed "has prefix '${expected}'") else + (test.failed "prefix '${expected}' not found in '${actual}'"); +} diff --git a/pkgs/development/ruby-modules/testing/driver.nix b/pkgs/development/ruby-modules/testing/driver.nix new file mode 100644 index 000000000000..65e7c8d4416d --- /dev/null +++ b/pkgs/development/ruby-modules/testing/driver.nix @@ -0,0 +1,20 @@ +/* +Run with: +nix-build -E 'with import { }; callPackage ./test.nix {}' --show-trace; and cat result + +Confusingly, the ideal result ends with something like: +error: build of ‘/nix/store/3245f3dcl2wxjs4rci7n069zjlz8qg85-test-results.tap.drv’ failed +*/ +{ writeText, lib, callPackage, testFiles, stdenv, ruby }@defs: +let + testTools = rec { + test = import ./testing.nix; + stubs = import ./stubs.nix defs; + should = import ./assertions.nix { inherit test lib; }; + }; + + tap = import ./tap-support.nix; + + results = builtins.concatLists (map (file: callPackage file testTools) testFiles); +in + writeText "test-results.tap" (tap.output results) diff --git a/pkgs/development/ruby-modules/testing/runtests.sh b/pkgs/development/ruby-modules/testing/runtests.sh new file mode 100755 index 000000000000..c3db8ed34afb --- /dev/null +++ b/pkgs/development/ruby-modules/testing/runtests.sh @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +nix-build -E 'with import { }; callPackage ./test.nix {}' --show-trace && cat result diff --git a/pkgs/development/ruby-modules/testing/stubs.nix b/pkgs/development/ruby-modules/testing/stubs.nix new file mode 100644 index 000000000000..3585681478c8 --- /dev/null +++ b/pkgs/development/ruby-modules/testing/stubs.nix @@ -0,0 +1,33 @@ +{ stdenv, lib, ruby, callPackage, ... }: +let + real = { + inherit (stdenv) mkDerivation; + }; + mkDerivation = {name, ...}@argSet: + derivation { + inherit name; + text = (builtins.toJSON (lib.filterAttrs ( n: v: builtins.any (x: x == n) ["name" "system"]) argSet)); + builder = stdenv.shell; + args = [ "-c" "echo $(<$textPath) > $out"]; + system = stdenv.system; + passAsFile = ["text"]; + }; + fetchurl = {url?"", urls ? [],...}: "fetchurl:${if urls == [] then url else builtins.head urls}"; + + stdenv' = stdenv // { + inherit mkDerivation; + stubbed = true; + }; + ruby' = ruby // { + stdenv = stdenv'; + stubbed = true; + }; +in + { + ruby = ruby'; + buildRubyGem = callPackage ../gem { + inherit fetchurl; + ruby = ruby'; + }; + stdenv = stdenv'; + } diff --git a/pkgs/development/ruby-modules/testing/tap-support.nix b/pkgs/development/ruby-modules/testing/tap-support.nix new file mode 100644 index 000000000000..ba576683d372 --- /dev/null +++ b/pkgs/development/ruby-modules/testing/tap-support.nix @@ -0,0 +1,20 @@ +with builtins; +let + withIndexes = list: genList (idx: (elemAt list idx) // {index = idx;}) (length list); + + testLine = report: "${okStr report} ${toString report.index} ${report.description}" + testDirective report + testYaml report; + + testDirective = report: ""; + + testYaml = report: ""; + + okStr = { result, ...}: if result == "pass" then "ok" else "not ok"; +in + { + output = reports: '' + TAP version 13 + 1..${toString (length reports)}'' + (foldl' (l: r: l + "\n" + r) "" (map testLine (withIndexes reports))) + '' + + # Finished at ${toString currentTime} + ''; + } diff --git a/pkgs/development/ruby-modules/testing/testing.nix b/pkgs/development/ruby-modules/testing/testing.nix new file mode 100644 index 000000000000..43d10fca0444 --- /dev/null +++ b/pkgs/development/ruby-modules/testing/testing.nix @@ -0,0 +1,62 @@ +with builtins; +let + /* + underTest = { + x = { + a = 1; + b = "2"; + }; + }; + + tests = [ + (root: false) + { + x = [ + (set: true) + { + a = (a: a > 1); + b = (b: b == "3"); + } + ]; + } + ]; + + results = run "Examples" underTest tests; + */ + + passed = desc: { + result = "pass"; + description = desc; + }; + + failed = desc: { + result = "failed"; + description = desc; + }; + + prefixName = name: res: { + inherit (res) result; + description = "${name}: ${res.description}"; + }; + + run = name: under: tests: if isList tests then + (concatLists (map (run name under) tests)) + else if isAttrs tests then + (concatLists (map ( + subName: run (name + "." + subName) (if hasAttr subName under then getAttr subName under else "") (getAttr subName tests) + ) (attrNames tests))) + else if isFunction tests then + let + res = tests under; + in + if isBool res then + [ + (prefixName name (if tests under then passed "passed" else failed "failed")) + ] + else + [ (prefixName name res) ] + else [ + failed (name ": not a function, list or set") + ]; +in + { inherit run passed failed; } -- cgit 1.4.1 From e4bb4d4788547e09c35e85d1271ffb07122d2b1b Mon Sep 17 00:00:00 2001 From: Judson Date: Sat, 27 May 2017 15:22:06 -0700 Subject: Cleaning out obsolete files --- .../ruby-modules/bundler-env/too-complicated.nix | 195 --------------------- pkgs/development/ruby-modules/testing/runtests.sh | 2 - 2 files changed, 197 deletions(-) delete mode 100644 pkgs/development/ruby-modules/bundler-env/too-complicated.nix delete mode 100755 pkgs/development/ruby-modules/testing/runtests.sh diff --git a/pkgs/development/ruby-modules/bundler-env/too-complicated.nix b/pkgs/development/ruby-modules/bundler-env/too-complicated.nix deleted file mode 100644 index 7d2f0efe0011..000000000000 --- a/pkgs/development/ruby-modules/bundler-env/too-complicated.nix +++ /dev/null @@ -1,195 +0,0 @@ -{ stdenv, runCommand, writeText, writeScript, writeScriptBin, ruby, lib -, callPackage, defaultGemConfig, fetchurl, fetchgit, buildRubyGem, buildEnv -, git -, makeWrapper -, bundler -, tree -}@defs: - -{ name ? null -, pname ? null -, gemdir ? null -, gemfile ? null -, lockfile ? null -, gemset ? null -, allBins ? false -, ruby ? defs.ruby -, gemConfig ? defaultGemConfig -, postBuild ? null -, document ? [] -, meta ? {} -, groups ? ["default"] -, ignoreCollisions ? false -, ... -}@args: - -let - drvName = - if name != null then name - else if pname != null then "${toString pname}-${mainGem.version}" - else throw "bundlerEnv: either pname or name must be set"; - - mainGem = - if pname == null then null - else gems."${pname}" or (throw "bundlerEnv: gem ${pname} not found"); - - gemfile' = - if gemfile == null then gemdir + "/Gemfile" - else gemfile; - - lockfile' = - if lockfile == null then gemdir + "/Gemfile.lock" - else lockfile; - - gemset' = - if gemset == null then gemdir + "/gemset.nix" - else gemset; - - importedGemset = import gemset'; - - platformMatches = attrs: ( - !(attrs ? "platforms") || - builtins.any (platform: - platform.engine == ruby.rubyEngine && - (!(platform ? "version") || platform.version == ruby.version.majMin) - ) attrs.platforms - ); - - groupMatches = attrs: ( - !(attrs ? "groups") || - builtins.any (gemGroup: builtins.any (group: group == gemGroup) groups) attrs.groups - ); - - filteredGemset = lib.filterAttrs (name: attrs: platformMatches attrs && groupMatches attrs) importedGemset; - - applyGemConfigs = attrs: - (if gemConfig ? "${attrs.gemName}" - then attrs // gemConfig."${attrs.gemName}" attrs - else attrs); - - configuredGemset = lib.flip lib.mapAttrs filteredGemset (name: attrs: - applyGemConfigs (attrs // { inherit ruby; gemName = name; }) - ); - - hasBundler = builtins.hasAttr "bundler" filteredGemset; - - bundler = - if hasBundler then gems.bundler - else defs.bundler.override (attrs: { inherit ruby; }); - - pathDerivation = { gemName, version, path, ... }: - let - res = { - type = "derivation"; - bundledByPath = true; - name = gemName; - version = version; - outPath = path; - outputs = [ "out" ]; - out = res; - outputName = "out"; - }; - in res; - - buildGem = name: attrs: ( - let - gemAttrs = ((removeAttrs attrs ["source"]) // attrs.source // { - inherit ruby; - gemName = name; - gemPath = map (gemName: gems."${gemName}") (attrs.dependencies or []); - }); - in - if gemAttrs.type == "path" then pathDerivation gemAttrs - else buildRubyGem gemAttrs); - - gems = lib.flip lib.mapAttrs configuredGemset (name: attrs: buildGem name attrs); - - maybeCopyAll = main: if main == null then "" else copyIfBundledByPath main; - - copyIfBundledByPath = { bundledByPath ? false, ...}@main: - (if bundledByPath then '' - cp -a ${gemdir}/* $out/ - '' else "" - ); - - # We have to normalize the Gemfile.lock, otherwise bundler tries to be - # helpful by doing so at run time, causing executables to immediately bail - # out. Yes, I'm serious. - confFiles = runCommand "gemfile-and-lockfile" {} '' - mkdir -p $out - ${maybeCopyAll mainGem} - cp ${gemfile'} $out/Gemfile || ls -l $out/Gemfile - cp ${lockfile'} $out/Gemfile.lock || ls -l $out/Gemfile.lock - ''; - - envPaths = lib.attrValues gems ++ lib.optional (!hasBundler) bundler; - - binPaths = if !allBins && mainGem != null then [ mainGem ] else envPaths; - - genStubs = binPaths: '' - ${ruby}/bin/ruby ${./gen-bin-stubs.rb} \ - "${ruby}/bin/ruby" \ - "${confFiles}/Gemfile" \ - "$out/${ruby.gemPath}" \ - "${bundler}/${ruby.gemPath}" \ - ${lib.escapeShellArg binPaths} \ - ${lib.escapeShellArg groups} - ''; - - bundlerEnv = buildEnv { - inherit ignoreCollisions; - - name = drvName; - - paths = envPaths; - pathsToLink = [ "/lib" ]; - - postBuild = (genStubs binPaths) + lib.optionalString (postBuild != null) postBuild; - - meta = { platforms = ruby.meta.platforms; } // meta; - - passthru = rec { - inherit ruby bundler gems; - - wrappedRuby = stdenv.mkDerivation { - name = "wrapped-ruby-${drvName}"; - nativeBuildInputs = [ makeWrapper ]; - buildCommand = '' - mkdir -p $out/bin - for i in ${ruby}/bin/*; do - makeWrapper "$i" $out/bin/$(basename "$i") \ - --set BUNDLE_GEMFILE ${confFiles}/Gemfile \ - --set BUNDLE_PATH ${bundlerEnv}/${ruby.gemPath} \ - --set BUNDLE_FROZEN 1 \ - --set GEM_HOME ${bundlerEnv}/${ruby.gemPath} \ - --set GEM_PATH ${bundlerEnv}/${ruby.gemPath} - done - ''; - }; - - env = let - irbrc = builtins.toFile "irbrc" '' - if !(ENV["OLD_IRBRC"].nil? || ENV["OLD_IRBRC"].empty?) - require ENV["OLD_IRBRC"] - end - require 'rubygems' - require 'bundler/setup' - ''; - in stdenv.mkDerivation { - name = "${drvName}-interactive-environment"; - nativeBuildInputs = [ wrappedRuby bundlerEnv ]; - shellHook = '' - export OLD_IRBRC="$IRBRC" - export IRBRC=${irbrc} - ''; - buildCommand = '' - echo >&2 "" - echo >&2 "*** Ruby 'env' attributes are intended for interactive nix-shell sessions, not for building! ***" - echo >&2 "" - exit 1 - ''; - }; - }; - }; -in - bundlerEnv diff --git a/pkgs/development/ruby-modules/testing/runtests.sh b/pkgs/development/ruby-modules/testing/runtests.sh deleted file mode 100755 index c3db8ed34afb..000000000000 --- a/pkgs/development/ruby-modules/testing/runtests.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env bash -nix-build -E 'with import { }; callPackage ./test.nix {}' --show-trace && cat result -- cgit 1.4.1 From 2b7cfdd6e9edeb5cd00730c11faae51f87e02be4 Mon Sep 17 00:00:00 2001 From: zimbatm Date: Mon, 29 May 2017 13:27:41 +0100 Subject: fix missing variable in bundler-env --- pkgs/development/ruby-modules/bundled-common/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/development/ruby-modules/bundled-common/default.nix b/pkgs/development/ruby-modules/bundled-common/default.nix index 33a379c02759..586e44a56c75 100644 --- a/pkgs/development/ruby-modules/bundled-common/default.nix +++ b/pkgs/development/ruby-modules/bundled-common/default.nix @@ -93,7 +93,7 @@ let meta = { platforms = ruby.meta.platforms; } // meta; passthru = rec { - inherit ruby bundler gems mainGem confFiles; # drvName; + inherit ruby bundler gems mainGem confFiles envPaths; wrappedRuby = stdenv.mkDerivation { -- cgit 1.4.1 From c4fc70f53cfaf673bde7fd009826d62bececa161 Mon Sep 17 00:00:00 2001 From: Judson Date: Wed, 31 May 2017 09:44:46 -0700 Subject: Starting to add tool builder. Extracting bundler file computation. --- .../ruby-modules/bundled-common/default.nix | 2 +- .../ruby-modules/bundled-common/functions.nix | 20 ++++++++++++++ .../ruby-modules/bundled-common/test.nix | 29 +++++++++++++++++++- .../ruby-modules/bundler-env/default.nix | 8 ++---- .../ruby-modules/testing/assertions.nix | 8 ++++-- .../ruby-modules/testing/tap-support.nix | 2 +- pkgs/development/ruby-modules/tool/default.nix | 32 ++++++++++++++++++++++ 7 files changed, 90 insertions(+), 11 deletions(-) create mode 100644 pkgs/development/ruby-modules/tool/default.nix diff --git a/pkgs/development/ruby-modules/bundled-common/default.nix b/pkgs/development/ruby-modules/bundled-common/default.nix index 33a379c02759..e532224195f9 100644 --- a/pkgs/development/ruby-modules/bundled-common/default.nix +++ b/pkgs/development/ruby-modules/bundled-common/default.nix @@ -7,10 +7,10 @@ { name , pname ? name +, gemdir , gemfile , lockfile , gemset -, gemdir , ruby ? defs.ruby , gemConfig ? defaultGemConfig , postBuild ? null diff --git a/pkgs/development/ruby-modules/bundled-common/functions.nix b/pkgs/development/ruby-modules/bundled-common/functions.nix index ce8a1b69c749..1d7c4878e13b 100644 --- a/pkgs/development/ruby-modules/bundled-common/functions.nix +++ b/pkgs/development/ruby-modules/bundled-common/functions.nix @@ -1,5 +1,25 @@ { lib, gemConfig, ... }: rec { + bundlerFiles = { + gemfile ? null + , lockfile ? null + , gemset ? null + , gemdir ? null + , ... + }: { + gemfile = + if gemfile == null then assert gemdir != null; gemdir + "/Gemfile" + else gemfile; + + lockfile = + if lockfile == null then assert gemdir != null; gemdir + "/Gemfile.lock" + else lockfile; + + gemset = + if gemset == null then assert gemdir != null; gemdir + "/gemset.nix" + else gemset; + }; + filterGemset = {ruby, groups,...}@env: gemset: lib.filterAttrs (name: attrs: platformMatches ruby attrs && groupMatches groups attrs) gemset; platformMatches = {rubyEngine, version, ...}@ruby: attrs: ( diff --git a/pkgs/development/ruby-modules/bundled-common/test.nix b/pkgs/development/ruby-modules/bundled-common/test.nix index b24a620ed507..ee3754595f39 100644 --- a/pkgs/development/ruby-modules/bundled-common/test.nix +++ b/pkgs/development/ruby-modules/bundled-common/test.nix @@ -7,7 +7,34 @@ let functions = (import ./functions.nix testConfigs); in builtins.concatLists [ - (test.run "Filter empty gemset" {} (set: functions.filterGemset {inherit ruby; groups = ["default"]; } set == {})) + ( test.run "All set, no gemdir" (functions.bundlerFiles { + gemfile = test/Gemfile; + lockfile = test/Gemfile.lock; + gemset = test/gemset.nix; + }) { + gemfile = should.equal test/Gemfile; + lockfile = should.equal test/Gemfile.lock; + gemset = should.equal test/gemset.nix; + }) + + ( test.run "Just gemdir" (functions.bundlerFiles { + gemdir = test/.; + }) { + gemfile = should.equal test/Gemfile; + lockfile = should.equal test/Gemfile.lock; + gemset = should.equal test/gemset.nix; + }) + + ( test.run "Gemset and dir" (functions.bundlerFiles { + gemdir = test/.; + gemset = test/extraGemset.nix; + }) { + gemfile = should.equal test/Gemfile; + lockfile = should.equal test/Gemfile.lock; + gemset = should.equal test/extraGemset.nix; + }) + + ( test.run "Filter empty gemset" {} (set: functions.filterGemset {inherit ruby; groups = ["default"]; } set == {})) ( let gemSet = { test = { groups = ["x" "y"]; }; }; in test.run "Filter matches a group" gemSet (set: functions.filterGemset {inherit ruby; groups = ["y" "z"];} set == gemSet)) diff --git a/pkgs/development/ruby-modules/bundler-env/default.nix b/pkgs/development/ruby-modules/bundler-env/default.nix index 46d9e99f671e..89fafb5f230b 100644 --- a/pkgs/development/ruby-modules/bundler-env/default.nix +++ b/pkgs/development/ruby-modules/bundler-env/default.nix @@ -1,10 +1,6 @@ { stdenv, runCommand, writeText, writeScript, writeScriptBin, ruby, lib , callPackage, defaultGemConfig, fetchurl, fetchgit, buildRubyGem, buildEnv -, linkFarm -, git -, makeWrapper -, bundler -, tree +, linkFarm, git, makeWrapper, bundler, tree }@defs: { name ? null @@ -13,12 +9,12 @@ , gemfile ? null , lockfile ? null , gemset ? null +, groups ? ["default"] , ruby ? defs.ruby , gemConfig ? defaultGemConfig , postBuild ? null , document ? [] , meta ? {} -, groups ? ["default"] , ignoreCollisions ? false , ... }@args: diff --git a/pkgs/development/ruby-modules/testing/assertions.nix b/pkgs/development/ruby-modules/testing/assertions.nix index 3cf67d6f3eb6..f28cfcd508d4 100644 --- a/pkgs/development/ruby-modules/testing/assertions.nix +++ b/pkgs/development/ruby-modules/testing/assertions.nix @@ -3,7 +3,11 @@ equal = expected: actual: if actual == expected then (test.passed "= ${toString expected}") else - (test.failed "'${toString actual}'(${builtins.typeOf actual}) != '${toString expected}'(${builtins.typeOf expected})"); + (test.failed ( + "expected '${toString expected}'(${builtins.typeOf expected})" + + " != "+ + "actual '${toString actual}'(${builtins.typeOf actual})" + )); beASet = actual: if builtins.isAttrs actual then @@ -15,7 +19,7 @@ (ex: builtins.any (ac: ex == ac) (builtins.attrNames actual)) expected then (test.passed "has expected keys") else - (test.failed "keys differ: expected [${lib.concatStringsSep ";" expected}] have [${lib.concatStringsSep ";" (builtins.attrNames actual)}]"); + (test.failed "keys differ: expected: [${lib.concatStringsSep ";" expected}] actual: [${lib.concatStringsSep ";" (builtins.attrNames actual)}]"); havePrefix = expected: actual: if lib.hasPrefix expected actual then diff --git a/pkgs/development/ruby-modules/testing/tap-support.nix b/pkgs/development/ruby-modules/testing/tap-support.nix index ba576683d372..3147ed066c11 100644 --- a/pkgs/development/ruby-modules/testing/tap-support.nix +++ b/pkgs/development/ruby-modules/testing/tap-support.nix @@ -2,7 +2,7 @@ with builtins; let withIndexes = list: genList (idx: (elemAt list idx) // {index = idx;}) (length list); - testLine = report: "${okStr report} ${toString report.index} ${report.description}" + testDirective report + testYaml report; + testLine = report: "${okStr report} ${toString (report.index + 1)} ${report.description}" + testDirective report + testYaml report; testDirective = report: ""; diff --git a/pkgs/development/ruby-modules/tool/default.nix b/pkgs/development/ruby-modules/tool/default.nix new file mode 100644 index 000000000000..02bf3b96a267 --- /dev/null +++ b/pkgs/development/ruby-modules/tool/default.nix @@ -0,0 +1,32 @@ +{ stdenv }@defs: + +{ + name +, gemdir +, exes ? [] +, scripts ? [] +, postBuild +}@args: + +let + basicEnv = (callPackage ../bundled-common {}) (args // { inherit name gemdir; + gemfile = gemfile'; + lockfile = lockfile'; + gemset = gemset'; + }); + + args = removeAttrs args_ [ "name" "postBuild" ] + // { inherit preferLocalBuild allowSubstitutes; }; # pass the defaults +in + runCommand name args '' + mkdir -p $out; cd $out; + ${(lib.concatMapStrings (x: "ln -s '${basicEnv}/bin/${x}' '${x}';\n") exes)} + ${(lib.concatMapStrings (s: "makeWrapper ${out}/bin/$(basename ${s}) $srcdir/${s} " + + "--set BUNDLE_GEMFILE ${basicEnv.confFiles}/Gemfile "+ + "--set BUNDLE_PATH ${basicEnv}/${ruby.gemPath} "+ + "--set BUNDLE_FROZEN 1 "+ + "--set GEM_HOME ${basicEnv}/${ruby.gemPath} "+ + "--set GEM_PATH ${basicEnv}/${ruby.gemPath} "+ + "--run \"cd $srcdir\";\n") scripts)} + ${postBuild} + '' -- cgit 1.4.1 From 964d9b7a067fc48d9774c5bff37d7fff41158f5a Mon Sep 17 00:00:00 2001 From: Judson Date: Fri, 9 Jun 2017 09:04:33 -0700 Subject: Made gemdir handling into a common function --- .../ruby-modules/bundled-common/default.nix | 21 +++++++++++---------- .../ruby-modules/bundler-env/default.nix | 18 +----------------- .../ruby-modules/testing/tap-support.nix | 1 + pkgs/development/ruby-modules/tool/default.nix | 14 ++++++++------ 4 files changed, 21 insertions(+), 33 deletions(-) diff --git a/pkgs/development/ruby-modules/bundled-common/default.nix b/pkgs/development/ruby-modules/bundled-common/default.nix index 30c82100d5e0..2aea35844fe5 100644 --- a/pkgs/development/ruby-modules/bundled-common/default.nix +++ b/pkgs/development/ruby-modules/bundled-common/default.nix @@ -7,10 +7,10 @@ { name , pname ? name -, gemdir -, gemfile -, lockfile -, gemset +, gemdir ? null +, gemfile ? null +, lockfile ? null +, gemset ? null , ruby ? defs.ruby , gemConfig ? defaultGemConfig , postBuild ? null @@ -24,8 +24,9 @@ with import ./functions.nix { inherit lib gemConfig; }; let + gemFiles = bundlerFiles args; - importedGemset = import gemset; + importedGemset = import gemFiles.gemset; filteredGemset = filterGemset { inherit ruby groups; } importedGemset; @@ -42,9 +43,9 @@ let gems = lib.flip lib.mapAttrs configuredGemset (name: attrs: buildGem name attrs); copyIfBundledByPath = { bundledByPath ? false, ...}@main: - (if bundledByPath then '' - cp -a ${gemdir}/* $out/ - '' else "" + (if bundledByPath then + assert gemFiles.gemdir != nil; "cp -a ${gemFiles.gemdir}/* $out/" + else "" ); maybeCopyAll = pname: if pname == null then "" else @@ -59,8 +60,8 @@ let confFiles = runCommand "gemfile-and-lockfile" {} '' mkdir -p $out ${maybeCopyAll pname} - cp ${gemfile} $out/Gemfile || ls -l $out/Gemfile - cp ${lockfile} $out/Gemfile.lock || ls -l $out/Gemfile.lock + cp ${gemFiles.gemfile} $out/Gemfile || ls -l $out/Gemfile + cp ${gemFiles.lockfile} $out/Gemfile.lock || ls -l $out/Gemfile.lock ''; buildGem = name: attrs: ( diff --git a/pkgs/development/ruby-modules/bundler-env/default.nix b/pkgs/development/ruby-modules/bundler-env/default.nix index 89fafb5f230b..a72647fb00a1 100644 --- a/pkgs/development/ruby-modules/bundler-env/default.nix +++ b/pkgs/development/ruby-modules/bundler-env/default.nix @@ -27,23 +27,7 @@ let else if pname != null then "${toString pname}-${basicEnv.gems."${pname}".version}" else throw "bundlerEnv: either pname or name must be set"; - gemfile' = - if gemfile == null then gemdir + "/Gemfile" - else gemfile; - - lockfile' = - if lockfile == null then gemdir + "/Gemfile.lock" - else lockfile; - - gemset' = - if gemset == null then gemdir + "/gemset.nix" - else gemset; - - basicEnv = (callPackage ../bundled-common {}) (args // { inherit pname name gemdir; - gemfile = gemfile'; - lockfile = lockfile'; - gemset = gemset'; - }); + basicEnv = (callPackage ../bundled-common {}) (args // { inherit pname name; }); inherit (basicEnv) envPaths; # Idea here is a mkDerivation that gen-bin-stubs new stubs "as specified" - diff --git a/pkgs/development/ruby-modules/testing/tap-support.nix b/pkgs/development/ruby-modules/testing/tap-support.nix index 3147ed066c11..555ce89d8332 100644 --- a/pkgs/development/ruby-modules/testing/tap-support.nix +++ b/pkgs/development/ruby-modules/testing/tap-support.nix @@ -4,6 +4,7 @@ let testLine = report: "${okStr report} ${toString (report.index + 1)} ${report.description}" + testDirective report + testYaml report; + # These are part of the TAP spec, not yet implemented. testDirective = report: ""; testYaml = report: ""; diff --git a/pkgs/development/ruby-modules/tool/default.nix b/pkgs/development/ruby-modules/tool/default.nix index 02bf3b96a267..04c385d75ae6 100644 --- a/pkgs/development/ruby-modules/tool/default.nix +++ b/pkgs/development/ruby-modules/tool/default.nix @@ -2,24 +2,26 @@ { name + # gemdir is the location of the Gemfile{,.lock} and gemset.nix; usually ./. , gemdir + # Exes is the list of executables provided by the gems in the Gemfile , exes ? [] + # Scripts are programs included directly in nixpkgs that depend on gems , scripts ? [] +, gemfile ? null +, lockfile ? null +, gemset ? null , postBuild }@args: let - basicEnv = (callPackage ../bundled-common {}) (args // { inherit name gemdir; - gemfile = gemfile'; - lockfile = lockfile'; - gemset = gemset'; - }); + basicEnv = (callPackage ../bundled-common {}) args; args = removeAttrs args_ [ "name" "postBuild" ] // { inherit preferLocalBuild allowSubstitutes; }; # pass the defaults in runCommand name args '' - mkdir -p $out; cd $out; + mkdir -p ${out}/bin; cd $out; ${(lib.concatMapStrings (x: "ln -s '${basicEnv}/bin/${x}' '${x}';\n") exes)} ${(lib.concatMapStrings (s: "makeWrapper ${out}/bin/$(basename ${s}) $srcdir/${s} " + "--set BUNDLE_GEMFILE ${basicEnv.confFiles}/Gemfile "+ -- cgit 1.4.1 From 53481f8f0b568b0185a7bd58102452153b827bbe Mon Sep 17 00:00:00 2001 From: Judson Date: Sat, 10 Jun 2017 16:58:32 -0700 Subject: Docs and extras on tool/ --- pkgs/development/ruby-modules/tool/default.nix | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkgs/development/ruby-modules/tool/default.nix b/pkgs/development/ruby-modules/tool/default.nix index 04c385d75ae6..97158213e10d 100644 --- a/pkgs/development/ruby-modules/tool/default.nix +++ b/pkgs/development/ruby-modules/tool/default.nix @@ -6,11 +6,13 @@ , gemdir # Exes is the list of executables provided by the gems in the Gemfile , exes ? [] - # Scripts are programs included directly in nixpkgs that depend on gems + # Scripts are ruby programs depend on gems in the Gemfile (e.g. scripts/rails) , scripts ? [] , gemfile ? null , lockfile ? null , gemset ? null +, preferLocalBuild ? false +, allowSubstitutes ? false , postBuild }@args: -- cgit 1.4.1 From dd86c6d25a0d06ea9234850fce7dafff34c987ec Mon Sep 17 00:00:00 2001 From: Judson Date: Sat, 10 Jun 2017 17:11:37 -0700 Subject: Adding Corundum as demo of rubyTool --- lib/maintainers.nix | 1 + pkgs/development/ruby-modules/tool/default.nix | 1 + pkgs/development/tools/corundum/Gemfile | 3 + pkgs/development/tools/corundum/Gemfile.lock | 56 +++++++++ pkgs/development/tools/corundum/default.nix | 13 +++ pkgs/development/tools/corundum/gemset.nix | 154 +++++++++++++++++++++++++ pkgs/top-level/all-packages.nix | 1 + 7 files changed, 229 insertions(+) create mode 100644 pkgs/development/tools/corundum/Gemfile create mode 100644 pkgs/development/tools/corundum/Gemfile.lock create mode 100644 pkgs/development/tools/corundum/default.nix create mode 100644 pkgs/development/tools/corundum/gemset.nix diff --git a/lib/maintainers.nix b/lib/maintainers.nix index 57fa0bdd565c..f3204ab3b345 100644 --- a/lib/maintainers.nix +++ b/lib/maintainers.nix @@ -372,6 +372,7 @@ np = "Nicolas Pouillard "; nslqqq = "Nikita Mikhailov "; nthorne = "Niklas Thörne "; + nyarly = "Judson Lester "; obadz = "obadz "; ocharles = "Oliver Charles "; odi = "Oliver Dunkl "; diff --git a/pkgs/development/ruby-modules/tool/default.nix b/pkgs/development/ruby-modules/tool/default.nix index 97158213e10d..5a11218fdeab 100644 --- a/pkgs/development/ruby-modules/tool/default.nix +++ b/pkgs/development/ruby-modules/tool/default.nix @@ -13,6 +13,7 @@ , gemset ? null , preferLocalBuild ? false , allowSubstitutes ? false +, meta ? {} , postBuild }@args: diff --git a/pkgs/development/tools/corundum/Gemfile b/pkgs/development/tools/corundum/Gemfile new file mode 100644 index 000000000000..5f817ae498a7 --- /dev/null +++ b/pkgs/development/tools/corundum/Gemfile @@ -0,0 +1,3 @@ +source "https://rubygems.org" + +gem "corundum", "=0.6.2" diff --git a/pkgs/development/tools/corundum/Gemfile.lock b/pkgs/development/tools/corundum/Gemfile.lock new file mode 100644 index 000000000000..40ad1948394f --- /dev/null +++ b/pkgs/development/tools/corundum/Gemfile.lock @@ -0,0 +1,56 @@ +GEM + remote: https://rubygems.org/ + specs: + calibrate (0.0.1) + caliph (0.3.1) + corundum (0.6.2) + bundler (~> 1.10) + caliph (~> 0.3) + mattock (~> 0.9) + paint (~> 0.8) + rspec (>= 2.0, < 4) + simplecov (>= 0.5) + simplecov-json (~> 0.2) + diff-lcs (1.3) + docile (1.1.5) + json (2.1.0) + mattock (0.10.1) + calibrate (~> 0.0.1) + caliph (~> 0.3) + rake (~> 10.0) + tilt (> 0) + valise (~> 1.1) + paint (0.9.0) + rake (10.5.0) + rspec (3.6.0) + rspec-core (~> 3.6.0) + rspec-expectations (~> 3.6.0) + rspec-mocks (~> 3.6.0) + rspec-core (3.6.0) + rspec-support (~> 3.6.0) + rspec-expectations (3.6.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.6.0) + rspec-mocks (3.6.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.6.0) + rspec-support (3.6.0) + simplecov (0.14.1) + docile (~> 1.1.0) + json (>= 1.8, < 3) + simplecov-html (~> 0.10.0) + simplecov-html (0.10.1) + simplecov-json (0.2) + json + simplecov + tilt (2.0.7) + valise (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + corundum (= 0.6.2) + +BUNDLED WITH + 1.14.4 diff --git a/pkgs/development/tools/corundum/default.nix b/pkgs/development/tools/corundum/default.nix new file mode 100644 index 000000000000..36f5bb06c349 --- /dev/null +++ b/pkgs/development/tools/corundum/default.nix @@ -0,0 +1,13 @@ +{ rubyTool }: + +rubyTool { + name = "corundum-0.6.2"; + gemdir = ./.; + meta = { + description = "Tool and libraries for maintaining Ruby gems."; + homepage = http://sass-lang.com/; + license = licenses.mit; + maintainers = [ maintainers.nyarly ]; + platforms = platforms.unix; + }; +} diff --git a/pkgs/development/tools/corundum/gemset.nix b/pkgs/development/tools/corundum/gemset.nix new file mode 100644 index 000000000000..e395e098e6d1 --- /dev/null +++ b/pkgs/development/tools/corundum/gemset.nix @@ -0,0 +1,154 @@ +{ + calibrate = { + source = { + remotes = ["https://rubygems.org"]; + sha256 = "17kmlss7db70pjwdbbhag7mnixh8wasdq6n1v8663x50z9c7n2ng"; + type = "gem"; + }; + version = "0.0.1"; + }; + caliph = { + source = { + remotes = ["https://rubygems.org"]; + sha256 = "08d07n4m4yh1h9icq6n9dkw4jwgdmgd638f15mxr2pvqp4wycsnr"; + type = "gem"; + }; + version = "0.3.1"; + }; + corundum = { + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1y6shjrqaqyh14a1r4ic660g6jnq4abdrx9imglyalzyrlrwbsxq"; + type = "gem"; + }; + version = "0.6.2"; + }; + diff-lcs = { + source = { + remotes = ["https://rubygems.org"]; + sha256 = "18w22bjz424gzafv6nzv98h0aqkwz3d9xhm7cbr1wfbyas8zayza"; + type = "gem"; + }; + version = "1.3"; + }; + docile = { + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0m8j31whq7bm5ljgmsrlfkiqvacrw6iz9wq10r3gwrv5785y8gjx"; + type = "gem"; + }; + version = "1.1.5"; + }; + json = { + source = { + remotes = ["https://rubygems.org"]; + sha256 = "01v6jjpvh3gnq6sgllpfqahlgxzj50ailwhj9b3cd20hi2dx0vxp"; + type = "gem"; + }; + version = "2.1.0"; + }; + mattock = { + source = { + remotes = ["https://rubygems.org"]; + sha256 = "02d6igwr4sfj4jnky8d5h0rm2cc665k1bqz7sj4khzvr18nk3ai6"; + type = "gem"; + }; + version = "0.10.1"; + }; + paint = { + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1fcn7cfrhbl4nl95fmcd67q33h7bl3iafsafs6w9yj4nqzagz1yc"; + type = "gem"; + }; + version = "0.9.0"; + }; + rake = { + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0jcabbgnjc788chx31sihc5pgbqnlc1c75wakmqlbjdm8jns2m9b"; + type = "gem"; + }; + version = "10.5.0"; + }; + rspec = { + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1nd50hycab2a2vdah9lxi585g8f63jxjvmzmxqyln51grxwx9hzb"; + type = "gem"; + }; + version = "3.6.0"; + }; + rspec-core = { + source = { + remotes = ["https://rubygems.org"]; + sha256 = "18np8wyw2g79waclpaacba6nd7x60ixg07ncya0j0qj1z9b37grd"; + type = "gem"; + }; + version = "3.6.0"; + }; + rspec-expectations = { + source = { + remotes = ["https://rubygems.org"]; + sha256 = "028ifzf9mqp3kxx40q1nbwj40g72g9zk0wr78l146phblkv96w0a"; + type = "gem"; + }; + version = "3.6.0"; + }; + rspec-mocks = { + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0nv6jkxy24sag1i9w9wi3850k6skk2fm6yhcrgnmlz6vmwxvizp8"; + type = "gem"; + }; + version = "3.6.0"; + }; + rspec-support = { + source = { + remotes = ["https://rubygems.org"]; + sha256 = "050paqqpsml8w88nf4a15zbbj3vvm471zpv73sjfdnz7w21wnypb"; + type = "gem"; + }; + version = "3.6.0"; + }; + simplecov = { + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1r9fnsnsqj432cmrpafryn8nif3x0qg9mdnvrcf0wr01prkdlnww"; + type = "gem"; + }; + version = "0.14.1"; + }; + simplecov-html = { + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0f3psphismgp6jp1fxxz09zbswh7m2xxxr6gqlzdh7sgv415clvm"; + type = "gem"; + }; + version = "0.10.1"; + }; + simplecov-json = { + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0x9hr08pkj5d14nfzsn5h8b7ayl6q0xir45dcx5rv2a7g10kzlpp"; + type = "gem"; + }; + version = "0.2"; + }; + tilt = { + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1is1ayw5049z8pd7slsk870bddyy5g2imp4z78lnvl8qsl8l0s7b"; + type = "gem"; + }; + version = "2.0.7"; + }; + valise = { + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1arsbmk2gifrhv244qrld7s3202xrnxy6vlc5gqklg70dpsinbn5"; + type = "gem"; + }; + version = "1.2.1"; + }; +} \ No newline at end of file diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 867c35215af9..0c17e255ba40 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -6161,6 +6161,7 @@ with pkgs; bundix = callPackage ../development/ruby-modules/bundix { }; bundler = callPackage ../development/ruby-modules/bundler { }; bundlerEnv = callPackage ../development/ruby-modules/bundler-env { }; + rubyTool = callPackage ../development/ruby-modules/tool { }; inherit (callPackage ../development/interpreters/ruby {}) ruby_2_0_0 -- cgit 1.4.1 From 78cb9163a6a7960e3ae55c30eb377343cb0e2f5f Mon Sep 17 00:00:00 2001 From: Judson Date: Sat, 10 Jun 2017 17:22:13 -0700 Subject: Adding Corundum to all-packages --- pkgs/top-level/all-packages.nix | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 0c17e255ba40..0686adaea5f1 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -6462,6 +6462,8 @@ with pkgs; cookiecutter = pythonPackages.cookiecutter; + corundum = callPackage ../development/tools/corundum { }; + ctags = callPackage ../development/tools/misc/ctags { }; ctagsWrapped = callPackage ../development/tools/misc/ctags/wrapped.nix {}; -- cgit 1.4.1 From fc302bc07fd7a771751a6b94760730f1032e1f76 Mon Sep 17 00:00:00 2001 From: Judson Date: Sat, 10 Jun 2017 17:38:49 -0700 Subject: Not quite done - something fishy about the name attr --- pkgs/development/ruby-modules/tool/default.nix | 13 +++++++------ pkgs/development/tools/corundum/default.nix | 6 ++++-- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/pkgs/development/ruby-modules/tool/default.nix b/pkgs/development/ruby-modules/tool/default.nix index 5a11218fdeab..9b8848592b2c 100644 --- a/pkgs/development/ruby-modules/tool/default.nix +++ b/pkgs/development/ruby-modules/tool/default.nix @@ -1,4 +1,4 @@ -{ stdenv }@defs: +{ lib, stdenv, callPackage, runCommand, ruby }@defs: { name @@ -8,25 +8,26 @@ , exes ? [] # Scripts are ruby programs depend on gems in the Gemfile (e.g. scripts/rails) , scripts ? [] +, ruby ? defs.ruby , gemfile ? null , lockfile ? null , gemset ? null , preferLocalBuild ? false , allowSubstitutes ? false , meta ? {} -, postBuild +, postBuild ? "" }@args: let basicEnv = (callPackage ../bundled-common {}) args; - args = removeAttrs args_ [ "name" "postBuild" ] + cmdArgs = removeAttrs args [ "name" "postBuild" ] // { inherit preferLocalBuild allowSubstitutes; }; # pass the defaults in - runCommand name args '' - mkdir -p ${out}/bin; cd $out; + runCommand name cmdArgs '' + mkdir -p $out/bin; cd $out; ${(lib.concatMapStrings (x: "ln -s '${basicEnv}/bin/${x}' '${x}';\n") exes)} - ${(lib.concatMapStrings (s: "makeWrapper ${out}/bin/$(basename ${s}) $srcdir/${s} " + + ${(lib.concatMapStrings (s: "makeWrapper $out/bin/$(basename ${s}) $srcdir/${s} " + "--set BUNDLE_GEMFILE ${basicEnv.confFiles}/Gemfile "+ "--set BUNDLE_PATH ${basicEnv}/${ruby.gemPath} "+ "--set BUNDLE_FROZEN 1 "+ diff --git a/pkgs/development/tools/corundum/default.nix b/pkgs/development/tools/corundum/default.nix index 36f5bb06c349..53cb8e8f3b76 100644 --- a/pkgs/development/tools/corundum/default.nix +++ b/pkgs/development/tools/corundum/default.nix @@ -1,9 +1,11 @@ -{ rubyTool }: +{ lib, rubyTool }: rubyTool { name = "corundum-0.6.2"; gemdir = ./.; - meta = { + exes = [ "corundum-skel" ]; + + meta = with lib; { description = "Tool and libraries for maintaining Ruby gems."; homepage = http://sass-lang.com/; license = licenses.mit; -- cgit 1.4.1 From 603e84caefe2be319263ad6f83637af533834cc9 Mon Sep 17 00:00:00 2001 From: Judson Date: Sun, 25 Jun 2017 17:40:22 -0700 Subject: Fixing an overload of "pname" --- pkgs/development/ruby-modules/bundled-common/default.nix | 9 +++++---- pkgs/development/ruby-modules/bundled-common/functions.nix | 2 ++ pkgs/development/ruby-modules/bundler-env/default.nix | 2 +- pkgs/development/ruby-modules/tool/default.nix | 13 +++++++++++-- 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/pkgs/development/ruby-modules/bundled-common/default.nix b/pkgs/development/ruby-modules/bundled-common/default.nix index 2aea35844fe5..354353ffab11 100644 --- a/pkgs/development/ruby-modules/bundled-common/default.nix +++ b/pkgs/development/ruby-modules/bundled-common/default.nix @@ -7,6 +7,7 @@ { name , pname ? name +, mainGemName ? null , gemdir ? null , gemfile ? null , lockfile ? null @@ -44,13 +45,13 @@ let copyIfBundledByPath = { bundledByPath ? false, ...}@main: (if bundledByPath then - assert gemFiles.gemdir != nil; "cp -a ${gemFiles.gemdir}/* $out/" + assert gemFiles.gemdir != null; "cp -a ${gemFiles.gemdir}/* $out/" else "" ); - maybeCopyAll = pname: if pname == null then "" else + maybeCopyAll = pkgname: if pkgname == null then "" else let - mainGem = gems."${pname}" or (throw "bundlerEnv: gem ${pname} not found"); + mainGem = gems."${pkgname}" or (throw "bundlerEnv: gem ${pkgname} not found"); in copyIfBundledByPath mainGem; @@ -59,7 +60,7 @@ let # out. Yes, I'm serious. confFiles = runCommand "gemfile-and-lockfile" {} '' mkdir -p $out - ${maybeCopyAll pname} + ${maybeCopyAll mainGemName} cp ${gemFiles.gemfile} $out/Gemfile || ls -l $out/Gemfile cp ${gemFiles.lockfile} $out/Gemfile.lock || ls -l $out/Gemfile.lock ''; diff --git a/pkgs/development/ruby-modules/bundled-common/functions.nix b/pkgs/development/ruby-modules/bundled-common/functions.nix index 1d7c4878e13b..b17a4639e779 100644 --- a/pkgs/development/ruby-modules/bundled-common/functions.nix +++ b/pkgs/development/ruby-modules/bundled-common/functions.nix @@ -7,6 +7,8 @@ rec { , gemdir ? null , ... }: { + inherit gemdir; + gemfile = if gemfile == null then assert gemdir != null; gemdir + "/Gemfile" else gemfile; diff --git a/pkgs/development/ruby-modules/bundler-env/default.nix b/pkgs/development/ruby-modules/bundler-env/default.nix index a72647fb00a1..7d175cfeccb7 100644 --- a/pkgs/development/ruby-modules/bundler-env/default.nix +++ b/pkgs/development/ruby-modules/bundler-env/default.nix @@ -27,7 +27,7 @@ let else if pname != null then "${toString pname}-${basicEnv.gems."${pname}".version}" else throw "bundlerEnv: either pname or name must be set"; - basicEnv = (callPackage ../bundled-common {}) (args // { inherit pname name; }); + basicEnv = (callPackage ../bundled-common {}) (args // { inherit pname name; mainGemName = pname; }); inherit (basicEnv) envPaths; # Idea here is a mkDerivation that gen-bin-stubs new stubs "as specified" - diff --git a/pkgs/development/ruby-modules/tool/default.nix b/pkgs/development/ruby-modules/tool/default.nix index 9b8848592b2c..a5308b79ff3d 100644 --- a/pkgs/development/ruby-modules/tool/default.nix +++ b/pkgs/development/ruby-modules/tool/default.nix @@ -1,5 +1,14 @@ { lib, stdenv, callPackage, runCommand, ruby }@defs: +# Use for simple installation of Ruby tools shipped in a Gem. +# Start with a Gemfile that includes `gem ` +# > nix-shell -p bundler bundix +# (shell)> bundle lock +# (shell)> bundix +# Then use rubyTool in the default.nix: + +# rubyTool { name = "gemifiedTool"; gemdir = ./.; exes = ["gemified-tool"]; } +# The 'exes' parameter ensures that a copy of e.g. rake doesn't polute the system. { name # gemdir is the location of the Gemfile{,.lock} and gemset.nix; usually ./. @@ -25,8 +34,8 @@ let // { inherit preferLocalBuild allowSubstitutes; }; # pass the defaults in runCommand name cmdArgs '' - mkdir -p $out/bin; cd $out; - ${(lib.concatMapStrings (x: "ln -s '${basicEnv}/bin/${x}' '${x}';\n") exes)} + mkdir -p $out/bin; + ${(lib.concatMapStrings (x: "ln -s '${basicEnv}/bin/${x}' $out/bin/${x};\n") exes)} ${(lib.concatMapStrings (s: "makeWrapper $out/bin/$(basename ${s}) $srcdir/${s} " + "--set BUNDLE_GEMFILE ${basicEnv.confFiles}/Gemfile "+ "--set BUNDLE_PATH ${basicEnv}/${ruby.gemPath} "+ -- cgit 1.4.1 From 70e7e543c5493761cf065dc96ec8c8cbafe40aba Mon Sep 17 00:00:00 2001 From: Judson Date: Tue, 27 Jun 2017 10:56:36 -0700 Subject: A few cleanups and renames. One feature remains... --- .../ruby-modules/bundled-common/default.nix | 2 - .../ruby-modules/bundler-app/default.nix | 47 ++++++++++++++++++++++ pkgs/development/ruby-modules/tool/default.nix | 47 ---------------------- pkgs/development/tools/corundum/default.nix | 4 +- pkgs/top-level/all-packages.nix | 2 +- 5 files changed, 50 insertions(+), 52 deletions(-) create mode 100644 pkgs/development/ruby-modules/bundler-app/default.nix delete mode 100644 pkgs/development/ruby-modules/tool/default.nix diff --git a/pkgs/development/ruby-modules/bundled-common/default.nix b/pkgs/development/ruby-modules/bundled-common/default.nix index 354353ffab11..6e7bd7a898bd 100644 --- a/pkgs/development/ruby-modules/bundled-common/default.nix +++ b/pkgs/development/ruby-modules/bundled-common/default.nix @@ -82,8 +82,6 @@ let name = if name == null then pname else name; - #name = pname; - paths = envPaths; pathsToLink = [ "/lib" ]; diff --git a/pkgs/development/ruby-modules/bundler-app/default.nix b/pkgs/development/ruby-modules/bundler-app/default.nix new file mode 100644 index 000000000000..a5308b79ff3d --- /dev/null +++ b/pkgs/development/ruby-modules/bundler-app/default.nix @@ -0,0 +1,47 @@ +{ lib, stdenv, callPackage, runCommand, ruby }@defs: + +# Use for simple installation of Ruby tools shipped in a Gem. +# Start with a Gemfile that includes `gem ` +# > nix-shell -p bundler bundix +# (shell)> bundle lock +# (shell)> bundix +# Then use rubyTool in the default.nix: + +# rubyTool { name = "gemifiedTool"; gemdir = ./.; exes = ["gemified-tool"]; } +# The 'exes' parameter ensures that a copy of e.g. rake doesn't polute the system. +{ + name + # gemdir is the location of the Gemfile{,.lock} and gemset.nix; usually ./. +, gemdir + # Exes is the list of executables provided by the gems in the Gemfile +, exes ? [] + # Scripts are ruby programs depend on gems in the Gemfile (e.g. scripts/rails) +, scripts ? [] +, ruby ? defs.ruby +, gemfile ? null +, lockfile ? null +, gemset ? null +, preferLocalBuild ? false +, allowSubstitutes ? false +, meta ? {} +, postBuild ? "" +}@args: + +let + basicEnv = (callPackage ../bundled-common {}) args; + + cmdArgs = removeAttrs args [ "name" "postBuild" ] + // { inherit preferLocalBuild allowSubstitutes; }; # pass the defaults +in + runCommand name cmdArgs '' + mkdir -p $out/bin; + ${(lib.concatMapStrings (x: "ln -s '${basicEnv}/bin/${x}' $out/bin/${x};\n") exes)} + ${(lib.concatMapStrings (s: "makeWrapper $out/bin/$(basename ${s}) $srcdir/${s} " + + "--set BUNDLE_GEMFILE ${basicEnv.confFiles}/Gemfile "+ + "--set BUNDLE_PATH ${basicEnv}/${ruby.gemPath} "+ + "--set BUNDLE_FROZEN 1 "+ + "--set GEM_HOME ${basicEnv}/${ruby.gemPath} "+ + "--set GEM_PATH ${basicEnv}/${ruby.gemPath} "+ + "--run \"cd $srcdir\";\n") scripts)} + ${postBuild} + '' diff --git a/pkgs/development/ruby-modules/tool/default.nix b/pkgs/development/ruby-modules/tool/default.nix deleted file mode 100644 index a5308b79ff3d..000000000000 --- a/pkgs/development/ruby-modules/tool/default.nix +++ /dev/null @@ -1,47 +0,0 @@ -{ lib, stdenv, callPackage, runCommand, ruby }@defs: - -# Use for simple installation of Ruby tools shipped in a Gem. -# Start with a Gemfile that includes `gem ` -# > nix-shell -p bundler bundix -# (shell)> bundle lock -# (shell)> bundix -# Then use rubyTool in the default.nix: - -# rubyTool { name = "gemifiedTool"; gemdir = ./.; exes = ["gemified-tool"]; } -# The 'exes' parameter ensures that a copy of e.g. rake doesn't polute the system. -{ - name - # gemdir is the location of the Gemfile{,.lock} and gemset.nix; usually ./. -, gemdir - # Exes is the list of executables provided by the gems in the Gemfile -, exes ? [] - # Scripts are ruby programs depend on gems in the Gemfile (e.g. scripts/rails) -, scripts ? [] -, ruby ? defs.ruby -, gemfile ? null -, lockfile ? null -, gemset ? null -, preferLocalBuild ? false -, allowSubstitutes ? false -, meta ? {} -, postBuild ? "" -}@args: - -let - basicEnv = (callPackage ../bundled-common {}) args; - - cmdArgs = removeAttrs args [ "name" "postBuild" ] - // { inherit preferLocalBuild allowSubstitutes; }; # pass the defaults -in - runCommand name cmdArgs '' - mkdir -p $out/bin; - ${(lib.concatMapStrings (x: "ln -s '${basicEnv}/bin/${x}' $out/bin/${x};\n") exes)} - ${(lib.concatMapStrings (s: "makeWrapper $out/bin/$(basename ${s}) $srcdir/${s} " + - "--set BUNDLE_GEMFILE ${basicEnv.confFiles}/Gemfile "+ - "--set BUNDLE_PATH ${basicEnv}/${ruby.gemPath} "+ - "--set BUNDLE_FROZEN 1 "+ - "--set GEM_HOME ${basicEnv}/${ruby.gemPath} "+ - "--set GEM_PATH ${basicEnv}/${ruby.gemPath} "+ - "--run \"cd $srcdir\";\n") scripts)} - ${postBuild} - '' diff --git a/pkgs/development/tools/corundum/default.nix b/pkgs/development/tools/corundum/default.nix index 53cb8e8f3b76..b7c0006a7b51 100644 --- a/pkgs/development/tools/corundum/default.nix +++ b/pkgs/development/tools/corundum/default.nix @@ -1,7 +1,7 @@ { lib, rubyTool }: -rubyTool { - name = "corundum-0.6.2"; +bundlerApp { + pname = "corundum"; gemdir = ./.; exes = [ "corundum-skel" ]; diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 0686adaea5f1..e6c1d9e23301 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -6161,7 +6161,7 @@ with pkgs; bundix = callPackage ../development/ruby-modules/bundix { }; bundler = callPackage ../development/ruby-modules/bundler { }; bundlerEnv = callPackage ../development/ruby-modules/bundler-env { }; - rubyTool = callPackage ../development/ruby-modules/tool { }; + bundlerApp = callPackage ../development/ruby-modules/bundler-app { }; inherit (callPackage ../development/interpreters/ruby {}) ruby_2_0_0 -- cgit 1.4.1 From e149f0234451e6ac714492076e5796546a2b035b Mon Sep 17 00:00:00 2001 From: Judson Date: Tue, 27 Jun 2017 22:33:18 -0700 Subject: Using pname and fetching versions --- .../ruby-modules/bundled-common/default.nix | 24 ++++++++++++++++++---- .../ruby-modules/bundler-app/default.nix | 9 ++++---- .../ruby-modules/bundler-env/default.nix | 7 +------ pkgs/development/tools/corundum/default.nix | 2 +- 4 files changed, 27 insertions(+), 15 deletions(-) diff --git a/pkgs/development/ruby-modules/bundled-common/default.nix b/pkgs/development/ruby-modules/bundled-common/default.nix index 6e7bd7a898bd..09eb36a247a4 100644 --- a/pkgs/development/ruby-modules/bundled-common/default.nix +++ b/pkgs/development/ruby-modules/bundled-common/default.nix @@ -5,8 +5,8 @@ }@defs: { - name -, pname ? name + name ? null +, pname ? null , mainGemName ? null , gemdir ? null , gemfile ? null @@ -22,6 +22,8 @@ , ... }@args: +assert name == null -> pname != null; + with import ./functions.nix { inherit lib gemConfig; }; let @@ -43,6 +45,20 @@ let gems = lib.flip lib.mapAttrs configuredGemset (name: attrs: buildGem name attrs); + name' = if name != null then + name + else + let + gem = gems."${pname}"; + version = gem.version; + in + "${pname}-${version}"; + + pname' = if pname != null then + pname + else + name; + copyIfBundledByPath = { bundledByPath ? false, ...}@main: (if bundledByPath then assert gemFiles.gemdir != null; "cp -a ${gemFiles.gemdir}/* $out/" @@ -78,9 +94,9 @@ let envPaths = lib.attrValues gems ++ lib.optional (!hasBundler) bundler; basicEnv = buildEnv { - inherit ignoreCollisions; + inherit ignoreCollisions; - name = if name == null then pname else name; + name = name'; paths = envPaths; pathsToLink = [ "/lib" ]; diff --git a/pkgs/development/ruby-modules/bundler-app/default.nix b/pkgs/development/ruby-modules/bundler-app/default.nix index a5308b79ff3d..99d1dd64dc4f 100644 --- a/pkgs/development/ruby-modules/bundler-app/default.nix +++ b/pkgs/development/ruby-modules/bundler-app/default.nix @@ -7,10 +7,11 @@ # (shell)> bundix # Then use rubyTool in the default.nix: -# rubyTool { name = "gemifiedTool"; gemdir = ./.; exes = ["gemified-tool"]; } +# rubyTool { pname = "gemifiedTool"; gemdir = ./.; exes = ["gemified-tool"]; } # The 'exes' parameter ensures that a copy of e.g. rake doesn't polute the system. { - name + # use the name of the name in question; its version will be picked up from the gemset + pname # gemdir is the location of the Gemfile{,.lock} and gemset.nix; usually ./. , gemdir # Exes is the list of executables provided by the gems in the Gemfile @@ -30,10 +31,10 @@ let basicEnv = (callPackage ../bundled-common {}) args; - cmdArgs = removeAttrs args [ "name" "postBuild" ] + cmdArgs = removeAttrs args [ "pname" "postBuild" ] // { inherit preferLocalBuild allowSubstitutes; }; # pass the defaults in - runCommand name cmdArgs '' + runCommand basicEnv.name cmdArgs '' mkdir -p $out/bin; ${(lib.concatMapStrings (x: "ln -s '${basicEnv}/bin/${x}' $out/bin/${x};\n") exes)} ${(lib.concatMapStrings (s: "makeWrapper $out/bin/$(basename ${s}) $srcdir/${s} " + diff --git a/pkgs/development/ruby-modules/bundler-env/default.nix b/pkgs/development/ruby-modules/bundler-env/default.nix index 7d175cfeccb7..2e2653621a76 100644 --- a/pkgs/development/ruby-modules/bundler-env/default.nix +++ b/pkgs/development/ruby-modules/bundler-env/default.nix @@ -22,11 +22,6 @@ let inherit (import ../bundled-common/functions.nix {inherit lib ruby gemConfig groups; }) genStubsScript; - drvName = - if name != null then lib.traceVal name - else if pname != null then "${toString pname}-${basicEnv.gems."${pname}".version}" - else throw "bundlerEnv: either pname or name must be set"; - basicEnv = (callPackage ../bundled-common {}) (args // { inherit pname name; mainGemName = pname; }); inherit (basicEnv) envPaths; @@ -48,7 +43,7 @@ in (buildEnv { inherit ignoreCollisions; - name = drvName; + name = basicEnv.name; paths = envPaths; pathsToLink = [ "/lib" ]; diff --git a/pkgs/development/tools/corundum/default.nix b/pkgs/development/tools/corundum/default.nix index b7c0006a7b51..e149a25859ad 100644 --- a/pkgs/development/tools/corundum/default.nix +++ b/pkgs/development/tools/corundum/default.nix @@ -1,4 +1,4 @@ -{ lib, rubyTool }: +{ lib, bundlerApp }: bundlerApp { pname = "corundum"; -- cgit 1.4.1 From 0641253ae66d748b5ff0562c4edba3f9502a38e3 Mon Sep 17 00:00:00 2001 From: Judson Date: Sun, 2 Jul 2017 17:18:58 -0700 Subject: Small changes in response to review. --- pkgs/development/ruby-modules/bundled-common/default.nix | 2 +- pkgs/development/ruby-modules/runtests.sh | 2 +- pkgs/development/ruby-modules/testing/tap-support.nix | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pkgs/development/ruby-modules/bundled-common/default.nix b/pkgs/development/ruby-modules/bundled-common/default.nix index 09eb36a247a4..1bf6257f6559 100644 --- a/pkgs/development/ruby-modules/bundled-common/default.nix +++ b/pkgs/development/ruby-modules/bundled-common/default.nix @@ -140,7 +140,7 @@ let name = "${pname}-interactive-environment"; nativeBuildInputs = [ wrappedRuby basicEnv ]; shellHook = '' - export OLD_IRBRC="$IRBRC" + export OLD_IRBRC=$IRBRC export IRBRC=${irbrc} ''; buildCommand = '' diff --git a/pkgs/development/ruby-modules/runtests.sh b/pkgs/development/ruby-modules/runtests.sh index d0faaf971dba..8bb8c8a5462c 100755 --- a/pkgs/development/ruby-modules/runtests.sh +++ b/pkgs/development/ruby-modules/runtests.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash set -o xtrace -pwd +cd $(dirname $0) find . -name text.nix testfiles=$(find . -name test.nix) nix-build -E "with import {}; callPackage testing/driver.nix { testFiles = [ $testfiles ]; }" --show-trace && cat result diff --git a/pkgs/development/ruby-modules/testing/tap-support.nix b/pkgs/development/ruby-modules/testing/tap-support.nix index 555ce89d8332..74fcceebaa04 100644 --- a/pkgs/development/ruby-modules/testing/tap-support.nix +++ b/pkgs/development/ruby-modules/testing/tap-support.nix @@ -5,8 +5,8 @@ let testLine = report: "${okStr report} ${toString (report.index + 1)} ${report.description}" + testDirective report + testYaml report; # These are part of the TAP spec, not yet implemented. + #c.f. https://github.com/NixOS/nixpkgs/issues/27071 testDirective = report: ""; - testYaml = report: ""; okStr = { result, ...}: if result == "pass" then "ok" else "not ok"; -- cgit 1.4.1 From 728bb987ec4c3bcf7e43cb7b98db229ec52b93ed Mon Sep 17 00:00:00 2001 From: Judson Date: Sun, 2 Jul 2017 17:55:41 -0700 Subject: Adding docs for bundlerApp. --- doc/languages-frameworks/ruby.xml | 27 ++++++++++++++++++++++++--- pkgs/development/tools/corundum/default.nix | 2 +- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/doc/languages-frameworks/ruby.xml b/doc/languages-frameworks/ruby.xml index 3c6e4f5e01a4..6a14854b5c56 100644 --- a/doc/languages-frameworks/ruby.xml +++ b/doc/languages-frameworks/ruby.xml @@ -41,12 +41,34 @@ bundlerEnv rec { Please check in the Gemfile, Gemfile.lock and the gemset.nix so future updates can be run easily. -Resulting derivations also have two helpful items, env and wrapper. The first one allows one to quickly drop into +For tools written in Ruby - i.e. where the desire is to install a package and then execute e.g. rake at the command line, there is an alternative builder called bundlerApp. Set up the gemset.nix the same way, and then, for example: + + + + + +The chief advantage of bundlerApp over bundlerEnv is the the executables introduced in the environment are precisely those selected in the exes list, as opposed to bundlerEnv which adds all the executables made available by gems in the gemset, which can mean e.g. rspec or rake in unpredicable versions available from various packages. + +Resulting derivations for both builders also have two helpful items, env and wrapper. The first one allows one to quickly drop into nix-shell with the specified environment present. E.g. nix-shell -A sensu.env would give you an environment with Ruby preset so it has all the libraries necessary for sensu in its paths. The second one can be used to make derivations from custom Ruby scripts which have Gemfiles with their dependencies specified. It is a derivation with ruby wrapped so it can find all the needed dependencies. For example, to make a derivation my-script for a my-script.rb (which should be placed in bin) you should -run bundix as specified above and then use bundlerEnv lile this: +run bundix as specified above and then use bundlerEnv like this: - diff --git a/pkgs/development/tools/corundum/default.nix b/pkgs/development/tools/corundum/default.nix index e149a25859ad..22d7b236ffa4 100644 --- a/pkgs/development/tools/corundum/default.nix +++ b/pkgs/development/tools/corundum/default.nix @@ -7,7 +7,7 @@ bundlerApp { meta = with lib; { description = "Tool and libraries for maintaining Ruby gems."; - homepage = http://sass-lang.com/; + homepage = https://github.com/nyarly/corundum; license = licenses.mit; maintainers = [ maintainers.nyarly ]; platforms = platforms.unix; -- cgit 1.4.1 From 5142e8f2b2057ec02c59f4406019d41bebaff59f Mon Sep 17 00:00:00 2001 From: Judson Date: Wed, 5 Jul 2017 09:12:03 -0700 Subject: Grammar, spelling fixed. --- doc/languages-frameworks/ruby.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/languages-frameworks/ruby.xml b/doc/languages-frameworks/ruby.xml index 6a14854b5c56..eb1696ad2248 100644 --- a/doc/languages-frameworks/ruby.xml +++ b/doc/languages-frameworks/ruby.xml @@ -61,9 +61,9 @@ bundlerApp { }; }]]> -The chief advantage of bundlerApp over bundlerEnv is the the executables introduced in the environment are precisely those selected in the exes list, as opposed to bundlerEnv which adds all the executables made available by gems in the gemset, which can mean e.g. rspec or rake in unpredicable versions available from various packages. +The chief advantage of bundlerApp over bundlerEnv is the executables introduced in the environment are precisely those selected in the exes list, as opposed to bundlerEnv which adds all the executables made available by gems in the gemset, which can mean e.g. rspec or rake in unpredictable versions available from various packages. -Resulting derivations for both builders also have two helpful items, env and wrapper. The first one allows one to quickly drop into +Resulting derivations for both builders also have two helpful attributes, env and wrapper. The first one allows one to quickly drop into nix-shell with the specified environment present. E.g. nix-shell -A sensu.env would give you an environment with Ruby preset so it has all the libraries necessary for sensu in its paths. The second one can be used to make derivations from custom Ruby scripts which have Gemfiles with their dependencies specified. It is a derivation with ruby wrapped so it can find all the needed dependencies. -- cgit 1.4.1