push sheeet
Some checks failed
Periodic Merges (6h) / master → staging-nixos (push) Failing after 12m50s
Periodic Merges (6h) / master → staging-next (push) Failing after 12m54s
Periodic Merges (24h) / merge-base(master,staging) → haskell-updates (push) Failing after 11m54s
Periodic Merges (6h) / staging-next → staging (push) Failing after 12m13s
Periodic Merges (24h) / staging-next-25.05 → staging-25.05 (push) Failing after 13m24s
Periodic Merges (24h) / release-25.05 → staging-next-25.05 (push) Failing after 14m28s

This commit is contained in:
Dark Steveneq
2025-10-09 14:15:47 +02:00
commit 646b892680
49168 changed files with 5897842 additions and 0 deletions

View File

@@ -0,0 +1,256 @@
{
stdenv,
lib,
buildPackages,
runCommand,
ruby,
defaultGemConfig,
buildRubyGem,
buildEnv,
makeBinaryWrapper,
bundler,
}@defs:
{
name ? null,
pname ? null,
version ? null,
mainGemName ? null,
gemdir ? null,
gemfile ? null,
lockfile ? null,
gemset ? null,
ruby ? defs.ruby,
copyGemFiles ? false, # Copy gem files instead of symlinking
gemConfig ? defaultGemConfig,
postBuild ? null,
document ? [ ],
meta ? { },
groups ? null,
ignoreCollisions ? false,
nativeBuildInputs ? [ ],
buildInputs ? [ ],
extraConfigPaths ? [ ],
passthru ? { },
...
}@args:
assert name == null -> pname != null;
let
functions = import ./functions.nix { inherit lib gemConfig; };
inherit (functions)
applyGemConfigs
bundlerFiles
composeGemAttrs
filterGemset
genStubsScript
pathDerivation
;
gemFiles = bundlerFiles args;
importedGemset =
if builtins.typeOf gemFiles.gemset != "set" then import gemFiles.gemset else gemFiles.gemset;
filteredGemset = filterGemset { inherit ruby groups; } importedGemset;
configuredGemset = lib.flip lib.mapAttrs filteredGemset (
name: attrs:
applyGemConfigs (
attrs
// {
inherit ruby document;
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);
version' =
if version != null then
version
else if pname != null then
gems.${pname}.suffix
else
null;
name' = if name != null then name else "${pname}-${version'}";
pname' = if pname != null then pname else name;
copyIfBundledByPath =
{
bundledByPath ? false,
...
}:
(lib.optionalString bundledByPath (
assert gemFiles.gemdir != null;
"cp -a ${gemFiles.gemdir}/* $out/"
) # */
);
maybeCopyAll =
pkgname:
lib.optionalString (pkgname != null) (
let
mainGem = gems.${pkgname} or (throw "bundlerEnv: gem ${pkgname} 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 mainGemName}
cp ${gemFiles.gemfile} $out/Gemfile || ls -l $out/Gemfile
cp ${gemFiles.lockfile} $out/Gemfile.lock || ls -l $out/Gemfile.lock
${lib.concatMapStringsSep "\n" (path: "cp -r ${path} $out/") extraConfigPaths}
'';
buildGem =
name: attrs:
(
let
gemAttrs = composeGemAttrs ruby gems name attrs;
in
if gemAttrs.type == "path" then
pathDerivation (gemAttrs.source // gemAttrs)
else
buildRubyGem gemAttrs
);
envPaths = lib.attrValues gems ++ lib.optional (!hasBundler) bundler;
basicEnvArgs = {
inherit
nativeBuildInputs
buildInputs
ignoreCollisions
pname
;
name = name';
version = version';
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 = (
lib.optionalAttrs (pname != null) {
inherit (gems.${pname}) gemType;
}
// rec {
inherit
ruby
bundler
gems
confFiles
envPaths
;
wrappedRuby = stdenv.mkDerivation {
name = "wrapped-ruby-${pname'}";
nativeBuildInputs = [ makeBinaryWrapper ];
dontUnpack = true;
buildPhase = ''
mkdir -p $out/bin
for i in ${ruby}/bin/*; do
makeWrapper "$i" $out/bin/$(basename "$i") \
--set BUNDLE_GEMFILE ${confFiles}/Gemfile \
--unset BUNDLE_PATH \
--set BUNDLE_FROZEN 1 \
--set GEM_HOME ${basicEnv}/${ruby.gemPath} \
--set GEM_PATH ${basicEnv}/${ruby.gemPath}
done
'';
dontInstall = true;
doCheck = true;
checkPhase = ''
$out/bin/ruby --help > /dev/null
'';
inherit (ruby) meta;
};
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
'';
};
}
// passthru
);
};
basicEnv =
if copyGemFiles then
runCommand name' basicEnvArgs ''
mkdir -p $out
for i in $paths; do
${buildPackages.rsync}/bin/rsync -a $i/lib $out/
done
eval "$postBuild"
''
else
buildEnv basicEnvArgs;
in
basicEnv

View File

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

View File

@@ -0,0 +1,66 @@
#!/usr/bin/env ruby
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_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")
.force_encoding('UTF-8').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.delete 'BUNDLE_PATH'
ENV['BUNDLE_FROZEN'] = '1'
ENV['BUNDLE_IGNORE_CONFIG'] = '1'
Gem.paths = { 'GEM_HOME' => #{bundle_path.dump} }
$LOAD_PATH.unshift #{File.join(bundler_path, "/lib").dump}
require 'bundler'
# Monkey-patch out the check that Bundler performs to determine
# whether the bundler env is writable. It's not writable, even for
# root! And for this use of Bundler, it shouldn't be necessary since
# we're not trying to perform any package management operations, only
# produce a Gem path. Thus, we replace it with a method that will
# always return false, to squelch a warning from Bundler saying that
# sudo may be required.
module Bundler
class <<self
def requires_sudo?
return false
end
end
end
Bundler.setup(#{groups.map(&:dump).join(', ')})
load Gem.bin_path(#{name.dump}, #{exe.dump})
EOF
FileUtils.chmod("+x", "#{out}/bin/#{exe}")
end
end
end

View File

@@ -0,0 +1,140 @@
{
lib,
ruby,
defaultGemConfig,
test,
should,
}:
let
testConfigs = {
inherit lib;
gemConfig = defaultGemConfig;
};
functions = (import ./functions.nix testConfigs);
in
builtins.concatLists [
(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
)
)
(
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 == { }
)
)
]

View File

@@ -0,0 +1,105 @@
{
lib,
callPackage,
runCommand,
makeWrapper,
ruby,
}@defs:
# Use for simple installation of Ruby tools shipped in a Gem.
# Start with a Gemfile that includes `gem <toolgem>`
# > nix-shell -p bundler bundix
# (shell)> bundle lock
# (shell)> bundix
# Then use rubyTool in the default.nix:
# rubyTool { pname = "gemifiedTool"; gemdir = ./.; exes = ["gemified-tool"]; }
# The 'exes' parameter ensures that a copy of e.g. rake doesn't pollute the system.
{
# 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 ./.
# This is required unless gemfile, lockfile, and gemset are all provided
gemdir ? null,
# 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,
installManpages ? true,
meta ? { },
nativeBuildInputs ? [ ],
buildInputs ? [ ],
postBuild ? "",
gemConfig ? null,
passthru ? { },
}@args:
let
basicEnv =
(callPackage ../bundled-common {
inherit ruby;
})
args;
cmdArgs =
removeAttrs args [
"postBuild"
"gemConfig"
"passthru"
"gemset"
"gemdir"
]
// {
inherit preferLocalBuild allowSubstitutes; # pass the defaults
inherit (basicEnv) version;
nativeBuildInputs = nativeBuildInputs ++ lib.optionals (scripts != [ ]) [ makeWrapper ];
meta = {
mainProgram = pname;
inherit (ruby.meta) platforms;
}
// meta;
passthru =
basicEnv.passthru
// {
inherit basicEnv;
inherit (basicEnv) env;
}
// passthru;
};
in
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} "
+ "--set BUNDLE_GEMFILE ${basicEnv.confFiles}/Gemfile "
+ "--unset BUNDLE_PATH "
+ "--set BUNDLE_FROZEN 1 "
+ "--set GEM_HOME ${basicEnv}/${ruby.gemPath} "
+ "--set GEM_PATH ${basicEnv}/${ruby.gemPath} "
+ "--chdir \"$srcdir\";\n"
) scripts)
}
${lib.optionalString installManpages ''
for section in {1..9}; do
mandir="$out/share/man/man$section"
# See: https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/ruby-modules/gem/default.nix#L184-L200
# See: https://github.com/rubygems/rubygems/blob/7a7b234721c375874b7e22b1c5b14925b943f04e/bundler/lib/bundler.rb#L285-L291
find -L ${basicEnv}/${ruby.gemPath}/${
lib.optionalString (basicEnv.gemType == "git" || basicEnv.gemType == "url") "bundler/"
}gems/${basicEnv.name} \( -wholename "*/man/*.$section" -o -wholename "*/man/man$section/*.$section" \) -print -execdir mkdir -p $mandir \; -execdir cp '{}' $mandir \;
done
''}
''

View File

@@ -0,0 +1,113 @@
{
ruby,
lib,
callPackage,
defaultGemConfig,
buildEnv,
runCommand,
buildPackages,
bundler,
}@defs:
{
name ? null,
pname ? null,
gemdir ? null,
gemfile ? null,
lockfile ? null,
gemset ? null,
groups ? [ "default" ],
ruby ? defs.ruby,
copyGemFiles ? false, # Copy gem files instead of symlinking
gemConfig ? defaultGemConfig,
postBuild ? null,
document ? [ ],
meta ? { },
ignoreCollisions ? false,
passthru ? { },
...
}@args:
let
inherit
(import ../bundled-common/functions.nix {
inherit
lib
ruby
gemConfig
groups
;
})
genStubsScript
;
basicEnv = (callPackage ../bundled-common { inherit bundler; }) (
args
// {
inherit pname name;
mainGemName = pname;
}
);
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.
# When stubbing the bins for a gem, we should use the gem expression
# directly, which means that basicEnv should somehow make it available.
# Different use cases should use different variations on this file, rather
# than the expression trying to deduce a use case.
in
# The basicEnv should be put into passthru so that e.g. nix-shell can use it.
if pname == null then
basicEnv // { inherit name basicEnv; }
else
let
bundlerEnvArgs = {
inherit ignoreCollisions;
name = basicEnv.name;
paths = envPaths;
pathsToLink = [ "/lib" ];
postBuild =
genStubsScript {
inherit
lib
runCommand
ruby
bundler
groups
;
confFiles = basicEnv.confFiles;
binPaths = [ basicEnv.gems.${pname} ];
}
+ lib.optionalString (postBuild != null) postBuild;
meta = {
platforms = ruby.meta.platforms;
}
// meta;
passthru =
basicEnv.passthru
// {
inherit basicEnv;
inherit (basicEnv) env;
}
// passthru;
};
in
if copyGemFiles then
runCommand basicEnv.name bundlerEnvArgs ''
mkdir -p $out
for i in $paths; do
${buildPackages.rsync}/bin/rsync -a $i/lib $out/
done
eval "$postBuild"
''
else
buildEnv bundlerEnvArgs

View File

@@ -0,0 +1,41 @@
{
callPackage,
test,
stubs,
should,
}:
let
bundlerEnv = callPackage ./default.nix stubs // {
basicEnv = callPackage ../bundled-common stubs;
};
justName = bundlerEnv {
name = "test-0.1.2";
gemset = ./test/gemset.nix;
};
pnamed = bundlerEnv {
pname = "test";
gemdir = ./test;
gemset = ./test/gemset.nix;
gemfile = ./test/Gemfile;
lockfile = ./test/Gemfile.lock;
};
in
builtins.concatLists [
(test.run "bundlerEnv { name }" justName {
name = should.equal "test-0.1.2";
})
(test.run "bundlerEnv { pname }" pnamed [
(should.haveKeys [
"name"
"env"
"postBuild"
])
{
name = should.equal "test-0.1.2";
env = should.beASet;
postBuild = should.havePrefix "/nix/store";
}
])
]

View File

@@ -0,0 +1,10 @@
{
test = {
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "1j5r0anj8m4qlf2psnldip4b8ha2bsscv11lpdgnfh4nnchzjnxw";
type = "gem";
};
version = "0.1.2";
};
}

View File

@@ -0,0 +1,50 @@
{
runtimeShell,
lib,
writeScript,
bundix,
bundler,
coreutils,
git,
nix,
nixfmt,
}:
attrPath:
let
updateScript = writeScript "bundler-update-script" ''
#!${runtimeShell}
PATH=${
lib.makeBinPath [
bundler
bundix
coreutils
git
nix
nixfmt
]
}
set -o errexit
set -o nounset
set -o pipefail
attrPath=$1
toplevel=$(git rev-parse --show-toplevel)
position=$(nix --extra-experimental-features nix-command eval -f "$toplevel" --raw "$attrPath.meta.position")
gemdir=$(dirname "$position")
cd "$gemdir"
rm -f gemset.nix Gemfile.lock
export BUNDLE_FORCE_RUBY_PLATFORM=1
bundler lock --update
bundix
nixfmt gemset.nix
'';
in
[
updateScript
attrPath
]

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,48 @@
diff --git a/ext/fast_xs/fast_xs.c b/ext/fast_xs/fast_xs.c
index 11ef71f..d5eb8d8 100644
--- a/ext/fast_xs/fast_xs.c
+++ b/ext/fast_xs/fast_xs.c
@@ -144,7 +144,7 @@ static VALUE unpack_utf8(VALUE self)
return rb_funcall(self, unpack_id, 1, U_fmt);
}
-static VALUE unpack_uchar(VALUE self)
+static VALUE unpack_uchar(VALUE self, VALUE _exn)
{
return rb_funcall(self, unpack_id, 1, C_fmt);
}
diff --git a/ext/hpricot_scan/hpricot_scan.c b/ext/hpricot_scan/hpricot_scan.c
index f11cbb5..161ebd4 100644
--- a/ext/hpricot_scan/hpricot_scan.c
+++ b/ext/hpricot_scan/hpricot_scan.c
@@ -22,7 +22,7 @@ struct hpricot_struct {
#define RSTRING_PTR(str) RSTRING(str)->ptr
#endif
-VALUE hpricot_css(VALUE, VALUE, VALUE, VALUE, VALUE);
+VALUE hpricot_css(VALUE, VALUE, VALUE, VALUE);
#define NO_WAY_SERIOUSLY "*** This should not happen, please file a bug report with the HTML you're parsing at http://github.com/hpricot/hpricot/issues. So sorry!"
diff --git a/ext/hpricot_scan/hpricot_scan.rl b/ext/hpricot_scan/hpricot_scan.rl
index 0f17f11..8b00a38 100644
--- a/ext/hpricot_scan/hpricot_scan.rl
+++ b/ext/hpricot_scan/hpricot_scan.rl
@@ -20,7 +20,7 @@ struct hpricot_struct {
#define RSTRING_PTR(str) RSTRING(str)->ptr
#endif
-VALUE hpricot_css(VALUE, VALUE, VALUE, VALUE, VALUE);
+VALUE hpricot_css(VALUE, VALUE, VALUE, VALUE);
#define NO_WAY_SERIOUSLY "*** This should not happen, please file a bug report with the HTML you're parsing at http://github.com/hpricot/hpricot/issues. So sorry!"
@@ -806,7 +806,7 @@ make_hpricot_struct(VALUE members, VALUE (*alloc)(VALUE klass))
for (i = 0; i < len; i++) {
ID id = SYM2ID(rb_ary_entry(members, i));
const char* name = rb_id2name(id);
- int len = strlen(name);
+ size_t len = strlen(name);
memcpy(attr_set, name, strlen(name));
attr_set[len] = '=';

View File

@@ -0,0 +1,14 @@
diff --git a/ext/extconf.rb b/ext/extconf.rb
index 30764cb..b87ac2b 100644
--- a/ext/extconf.rb
+++ b/ext/extconf.rb
@@ -46,4 +46,9 @@ if /mswin/.match RbConfig::CONFIG['host_os']
$defs.push("-Dinline=__inline")
end
+$srcs = %w[
+ rdiscount.c
+]
+have_library('markdown')
+
create_makefile('rdiscount')

View File

@@ -0,0 +1,33 @@
# encoding: utf-8
# Install the xapian binaries into the lib folder of the gem
require 'rbconfig'
c = RbConfig::CONFIG
source_dir = 'xapian_source'
bindings = Dir["#{source_dir}/xapian-bindings-*"].first
bindings = File.basename(bindings, ".tar.xz")
task :default do
sh "tar -xJf #{source_dir}/#{bindings}.tar.xz"
prefix = Dir.pwd
ENV['LDFLAGS'] = "-L#{prefix}/lib"
sh "mkdir -p lib"
Dir.chdir bindings do
ENV['RUBY'] ||= "#{c['bindir']}/#{c['RUBY_INSTALL_NAME']}"
sh "./configure --prefix=#{prefix} --exec-prefix=#{prefix} --with-ruby"
sh "make clean all"
end
sh "cp -r #{bindings}/ruby/.libs/_xapian.* lib"
sh "cp #{bindings}/ruby/xapian.rb lib"
sh "rm lib/*.la"
sh "rm lib/*.lai"
sh "rm -R #{bindings}"
sh "rm -R #{source_dir}"
end

View File

@@ -0,0 +1,307 @@
# This builds gems in a way that is compatible with bundler.
#
# Bundler installs gems from git sources _very_ differently from how RubyGems
# installs gem packages, though they both install gem packages similarly.
#
# We monkey-patch Bundler to remove any impurities and then drive its internals
# to install git gems.
#
# For the sake of simplicity, gem packages are installed with the standard `gem`
# program.
#
# Note that bundler does not support multiple prefixes; it assumes that all
# gems are installed in a common prefix, and has no support for specifying
# otherwise. Therefore, if you want to be able to use the resulting derivations
# with bundler, you need to create a symlink forrest first, which is what
# `bundlerEnv` does for you.
#
# Normal gem packages can be used outside of bundler; a binstub is created in
# $out/bin.
{
lib,
fetchurl,
fetchgit,
makeWrapper,
gitMinimal,
ruby,
bundler,
}@defs:
lib.makeOverridable (
{
name ? null,
gemName,
version ? null,
type ? "gem",
document ? [ ], # e.g. [ "ri" "rdoc" ]
platform ? "ruby",
ruby ? defs.ruby,
stdenv ? ruby.stdenv,
namePrefix ? (
let
rubyName = builtins.parseDrvName ruby.name;
in
"${rubyName.name}${lib.versions.majorMinor rubyName.version}-"
),
nativeBuildInputs ? [ ],
buildInputs ? [ ],
meta ? { },
patches ? [ ],
gemPath ? [ ],
dontStrip ? false,
# Assume we don't have to build unless strictly necessary (e.g. the source is a
# git checkout).
# If you need to apply patches, make sure to set `dontBuild = false`;
dontBuild ? true,
dontInstallManpages ? false,
propagatedBuildInputs ? [ ],
propagatedUserEnvPkgs ? [ ],
buildFlags ? [ ],
passthru ? { },
# bundler expects gems to be stored in the cache directory for certain actions
# such as `bundler install --redownload`.
# At the cost of increasing the store size, you can keep the gems to have closer
# alignment with what Bundler expects.
keepGemCache ? false,
...
}@attrs:
let
src =
attrs.src or (
if type == "gem" then
fetchurl {
urls = map (remote: "${remote}/gems/${gemName}-${suffix}.gem") (
attrs.source.remotes or [ "https://rubygems.org" ]
);
inherit (attrs.source) sha256;
}
else if type == "git" then
fetchgit {
inherit (attrs.source)
url
rev
sha256
fetchSubmodules
;
}
else if type == "url" then
fetchurl attrs.source
else
throw "buildRubyGem: don't know how to build a gem of type \"${type}\""
);
# See: https://github.com/rubygems/rubygems/blob/7a7b234721c375874b7e22b1c5b14925b943f04e/bundler/lib/bundler/source/git.rb#L103
suffix =
if type == "git" then
builtins.substring 0 12 attrs.source.rev
else if platform != "ruby" then
"${version}-${platform}"
else
version;
documentFlag = if document == [ ] then "-N" else "--document ${lib.concatStringsSep "," document}";
in
stdenv.mkDerivation (
(removeAttrs attrs [ "source" ])
// {
inherit ruby;
inherit dontBuild;
inherit dontStrip;
inherit suffix;
gemType = type;
nativeBuildInputs = [
ruby
makeWrapper
]
++ lib.optionals (type == "git") [ gitMinimal ]
++ lib.optionals (type != "gem") [ bundler ]
++ nativeBuildInputs;
buildInputs = [
ruby
]
++ buildInputs;
#name = builtins.trace (attrs.name or "no attr.name" ) "${namePrefix}${gemName}-${version}";
name = attrs.name or "${namePrefix}${gemName}-${suffix}";
inherit src;
unpackPhase =
attrs.unpackPhase or ''
runHook preUnpack
if [[ -f $src && $src == *.gem ]]; then
if [[ -z "''${dontBuild-}" ]]; then
# we won't know the name of the directory that RubyGems creates,
# so we'll just use a glob to find it and move it over.
gempkg="$src"
sourceRoot=source
gem unpack $gempkg --target=container
cp -r container/* $sourceRoot
rm -r container
# copy out the original gemspec, for convenience during patching /
# overrides.
gem specification $gempkg --ruby > original.gemspec
gemspec=$(readlink -f .)/original.gemspec
else
gempkg="$src"
fi
else
# Fall back to the original thing for everything else.
dontBuild=""
preUnpack="" postUnpack="" unpackPhase
fi
runHook postUnpack
'';
# As of ruby 3.0, ruby headers require -fdeclspec when building with clang
# Introduced in https://github.com/ruby/ruby/commit/0958e19ffb047781fe1506760c7cbd8d7fe74e57
env = lib.optionalAttrs (attrs ? env) attrs.env // {
NIX_CFLAGS_COMPILE = toString (
lib.optionals
(ruby.rubyEngine == "ruby" && stdenv.cc.isClang && lib.versionAtLeast ruby.version.major "3")
[
"-fdeclspec"
]
++ lib.optional (attrs.env.NIX_CFLAGS_COMPILE or "" != "") attrs.env.NIX_CFLAGS_COMPILE
);
};
buildPhase =
attrs.buildPhase or ''
runHook preBuild
if [[ "$gemType" == "gem" ]]; then
if [[ -z "$gemspec" ]]; then
gemspec="$(find . -name '*.gemspec')"
echo "found the following gemspecs:"
echo "$gemspec"
gemspec="$(echo "$gemspec" | head -n1)"
fi
exec 3>&1
output="$(gem build $gemspec | tee >(cat - >&3))"
exec 3>&-
gempkg=$(echo "$output" | grep -oP 'File: \K(.*)')
echo "gem package built: $gempkg"
elif [[ "$gemType" == "git" ]]; then
git init
# remove variations to improve the likelihood of a bit-reproducible output
rm -rf .git/logs/ .git/hooks/ .git/index .git/FETCH_HEAD .git/ORIG_HEAD .git/refs/remotes/origin/HEAD .git/config
# support `git ls-files`
git add .
fi
runHook postBuild
'';
# Note:
# We really do need to keep the $out/${ruby.gemPath}/cache.
# This is very important in order for many parts of RubyGems/Bundler to not blow up.
# See https://github.com/bundler/bundler/issues/3327
installPhase =
attrs.installPhase or ''
runHook preInstall
export GEM_HOME=$out/${ruby.gemPath}
mkdir -p $GEM_HOME
echo "buildFlags: $buildFlags"
${lib.optionalString (type == "url") ''
ruby ${./nix-bundle-install.rb} \
"path" \
'${gemName}' \
'${version}' \
'${lib.escapeShellArgs buildFlags}'
''}
${lib.optionalString (type == "git") ''
ruby ${./nix-bundle-install.rb} \
"git" \
'${gemName}' \
'${version}' \
'${lib.escapeShellArgs buildFlags}' \
'${attrs.source.url}' \
'.' \
'${attrs.source.rev}'
''}
${lib.optionalString (type == "gem") ''
if [[ -z "$gempkg" ]]; then
echo "failure: \$gempkg path unspecified" 1>&2
exit 1
elif [[ ! -f "$gempkg" ]]; then
echo "failure: \$gempkg path invalid" 1>&2
exit 1
fi
gem install \
--local \
--force \
--http-proxy 'http://nodtd.invalid' \
--ignore-dependencies \
--install-dir "$GEM_HOME" \
--build-root '/' \
--backtrace \
--no-env-shebang \
${documentFlag} \
$gempkg $gemFlags -- $buildFlags
# looks like useless files which break build repeatability and consume space
pushd $out/${ruby.gemPath}
find doc/ -iname created.rid -delete -print
find gems/*/ext/ extensions/ \( -iname Makefile -o -iname mkmf.log -o -iname gem_make.out \) -delete -print
${lib.optionalString (!keepGemCache) "rm -fvr cache"}
popd
# write out metadata and binstubs
spec=$(echo $out/${ruby.gemPath}/specifications/*.gemspec)
ruby ${./gem-post-build.rb} "$spec"
''}
${lib.optionalString (!dontInstallManpages) ''
for section in {1..9}; do
mandir="$out/share/man/man$section"
find $out/lib \( -wholename "*/man/*.$section" -o -wholename "*/man/man$section/*.$section" \) \
-execdir mkdir -p $mandir \; -execdir cp '{}' $mandir \;
done
''}
# For Ruby-generated binstubs, shebang paths are already in Nix store but for
# ruby used to build the package. Update them to match the host system. Note
# that patchShebangsAuto ignores scripts where shebang line is already in Nix
# store.
if [[ -d $GEM_HOME/bin ]]; then
patchShebangs --update --host -- "$GEM_HOME"/bin
fi
runHook postInstall
'';
propagatedBuildInputs = gemPath ++ propagatedBuildInputs;
propagatedUserEnvPkgs = gemPath ++ propagatedUserEnvPkgs;
passthru = passthru // {
isRubyGem = true;
};
meta = {
# default to Ruby's platforms
platforms = ruby.meta.platforms;
mainProgram = gemName;
}
// meta;
}
)
)

View File

@@ -0,0 +1,81 @@
require 'rbconfig'
require 'rubygems'
require 'rubygems/specification'
require 'fileutils'
ruby = File.join(ENV["ruby"], "bin", RbConfig::CONFIG['ruby_install_name'])
out = ENV["out"]
bin_path = File.join(ENV["out"], "bin")
gem_home = ENV["GEM_HOME"]
gem_path = ENV["GEM_PATH"].split(File::PATH_SEPARATOR).uniq
install_path = Dir.glob("#{gem_home}/gems/*").first
gemspec_path = ARGV[0]
if defined?(Encoding.default_internal)
Encoding.default_internal = Encoding::UTF_8
Encoding.default_external = Encoding::UTF_8
end
gemspec_content = File.read(gemspec_path)
spec = nil
if gemspec_content[0..2] == "---" # YAML header
spec = Gem::Specification.from_yaml(gemspec_content)
else
spec = Gem::Specification.load(gemspec_path)
end
FileUtils.mkdir_p("#{out}/nix-support")
# write meta-data
meta = "#{out}/nix-support/gem-meta"
FileUtils.mkdir_p(meta)
FileUtils.ln_s(gemspec_path, "#{meta}/spec")
File.open("#{meta}/name", "w") do |f|
f.write(spec.name)
end
File.open("#{meta}/install-path", "w") do |f|
f.write(install_path)
end
File.open("#{meta}/require-paths", "w") do |f|
f.write(spec.require_paths.join(" "))
end
File.open("#{meta}/executables", "w") do |f|
f.write(spec.executables.join(" "))
end
# add this gem to the GEM_PATH for dependencies
File.open("#{out}/nix-support/setup-hook", "a") do |f|
f.puts("addToSearchPath GEM_PATH #{gem_home}")
spec.require_paths.each do |dir|
f.puts("addToSearchPath RUBYLIB #{install_path}/#{dir}")
end
end
# create regular rubygems binstubs
FileUtils.mkdir_p(bin_path)
spec.executables.each do |exe|
File.open("#{bin_path}/#{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.
#
require 'rubygems'
Gem.paths = {
'GEM_PATH' => (
ENV['GEM_PATH'].to_s.split(File::PATH_SEPARATOR) +
#{([gem_home] + gem_path).to_s}
).join(File::PATH_SEPARATOR)
}
load Gem.activate_bin_path(#{spec.name.inspect}, #{exe.inspect}, #{spec.version.to_s.inspect})
EOF
end
FileUtils.chmod("+x", "#{bin_path}/#{exe}")
end

View File

@@ -0,0 +1,181 @@
require 'rbconfig'
require 'bundler/vendored_thor'
require 'bundler'
require 'rubygems/command'
require 'fileutils'
require 'pathname'
require 'tmpdir'
require 'shellwords'
if defined?(Encoding.default_internal)
Encoding.default_internal = Encoding::UTF_8
Encoding.default_external = Encoding::UTF_8
end
# Options:
#
# type - installation type, either "git" or "path"
# name - the gem name
# version - gem version
# build-flags - build arguments
#
# Git-only options:
#
# uri - git repo uri
# repo - path to local checkout
# ref - the commit hash
ruby = File.join(ENV["ruby"], "bin", RbConfig::CONFIG['ruby_install_name'])
out = ENV["out"]
bin_dir = File.join(ENV["out"], "bin")
type = ARGV[0]
name = ARGV[1]
version = ARGV[2]
build_flags = Shellwords.split(ARGV[3])
if type == "git"
uri = ARGV[4]
REPO = ARGV[5]
ref = ARGV[6]
end
# options to pass to bundler
options = {
"name" => name,
"version" => version,
}
if type == "path"
options.merge!({
"path" => Dir.pwd,
})
elsif type == "git"
options.merge!({
"uri" => uri,
"ref" => ref,
})
end
# Monkey-patch Bundler to use our local checkout.
# I wish we didn't have to do this, but bundler does not expose an API to do
# these kinds of things.
Bundler.module_eval do
def self.requires_sudo?
false
end
def self.root
# we don't have a Gemfile, so it doesn't make sense to try to make paths
# relative to the (non existent) parent directory thereof, so we give a
# nonsense path here.
Pathname.new("/no-root-path")
end
def self.bundle_path
Pathname.new(ENV["GEM_HOME"])
end
def self.locked_gems
nil
end
end
if type == "git"
Bundler::Source::Git.class_eval do
def allow_git_ops?
true
end
end
Bundler::Source::Git::GitProxy.class_eval do
def checkout
unless path.exist?
FileUtils.mkdir_p(path.dirname)
FileUtils.cp_r(File.join(REPO, ".git"), path)
system("chmod -R +w #{path}")
end
end
def copy_to(destination, submodules=false)
unless File.exist?(destination.join(".git"))
FileUtils.mkdir_p(destination.dirname)
FileUtils.cp_r(REPO, destination)
system("chmod -R +w #{destination}")
end
end
end
end
# UI
verbose = false
no_color = false
Bundler.ui = Bundler::UI::Shell.new({"no-color" => no_color})
Bundler.ui.level = "debug" if verbose
# Install
if type == "git"
source = Bundler::Source::Git.new(options)
else
source = Bundler::Source::Path.new(options)
end
spec = source.specs.search_all(name).first
source.install(spec, :build_args => build_flags)
msg = spec.post_install_message
if msg
Bundler.ui.confirm "Post-install message from #{name}:"
Bundler.ui.info msg
end
# Write out the binstubs
if spec.executables.any?
FileUtils.mkdir_p(bin_dir)
spec.executables.each do |exe|
wrapper = File.join(bin_dir, exe)
File.open(wrapper, "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.
#
require 'rubygems'
require 'bundler/setup'
load Gem.bin_path(#{spec.name.inspect}, #{exe.inspect})
EOF
end
FileUtils.chmod("+x", wrapper)
end
end
# Write out metadata
meta = "#{out}/nix-support/gem-meta"
FileUtils.mkdir_p(meta)
FileUtils.ln_s(spec.loaded_from.to_s, "#{meta}/spec")
File.open("#{meta}/name", "w") do |f|
f.write spec.name
end
if type == "git"
File.open("#{meta}/install-path", "w") do |f|
f.write source.install_path.to_s
end
end
File.open("#{meta}/require-paths", "w") do |f|
f.write spec.require_paths.join(" ")
end
File.open("#{meta}/executables", "w") do |f|
f.write spec.executables.join(" ")
end
# make the lib available during bundler/git installs
if type == "git"
File.open("#{out}/nix-support/setup-hook", "a") do |f|
spec.require_paths.each do |dir|
f.puts("addToSearchPath RUBYLIB #{source.install_path}/#{dir}")
end
end
end

View File

@@ -0,0 +1,6 @@
#!/usr/bin/env bash
set -o xtrace
cd $(dirname $0)
find . -name text.nix
testfiles=$(find . -name test.nix)
nix-build -E "with import <nixpkgs> {}; callPackage testing/driver.nix { testFiles = [ $testfiles ]; }" --show-trace && cat result

View File

@@ -0,0 +1,34 @@
{ test, lib, ... }:
{
equal =
expected: actual:
if actual == expected then
(test.passed "= ${toString expected}")
else
(test.failed (
"expected '${toString expected}'(${builtins.typeOf expected})"
+ " != "
+ "actual '${toString actual}'(${builtins.typeOf actual})"
));
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}] actual: [${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}'");
}

View File

@@ -0,0 +1,26 @@
/*
Run with:
nix-build -E 'with import <nixpkgs> { }; 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,
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)

View File

@@ -0,0 +1,56 @@
{
stdenv,
lib,
ruby,
callPackage,
...
}:
let
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.hostPlatform.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';
}

View File

@@ -0,0 +1,29 @@
with builtins;
let
withIndexes = list: genList (idx: (elemAt list idx) // { index = idx; }) (length list);
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";
in
{
output =
reports:
''
TAP version 13
1..${toString (length reports)}''
+ (foldl' (l: r: l + "\n" + r) "" (map testLine (withIndexes reports)))
+ ''
# Finished at ${toString currentTime}
'';
}

View File

@@ -0,0 +1,73 @@
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 "<MISSING!>") (
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;
}

View File

@@ -0,0 +1,167 @@
source 'https://rubygems.org'
gem 'addressable'
gem 'ansi'
gem 'atk'
gem 'awesome_print'
gem 'bacon'
# gem 'bundler' already got a package for that
gem 'byebug'
gem 'cairo'
gem 'cairo-gobject'
gem 'camping', '~> 3'
# gem 'capybara-webkit' takes too long to build right now since webkit depends on ruby
gem 'charlock_holmes'
gem 'cf-uaac'
gem 'cld3'
gem 'cocoapods'
gem 'cocoapods-acknowledgements'
gem 'cocoapods-art'
gem 'cocoapods-browser'
gem 'cocoapods-clean'
gem 'cocoapods-clean_build_phases_scripts'
gem 'cocoapods-coverage'
gem 'cocoapods-deintegrate'
gem 'cocoapods-dependencies'
gem 'cocoapods-deploy'
gem 'cocoapods-downloader'
gem 'cocoapods-expert-difficulty'
gem 'cocoapods-fix-react-native'
gem 'cocoapods-generate'
gem 'cocoapods-git_url_rewriter'
gem 'cocoapods-keys'
gem 'cocoapods-open'
gem 'cocoapods-plugins'
gem 'cocoapods-search'
gem 'cocoapods-testing'
gem 'cocoapods-trunk'
gem 'cocoapods-try'
gem 'cocoapods-try-release-fix'
gem 'cocoapods-update-if-you-dare'
gem 'cocoapods-whitelist'
gem 'cocoapods-wholemodule'
gem 'coderay'
gem 'concurrent-ruby'
gem 'curb'
gem 'curses'
gem 'daemons'
gem 'dep-selector-libgecode'
gem 'digest-sha3'
gem 'dip'
gem 'domain_name'
gem 'do_sqlite3'
gem 'erb-formatter'
gem 'ethon'
gem 'eventmachine'
gem 'excon'
gem 'faraday'
gem 'ffi'
gem 'ffi-rzmq-core'
gem 'fog-dnsimple'
gem 'gdk_pixbuf2'
gem 'gettext'
gem 'gio2'
gem 'git'
gem 'github-pages'
gem 'gitlab-markup'
gem 'glib2'
# gem 'gobject-introspection' fails on require
gem 'gpgme'
# gem 'grpc' fails to build
gem 'gtk3'
gem 'hashie'
gem 'highline'
gem 'hike'
gem 'hitimes'
gem 'hpricot'
gem 'httpclient'
gem 'http-cookie'
gem 'iconv'
gem 'idn-ruby'
gem 'jbuilder'
gem 'jekyll'
gem 'jekyll-archives'
gem 'jekyll-favicon'
gem 'jekyll-spaceship'
gem 'jekyll-webmention_io'
gem 'jmespath'
gem 'jwt'
gem 'kramdown-rfc2629'
gem 'libxml-ruby'
gem 'mail'
gem 'magic'
gem 'markaby'
gem 'method_source'
gem 'mini_magick'
gem 'msgpack'
gem 'mysql2'
# gem 'mysql' deprecated
gem 'ncursesw'
gem 'netrc'
gem 'net-scp'
gem 'net-ssh'
gem 'nokogiri'
gem 'opus-ruby'
gem 'ovirt-engine-sdk'
gem 'pandocomatic'
gem 'pango'
gem 'patron'
gem 'pcaprub'
gem 'pg'
gem 'prettier'
gem 'pry'
gem 'pry-byebug'
gem 'pry-doc'
gem 'public_suffix'
gem 'puma'
gem 'pwntools'
gem 'rails', '~> 8'
gem 'rainbow'
# gem 'rbczmq' deprecated
gem 'rbnacl'
gem 'rb-readline'
gem 're2'
gem 'redis'
gem 'redis-rack'
gem 'rest-client'
gem 'rmagick'
gem 'rpam2'
gem 'rspec'
gem 'rubocop'
gem 'rubocop-performance'
gem 'ruby-libvirt'
gem 'ruby-lsp'
gem 'ruby-lxc'
gem 'ruby-progressbar'
gem 'ruby-terminfo'
gem 'ruby-vips'
gem 'rubyzip', '~>3'
gem 'rugged'
gem 'sassc'
gem 'scrypt'
gem 'seccomp-tools'
gem 'semian'
gem 'sequel'
gem 'sequel_pg'
gem 'simplecov'
gem 'sinatra'
gem 'slop'
gem 'snappy'
gem 'solargraph'
gem 'snmp'
gem 'sqlite3'
gem 'standard'
gem 'taglib-ruby'
gem 'thrift'
gem 'tilt'
gem 'tiny_tds'
gem 'treetop'
gem 'tty-command'
gem 'tty-option'
gem 'typhoeus'
gem 'tzinfo'
gem 'unf_ext'
gem 'uuid4r'
gem 'whois'
# gem 'xapian-ruby' doesn't contain ruby code
gem 'zookeeper'

View File

@@ -0,0 +1,104 @@
{
stdenv,
lib,
buildEnv,
buildRubyGem,
ruby,
gemConfig,
makeBinaryWrapper,
}:
/*
Example usage:
nix-shell -E "(import <nixpkgs> {}).ruby.withPackages (pkgs: with pkgs; [ pry nokogiri ])"
You can also use this for writing ruby scripts that run anywhere that has nix
using a nix-shell shebang:
#!/usr/bin/env nix-shell
#!nix-shell -i ruby -p "ruby.withPackages (pkgs: with pkgs; [ pry nokogiri ])"
Run the following in the nixpkgs root directory to update the ruby-packages.nix:
./maintainers/scripts/update-ruby-packages
*/
let
functions = import ../bundled-common/functions.nix { inherit lib gemConfig; };
buildGems =
gemset:
let
realGemset = if builtins.isAttrs gemset then gemset else import gemset;
builtGems = lib.mapAttrs (
name: initialAttrs:
let
attrs = functions.applyGemConfigs (
{
inherit ruby;
gemName = name;
}
// initialAttrs
);
in
buildRubyGem (functions.composeGemAttrs ruby builtGems name attrs)
) realGemset;
in
builtGems;
gems = buildGems (import ../../../top-level/ruby-packages.nix);
withPackages =
selector:
let
selected = selector gems;
gemEnv = buildEnv {
name = "ruby-gems";
paths = selected;
pathsToLink = [
"/lib"
"/bin"
"/nix-support"
];
};
wrappedRuby = stdenv.mkDerivation {
name = "wrapped-${ruby.name}";
nativeBuildInputs = [ makeBinaryWrapper ];
buildCommand = ''
mkdir -p $out/bin
for i in ${ruby}/bin/*; do
makeWrapper "$i" $out/bin/$(basename "$i") --set GEM_PATH ${gemEnv}/${ruby.gemPath}
done
'';
};
in
stdenv.mkDerivation {
name = "${ruby.name}-with-packages";
nativeBuildInputs = [ makeBinaryWrapper ];
buildInputs = [
selected
ruby
];
dontUnpack = true;
installPhase = ''
for i in ${ruby}/bin/* ${gemEnv}/bin/*; do
rm -f $out/bin/$(basename "$i")
makeWrapper "$i" $out/bin/$(basename "$i") --set GEM_PATH ${gemEnv}/${ruby.gemPath}
done
ln -s ${ruby}/nix-support $out/nix-support
'';
passthru = {
inherit wrappedRuby;
gems = selected;
};
};
in
{
inherit withPackages gems buildGems;
}

View File

@@ -0,0 +1,99 @@
let
cocoapod-plugin = name: ''
require "cocoapods"
require "#{Gem::Specification.find_by_name(%(${name})).gem_dir}/lib/cocoapods_plugin"
'';
in
{
actioncable = [ "action_cable" ];
actionmailer = [ "action_mailer" ];
actionpack = [ "action_pack" ];
actionview = [ "action_view" ];
activejob = [ "active_job" ];
activemodel = [ "active_model" ];
activerecord = [ "active_record" ];
activestorage = [ "active_storage" ];
activesupport = [ "active_support" ];
atk = [ "atk" ];
CFPropertyList = [ "cfpropertylist" ];
cocoapods-acknowledgements = [
"cocoapods"
"cocoapods_acknowledgements"
];
cocoapods-art = [ "cocoapods_art" ];
cocoapods-browser = [
"cocoapods"
"cocoapods_plugin"
];
cocoapods-bugsnag = cocoapod-plugin "cocoapods-bugsnag";
cocoapods-clean = [ "cocoapods_clean" ];
cocoapods-coverage = [ "cocoapods_coverage" ];
cocoapods-deintegrate = [ ]; # used by cocoapods
cocoapods-dependencies = [ "cocoapods_dependencies" ];
cocoapods-deploy = cocoapod-plugin "cocoapods-deploy";
cocoapods-generate = cocoapod-plugin "cocoapods-generate";
cocoapods-git_url_rewriter = cocoapod-plugin "cocoapods-git_url_rewriter";
cocoapods-keys = [ ]; # osx only cocoapod-plugin "cocoapods-keys";
cocoapods-open = [
"cocoapods"
"cocoapods_plugin"
];
cocoapods-packager = [ "cocoapods_packager" ];
cocoapods-packager-pro = [ ]; # requires osx
cocoapods-plugins = [ "cocoapods_plugins" ];
cocoapods-sorted-search = [ ]; # requires osx
cocoapods-check = cocoapod-plugin "cocoapods-check";
cocoapods-disable-podfile-validations = cocoapod-plugin "cocoapods-disable-podfile-validations";
cocoapods-stats = [ "cocoapods_stats" ];
cocoapods-testing = [ "cocoapods_testing" ];
cocoapods-trunk = [ "cocoapods_trunk" ];
cocoapods-try = [ "cocoapods_try" ];
cocoapods-try-release-fix = cocoapod-plugin "cocoapods-try-release-fix";
digest-sha3 = [ "digest/sha3" ];
ffi-compiler = [ "ffi-compiler/loader" ];
fog-core = [ "fog/core" ];
fog-dnsimple = [ "fog/dnsimple" ];
fog-json = [ "fog/json" ];
forwardable-extended = [ "forwardable/extended" ];
gdk_pixbuf2 = [ "gdk_pixbuf2" ];
gitlab-markup = [ "github/markup" ];
gobject-introspection = [ "gobject-introspection" ];
gtk2 = [ ]; # requires display
idn-ruby = [ "idn" ];
jekyll-sass-converter = [ ]; # tested through jekyll
libxml-ruby = [ "libxml" ];
multipart-post = [ "multipart_post" ];
unicode-display_width = [ "unicode/display_width" ];
nap = [ "rest" ];
net-scp = [ "net/scp" ];
net-ssh = [ "net/ssh" ];
nio4r = [ "nio" ];
osx_keychain = [ ]; # requires osx
ovirt-engine-sdk = [ "ovirtsdk4" ];
pango = [ "pango" ];
rack-test = [ "rack/test" ];
railties = [ "rails" ];
rspec-core = [ "rspec/core" ];
rspec-expectations = [ "rspec/expectations" ];
rspec-mocks = [ "rspec/mocks" ];
rspec-support = [ "rspec/support" ];
RubyInline = [ "inline" ];
ruby-libvirt = [ "libvirt" ];
ruby-lxc = [ "lxc" ];
ruby-macho = [ "macho" ];
ruby-terminfo = [ "terminfo" ];
rubyzip = [ "zip" ];
sequel_pg = [
"pg"
"sequel"
"sequel/adapters/postgresql"
"sequel_pg"
];
simplecov-html = [ ]; # tested through simplecov
sinatra = [ "sinatra/base" ];
sprockets-rails = [ "sprockets/rails" ];
taglib-ruby = [ "taglib" ];
websocket-driver = [ "websocket/driver" ];
websocket-extensions = [ "websocket/extensions" ];
ZenTest = [ "zentest" ];
}

View File

@@ -0,0 +1,66 @@
# a generic test suite for all gems for all ruby versions.
# use via nix-build.
let
pkgs = import ../../../.. { };
lib = pkgs.lib;
stdenv = pkgs.stdenv;
rubyVersions = with pkgs; [
ruby_3_2
];
gemTests = (lib.mapAttrs (name: gem: [ name ]) pkgs.ruby.gems) // (import ./require_exceptions.nix);
testWrapper =
ruby:
stdenv.mkDerivation {
name = "test-wrappedRuby-${ruby.name}";
buildInputs = [ ((ruby.withPackages (ps: [ ])).wrappedRuby) ];
buildCommand = ''
cat <<'EOF' > test-ruby
#!/usr/bin/env ruby
puts RUBY_VERSION
EOF
chmod +x test-ruby
patchShebangs test-ruby
[[ $(./test-ruby) = $(${ruby}/bin/ruby test-ruby) ]]
touch $out
'';
};
tests =
ruby:
lib.mapAttrs (
name: gem:
let
test =
if builtins.isList gemTests.${name} then
pkgs.writeText "${name}.rb" ''
puts "${name} GEM_HOME: #{ENV['GEM_HOME']}"
${lib.concatStringsSep "\n" (map (n: "require '${n}'") gemTests.${name})}
''
else
pkgs.writeText "${name}.rb" gemTests.${name};
deps = ruby.withPackages (g: [ g.${name} ]);
in
stdenv.mkDerivation {
name = "test-gem-${ruby.name}-${name}";
buildInputs = [ deps ];
buildCommand = ''
INLINEDIR=$PWD ruby ${test}
touch $out
'';
}
) ruby.gems;
in
stdenv.mkDerivation {
name = "test-all-ruby-gems";
buildInputs = builtins.foldl' (
sum: ruby: sum ++ [ (testWrapper ruby) ] ++ (builtins.attrValues (tests ruby))
) [ ] rubyVersions;
buildCommand = ''
touch $out
'';
}

View File

@@ -0,0 +1,76 @@
#!/usr/bin/env ruby
# this is a quick and dirty test suite for easier analyzing of breakages in a
# manual testing.
# For automated testing use the test.nix
require 'fileutils'
class FakeGemfile
attr_reader :gems
def initialize
@gems = []
end
def source(_source, &block)
instance_exec(&block)
end
def gem(name)
@gems << name
end
end
gemfile = File.expand_path(File.join(__dir__, 'Gemfile'))
packages = FakeGemfile.new.instance_eval(File.read(gemfile), gemfile)
test_cases = packages.map { |pkg| [pkg, "require '#{pkg}'"] }.to_h
test_cases.merge!(
'digest-sha3' => "require 'digest/sha3'",
'gitlab-markup' => "require 'github/markup'",
'idn-ruby' => "require 'idn'",
'net-scp' => "require 'net/scp'",
'taglib-ruby' => "require 'taglib'",
'net-ssh' => "require 'net/ssh'",
'ruby-libvirt' => "require 'libvirt'",
'ruby-lxc' => "require 'lxc'",
'rubyzip' => "require 'zip'",
'sinatra' => "require 'sinatra/base'",
'libxml-ruby' => "require 'libxml'",
'ruby-terminfo' => "require 'terminfo'",
'ovirt-engine-sdk' => "require 'ovirtsdk4'",
'fog-dnsimple' => "require 'fog/dnsimple'"
)
test_cases['sequel_pg'] = <<~TEST
require 'pg'
require 'sequel'
require 'sequel/adapters/postgresql'
require 'sequel_pg'
TEST
tmpdir = File.expand_path(File.join(__dir__, 'tests'))
FileUtils.rm_rf(tmpdir)
FileUtils.mkdir_p(tmpdir)
failing = test_cases.reject do |name, test_case|
test_case = <<~SHELL
#!/usr/bin/env nix-shell
#!nix-shell -i ruby -E "(import ../../../.. {}).ruby.withPackages (r: [ r.#{name} ] )"
#{test_case}
SHELL
file = File.join(tmpdir, "#{name}_test.rb")
File.write(file, test_case)
FileUtils.chmod('u=wrx', file)
system(file) && FileUtils.rm(file)
end
exit if failing.empty?
puts "Following gems failed: #{failing.keys.join(' ')}"
puts "tests for failing gems remain in #{tmpdir}"
exit 1