3
0
Fork 0
forked from mirrors/nixpkgs

redmine: refactor, cleanup, bug fix, and add functionality

- added package option to specify which version of redmine
- added themes option back in to allow specifying redmine themes
- added plugins option back in to allow specifying redmine plugins
- added database.socket option to allow mysql unix socket authentication
- added port option to allow specifying the port rails runs on

- cleaned up Gemfile so it is much less hacky
- switched to ruby version 2.4 by default as suggested by documentation http://www.redmine.org/projects/redmine/wiki/redmineinstall#Installing-Redmine
- fixed an annoyance (bug) in the service causing recursive symlinks
- fixed ownership bug on log files generated by redmine
- updates reflecting renames in nixos options

- added a nixos test
This commit is contained in:
Aaron Andersen 2018-10-10 21:04:08 -04:00
parent e7334bc6e9
commit 1cb5b509f1
7 changed files with 384 additions and 82 deletions

View file

@ -5,7 +5,7 @@ with lib;
let let
cfg = config.services.redmine; cfg = config.services.redmine;
bundle = "${pkgs.redmine}/share/redmine/bin/bundle"; bundle = "${cfg.package}/share/redmine/bin/bundle";
databaseYml = pkgs.writeText "database.yml" '' databaseYml = pkgs.writeText "database.yml" ''
production: production:
@ -15,6 +15,7 @@ let
port: ${toString cfg.database.port} port: ${toString cfg.database.port}
username: ${cfg.database.user} username: ${cfg.database.user}
password: #dbpass# password: #dbpass#
${optionalString (cfg.database.socket != null) "socket: ${cfg.database.socket}"}
''; '';
configurationYml = pkgs.writeText "configuration.yml" '' configurationYml = pkgs.writeText "configuration.yml" ''
@ -29,6 +30,19 @@ let
${cfg.extraConfig} ${cfg.extraConfig}
''; '';
unpackTheme = unpack "theme";
unpackPlugin = unpack "plugin";
unpack = id: (name: source:
pkgs.stdenv.mkDerivation {
name = "redmine-${id}-${name}";
buildInputs = [ pkgs.unzip ];
buildCommand = ''
mkdir -p $out
cd $out
unpackFile ${source}
'';
});
in in
{ {
@ -40,6 +54,14 @@ in
description = "Enable the Redmine service."; description = "Enable the Redmine service.";
}; };
package = mkOption {
type = types.package;
default = pkgs.redmine;
defaultText = "pkgs.redmine";
description = "Which Redmine package to use.";
example = "pkgs.redmine.override { ruby = pkgs.ruby_2_3; }";
};
user = mkOption { user = mkOption {
type = types.str; type = types.str;
default = "redmine"; default = "redmine";
@ -52,6 +74,12 @@ in
description = "Group under which Redmine is ran."; description = "Group under which Redmine is ran.";
}; };
port = mkOption {
type = types.int;
default = 3000;
description = "Port on which Redmine is ran.";
};
stateDir = mkOption { stateDir = mkOption {
type = types.str; type = types.str;
default = "/var/lib/redmine"; default = "/var/lib/redmine";
@ -66,6 +94,41 @@ in
See https://guides.rubyonrails.org/action_mailer_basics.html#action-mailer-configuration See https://guides.rubyonrails.org/action_mailer_basics.html#action-mailer-configuration
''; '';
example = literalExample ''
email_delivery:
delivery_method: smtp
smtp_settings:
address: mail.example.com
port: 25
'';
};
themes = mkOption {
type = types.attrsOf types.path;
default = {};
description = "Set of themes.";
example = literalExample ''
{
dkuk-redmine_alex_skin = builtins.fetchurl {
url = https://bitbucket.org/dkuk/redmine_alex_skin/get/1842ef675ef3.zip;
sha256 = "0hrin9lzyi50k4w2bd2b30vrf1i4fi1c0gyas5801wn8i7kpm9yl";
};
}
'';
};
plugins = mkOption {
type = types.attrsOf types.path;
default = {};
description = "Set of plugins.";
example = literalExample ''
{
redmine_env_auth = builtins.fetchurl {
url = https://github.com/Intera/redmine_env_auth/archive/0.6.zip;
sha256 = "0yyr1yjd8gvvh832wdc8m3xfnhhxzk2pk3gm2psg5w9jdvd6skak";
};
}
'';
}; };
database = { database = {
@ -78,7 +141,7 @@ in
host = mkOption { host = mkOption {
type = types.str; type = types.str;
default = "127.0.0.1"; default = (if cfg.database.socket != null then "localhost" else "127.0.0.1");
description = "Database host address."; description = "Database host address.";
}; };
@ -119,6 +182,13 @@ in
<option>database.user</option>. <option>database.user</option>.
''; '';
}; };
socket = mkOption {
type = types.nullOr types.path;
default = null;
example = "/run/mysqld/mysqld.sock";
description = "Path to the unix socket file to use for authentication.";
};
}; };
}; };
}; };
@ -126,17 +196,20 @@ in
config = mkIf cfg.enable { config = mkIf cfg.enable {
assertions = [ assertions = [
{ assertion = cfg.database.passwordFile != null || cfg.database.password != ""; { assertion = cfg.database.passwordFile != null || cfg.database.password != "" || cfg.database.socket != null;
message = "either services.redmine.database.passwordFile or services.redmine.database.password must be set"; message = "one of services.redmine.database.socket, services.redmine.database.passwordFile, or services.redmine.database.password must be set";
}
{ assertion = cfg.database.socket != null -> (cfg.database.type == "mysql2");
message = "Socket authentication is only available for the mysql2 database type";
} }
]; ];
environment.systemPackages = [ pkgs.redmine ]; environment.systemPackages = [ cfg.package ];
systemd.services.redmine = { systemd.services.redmine = {
after = [ "network.target" (if cfg.database.type == "mysql2" then "mysql.service" else "postgresql.service") ]; after = [ "network.target" (if cfg.database.type == "mysql2" then "mysql.service" else "postgresql.service") ];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
environment.HOME = "${pkgs.redmine}/share/redmine"; environment.HOME = "${cfg.package}/share/redmine";
environment.RAILS_ENV = "production"; environment.RAILS_ENV = "production";
environment.RAILS_CACHE = "${cfg.stateDir}/cache"; environment.RAILS_CACHE = "${cfg.stateDir}/cache";
environment.REDMINE_LANG = "en"; environment.REDMINE_LANG = "en";
@ -151,43 +224,80 @@ in
subversion subversion
]; ];
preStart = '' preStart = ''
# start with a fresh config directory every time # ensure cache directory exists for db:migrate command
rm -rf ${cfg.stateDir}/config mkdir -p ${cfg.stateDir}/cache
cp -r ${pkgs.redmine}/share/redmine/config.dist ${cfg.stateDir}/config
# create the basic state directory layout pkgs.redmine expects # create the basic directory layout the redmine package expects
mkdir -p /run/redmine mkdir -p /run/redmine/public
for i in config files log plugins tmp; do for i in config files log plugins tmp; do
mkdir -p ${cfg.stateDir}/$i mkdir -p ${cfg.stateDir}/$i
ln -fs ${cfg.stateDir}/$i /run/redmine/$i ln -fs ${cfg.stateDir}/$i /run/redmine/
done done
# ensure cache directory exists for db:migrate command for i in plugin_assets themes; do
mkdir -p ${cfg.stateDir}/cache mkdir -p ${cfg.stateDir}/public/$i
ln -fs ${cfg.stateDir}/public/$i /run/redmine/public/
done
# start with a fresh config directory
# the config directory is copied instead of linked as some mutable data is stored in there
rm -rf ${cfg.stateDir}/config/*
cp -r ${cfg.package}/share/redmine/config.dist/* ${cfg.stateDir}/config/
# link in the application configuration # link in the application configuration
ln -fs ${configurationYml} ${cfg.stateDir}/config/configuration.yml ln -fs ${configurationYml} ${cfg.stateDir}/config/configuration.yml
# link in all user specified themes
rm -rf ${cfg.stateDir}/public/themes/*
for theme in ${concatStringsSep " " (mapAttrsToList unpackTheme cfg.themes)}; do
ln -fs $theme/* ${cfg.stateDir}/public/themes/
done
# link in redmine provided themes
ln -sf ${cfg.package}/share/redmine/public/themes.dist/* ${cfg.stateDir}/public/themes/
# link in all user specified plugins
rm -rf ${cfg.stateDir}/plugins/*
for plugin in ${concatStringsSep " " (mapAttrsToList unpackPlugin cfg.plugins)}; do
ln -fs $plugin/* ${cfg.stateDir}/plugins/''${plugin##*-redmine-plugin-}
done
# ensure correct permissions for most files
chmod -R ug+rwX,o-rwx+x ${cfg.stateDir}/ chmod -R ug+rwX,o-rwx+x ${cfg.stateDir}/
# handle database.passwordFile
# handle database.passwordFile & permissions
DBPASS=$(head -n1 ${cfg.database.passwordFile}) DBPASS=$(head -n1 ${cfg.database.passwordFile})
cp -f ${databaseYml} ${cfg.stateDir}/config/database.yml cp -f ${databaseYml} ${cfg.stateDir}/config/database.yml
sed -e "s,#dbpass#,$DBPASS,g" -i ${cfg.stateDir}/config/database.yml sed -e "s,#dbpass#,$DBPASS,g" -i ${cfg.stateDir}/config/database.yml
chmod 440 ${cfg.stateDir}/config/database.yml chmod 440 ${cfg.stateDir}/config/database.yml
# generate a secret token if required # generate a secret token if required
if ! test -e "${cfg.stateDir}/config/initializers/secret_token.rb"; then if ! test -e "${cfg.stateDir}/config/initializers/secret_token.rb"; then
${bundle} exec rake generate_secret_token ${bundle} exec rake generate_secret_token
chmod 440 ${cfg.stateDir}/config/initializers/secret_token.rb chmod 440 ${cfg.stateDir}/config/initializers/secret_token.rb
fi fi
# ensure everything is owned by ${cfg.user} # ensure everything is owned by ${cfg.user}
chown -R ${cfg.user}:${cfg.group} ${cfg.stateDir} chown -R ${cfg.user}:${cfg.group} ${cfg.stateDir}
${bundle} exec rake db:migrate
${bundle} exec rake redmine:load_default_data # execute redmine required commands prior to starting the application
# NOTE: su required in case using mysql socket authentication
/run/wrappers/bin/su -s ${pkgs.bash}/bin/bash -m -l redmine -c '${bundle} exec rake db:migrate'
/run/wrappers/bin/su -s ${pkgs.bash}/bin/bash -m -l redmine -c '${bundle} exec rake redmine:load_default_data'
# log files don't exist until after first command has been executed
# correct ownership of files generated by calling exec rake ...
chown -R ${cfg.user}:${cfg.group} ${cfg.stateDir}/log
''; '';
serviceConfig = { serviceConfig = {
@ -196,13 +306,13 @@ in
User = cfg.user; User = cfg.user;
Group = cfg.group; Group = cfg.group;
TimeoutSec = "300"; TimeoutSec = "300";
WorkingDirectory = "${pkgs.redmine}/share/redmine"; WorkingDirectory = "${cfg.package}/share/redmine";
ExecStart="${bundle} exec rails server webrick -e production -P ${cfg.stateDir}/redmine.pid"; ExecStart="${bundle} exec rails server webrick -e production -p ${toString cfg.port} -P ${cfg.stateDir}/redmine.pid";
}; };
}; };
users.extraUsers = optionalAttrs (cfg.user == "redmine") (singleton users.users = optionalAttrs (cfg.user == "redmine") (singleton
{ name = "redmine"; { name = "redmine";
group = cfg.group; group = cfg.group;
home = cfg.stateDir; home = cfg.stateDir;
@ -210,7 +320,7 @@ in
uid = config.ids.uids.redmine; uid = config.ids.uids.redmine;
}); });
users.extraGroups = optionalAttrs (cfg.group == "redmine") (singleton users.groups = optionalAttrs (cfg.group == "redmine") (singleton
{ name = "redmine"; { name = "redmine";
gid = config.ids.gids.redmine; gid = config.ids.gids.redmine;
}); });

40
nixos/tests/redmine.nix Normal file
View file

@ -0,0 +1,40 @@
import ./make-test.nix ({ pkgs, lib, ... }:
{
name = "redmine";
meta.maintainers = [ lib.maintainers.aanderse ];
machine =
{ config, pkgs, ... }:
{ services.mysql.enable = true;
services.mysql.package = pkgs.mariadb;
services.mysql.ensureDatabases = [ "redmine" ];
services.mysql.ensureUsers = [
{ name = "redmine";
ensurePermissions = { "redmine.*" = "ALL PRIVILEGES"; };
}
];
services.redmine.enable = true;
services.redmine.database.socket = "/run/mysqld/mysqld.sock";
services.redmine.plugins = {
redmine_env_auth = builtins.fetchurl {
url = https://github.com/Intera/redmine_env_auth/archive/0.6.zip;
sha256 = "0yyr1yjd8gvvh832wdc8m3xfnhhxzk2pk3gm2psg5w9jdvd6skak";
};
};
services.redmine.themes = {
dkuk-redmine_alex_skin = builtins.fetchurl {
url = https://bitbucket.org/dkuk/redmine_alex_skin/get/1842ef675ef3.zip;
sha256 = "0hrin9lzyi50k4w2bd2b30vrf1i4fi1c0gyas5801wn8i7kpm9yl";
};
};
};
testScript = ''
startAll;
$machine->waitForUnit('redmine.service');
$machine->waitForOpenPort('3000');
$machine->succeed("curl --fail http://localhost:3000/");
'';
})

View file

@ -54,60 +54,26 @@ platforms :mri, :mingw, :x64_mingw do
end end
end end
# Include database gems for the adapters found in the database # Include database gems for the database adapters NixOS supports
# configuration file
require 'erb'
require 'yaml'
# NixOS - manually added to ensure mysql and postgres will always be include
gem "mysql2", "~> 0.4.6", :platforms => [:mri, :mingw, :x64_mingw] gem "mysql2", "~> 0.4.6", :platforms => [:mri, :mingw, :x64_mingw]
gem "pg", "~> 0.18.1", :platforms => [:mri, :mingw, :x64_mingw] gem "pg", "~> 0.18.1", :platforms => [:mri, :mingw, :x64_mingw]
database_file = File.join(File.dirname(__FILE__), "config/database.yml") group :development do
if File.exist?(database_file) gem "rdoc", "~> 4.3"
database_config = YAML::load(ERB.new(IO.read(database_file)).result) gem "yard"
adapters = database_config.values.map {|c| c['adapter']}.compact.uniq
if adapters.any?
adapters.each do |adapter|
case adapter
when 'mysql2'
gem "mysql2", "~> 0.4.6", :platforms => [:mri, :mingw, :x64_mingw]
when /postgresql/
gem "pg", "~> 0.18.1", :platforms => [:mri, :mingw, :x64_mingw]
when /sqlite3/
gem "sqlite3", (RUBY_VERSION < "2.0" && RUBY_PLATFORM =~ /mingw/ ? "1.3.12" : "~>1.3.12"),
:platforms => [:mri, :mingw, :x64_mingw]
when /sqlserver/
gem "tiny_tds", (RUBY_VERSION >= "2.0" ? "~> 1.0.5" : "~> 0.7.0"), :platforms => [:mri, :mingw, :x64_mingw]
gem "activerecord-sqlserver-adapter", :platforms => [:mri, :mingw, :x64_mingw]
else
warn("Unknown database adapter `#{adapter}` found in config/database.yml, use Gemfile.local to load your own database gems")
end
end
else
warn("No adapter found in config/database.yml, please configure it first")
end
else
warn("Please configure your config/database.yml first")
end end
# NixOS - manually removed because I couldn't figure out how to get "bundle exec rails server webrick -e production" to ignore these groups group :test do
#group :development do gem "minitest"
# gem "rdoc", "~> 4.3" gem "rails-dom-testing"
# gem "yard" gem "mocha"
#end gem "simplecov", "~> 0.9.1", :require => false
# TODO: remove this after upgrading to Rails 5
#group :test do gem "test_after_commit", "~> 0.4.2"
# gem "minitest" # For running UI tests
# gem "rails-dom-testing" gem "capybara"
# gem "mocha" gem "selenium-webdriver", "~> 2.53.4"
# gem "simplecov", "~> 0.9.1", :require => false end
# # TODO: remove this after upgrading to Rails 5
# gem "test_after_commit", "~> 0.4.2"
# # For running UI tests
# gem "capybara"
# gem "selenium-webdriver", "~> 2.53.4"
#end
local_gemfile = File.join(File.dirname(__FILE__), "Gemfile.local") local_gemfile = File.join(File.dirname(__FILE__), "Gemfile.local")
if File.exists?(local_gemfile) if File.exists?(local_gemfile)

View file

@ -41,12 +41,23 @@ GEM
public_suffix (>= 2.0.2, < 4.0) public_suffix (>= 2.0.2, < 4.0)
arel (6.0.4) arel (6.0.4)
builder (3.2.3) builder (3.2.3)
capybara (3.9.0)
addressable
mini_mime (>= 0.1.3)
nokogiri (~> 1.8)
rack (>= 1.6.0)
rack-test (>= 0.6.3)
xpath (~> 3.1)
childprocess (0.9.0)
ffi (~> 1.0, >= 1.0.11)
coderay (1.1.2) coderay (1.1.2)
concurrent-ruby (1.0.5) concurrent-ruby (1.0.5)
crass (1.0.4) crass (1.0.4)
css_parser (1.6.0) css_parser (1.6.0)
addressable addressable
docile (1.1.5)
erubis (2.7.0) erubis (2.7.0)
ffi (1.9.25)
globalid (0.4.1) globalid (0.4.1)
activesupport (>= 4.2.0) activesupport (>= 4.2.0)
htmlentities (4.3.4) htmlentities (4.3.4)
@ -59,15 +70,20 @@ GEM
nokogiri (>= 1.5.9) nokogiri (>= 1.5.9)
mail (2.6.6) mail (2.6.6)
mime-types (>= 1.16, < 4) mime-types (>= 1.16, < 4)
metaclass (0.0.4)
mime-types (3.2.2) mime-types (3.2.2)
mime-types-data (~> 3.2015) mime-types-data (~> 3.2015)
mime-types-data (3.2018.0812) mime-types-data (3.2018.0812)
mimemagic (0.3.2) mimemagic (0.3.2)
mini_mime (1.0.1)
mini_portile2 (2.3.0) mini_portile2 (2.3.0)
minitest (5.11.3) minitest (5.11.3)
mocha (1.7.0)
metaclass (~> 0.0.1)
multi_json (1.13.1)
mysql2 (0.4.10) mysql2 (0.4.10)
net-ldap (0.12.1) net-ldap (0.12.1)
nokogiri (1.8.4) nokogiri (1.8.5)
mini_portile2 (~> 2.3.0) mini_portile2 (~> 2.3.0)
pg (0.18.4) pg (0.18.4)
protected_attributes (1.1.4) protected_attributes (1.1.4)
@ -104,10 +120,11 @@ GEM
rake (>= 0.8.7) rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0) thor (>= 0.18.1, < 2.0)
rake (12.3.1) rake (12.3.1)
rbpdf (1.19.5) rbpdf (1.19.6)
htmlentities htmlentities
rbpdf-font (~> 1.19.0) rbpdf-font (~> 1.19.0)
rbpdf-font (1.19.1) rbpdf-font (1.19.1)
rdoc (4.3.0)
redcarpet (3.4.0) redcarpet (3.4.0)
request_store (1.0.5) request_store (1.0.5)
rmagick (2.16.0) rmagick (2.16.0)
@ -118,6 +135,16 @@ GEM
railties (>= 3.0, < 5.1) railties (>= 3.0, < 5.1)
roadie (~> 3.1) roadie (~> 3.1)
ruby-openid (2.3.0) ruby-openid (2.3.0)
rubyzip (1.2.2)
selenium-webdriver (2.53.4)
childprocess (~> 0.5)
rubyzip (~> 1.0)
websocket (~> 1.0)
simplecov (0.9.2)
docile (~> 1.1.0)
multi_json (~> 1.0)
simplecov-html (~> 0.9.0)
simplecov-html (0.9.0)
sprockets (3.7.2) sprockets (3.7.2)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
rack (> 1, < 3) rack (> 1, < 3)
@ -125,22 +152,31 @@ GEM
actionpack (>= 4.0) actionpack (>= 4.0)
activesupport (>= 4.0) activesupport (>= 4.0)
sprockets (>= 3.0.0) sprockets (>= 3.0.0)
test_after_commit (0.4.2)
activerecord (>= 3.2)
thor (0.20.0) thor (0.20.0)
thread_safe (0.3.6) thread_safe (0.3.6)
tzinfo (1.2.5) tzinfo (1.2.5)
thread_safe (~> 0.1) thread_safe (~> 0.1)
websocket (1.2.8)
xpath (3.1.0)
nokogiri (~> 1.8)
yard (0.9.16)
PLATFORMS PLATFORMS
ruby ruby
DEPENDENCIES DEPENDENCIES
actionpack-xml_parser actionpack-xml_parser
capybara
coderay (~> 1.1.1) coderay (~> 1.1.1)
i18n (~> 0.7.0) i18n (~> 0.7.0)
jquery-rails (~> 3.1.4) jquery-rails (~> 3.1.4)
mail (~> 2.6.4) mail (~> 2.6.4)
mime-types (~> 3.0) mime-types (~> 3.0)
mimemagic mimemagic
minitest
mocha
mysql2 (~> 0.4.6) mysql2 (~> 0.4.6)
net-ldap (~> 0.12.0) net-ldap (~> 0.12.0)
nokogiri (~> 1.8.1) nokogiri (~> 1.8.1)
@ -148,15 +184,21 @@ DEPENDENCIES
protected_attributes protected_attributes
rack-openid rack-openid
rails (= 4.2.8) rails (= 4.2.8)
rails-dom-testing
rails-html-sanitizer (>= 1.0.3) rails-html-sanitizer (>= 1.0.3)
rbpdf (~> 1.19.3) rbpdf (~> 1.19.3)
rdoc (~> 4.3)
redcarpet (~> 3.4.0) redcarpet (~> 3.4.0)
request_store (= 1.0.5) request_store (= 1.0.5)
rmagick (>= 2.14.0) rmagick (>= 2.14.0)
roadie (~> 3.2.1) roadie (~> 3.2.1)
roadie-rails (~> 1.1.1) roadie-rails (~> 1.1.1)
ruby-openid (~> 2.3.0) ruby-openid (~> 2.3.0)
selenium-webdriver (~> 2.53.4)
simplecov (~> 0.9.1)
test_after_commit (~> 0.4.2)
tzinfo-data tzinfo-data
yard
BUNDLED WITH BUNDLED WITH
1.16.1 1.16.3

View file

@ -7,6 +7,7 @@ let
inherit ruby; inherit ruby;
gemdir = ./.; gemdir = ./.;
groups = [ "ldap" "openid" ];
}; };
in in
stdenv.mkDerivation rec { stdenv.mkDerivation rec {
@ -21,15 +22,15 @@ in
buildPhase = '' buildPhase = ''
mv config config.dist mv config config.dist
mv public/themes public/themes.dist
''; '';
installPhase = '' installPhase = ''
mkdir -p $out/share mkdir -p $out/share
cp -r . $out/share/redmine cp -r . $out/share/redmine
for i in config files log plugins public/plugin_assets public/themes tmp; do
for i in config files log plugins tmp; do
rm -rf $out/share/redmine/$i rm -rf $out/share/redmine/$i
ln -fs /run/redmine/$i $out/share/redmine/ ln -fs /run/redmine/$i $out/share/redmine/$i
done done
''; '';
@ -39,4 +40,4 @@ in
maintainers = [ maintainers.garbas ]; maintainers = [ maintainers.garbas ];
license = licenses.gpl2; license = licenses.gpl2;
}; };
} }

View file

@ -96,6 +96,24 @@
}; };
version = "3.2.3"; version = "3.2.3";
}; };
capybara = {
dependencies = ["addressable" "mini_mime" "nokogiri" "rack" "rack-test" "xpath"];
source = {
remotes = ["https://rubygems.org"];
sha256 = "1sz6ick0pn7886jh9fd4571wyplshnpb95pr22ds4hd51zcrnfi4";
type = "gem";
};
version = "3.9.0";
};
childprocess = {
dependencies = ["ffi"];
source = {
remotes = ["https://rubygems.org"];
sha256 = "0a61922kmvcxyj5l70fycapr87gz1dzzlkfpq85rfqk5vdh3d28p";
type = "gem";
};
version = "0.9.0";
};
coderay = { coderay = {
source = { source = {
remotes = ["https://rubygems.org"]; remotes = ["https://rubygems.org"];
@ -129,6 +147,14 @@
}; };
version = "1.6.0"; version = "1.6.0";
}; };
docile = {
source = {
remotes = ["https://rubygems.org"];
sha256 = "0m8j31whq7bm5ljgmsrlfkiqvacrw6iz9wq10r3gwrv5785y8gjx";
type = "gem";
};
version = "1.1.5";
};
erubis = { erubis = {
source = { source = {
remotes = ["https://rubygems.org"]; remotes = ["https://rubygems.org"];
@ -137,6 +163,14 @@
}; };
version = "2.7.0"; version = "2.7.0";
}; };
ffi = {
source = {
remotes = ["https://rubygems.org"];
sha256 = "0jpm2dis1j7zvvy3lg7axz9jml316zrn7s0j59vyq3qr127z0m7q";
type = "gem";
};
version = "1.9.25";
};
globalid = { globalid = {
dependencies = ["activesupport"]; dependencies = ["activesupport"];
source = { source = {
@ -189,6 +223,14 @@
}; };
version = "2.6.6"; version = "2.6.6";
}; };
metaclass = {
source = {
remotes = ["https://rubygems.org"];
sha256 = "0hp99y2b1nh0nr8pc398n3f8lakgci6pkrg4bf2b2211j1f6hsc5";
type = "gem";
};
version = "0.0.4";
};
mime-types = { mime-types = {
dependencies = ["mime-types-data"]; dependencies = ["mime-types-data"];
source = { source = {
@ -214,6 +256,14 @@
}; };
version = "0.3.2"; version = "0.3.2";
}; };
mini_mime = {
source = {
remotes = ["https://rubygems.org"];
sha256 = "1q4pshq387lzv9m39jv32vwb8wrq3wc4jwgl4jk209r4l33v09d3";
type = "gem";
};
version = "1.0.1";
};
mini_portile2 = { mini_portile2 = {
source = { source = {
remotes = ["https://rubygems.org"]; remotes = ["https://rubygems.org"];
@ -230,6 +280,23 @@
}; };
version = "5.11.3"; version = "5.11.3";
}; };
mocha = {
dependencies = ["metaclass"];
source = {
remotes = ["https://rubygems.org"];
sha256 = "13whjmrm4n48rwx7h7a2jwa5grar3m0fxspbm2pm4lyp7hi119c1";
type = "gem";
};
version = "1.7.0";
};
multi_json = {
source = {
remotes = ["https://rubygems.org"];
sha256 = "1rl0qy4inf1mp8mybfk56dfga0mvx97zwpmq5xmiwl5r770171nv";
type = "gem";
};
version = "1.13.1";
};
mysql2 = { mysql2 = {
source = { source = {
remotes = ["https://rubygems.org"]; remotes = ["https://rubygems.org"];
@ -250,10 +317,10 @@
dependencies = ["mini_portile2"]; dependencies = ["mini_portile2"];
source = { source = {
remotes = ["https://rubygems.org"]; remotes = ["https://rubygems.org"];
sha256 = "1h9nml9h3m0mpvmh8jfnqvblnz5n5y3mmhgfc38avfmfzdrq9bgc"; sha256 = "0byyxrazkfm29ypcx5q4syrv126nvjnf7z6bqi01sqkv4llsi4qz";
type = "gem"; type = "gem";
}; };
version = "1.8.4"; version = "1.8.5";
}; };
pg = { pg = {
source = { source = {
@ -363,10 +430,10 @@
dependencies = ["htmlentities" "rbpdf-font"]; dependencies = ["htmlentities" "rbpdf-font"];
source = { source = {
remotes = ["https://rubygems.org"]; remotes = ["https://rubygems.org"];
sha256 = "021fda3gcz9pyydxnn40vs1nrkycwslb9ip4q0yg3hlip41k1b49"; sha256 = "159vg56bzy09f6zrh9h3rxm2r0vkvsfn9qczqmv1vi5xkd918s0d";
type = "gem"; type = "gem";
}; };
version = "1.19.5"; version = "1.19.6";
}; };
rbpdf-font = { rbpdf-font = {
source = { source = {
@ -376,6 +443,14 @@
}; };
version = "1.19.1"; version = "1.19.1";
}; };
rdoc = {
source = {
remotes = ["https://rubygems.org"];
sha256 = "13ba2mhqqcsp3k97x3iz9x29xk26rv4561lfzzzibcy41vvj1n4c";
type = "gem";
};
version = "4.3.0";
};
redcarpet = { redcarpet = {
source = { source = {
remotes = ["https://rubygems.org"]; remotes = ["https://rubygems.org"];
@ -426,6 +501,40 @@
}; };
version = "2.3.0"; version = "2.3.0";
}; };
rubyzip = {
source = {
remotes = ["https://rubygems.org"];
sha256 = "1n1lb2sdwh9h27y244hxzg1lrxxg2m53pk1vq7p33bna003qkyrj";
type = "gem";
};
version = "1.2.2";
};
selenium-webdriver = {
dependencies = ["childprocess" "rubyzip" "websocket"];
source = {
remotes = ["https://rubygems.org"];
sha256 = "15qyf7b9fa2nxhhwp551b9fjj82kb3wmy65559yrrcwpdadqvcs4";
type = "gem";
};
version = "2.53.4";
};
simplecov = {
dependencies = ["docile" "multi_json" "simplecov-html"];
source = {
remotes = ["https://rubygems.org"];
sha256 = "1a3wy9zlmfwl3f47cibnxyxrgfz16y6fmy0dj1vyidzyys4mvy12";
type = "gem";
};
version = "0.9.2";
};
simplecov-html = {
source = {
remotes = ["https://rubygems.org"];
sha256 = "0jv9pmpaxihrcsgcf6mgl3qg7rhf9scl5l2k67d768w9cz63xgvc";
type = "gem";
};
version = "0.9.0";
};
sprockets = { sprockets = {
dependencies = ["concurrent-ruby" "rack"]; dependencies = ["concurrent-ruby" "rack"];
source = { source = {
@ -444,6 +553,15 @@
}; };
version = "3.2.1"; version = "3.2.1";
}; };
test_after_commit = {
dependencies = ["activerecord"];
source = {
remotes = ["https://rubygems.org"];
sha256 = "1fzg8qan6f0n0ynr594bld2k0rwwxj99yzhiga2f3pkj9ina1abb";
type = "gem";
};
version = "0.4.2";
};
thor = { thor = {
source = { source = {
remotes = ["https://rubygems.org"]; remotes = ["https://rubygems.org"];
@ -469,4 +587,29 @@
}; };
version = "1.2.5"; version = "1.2.5";
}; };
websocket = {
source = {
remotes = ["https://rubygems.org"];
sha256 = "0f11rcn4qgffb1rq4kjfwi7di79w8840x9l74pkyif5arp0mb08x";
type = "gem";
};
version = "1.2.8";
};
xpath = {
dependencies = ["nokogiri"];
source = {
remotes = ["https://rubygems.org"];
sha256 = "1y61ijvv04bwga802s8py5xd7fcxci6478wgr9wkd35p45x20jzi";
type = "gem";
};
version = "3.1.0";
};
yard = {
source = {
remotes = ["https://rubygems.org"];
sha256 = "0lmmr1839qgbb3zxfa7jf5mzy17yjl1yirwlgzdhws4452gqhn67";
type = "gem";
};
version = "0.9.16";
};
} }

View file

@ -4968,7 +4968,7 @@ with pkgs;
redir = callPackage ../tools/networking/redir { }; redir = callPackage ../tools/networking/redir { };
redmine = callPackage ../applications/version-management/redmine { }; redmine = callPackage ../applications/version-management/redmine { ruby = pkgs.ruby_2_4; };
redsocks = callPackage ../tools/networking/redsocks { }; redsocks = callPackage ../tools/networking/redsocks { };