summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Raskin <7c6f434c@mail.ru>2018-08-21 14:04:02 +0000
committerGitHub <noreply@github.com>2018-08-21 14:04:02 +0000
commit980cbff93c20b5dcd4ac63384db84490f5e07a45 (patch)
tree6ebefef332f6cdaffe503929ebcae23243b6af88
parentabfd2143e42d12da06ce01225801100ec8036581 (diff)
parente180796caae6ea053c316c04f22d519848ed3563 (diff)
downloadnixlib-980cbff93c20b5dcd4ac63384db84490f5e07a45.tar
nixlib-980cbff93c20b5dcd4ac63384db84490f5e07a45.tar.gz
nixlib-980cbff93c20b5dcd4ac63384db84490f5e07a45.tar.bz2
nixlib-980cbff93c20b5dcd4ac63384db84490f5e07a45.tar.lz
nixlib-980cbff93c20b5dcd4ac63384db84490f5e07a45.tar.xz
nixlib-980cbff93c20b5dcd4ac63384db84490f5e07a45.tar.zst
nixlib-980cbff93c20b5dcd4ac63384db84490f5e07a45.zip
Merge pull request #45353 from aanderse/redmine
redmine: 2.5.2 -> 3.4.6
-rw-r--r--nixos/modules/services/misc/redmine.nix294
-rw-r--r--pkgs/applications/version-management/redmine/2002_FHS_through_env_vars.patch100
-rw-r--r--pkgs/applications/version-management/redmine/2003_externalize_session_config.patch72
-rw-r--r--pkgs/applications/version-management/redmine/2004_FHS_plugins_assets.patch11
-rw-r--r--pkgs/applications/version-management/redmine/Gemfile120
-rw-r--r--pkgs/applications/version-management/redmine/Gemfile.lock278
-rw-r--r--pkgs/applications/version-management/redmine/Gemfile.nix332
-rw-r--r--pkgs/applications/version-management/redmine/README6
-rw-r--r--pkgs/applications/version-management/redmine/bootstrap.nix47
-rw-r--r--pkgs/applications/version-management/redmine/default.nix108
-rw-r--r--pkgs/applications/version-management/redmine/gemset.nix472
-rw-r--r--pkgs/applications/version-management/redmine/generate_nix_requirements.rb56
12 files changed, 926 insertions, 970 deletions
diff --git a/nixos/modules/services/misc/redmine.nix b/nixos/modules/services/misc/redmine.nix
index 9a9424449f80..f763ba21d0b2 100644
--- a/nixos/modules/services/misc/redmine.nix
+++ b/nixos/modules/services/misc/redmine.nix
@@ -1,121 +1,124 @@
 { config, lib, pkgs, ... }:
 
-# TODO: support non-postgresql
-
 with lib;
 
 let
   cfg = config.services.redmine;
 
-  ruby = pkgs.ruby;
+  bundle = "${pkgs.redmine}/share/redmine/bin/bundle";
 
-  databaseYml = ''
+  databaseYml = pkgs.writeText "database.yml" ''
     production:
-      adapter: postgresql
-      database: ${cfg.databaseName}
-      host: ${cfg.databaseHost}
-      password: ${cfg.databasePassword}
-      username: ${cfg.databaseUsername}
-      encoding: utf8
+      adapter: ${cfg.database.type}
+      database: ${cfg.database.name}
+      host: ${cfg.database.host}
+      port: ${toString cfg.database.port}
+      username: ${cfg.database.user}
+      password: #dbpass#
   '';
 
-  configurationYml = ''
+  configurationYml = pkgs.writeText "configuration.yml" ''
     default:
-      # Absolute path to the directory where attachments are stored.
-      # The default is the 'files' directory in your Redmine instance.
-      # Your Redmine instance needs to have write permission on this
-      # directory.
-      # Examples:
-      # attachments_storage_path: /var/redmine/files
-      # attachments_storage_path: D:/redmine/files
-      attachments_storage_path: ${cfg.stateDir}/files
-
-      # Absolute path to the SCM commands errors (stderr) log file.
-      # The default is to log in the 'log' directory of your Redmine instance.
-      # Example:
-      # scm_stderr_log_file: /var/log/redmine_scm_stderr.log
-      scm_stderr_log_file: ${cfg.stateDir}/redmine_scm_stderr.log
-
-      ${cfg.extraConfig}
+      scm_subversion_command: ${pkgs.subversion}/bin/svn
+      scm_mercurial_command: ${pkgs.mercurial}/bin/hg
+      scm_git_command: ${pkgs.gitAndTools.git}/bin/git
+      scm_cvs_command: ${pkgs.cvs}/bin/cvs
+      scm_bazaar_command: ${pkgs.bazaar}/bin/bzr
+      scm_darcs_command: ${pkgs.darcs}/bin/darcs
+
+    ${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
 
+{
   options = {
     services.redmine = {
       enable = mkOption {
         type = types.bool;
         default = false;
-        description = ''
-          Enable the redmine service.
-        '';
+        description = "Enable the Redmine service.";
       };
 
-      stateDir = mkOption {
+      user = mkOption {
         type = types.str;
-        default = "/var/redmine";
-        description = "The state directory, logs and plugins are stored here";
-      };
-
-      extraConfig = mkOption {
-        type = types.lines;
-        default = "";
-        description = "Extra configuration in configuration.yml";
-      };
-
-      themes = mkOption {
-        type = types.attrsOf types.path;
-        default = {};
-        description = "Set of themes";
+        default = "redmine";
+        description = "User under which Redmine is ran.";
       };
 
-      plugins = mkOption {
-        type = types.attrsOf types.path;
-        default = {};
-        description = "Set of plugins";
+      group = mkOption {
+        type = types.str;
+        default = "redmine";
+        description = "Group under which Redmine is ran.";
       };
 
-      #databaseType = mkOption {
-      #  type = types.str;
-      #  default = "postgresql";
-      #  description = "Type of database";
-      #};
-
-      databaseHost = mkOption {
+      stateDir = mkOption {
         type = types.str;
-        default = "127.0.0.1";
-        description = "Database hostname";
+        default = "/var/lib/redmine";
+        description = "The state directory, logs and plugins are stored here.";
       };
 
-      databasePassword = mkOption {
-        type = types.str;
+      extraConfig = mkOption {
+        type = types.lines;
         default = "";
-        description = "Database user password";
-      };
+        description = ''
+          Extra configuration in configuration.yml.
 
-      databaseName = mkOption {
-        type = types.str;
-        default = "redmine";
-        description = "Database name";
+          See https://guides.rubyonrails.org/action_mailer_basics.html#action-mailer-configuration
+        '';
       };
 
-      databaseUsername = mkOption {
-        type = types.str;
-        default = "redmine";
-        description = "Database user";
+      database = {
+        type = mkOption {
+          type = types.enum [ "mysql2" "postgresql" ];
+          example = "postgresql";
+          default = "mysql2";
+          description = "Database engine to use.";
+        };
+
+        host = mkOption {
+          type = types.str;
+          default = "127.0.0.1";
+          description = "Database host address.";
+        };
+
+        port = mkOption {
+          type = types.int;
+          default = 3306;
+          description = "Database host port.";
+        };
+
+        name = mkOption {
+          type = types.str;
+          default = "redmine";
+          description = "Database name.";
+        };
+
+        user = mkOption {
+          type = types.str;
+          default = "redmine";
+          description = "Database user.";
+        };
+
+        password = mkOption {
+          type = types.str;
+          default = "";
+          description = ''
+            The password corresponding to <option>database.user</option>.
+            Warning: this is stored in cleartext in the Nix store!
+            Use <option>database.passwordFile</option> instead.
+          '';
+        };
+
+        passwordFile = mkOption {
+          type = types.nullOr types.path;
+          default = null;
+          example = "/run/keys/redmine-dbpassword";
+          description = ''
+            A file containing the password corresponding to
+            <option>database.user</option>.
+          '';
+        };
       };
     };
   };
@@ -123,99 +126,106 @@ in {
   config = mkIf cfg.enable {
 
     assertions = [
-      { assertion = cfg.databasePassword != "";
-        message = "services.redmine.databasePassword must be set";
+      { assertion = cfg.database.passwordFile != null || cfg.database.password != "";
+        message = "either services.redmine.database.passwordFile or services.redmine.database.password must be set";
       }
     ];
 
-    users.users = [
-      { name = "redmine";
-        group = "redmine";
-        uid = config.ids.uids.redmine;
-      } ];
-
-    users.groups = [
-      { name = "redmine";
-        gid = config.ids.gids.redmine;
-      } ];
+    environment.systemPackages = [ pkgs.redmine ];
 
     systemd.services.redmine = {
-      after = [ "network.target" "postgresql.service" ];
+      after = [ "network.target" (if cfg.database.type == "mysql2" then "mysql.service" else "postgresql.service") ];
       wantedBy = [ "multi-user.target" ];
+      environment.HOME = "${pkgs.redmine}/share/redmine";
       environment.RAILS_ENV = "production";
-      environment.RAILS_ETC = "${cfg.stateDir}/config";
-      environment.RAILS_LOG = "${cfg.stateDir}/log";
-      environment.RAILS_VAR = "${cfg.stateDir}/var";
       environment.RAILS_CACHE = "${cfg.stateDir}/cache";
-      environment.RAILS_PLUGINS = "${cfg.stateDir}/plugins";
-      environment.RAILS_PUBLIC = "${cfg.stateDir}/public";
-      environment.RAILS_TMP = "${cfg.stateDir}/tmp";
-      environment.SCHEMA = "${cfg.stateDir}/cache/schema.db";
-      environment.HOME = "${pkgs.redmine}/share/redmine";
       environment.REDMINE_LANG = "en";
-      environment.GEM_HOME = "${pkgs.redmine}/share/redmine/vendor/bundle/ruby/1.9.1";
-      environment.GEM_PATH = "${pkgs.bundler}/${pkgs.bundler.ruby.gemPath}";
+      environment.SCHEMA = "${cfg.stateDir}/cache/schema.db";
       path = with pkgs; [
         imagemagickBig
-        subversion
-        mercurial
-        cvs
-        config.services.postgresql.package
         bazaar
+        cvs
+        darcs
         gitAndTools.git
-        # once we build binaries for darc enable it
-        #darcs
+        mercurial
+        subversion
       ];
       preStart = ''
-        # TODO: use env vars
-        for i in plugins public/plugin_assets db files log config cache var/files tmp; do
+        # start with a fresh config directory every time
+        rm -rf ${cfg.stateDir}/config
+        cp -r ${pkgs.redmine}/share/redmine/config.dist ${cfg.stateDir}/config
+
+        # create the basic state directory layout pkgs.redmine expects
+        mkdir -p /run/redmine
+
+        for i in config files log plugins tmp; do
           mkdir -p ${cfg.stateDir}/$i
+          ln -fs ${cfg.stateDir}/$i /run/redmine/$i
         done
 
-        chown -R redmine:redmine ${cfg.stateDir}
-        chmod -R 755 ${cfg.stateDir}
+        # ensure cache directory exists for db:migrate command
+        mkdir -p ${cfg.stateDir}/cache
 
-        rm -rf ${cfg.stateDir}/public/*
-        cp -R ${pkgs.redmine}/share/redmine/public/* ${cfg.stateDir}/public/
-        for theme in ${concatStringsSep " " (mapAttrsToList unpackTheme cfg.themes)}; do
-          ln -fs $theme/* ${cfg.stateDir}/public/themes/
-        done
+        # link in the application configuration
+        ln -fs ${configurationYml} ${cfg.stateDir}/config/configuration.yml
 
-        rm -rf ${cfg.stateDir}/plugins/*
-        for plugin in ${concatStringsSep " " (mapAttrsToList unpackPlugin cfg.plugins)}; do
-          ln -fs $plugin/* ${cfg.stateDir}/plugins/''${plugin##*-redmine-plugin-}
-        done
+        chmod -R ug+rwX,o-rwx+x ${cfg.stateDir}/
 
-        ln -fs ${pkgs.writeText "database.yml" databaseYml} ${cfg.stateDir}/config/database.yml
-        ln -fs ${pkgs.writeText "configuration.yml" configurationYml} ${cfg.stateDir}/config/configuration.yml
+        # handle database.passwordFile
+        DBPASS=$(head -n1 ${cfg.database.passwordFile})
+        cp -f ${databaseYml} ${cfg.stateDir}/config/database.yml
+        sed -e "s,#dbpass#,$DBPASS,g" -i ${cfg.stateDir}/config/database.yml
+        chmod 440 ${cfg.stateDir}/config/database.yml
 
-        if [ "${cfg.databaseHost}" = "127.0.0.1" ]; then
-          if ! test -e "${cfg.stateDir}/db-created"; then
-            psql postgres -c "CREATE ROLE redmine WITH LOGIN NOCREATEDB NOCREATEROLE ENCRYPTED PASSWORD '${cfg.databasePassword}'"
-            ${config.services.postgresql.package}/bin/createdb --owner redmine redmine || true
-            touch "${cfg.stateDir}/db-created"
-          fi
+        # generate a secret token if required
+        if ! test -e "${cfg.stateDir}/config/initializers/secret_token.rb"; then
+          ${bundle} exec rake generate_secret_token
+          chmod 440 ${cfg.stateDir}/config/initializers/secret_token.rb
         fi
 
-        cd ${pkgs.redmine}/share/redmine/
-        ${ruby}/bin/rake db:migrate
-        ${ruby}/bin/rake redmine:plugins:migrate
-        ${ruby}/bin/rake redmine:load_default_data
-        ${ruby}/bin/rake generate_secret_token
+        # ensure everything is owned by ${cfg.user}
+        chown -R ${cfg.user}:${cfg.group} ${cfg.stateDir}
+
+        ${bundle} exec rake db:migrate
+        ${bundle} exec rake redmine:load_default_data
       '';
 
       serviceConfig = {
         PermissionsStartOnly = true; # preStart must be run as root
         Type = "simple";
-        User = "redmine";
-        Group = "redmine";
+        User = cfg.user;
+        Group = cfg.group;
         TimeoutSec = "300";
         WorkingDirectory = "${pkgs.redmine}/share/redmine";
-        ExecStart="${ruby}/bin/ruby ${pkgs.redmine}/share/redmine/script/rails server webrick -e production -P ${cfg.stateDir}/redmine.pid";
+        ExecStart="${bundle} exec rails server webrick -e production -P ${cfg.stateDir}/redmine.pid";
       };
 
     };
 
+    users.extraUsers = optionalAttrs (cfg.user == "redmine") (singleton
+      { name = "redmine";
+        group = cfg.group;
+        home = cfg.stateDir;
+        createHome = true;
+        uid = config.ids.uids.redmine;
+      });
+
+    users.extraGroups = optionalAttrs (cfg.group == "redmine") (singleton
+      { name = "redmine";
+        gid = config.ids.gids.redmine;
+      });
+
+    warnings = optional (cfg.database.password != "")
+      ''config.services.redmine.database.password will be stored as plaintext
+      in the Nix store. Use database.passwordFile instead.'';
+
+    # Create database passwordFile default when password is configured.
+    services.redmine.database.passwordFile =
+      (mkDefault (toString (pkgs.writeTextFile {
+        name = "redmine-database-password";
+        text = cfg.database.password;
+      })));
+
   };
 
 }
diff --git a/pkgs/applications/version-management/redmine/2002_FHS_through_env_vars.patch b/pkgs/applications/version-management/redmine/2002_FHS_through_env_vars.patch
deleted file mode 100644
index 889b8c930e73..000000000000
--- a/pkgs/applications/version-management/redmine/2002_FHS_through_env_vars.patch
+++ /dev/null
@@ -1,100 +0,0 @@
-Description: FHS through env vars
-Forwarded: not-needed
-Author: Jérémy Lal <kapouer@melix.org>
-Last-Update: 2013-09-28
---- redmine.orig/app/models/attachment.rb
-+++ redmine/app/models/attachment.rb
-@@ -46,10 +46,10 @@ class Attachment < ActiveRecord::Base
-                                                         "LEFT JOIN #{Project.table_name} ON #{Document.table_name}.project_id = #{Project.table_name}.id"}
- 
-   cattr_accessor :storage_path
--  @@storage_path = Redmine::Configuration['attachments_storage_path'] || File.join(Rails.root, "files")
-+  @@storage_path = Redmine::Configuration['attachments_storage_path'] || ENV['RAILS_VAR'] ? File.join(ENV['RAILS_VAR'], "files") : File.join(Rails.root, "files")
- 
-   cattr_accessor :thumbnails_storage_path
--  @@thumbnails_storage_path = File.join(Rails.root, "tmp", "thumbnails")
-+  @@thumbnails_storage_path = ENV['RAILS_TMP'] ? File.join(ENV['RAILS_TMP'], "thumbnails") : File.join(Rails.root, "tmp", "thumbnails")
- 
-   before_save :files_to_final_location
-   after_destroy :delete_from_disk
---- redmine.orig/lib/redmine/configuration.rb
-+++ redmine/lib/redmine/configuration.rb
-@@ -32,7 +32,7 @@ module Redmine
-       # * <tt>:file</tt>: the configuration file to load (default: config/configuration.yml)
-       # * <tt>:env</tt>: the environment to load the configuration for (default: Rails.env)
-       def load(options={})
--        filename = options[:file] || File.join(Rails.root, 'config', 'configuration.yml')
-+        filename = options[:file] || ENV['RAILS_ETC'] ? File.join(ENV['RAILS_ETC'], 'configuration.yml') : File.join(Rails.root, 'config', 'configuration.yml')
-         env = options[:env] || Rails.env
- 
-         @config = @defaults.dup
-@@ -103,7 +103,7 @@ module Redmine
-       end
- 
-       def load_deprecated_email_configuration(env)
--        deprecated_email_conf = File.join(Rails.root, 'config', 'email.yml')
-+        deprecated_email_conf = ENV['RAILS_ETC'] ? File.join(ENV['RAILS_ETC'], 'email.yml') : File.join(Rails.root, 'config', 'email.yml')
-         if File.file?(deprecated_email_conf)
-           warn "Storing outgoing emails configuration in config/email.yml is deprecated. You should now store it in config/configuration.yml using the email_delivery setting."
-           @config.merge!({'email_delivery' => load_from_yaml(deprecated_email_conf, env)})
---- redmine.orig/lib/redmine/export/pdf.rb
-+++ redmine/lib/redmine/export/pdf.rb
-@@ -38,7 +38,7 @@ module Redmine
-         attr_accessor :footer_date
- 
-         def initialize(lang, orientation='P')
--          @@k_path_cache = Rails.root.join('tmp', 'pdf')
-+          @@k_path_cache = ENV['RAILS_TMP'] ? File.join(ENV['RAILS_TMP'], 'pdf') : Rails.root.join('tmp', 'pdf')
-           FileUtils.mkdir_p @@k_path_cache unless File::exist?(@@k_path_cache)
-           set_language_if_valid lang
-           pdf_encoding = l(:general_pdf_encoding).upcase
---- redmine.orig/config/application.rb
-+++ redmine/config/application.rb
-@@ -52,8 +63,21 @@ module RedmineApp
-     # Do not include all helpers
-     config.action_controller.include_all_helpers = false
- 
-+    # move tmp directory to RAILS_TMP
-+    config.paths['tmp'] = ENV['RAILS_TMP']
-+
-     config.session_store :cookie_store, :key => '_redmine_session'
- 
-+    # log path
-+    config.paths['log'] = File.join(ENV['RAILS_LOG'], "#{Rails.env}.log") unless !ENV['RAILS_LOG']
-+
-+    config.paths['public'] = ENV['RAILS_PUBLIC'] unless !ENV['RAILS_PUBLIC']
-+
-+    config.cache_store = :file_store, File.join(ENV['RAILS_TMP'], "cache")
-+
-+    # Set Active Record's database.yml path
-+    config.paths['config/database'] = File.join(ENV['RAILS_ETC'], 'database.yml') unless !ENV['RAILS_ETC']
-+
-     if File.exists?(File.join(File.dirname(__FILE__), 'additional_environment.rb'))
-       instance_eval File.read(File.join(File.dirname(__FILE__), 'additional_environment.rb'))
-     end
---- redmine.orig/lib/plugins/rfpdf/lib/tcpdf.rb
-+++ redmine/lib/plugins/rfpdf/lib/tcpdf.rb
-@@ -89,10 +89,10 @@ class TCPDF
-   @@k_small_ratio = 2/3.0
-   
-   cattr_accessor :k_path_cache
--  @@k_path_cache = Rails.root.join('tmp')
-+  @@k_path_cache = ENV['RAILS_TMP'] ? ENV['RAILS_TMP'] : Rails.root.join('tmp')
-   
-   cattr_accessor :k_path_url_cache
--  @@k_path_url_cache = Rails.root.join('tmp')
-+  @@k_path_url_cache = ENV['RAILS_TMP'] ? ENV['RAILS_TMP'] : Rails.root.join('tmp')
-   
- 	attr_accessor :barcode
- 	
---- redmine.orig/lib/redmine/scm/adapters/abstract_adapter.rb
-+++ redmine/lib/redmine/scm/adapters/abstract_adapter.rb
-@@ -222,7 +222,7 @@ module Redmine
-           if @stderr_log_file.nil?
-             writable = false
-             path = Redmine::Configuration['scm_stderr_log_file'].presence
--            path ||= Rails.root.join("log/#{Rails.env}.scm.stderr.log").to_s
-+            path ||= ENV['RAILS_LOG'] ? File.join(ENV['RAILS_LOG'], "#{Rails.env}.scm.stderr.log").to_s : Rails.root.join("log/#{Rails.env}.scm.stderr.log").to_s
-             if File.exists?(path)
-               if File.file?(path) && File.writable?(path) 
-                 writable = true
diff --git a/pkgs/applications/version-management/redmine/2003_externalize_session_config.patch b/pkgs/applications/version-management/redmine/2003_externalize_session_config.patch
deleted file mode 100644
index 39af8e02e556..000000000000
--- a/pkgs/applications/version-management/redmine/2003_externalize_session_config.patch
+++ /dev/null
@@ -1,72 +0,0 @@
-Description: Externalize session config to yml in /etc
-Forwarded: not-needed
-Author: Jérémy Lal <kapouer@melix.org>
-Last-Update: 2010-01-10
---- redmine.orig/lib/tasks/initializers.rake
-+++ redmine/lib/tasks/initializers.rake
-@@ -1,11 +1,12 @@
- desc 'Generates a secret token for the application.'
-+task :generate_secret_token do
- 
--file 'config/initializers/secret_token.rb' do
--  path = File.join(Rails.root, 'config', 'initializers', 'secret_token.rb')
--  secret = SecureRandom.hex(40)
--  File.open(path, 'w') do |f|
--    f.write <<"EOF"
--# This file was generated by 'rake generate_secret_token', and should
-+filename = ENV['YML_SESSION_FILENAME'] ? ENV['YML_SESSION_FILENAME'] : 'session.yml'
-+path = File.join(ENV['RAILS_ETC'] ? ENV['RAILS_ETC'] : File.join(Rails.root, 'config'), filename)
-+secret = SecureRandom.hex(40)
-+File.open(path, 'w') do |f|
-+  f.write <<"EOF"
-+# This file was generated by 'rake generate_session_store',
- # not be made visible to public.
- # If you have a load-balancing Redmine cluster, you will need to use the
- # same version of this file on each machine. And be sure to restart your
-@@ -15,10 +18,18 @@ file 'config/initializers/secret_token.r
- # change this key, all old sessions will become invalid! Make sure the
- # secret is at least 30 characters and all random, no regular words or
- # you'll be exposed to dictionary attacks.
--RedmineApp::Application.config.secret_token = '#{secret}'
-+
-+production:
-+  key: _redmine_
-+  secret: #{secret}
-+
-+development:
-+  key: _redmine_
-+  secret: #{secret}
-+
-+test:
-+  key: _redmine_
-+  secret: #{secret}
- EOF
-   end
- end
--
--desc 'Generates a secret token for the application.'
--task :generate_secret_token => ['config/initializers/secret_token.rb']
---- redmine.orig/config/application.rb
-+++ redmine/config/application.rb
-@@ -66,7 +66,20 @@ module RedmineApp
-     # move tmp directory to RAILS_TMP
-     config.paths['tmp'] = ENV['RAILS_TMP']
- 
--    config.session_store :cookie_store, :key => '_redmine_session'
-+    # loads cookie based session session and secret keys
-+    # this is needed here because initializers are loaded after plugins,
-+    # and some plugins initialize ActionController which requires a secret to be set.
-+    # crash if file not found
-+    relativeUrlRoot = ENV['RAILS_RELATIVE_URL_ROOT']
-+    filename = ENV['RAILS_ETC'] ? File.join(ENV['RAILS_ETC'], 'session.yml') : File.join(File.dirname(__FILE__), '..', 'session.yml')
-+    if File.exists?(filename)
-+      sessionconfig = YAML::load_file(filename)
-+      config.session_store :cookie_store, :key => sessionconfig[Rails.env]['key'], :path => (relativeUrlRoot.blank?) ? '/' : relativeUrlRoot
-+      config.secret_token = sessionconfig[Rails.env]['secret']
-+    else
-+      # temporary settings before session.yml is created
-+      config.session_store :cookie_store, :key => '_redmine_session', :path => (relativeUrlRoot.blank?) ? '/' : relativeUrlRoot
-+    end
- 
-     # log path
-     config.paths['log'] = File.join(ENV['RAILS_LOG'], "#{Rails.env}.log") unless !ENV['RAILS_LOG']
diff --git a/pkgs/applications/version-management/redmine/2004_FHS_plugins_assets.patch b/pkgs/applications/version-management/redmine/2004_FHS_plugins_assets.patch
deleted file mode 100644
index d9a6844a6a35..000000000000
--- a/pkgs/applications/version-management/redmine/2004_FHS_plugins_assets.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- redmine.orig/lib/redmine/plugin.rb
-+++ redmine/lib/redmine/plugin.rb
-@@ -47,7 +47,7 @@ module Redmine #:nodoc:
-     self.directory = File.join(Rails.root, 'plugins')
- 
-     cattr_accessor :public_directory
--    self.public_directory = File.join(Rails.root, 'public', 'plugin_assets')
-+    self.public_directory = ENV['RAILS_TMP'] ? File.join(ENV['RAILS_TMP'], 'plugin_assets') : File.join(Rails.root, 'public', 'plugin_assets')
- 
-     @registered_plugins = {}
-     class << self
diff --git a/pkgs/applications/version-management/redmine/Gemfile b/pkgs/applications/version-management/redmine/Gemfile
new file mode 100644
index 000000000000..744d6bfdd74e
--- /dev/null
+++ b/pkgs/applications/version-management/redmine/Gemfile
@@ -0,0 +1,120 @@
+source 'https://rubygems.org'
+
+if Gem::Version.new(Bundler::VERSION) < Gem::Version.new('1.5.0')
+  abort "Redmine requires Bundler 1.5.0 or higher (you're using #{Bundler::VERSION}).\nPlease update with 'gem update bundler'."
+end
+
+gem "rails", "4.2.8"
+gem "addressable", "2.4.0" if RUBY_VERSION < "2.0"
+if RUBY_VERSION < "2.1"
+  gem "public_suffix", (RUBY_VERSION < "2.0" ? "~> 1.4" : "~> 2.0.5")
+end
+gem "jquery-rails", "~> 3.1.4"
+gem "coderay", "~> 1.1.1"
+gem "request_store", "1.0.5"
+gem "mime-types", (RUBY_VERSION >= "2.0" ? "~> 3.0" : "~> 2.99")
+gem "protected_attributes"
+gem "actionpack-xml_parser"
+gem "roadie-rails", "~> 1.1.1"
+gem "roadie", "~> 3.2.1"
+gem "mimemagic"
+gem "mail", "~> 2.6.4"
+
+gem "nokogiri", (RUBY_VERSION >= "2.1" ? "~> 1.8.1" : "~> 1.6.8")
+gem "i18n", "~> 0.7.0"
+gem "ffi", "1.9.14", :platforms => :mingw if RUBY_VERSION < "2.0"
+
+# Request at least rails-html-sanitizer 1.0.3 because of security advisories
+gem "rails-html-sanitizer", ">= 1.0.3"
+
+# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
+gem 'tzinfo-data', platforms: [:mingw, :x64_mingw, :mswin]
+gem "rbpdf", "~> 1.19.3"
+
+# Optional gem for LDAP authentication
+group :ldap do
+  gem "net-ldap", "~> 0.12.0"
+end
+
+# Optional gem for OpenID authentication
+group :openid do
+  gem "ruby-openid", "~> 2.3.0", :require => "openid"
+  gem "rack-openid"
+end
+
+platforms :mri, :mingw, :x64_mingw do
+  # Optional gem for exporting the gantt to a PNG file, not supported with jruby
+  group :rmagick do
+    gem "rmagick", ">= 2.14.0"
+  end
+
+  # Optional Markdown support, not for JRuby
+  group :markdown do
+    gem "redcarpet", "~> 3.4.0"
+  end
+end
+
+# Include database gems for the adapters found in the database
+# 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 "pg", "~> 0.18.1", :platforms => [:mri, :mingw, :x64_mingw]
+
+database_file = File.join(File.dirname(__FILE__), "config/database.yml")
+if File.exist?(database_file)
+  database_config = YAML::load(ERB.new(IO.read(database_file)).result)
+  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
+
+# NixOS - manually removed because I couldn't figure out how to get "bundle exec rails server webrick -e production" to ignore these groups
+#group :development do
+#  gem "rdoc", "~> 4.3"
+#  gem "yard"
+#end
+
+#group :test do
+#  gem "minitest"
+#  gem "rails-dom-testing"
+#  gem "mocha"
+#  gem "simplecov", "~> 0.9.1", :require => false
+#  # 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")
+if File.exists?(local_gemfile)
+  eval_gemfile local_gemfile
+end
+
+# Load plugins' Gemfiles
+Dir.glob File.expand_path("../plugins/*/{Gemfile,PluginGemfile}", __FILE__) do |file|
+  eval_gemfile file
+end
diff --git a/pkgs/applications/version-management/redmine/Gemfile.lock b/pkgs/applications/version-management/redmine/Gemfile.lock
index c660e73f4a0f..589537c2af75 100644
--- a/pkgs/applications/version-management/redmine/Gemfile.lock
+++ b/pkgs/applications/version-management/redmine/Gemfile.lock
@@ -1,152 +1,162 @@
 GEM
   remote: https://rubygems.org/
   specs:
-    actionmailer (3.2.19)
-      actionpack (= 3.2.19)
-      mail (~> 2.5.4)
-    actionpack (3.2.19)
-      activemodel (= 3.2.19)
-      activesupport (= 3.2.19)
-      builder (~> 3.0.0)
+    actionmailer (4.2.8)
+      actionpack (= 4.2.8)
+      actionview (= 4.2.8)
+      activejob (= 4.2.8)
+      mail (~> 2.5, >= 2.5.4)
+      rails-dom-testing (~> 1.0, >= 1.0.5)
+    actionpack (4.2.8)
+      actionview (= 4.2.8)
+      activesupport (= 4.2.8)
+      rack (~> 1.6)
+      rack-test (~> 0.6.2)
+      rails-dom-testing (~> 1.0, >= 1.0.5)
+      rails-html-sanitizer (~> 1.0, >= 1.0.2)
+    actionpack-xml_parser (1.0.2)
+      actionpack (>= 4.0.0, < 5)
+    actionview (4.2.8)
+      activesupport (= 4.2.8)
+      builder (~> 3.1)
       erubis (~> 2.7.0)
-      journey (~> 1.0.4)
-      rack (~> 1.4.5)
-      rack-cache (~> 1.2)
-      rack-test (~> 0.6.1)
-      sprockets (~> 2.2.1)
-    activemodel (3.2.19)
-      activesupport (= 3.2.19)
-      builder (~> 3.0.0)
-    activerecord (3.2.19)
-      activemodel (= 3.2.19)
-      activesupport (= 3.2.19)
-      arel (~> 3.0.2)
-      tzinfo (~> 0.3.29)
-    activeresource (3.2.19)
-      activemodel (= 3.2.19)
-      activesupport (= 3.2.19)
-    activesupport (3.2.19)
-      i18n (~> 0.6, >= 0.6.4)
-      multi_json (~> 1.0)
-    arel (3.0.3)
-    awesome_nested_set (2.1.6)
-      activerecord (>= 3.0.0)
-    builder (3.0.0)
-    capybara (2.1.0)
-      mime-types (>= 1.16)
-      nokogiri (>= 1.3.3)
-      rack (>= 1.0.0)
-      rack-test (>= 0.5.4)
-      xpath (~> 2.0)
-    childprocess (0.5.5)
-      ffi (~> 1.0, >= 1.0.11)
-    coderay (1.1.0)
+      rails-dom-testing (~> 1.0, >= 1.0.5)
+      rails-html-sanitizer (~> 1.0, >= 1.0.3)
+    activejob (4.2.8)
+      activesupport (= 4.2.8)
+      globalid (>= 0.3.0)
+    activemodel (4.2.8)
+      activesupport (= 4.2.8)
+      builder (~> 3.1)
+    activerecord (4.2.8)
+      activemodel (= 4.2.8)
+      activesupport (= 4.2.8)
+      arel (~> 6.0)
+    activesupport (4.2.8)
+      i18n (~> 0.7)
+      minitest (~> 5.1)
+      thread_safe (~> 0.3, >= 0.3.4)
+      tzinfo (~> 1.1)
+    addressable (2.5.2)
+      public_suffix (>= 2.0.2, < 4.0)
+    arel (6.0.4)
+    builder (3.2.3)
+    coderay (1.1.2)
+    concurrent-ruby (1.0.5)
+    crass (1.0.4)
+    css_parser (1.6.0)
+      addressable
     erubis (2.7.0)
-    fastercsv (1.5.5)
-    ffi (1.9.5)
-    hike (1.2.3)
-    i18n (0.6.11)
-    journey (1.0.4)
-    jquery-rails (2.0.3)
-      railties (>= 3.1.0, < 5.0)
-      thor (~> 0.14)
-    json (1.8.3)
-    mail (2.5.4)
-      mime-types (~> 1.16)
-      treetop (~> 1.4.8)
-    metaclass (0.0.4)
-    mime-types (1.25.1)
-    mini_portile (0.6.0)
-    mocha (1.0.0)
-      metaclass (~> 0.0.1)
-    multi_json (1.10.1)
-    net-ldap (0.3.1)
-    nokogiri (1.6.3.1)
-      mini_portile (= 0.6.0)
-    pg (0.17.1)
-    polyglot (0.3.5)
-    rack (1.4.5)
-    rack-cache (1.2)
-      rack (>= 0.4)
+    globalid (0.4.1)
+      activesupport (>= 4.2.0)
+    htmlentities (4.3.4)
+    i18n (0.7.0)
+    jquery-rails (3.1.5)
+      railties (>= 3.0, < 5.0)
+      thor (>= 0.14, < 2.0)
+    loofah (2.2.2)
+      crass (~> 1.0.2)
+      nokogiri (>= 1.5.9)
+    mail (2.6.6)
+      mime-types (>= 1.16, < 4)
+    mime-types (3.2.2)
+      mime-types-data (~> 3.2015)
+    mime-types-data (3.2018.0812)
+    mimemagic (0.3.2)
+    mini_portile2 (2.3.0)
+    minitest (5.11.3)
+    mysql2 (0.4.10)
+    net-ldap (0.12.1)
+    nokogiri (1.8.4)
+      mini_portile2 (~> 2.3.0)
+    pg (0.18.4)
+    protected_attributes (1.1.4)
+      activemodel (>= 4.0.1, < 5.0)
+    public_suffix (3.0.3)
+    rack (1.6.10)
     rack-openid (1.4.2)
       rack (>= 1.1.0)
       ruby-openid (>= 2.1.8)
-    rack-ssl (1.3.4)
-      rack
-    rack-test (0.6.2)
+    rack-test (0.6.3)
       rack (>= 1.0)
-    rails (3.2.19)
-      actionmailer (= 3.2.19)
-      actionpack (= 3.2.19)
-      activerecord (= 3.2.19)
-      activeresource (= 3.2.19)
-      activesupport (= 3.2.19)
-      bundler (~> 1.0)
-      railties (= 3.2.19)
-    railties (3.2.19)
-      actionpack (= 3.2.19)
-      activesupport (= 3.2.19)
-      rack-ssl (~> 1.3.2)
+    rails (4.2.8)
+      actionmailer (= 4.2.8)
+      actionpack (= 4.2.8)
+      actionview (= 4.2.8)
+      activejob (= 4.2.8)
+      activemodel (= 4.2.8)
+      activerecord (= 4.2.8)
+      activesupport (= 4.2.8)
+      bundler (>= 1.3.0, < 2.0)
+      railties (= 4.2.8)
+      sprockets-rails
+    rails-deprecated_sanitizer (1.0.3)
+      activesupport (>= 4.2.0.alpha)
+    rails-dom-testing (1.0.9)
+      activesupport (>= 4.2.0, < 5.0)
+      nokogiri (~> 1.6)
+      rails-deprecated_sanitizer (>= 1.0.1)
+    rails-html-sanitizer (1.0.4)
+      loofah (~> 2.2, >= 2.2.2)
+    railties (4.2.8)
+      actionpack (= 4.2.8)
+      activesupport (= 4.2.8)
       rake (>= 0.8.7)
-      rdoc (~> 3.4)
-      thor (>= 0.14.6, < 2.0)
-    rake (10.1.1)
-    rdoc (3.12.2)
-      json (~> 1.4)
-    redcarpet (2.3.0)
-    rmagick (2.13.3)
+      thor (>= 0.18.1, < 2.0)
+    rake (12.3.1)
+    rbpdf (1.19.5)
+      htmlentities
+      rbpdf-font (~> 1.19.0)
+    rbpdf-font (1.19.1)
+    redcarpet (3.4.0)
+    request_store (1.0.5)
+    rmagick (2.16.0)
+    roadie (3.2.2)
+      css_parser (~> 1.4)
+      nokogiri (~> 1.5)
+    roadie-rails (1.1.1)
+      railties (>= 3.0, < 5.1)
+      roadie (~> 3.1)
     ruby-openid (2.3.0)
-    rubyzip (1.1.6)
-    selenium-webdriver (2.43.0)
-      childprocess (~> 0.5)
-      multi_json (~> 1.0)
-      rubyzip (~> 1.0)
-      websocket (~> 1.0)
-    shoulda (3.3.2)
-      shoulda-context (~> 1.0.1)
-      shoulda-matchers (~> 1.4.1)
-    shoulda-context (1.0.2)
-    shoulda-matchers (1.4.1)
-      activesupport (>= 3.0.0)
-    sprockets (2.2.2)
-      hike (~> 1.2)
-      multi_json (~> 1.0)
-      rack (~> 1.0)
-      tilt (~> 1.1, != 1.3.0)
-    thor (0.19.1)
-    tilt (1.4.1)
-    treetop (1.4.15)
-      polyglot
-      polyglot (>= 0.3.1)
-    tzinfo (0.3.41)
-    websocket (1.2.1)
-    xpath (2.0.0)
-      nokogiri (~> 1.3)
-    yard (0.8.7.4)
+    sprockets (3.7.2)
+      concurrent-ruby (~> 1.0)
+      rack (> 1, < 3)
+    sprockets-rails (3.2.1)
+      actionpack (>= 4.0)
+      activesupport (>= 4.0)
+      sprockets (>= 3.0.0)
+    thor (0.20.0)
+    thread_safe (0.3.6)
+    tzinfo (1.2.5)
+      thread_safe (~> 0.1)
 
 PLATFORMS
   ruby
 
 DEPENDENCIES
-  activerecord-jdbc-adapter (~> 1.3.2)
-  activerecord-jdbcpostgresql-adapter
-  awesome_nested_set (= 2.1.6)
-  builder (= 3.0.0)
-  capybara (~> 2.1.0)
-  coderay (~> 1.1.0)
-  fastercsv (~> 1.5.0)
-  jquery-rails (~> 2.0.2)
-  mime-types
-  mocha (~> 1.0.0)
-  net-ldap (~> 0.3.1)
-  pg (>= 0.11.0)
+  actionpack-xml_parser
+  coderay (~> 1.1.1)
+  i18n (~> 0.7.0)
+  jquery-rails (~> 3.1.4)
+  mail (~> 2.6.4)
+  mime-types (~> 3.0)
+  mimemagic
+  mysql2 (~> 0.4.6)
+  net-ldap (~> 0.12.0)
+  nokogiri (~> 1.8.1)
+  pg (~> 0.18.1)
+  protected_attributes
   rack-openid
-  rails (= 3.2.19)
-  rake (~> 10.1.1)
-  rdoc (>= 2.4.2)
-  redcarpet (~> 2.3.0)
-  rmagick (>= 2.0.0)
+  rails (= 4.2.8)
+  rails-html-sanitizer (>= 1.0.3)
+  rbpdf (~> 1.19.3)
+  redcarpet (~> 3.4.0)
+  request_store (= 1.0.5)
+  rmagick (>= 2.14.0)
+  roadie (~> 3.2.1)
+  roadie-rails (~> 1.1.1)
   ruby-openid (~> 2.3.0)
-  selenium-webdriver
-  shoulda (~> 3.3.2)
-  yard
+  tzinfo-data
+
+BUNDLED WITH
+   1.16.1
diff --git a/pkgs/applications/version-management/redmine/Gemfile.nix b/pkgs/applications/version-management/redmine/Gemfile.nix
deleted file mode 100644
index 77adfba334ec..000000000000
--- a/pkgs/applications/version-management/redmine/Gemfile.nix
+++ /dev/null
@@ -1,332 +0,0 @@
-[
-{
-name = "actionmailer";
-hash = "cd9f0b22f755b0adeae13cf949adaf63fa1c068c72d0a100572c6a11aecd3ba7";
-url = "http://rubygems.org/downloads/actionmailer-3.2.19.gem";
-version = "3.2.19";
-}
-{
-name = "actionpack";
-hash = "c58ca2342aff2062f4f478551ce46d81918ac93200bc62d099764d2cd7499fcd";
-url = "http://rubygems.org/downloads/actionpack-3.2.19.gem";
-version = "3.2.19";
-}
-{
-name = "activemodel";
-hash = "4ea3abf790eca9ee8228e9e2a465350e258294270a639b63f0e1dfad236fe70e";
-url = "http://rubygems.org/downloads/activemodel-3.2.19.gem";
-version = "3.2.19";
-}
-{
-name = "activerecord";
-hash = "052945ad510744aaa3e35a817a6f515a2316e7dd96df6460f75b36067bb60372";
-url = "http://rubygems.org/downloads/activerecord-3.2.19.gem";
-version = "3.2.19";
-}
-{
-name = "activeresource";
-hash = "8617d24537ca937cc67aac46aaa29782510d66136605426d0a23a3585a839daf";
-url = "http://rubygems.org/downloads/activeresource-3.2.19.gem";
-version = "3.2.19";
-}
-{
-name = "activesupport";
-hash = "2c837a59250da14b12a6b0cfb6774f0afae90aa749fd96ad4347344d8417ad3d";
-url = "http://rubygems.org/downloads/activesupport-3.2.19.gem";
-version = "3.2.19";
-}
-{
-name = "arel";
-hash = "c0006e2169deee3b8cc2d258296388822eeb2db59832450b9b7316e1387d0da4";
-url = "http://rubygems.org/downloads/arel-3.0.3.gem";
-version = "3.0.3";
-}
-{
-name = "awesome_nested_set";
-hash = "0dcd801aea5048f5ab907b62b4174b6763b191eaa4e1e11bb83f996f01349af8";
-url = "http://rubygems.org/downloads/awesome_nested_set-2.1.6.gem";
-version = "2.1.6";
-}
-{
-name = "builder";
-hash = "fbd3e15e5de02245f7d649b3415b2c2875cdc9a14dccde89aa30fc14a314618e";
-url = "http://rubygems.org/downloads/builder-3.0.0.gem";
-version = "3.0.0";
-}
-{
-name = "capybara";
-hash = "a9a19f8d6bb2dfcb1f05ea3e1727cb556d1cba0d234d1712b481e8d4f7bbb91e";
-url = "http://rubygems.org/downloads/capybara-2.1.0.gem";
-version = "2.1.0";
-}
-{
-name = "childprocess";
-hash = "9b583295a11932d2eeffa1e8f5b8fb2fb0064a2f0111ad98c3b752b94f80bf33";
-url = "http://rubygems.org/downloads/childprocess-0.5.5.gem";
-version = "0.5.5";
-}
-{
-name = "coderay";
-hash = "5a943c59e36f7ef9dd2677855735656413af02e3f302431e9c548aabe89f3c15";
-url = "http://rubygems.org/downloads/coderay-1.1.0.gem";
-version = "1.1.0";
-}
-{
-name = "erubis";
-hash = "63653f5174a7997f6f1d6f465fbe1494dcc4bdab1fb8e635f6216989fb1148ba";
-url = "http://rubygems.org/downloads/erubis-2.7.0.gem";
-version = "2.7.0";
-}
-{
-name = "fastercsv";
-hash = "d098199e62e4e10eec436a9ea9b8c189dacd5c06f2825f00d1e0f1c29fdbc3b5";
-url = "http://rubygems.org/downloads/fastercsv-1.5.5.gem";
-version = "1.5.5";
-}
-{
-name = "ffi";
-hash = "0d2ef90163eef8545689e8dfc27fb1245a2d82e3500d587de1e38290629e662f";
-url = "http://rubygems.org/downloads/ffi-1.9.5.gem";
-version = "1.9.5";
-}
-{
-name = "hike";
-hash = "154e2f2593845e5bcd8ed2ba3092600c55c6ad8c630722857de3fdaf334ccc44";
-url = "http://rubygems.org/downloads/hike-1.2.3.gem";
-version = "1.2.3";
-}
-{
-name = "i18n";
-hash = "b37dda25b30484f2674a851e24ae098a38564a61c976fa91a34bf8fceaa3923b";
-url = "http://rubygems.org/downloads/i18n-0.6.11.gem";
-version = "0.6.11";
-}
-{
-name = "journey";
-hash = "7454b8612530784000fbb17ea2df749a71b70702a0ac8ebef4a1e7f05aecc10f";
-url = "http://rubygems.org/downloads/journey-1.0.4.gem";
-version = "1.0.4";
-}
-{
-name = "jquery-rails";
-hash = "cc4eab342fb3b1fcbb2fc1c9a61b09ecd86d795b1f74d607994b0bc6fd5ef444";
-url = "http://rubygems.org/downloads/jquery-rails-2.0.3.gem";
-version = "2.0.3";
-}
-{
-name = "json";
-hash = "1nsby6ry8l9xg3yw4adlhk2pnc7i0h0rznvcss4vk3v74qg0k8lc";
-url = "http://rubygems.org/downloads/json-1.8.3.gem";
-version = "1.8.3";
-}
-{
-name = "mail";
-hash = "446585c38b062121252688dcc9cc70af1f470822e30db021bb97d185969e257c";
-url = "http://rubygems.org/downloads/mail-2.5.4.gem";
-version = "2.5.4";
-}
-{
-name = "metaclass";
-hash = "8569685c902108b1845be4e5794d646f2a8adcb0280d7651b600dab0844fe942";
-url = "http://rubygems.org/downloads/metaclass-0.0.4.gem";
-version = "0.0.4";
-}
-{
-name = "mime-types";
-hash = "88ef3c596481678710ffd4018fa40f1999b02d97babea39682ba7d5badd21f56";
-url = "http://rubygems.org/downloads/mime-types-1.25.1.gem";
-version = "1.25.1";
-}
-{
-name = "mini_portile";
-hash = "762b3e241362de24b2eb2bb1b98638399b931e9e51bece5f8e2df7611eb16c26";
-url = "http://rubygems.org/downloads/mini_portile-0.6.0.gem";
-version = "0.6.0";
-}
-{
-name = "mocha";
-hash = "788fd93c8009a7e0eebd155509953e5987f4681902aad666a294283baa09899a";
-url = "http://rubygems.org/downloads/mocha-1.0.0.gem";
-version = "1.0.0";
-}
-{
-name = "multi_json";
-hash = "2c98979877e87df0b338ebf5c86091b390f53d62c11a8232bd51ca007e0b82d2";
-url = "http://rubygems.org/downloads/multi_json-1.10.1.gem";
-version = "1.10.1";
-}
-{
-name = "net-ldap";
-hash = "953551665fb0d398740a72a26314c6d34bd70fa35419c96dc58351f17d9a5081";
-url = "http://rubygems.org/downloads/net-ldap-0.3.1.gem";
-version = "0.3.1";
-}
-{
-name = "nokogiri";
-hash = "91761a654439406b5bed71adf6092d49829e26332b4c0e7c8a23a2e628442585";
-url = "http://rubygems.org/downloads/nokogiri-1.6.3.1.gem";
-version = "1.6.3.1";
-}
-{
-name = "pg";
-hash = "e7933e8f7f184c28e820ed85ddfb3ad8a13933b2b2ab8656aa8f81cb0aa610a6";
-url = "http://rubygems.org/downloads/pg-0.17.1.gem";
-version = "0.17.1";
-}
-{
-name = "polyglot";
-hash = "59d66ef5e3c166431c39cb8b7c1d02af419051352f27912f6a43981b3def16af";
-url = "http://rubygems.org/downloads/polyglot-0.3.5.gem";
-version = "0.3.5";
-}
-{
-name = "rack";
-hash = "f7bf3faa8e09a2ff26475372de36a724e7470d6bdc33d189a0ec34b49605f308";
-url = "http://rubygems.org/downloads/rack-1.4.5.gem";
-version = "1.4.5";
-}
-{
-name = "rack-cache";
-hash = "02bfed05f8b3266db804f2fa445801636ca2c6d211a3137ec796f88af5756e1c";
-url = "http://rubygems.org/downloads/rack-cache-1.2.gem";
-version = "1.2";
-}
-{
-name = "rack-openid";
-hash = "8cd2305e738463a7da98791f9ac4df4cf3f6ed27908d982350430694ac2fe869";
-url = "http://rubygems.org/downloads/rack-openid-1.4.2.gem";
-version = "1.4.2";
-}
-{
-name = "rack-ssl";
-hash = "d703764fa2a0d44a2163d6add65be89f5dba4477d1959b90d3727682a9c37dcf";
-url = "http://rubygems.org/downloads/rack-ssl-1.3.4.gem";
-version = "1.3.4";
-}
-{
-name = "rack-test";
-hash = "7e920b6aac888e4a3846e5997fb1cbf456bdb5846322b58dc31697a54a38b306";
-url = "http://rubygems.org/downloads/rack-test-0.6.2.gem";
-version = "0.6.2";
-}
-{
-name = "rails";
-hash = "33b64cf78dfcf3206d961ce03e8fe6d260081da696e60da39d0b2a4a160fe22b";
-url = "http://rubygems.org/downloads/rails-3.2.19.gem";
-version = "3.2.19";
-}
-{
-name = "railties";
-hash = "c569009ee5c005190d208ac228087fdc094b10c6f0cf209f1d12c552b447cc10";
-url = "http://rubygems.org/downloads/railties-3.2.19.gem";
-version = "3.2.19";
-}
-{
-name = "rake";
-hash = "85e446590871dd3469c80dfe70a0296c20b76a9006af6b728c1f47d0b460412d";
-url = "http://rubygems.org/downloads/rake-10.1.1.gem";
-version = "10.1.1";
-}
-{
-name = "rdoc";
-hash = "a8e2b78f7e5ec4cc4716cd863975645f2f2377dc6db267a15e427e5fae2633ed";
-url = "http://rubygems.org/downloads/rdoc-3.12.2.gem";
-version = "3.12.2";
-}
-{
-name = "redcarpet";
-hash = "5c9bcc307fba97ff5a25eec74f08365c17e929d2a5c707db32d6fc99ec81f0b9";
-url = "http://rubygems.org/downloads/redcarpet-2.3.0.gem";
-version = "2.3.0";
-}
-{
-name = "rmagick";
-hash = "109f3b8be90afdea9abbdd2a79a955cd808b5cad65d937ed12676da22870d3b4";
-url = "http://rubygems.org/downloads/rmagick-2.13.3.gem";
-version = "2.13.3";
-}
-{
-name = "ruby-openid";
-hash = "f69ed004e95f7094e23bfd8bc9ebfb1dc88a7b46637252ca2907a1189870ea7b";
-url = "http://rubygems.org/downloads/ruby-openid-2.3.0.gem";
-version = "2.3.0";
-}
-{
-name = "rubyzip";
-hash = "a996435ee9698be6a09d3748f4d23ee15aaf45cbfef1749def165af6ea3c0a9e";
-url = "http://rubygems.org/downloads/rubyzip-1.1.6.gem";
-version = "1.1.6";
-}
-{
-name = "selenium-webdriver";
-hash = "09fe4374d1541cb45403ad1238c2d88129f3afb985218635af087a06c99a521a";
-url = "http://rubygems.org/downloads/selenium-webdriver-2.43.0.gem";
-version = "2.43.0";
-}
-{
-name = "shoulda";
-hash = "52e70b71cbfb7c01dace14e268a62d86c21ddd1e5ec0116c8b1e632d8e04e412";
-url = "http://rubygems.org/downloads/shoulda-3.3.2.gem";
-version = "3.3.2";
-}
-{
-name = "shoulda-context";
-hash = "ee5559aa13248c70fdec6868a3c144adf7438c904c59d1a76b04a002e5151de5";
-url = "http://rubygems.org/downloads/shoulda-context-1.0.2.gem";
-version = "1.0.2";
-}
-{
-name = "shoulda-matchers";
-hash = "c35693cbfa84213212dffbc2c87487427ef364927340151329a842f0a06086b9";
-url = "http://rubygems.org/downloads/shoulda-matchers-1.4.1.gem";
-version = "1.4.1";
-}
-{
-name = "sprockets";
-hash = "fae893b7e86e83c1936f6f2a64db3550510f86eabdd5fa9f0f23fb25d7e0cf96";
-url = "http://rubygems.org/downloads/sprockets-2.2.2.gem";
-version = "2.2.2";
-}
-{
-name = "thor";
-hash = "9ff834f031b5550c743bb8a3139317fefdae9cdebd02d60de376658f427fe522";
-url = "http://rubygems.org/downloads/thor-0.19.1.gem";
-version = "0.19.1";
-}
-{
-name = "tilt";
-hash = "39820562c4f5db45fe18de87ccc30a0e77a998bf5334b1d8c10a2f7dbc1f5903";
-url = "http://rubygems.org/downloads/tilt-1.4.1.gem";
-version = "1.4.1";
-}
-{
-name = "treetop";
-hash = "ffa68f201c0f62c26b0a1d13233d73194400596964696843f87ebb5d812f12ff";
-url = "http://rubygems.org/downloads/treetop-1.4.15.gem";
-version = "1.4.15";
-}
-{
-name = "tzinfo";
-hash = "381b22fd1744a35d0a0239f563f505773681e626e6d900063b14cb9b1b68e98c";
-url = "http://rubygems.org/downloads/tzinfo-0.3.41.gem";
-version = "0.3.41";
-}
-{
-name = "websocket";
-hash = "e626c8c3e8593735d900265fb1fc3439fd06b394069860177d8f40733b12ae9e";
-url = "http://rubygems.org/downloads/websocket-1.2.1.gem";
-version = "1.2.1";
-}
-{
-name = "xpath";
-hash = "9ca4a1cc88d9ab16c591468cce7b5d00ee06a8a76b841f8438970c7a44c86c12";
-url = "http://rubygems.org/downloads/xpath-2.0.0.gem";
-version = "2.0.0";
-}
-{
-name = "yard";
-hash = "e65a26f9b9dc6e2aa9b1d1d2e1a45bee3edf540a6a7e6c30fa6aa1df7f7a29b4";
-url = "http://rubygems.org/downloads/yard-0.8.7.4.gem";
-version = "0.8.7.4";
-}
-]
diff --git a/pkgs/applications/version-management/redmine/README b/pkgs/applications/version-management/redmine/README
deleted file mode 100644
index 1cc4772568a4..000000000000
--- a/pkgs/applications/version-management/redmine/README
+++ /dev/null
@@ -1,6 +0,0 @@
-to regenerate Gemfile.nix and Gemfile.lock you need to
-
-  % nix-build bootstrap.nix
-  % cp result/Gemfile.nix ./
-  % cp result/Gemfile.lock ./
-
diff --git a/pkgs/applications/version-management/redmine/bootstrap.nix b/pkgs/applications/version-management/redmine/bootstrap.nix
deleted file mode 100644
index 53757c37ed82..000000000000
--- a/pkgs/applications/version-management/redmine/bootstrap.nix
+++ /dev/null
@@ -1,47 +0,0 @@
-{ pkgs ? import <nixpkgs> {}
-}:
-
-with pkgs;
-
-let
-
-in stdenv.mkDerivation rec {
-  version = "2.5.2";
-  name = "redmine-${version}";
-  __noChroot = true;
-  src = fetchurl {
-    url = "http://www.redmine.org/releases/${name}.tar.gz";
-    sha256 = "0x0zwxyj4dwbk7l64s3lgny10mjf0ba8jwrbafsm4d72sncmacv0";
-  };
-
-  nativeBuildInputs = [ pkgconfig ];
-  buildInputs = [
-    ruby bundler libiconv libxslt libxml2
-    libffi imagemagickBig postgresql which stdenv
-  ];
-  installPhase = ''
-    unset http_proxy
-    unset ftp_proxy
-
-    cp -R . $out
-    cp ${./generate_nix_requirements.rb} $out/generate_nix_requirements.rb
-    cd $out
-
-    cat > config/database.yml <<EOF
-    production:
-      adapter: postgresql
-    EOF
-
-    bundle config --local build.nokogiri --use-system-libraries \
-      --with-iconv-dir=${libiconv} \
-      --with-xslt-dir=${libxslt.out} \
-      --with-xml2-dir=${libxml2.out} \
-      --with-pkg-config \
-      --with-pg-config=${postgresql}/bin/pg_config
-
-    bundle install --verbose --without development test rmagick --path /tmp/redmine-${version}
-
-    HOME="/tmp/redmine-${version}" ruby generate_nix_requirements.rb
-    rm -R /tmp/gems
-  '';
-}
diff --git a/pkgs/applications/version-management/redmine/default.nix b/pkgs/applications/version-management/redmine/default.nix
index 5a23c38a8863..3c3fd4da33d4 100644
--- a/pkgs/applications/version-management/redmine/default.nix
+++ b/pkgs/applications/version-management/redmine/default.nix
@@ -1,74 +1,42 @@
-{ stdenv, fetchurl, ruby, bundler, libiconv, libxslt, libxml2, pkgconfig, libffi, imagemagickBig, postgresql }:
+{ stdenv, fetchurl, bundlerEnv, ruby }:
 
 let
-  gemspec = map (gem: fetchurl { url=gem.url; sha256=gem.hash; }) (import ./Gemfile.nix);
-in stdenv.mkDerivation rec {
-  version = "2.5.2";
-  name = "redmine-${version}";
+  version = "3.4.6";
+  rubyEnv = bundlerEnv {
+    name = "redmine-env-${version}";
 
-  src = fetchurl {
-    url = "https://www.redmine.org/releases/${name}.tar.gz";
-    sha256 = "0x0zwxyj4dwbk7l64s3lgny10mjf0ba8jwrbafsm4d72sncmacv0";
+    inherit ruby;
+    gemdir = ./.;
   };
-
-  hardeningDisable = [ "format" ];
-
-  # taken from redmine (2.5.1-2~bpo70+3) in debian wheezy-backports
-  # needed to separate run-time and build-time directories
-  patches = [
-    ./2002_FHS_through_env_vars.patch
-    ./2004_FHS_plugins_assets.patch
-    ./2003_externalize_session_config.patch
-  ];
-
-  postPatch = ''
-    substituteInPlace lib/redmine/plugin.rb --replace "File.join(Rails.root, 'plugins')" "ENV['RAILS_PLUGINS']"
-    substituteInPlace lib/redmine/plugin.rb --replace "File.join(Rails.root, 'plugins', id.to_s, 'db', 'migrate')" "File.join(ENV['RAILS_PLUGINS'], id.to_s, 'db', 'migrate')"
-    substituteInPlace config/routes.rb --replace '"plugins/*", Rails.root' 'ENV["RAILS_PLUGINS"] + "/*"'
-  '';
-
-  buildInputs = [
-    ruby bundler libiconv
-    libxslt libxml2 pkgconfig libffi
-    imagemagickBig postgresql
-  ];
-
-  installPhase = ''
-    mkdir -p $out/share/redmine/
-    cp -R . $out/share/redmine/
-    cd $out/share/redmine
-    ln -s ${./Gemfile.lock} Gemfile.lock
-    export HOME=$(pwd)
-
-    cat > config/database.yml <<EOF
-      production:
-        adapter: postgresql
-    EOF
-
-    mkdir -p vendor/cache
-    ${stdenv.lib.concatStrings (map (gem: "ln -s ${gem} vendor/cache/${gem.name};") gemspec)}
-
-    bundle config build.nokogiri --use-system-libraries --with-iconv-dir="${libiconv}" --with-xslt-dir="${libxslt.dev}" --with-xml2-dir="${libxml2.dev}"
-
-    bundle install --verbose --local --deployment
-
-    # make sure we always load pg package
-    echo "gem \"pg\"" >> Gemfile
-
-    # make rails server happy
-    mkdir -p tmp/pids
-
-    # cleanup
-    rm config/database.yml
-  '';
-
-  meta = with stdenv.lib; {
-    homepage = http://www.redmine.org/;
-    platforms = platforms.linux;
-    maintainers = [ maintainers.garbas ];
-    license = licenses.gpl2;
-    # Marked as broken due to needing an update for security issues.
-    # See: https://github.com/NixOS/nixpkgs/issues/18856
-    broken = true;
-  };
-}
+in
+  stdenv.mkDerivation rec {
+    name = "redmine-${version}";
+
+    src = fetchurl {
+      url = "https://www.redmine.org/releases/${name}.tar.gz";
+      sha256 = "15akq6pn42w7cf7dg45xmvw06fixck1qznp7s8ix7nyxlmcyvcg3";
+    };
+
+    buildInputs = [ rubyEnv rubyEnv.wrappedRuby rubyEnv.bundler ];
+
+    buildPhase = ''
+      mv config config.dist
+    '';
+
+    installPhase = ''
+      mkdir -p $out/share
+      cp -r . $out/share/redmine
+
+      for i in config files log plugins tmp; do
+        rm -rf $out/share/redmine/$i
+        ln -fs /run/redmine/$i $out/share/redmine/
+      done
+    '';
+
+    meta = with stdenv.lib; {
+      homepage = http://www.redmine.org/;
+      platforms = platforms.linux;
+      maintainers = [ maintainers.garbas ];
+      license = licenses.gpl2;
+    };
+  }
diff --git a/pkgs/applications/version-management/redmine/gemset.nix b/pkgs/applications/version-management/redmine/gemset.nix
new file mode 100644
index 000000000000..7423fcdb9fb9
--- /dev/null
+++ b/pkgs/applications/version-management/redmine/gemset.nix
@@ -0,0 +1,472 @@
+{
+  actionmailer = {
+    dependencies = ["actionpack" "actionview" "activejob" "mail" "rails-dom-testing"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0pr3cmr0bpgg5d0f6wy1z6r45n14r9yin8jnr4hi3ssf402xpc0q";
+      type = "gem";
+    };
+    version = "4.2.8";
+  };
+  actionpack = {
+    dependencies = ["actionview" "activesupport" "rack" "rack-test" "rails-dom-testing" "rails-html-sanitizer"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "09fbazl0ja80na2wadfp3fzmdmdy1lsb4wd2yg7anbj0zk0ap7a9";
+      type = "gem";
+    };
+    version = "4.2.8";
+  };
+  actionpack-xml_parser = {
+    dependencies = ["actionpack"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "17am4nd7x6g8x7f8i35rzzv2qrxlkc230rbgzg98af0yf50j8gka";
+      type = "gem";
+    };
+    version = "1.0.2";
+  };
+  actionview = {
+    dependencies = ["activesupport" "builder" "erubis" "rails-dom-testing" "rails-html-sanitizer"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1mg4a8143q2wjhjq4mngl69jkv249z5jvg0jkdribdv4zkg586rp";
+      type = "gem";
+    };
+    version = "4.2.8";
+  };
+  activejob = {
+    dependencies = ["activesupport" "globalid"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0kazbpfgzz6cdmwjnlb9m671ps4qgggwv2hy8y9xi4h96djyyfqz";
+      type = "gem";
+    };
+    version = "4.2.8";
+  };
+  activemodel = {
+    dependencies = ["activesupport" "builder"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "11vhh7zmp92880s5sx8r32v2p0b7xg039mfr92pjynpkz4q901ld";
+      type = "gem";
+    };
+    version = "4.2.8";
+  };
+  activerecord = {
+    dependencies = ["activemodel" "activesupport" "arel"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1kk4dhn8jfhqfsf1dmb3a183gix6k46xr6cjkxj0rp51w2za1ns0";
+      type = "gem";
+    };
+    version = "4.2.8";
+  };
+  activesupport = {
+    dependencies = ["i18n" "minitest" "thread_safe" "tzinfo"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0wibdzd2f5l5rlsw1a1y3j3fhw2imrrbkxggdraa6q9qbdnc66hi";
+      type = "gem";
+    };
+    version = "4.2.8";
+  };
+  addressable = {
+    dependencies = ["public_suffix"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0viqszpkggqi8hq87pqp0xykhvz60g99nwmkwsb0v45kc2liwxvk";
+      type = "gem";
+    };
+    version = "2.5.2";
+  };
+  arel = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0nfcrdiys6q6ylxiblky9jyssrw2xj96fmxmal7f4f0jj3417vj4";
+      type = "gem";
+    };
+    version = "6.0.4";
+  };
+  builder = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0qibi5s67lpdv1wgcj66wcymcr04q6j4mzws6a479n0mlrmh5wr1";
+      type = "gem";
+    };
+    version = "3.2.3";
+  };
+  coderay = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "15vav4bhcc2x3jmi3izb11l4d9f3xv8hp2fszb7iqmpsccv1pz4y";
+      type = "gem";
+    };
+    version = "1.1.2";
+  };
+  concurrent-ruby = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "183lszf5gx84kcpb779v6a2y0mx9sssy8dgppng1z9a505nj1qcf";
+      type = "gem";
+    };
+    version = "1.0.5";
+  };
+  crass = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0bpxzy6gjw9ggjynlxschbfsgmx8lv3zw1azkjvnb8b9i895dqfi";
+      type = "gem";
+    };
+    version = "1.0.4";
+  };
+  css_parser = {
+    dependencies = ["addressable"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0gwvf8mc8gnz4aizfijplv3594998h2j44ydakpzsdmkivs07v61";
+      type = "gem";
+    };
+    version = "1.6.0";
+  };
+  erubis = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1fj827xqjs91yqsydf0zmfyw9p4l2jz5yikg3mppz6d7fi8kyrb3";
+      type = "gem";
+    };
+    version = "2.7.0";
+  };
+  globalid = {
+    dependencies = ["activesupport"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "02smrgdi11kziqi9zhnsy9i6yr2fnxrqlv3lllsvdjki3cd4is38";
+      type = "gem";
+    };
+    version = "0.4.1";
+  };
+  htmlentities = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1nkklqsn8ir8wizzlakncfv42i32wc0w9hxp00hvdlgjr7376nhj";
+      type = "gem";
+    };
+    version = "4.3.4";
+  };
+  i18n = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1i5z1ykl8zhszsxcs8mzl8d0dxgs3ylz8qlzrw74jb0gplkx6758";
+      type = "gem";
+    };
+    version = "0.7.0";
+  };
+  jquery-rails = {
+    dependencies = ["railties" "thor"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1lk7xqmms45czylxs22kv5khlbm7a0yqcchqijxb9m10zsqc6lp5";
+      type = "gem";
+    };
+    version = "3.1.5";
+  };
+  loofah = {
+    dependencies = ["crass" "nokogiri"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0yjs6wbcj3n06d3xjqpy3qbpx0bfa12h3x2rbpc2k33ldjlkx6zy";
+      type = "gem";
+    };
+    version = "2.2.2";
+  };
+  mail = {
+    dependencies = ["mime-types"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0d7lhj2dw52ycls6xigkfz6zvfhc6qggply9iycjmcyj9760yvz9";
+      type = "gem";
+    };
+    version = "2.6.6";
+  };
+  mime-types = {
+    dependencies = ["mime-types-data"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0fjxy1jm52ixpnv3vg9ld9pr9f35gy0jp66i1njhqjvmnvq0iwwk";
+      type = "gem";
+    };
+    version = "3.2.2";
+  };
+  mime-types-data = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "07wvp0aw2gjm4njibb70as6rh5hi1zzri5vky1q6jx95h8l56idc";
+      type = "gem";
+    };
+    version = "3.2018.0812";
+  };
+  mimemagic = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "00ibc1mhvdfyfyl103xwb45621nwyqxf124cni5hyfhag0fn1c3q";
+      type = "gem";
+    };
+    version = "0.3.2";
+  };
+  mini_portile2 = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "13d32jjadpjj6d2wdhkfpsmy68zjx90p49bgf8f7nkpz86r1fr11";
+      type = "gem";
+    };
+    version = "2.3.0";
+  };
+  minitest = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0icglrhghgwdlnzzp4jf76b0mbc71s80njn5afyfjn4wqji8mqbq";
+      type = "gem";
+    };
+    version = "5.11.3";
+  };
+  mysql2 = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0qjd97w6a0w9aldsrhb2y6jrc4wnnlbj5j8kcl7pp7vviwa0r5iq";
+      type = "gem";
+    };
+    version = "0.4.10";
+  };
+  net-ldap = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0z1j0zklbbx3vi91zcd2v0fnkfgkvq3plisa6hxaid8sqndyak46";
+      type = "gem";
+    };
+    version = "0.12.1";
+  };
+  nokogiri = {
+    dependencies = ["mini_portile2"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1h9nml9h3m0mpvmh8jfnqvblnz5n5y3mmhgfc38avfmfzdrq9bgc";
+      type = "gem";
+    };
+    version = "1.8.4";
+  };
+  pg = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "07dv4ma9xd75xpsnnwwg1yrpwpji7ydy0q1d9dl0yfqbzpidrw32";
+      type = "gem";
+    };
+    version = "0.18.4";
+  };
+  protected_attributes = {
+    dependencies = ["activemodel"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "18lvrvmcwjvjr2mrn20vaf68a0q6mg4cy9f0m1i7x83p0ljhhyar";
+      type = "gem";
+    };
+    version = "1.1.4";
+  };
+  public_suffix = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "08q64b5br692dd3v0a9wq9q5dvycc6kmiqmjbdxkxbfizggsvx6l";
+      type = "gem";
+    };
+    version = "3.0.3";
+  };
+  rack = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0in0amn0kwvzmi8h5zg6ijrx5wpsf8h96zrfmnk1kwh2ql4sxs2q";
+      type = "gem";
+    };
+    version = "1.6.10";
+  };
+  rack-openid = {
+    dependencies = ["rack" "ruby-openid"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0sg85yn981j3a0iri3ch4znzdwscvz29l7vrk3dafqw4fdg31llc";
+      type = "gem";
+    };
+    version = "1.4.2";
+  };
+  rack-test = {
+    dependencies = ["rack"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0h6x5jq24makgv2fq5qqgjlrk74dxfy62jif9blk43llw8ib2q7z";
+      type = "gem";
+    };
+    version = "0.6.3";
+  };
+  rails = {
+    dependencies = ["actionmailer" "actionpack" "actionview" "activejob" "activemodel" "activerecord" "activesupport" "railties" "sprockets-rails"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0dpbf3ybzbhqqkwg5vi60121860cr8fybvchrxk5wy3f2jcj0mch";
+      type = "gem";
+    };
+    version = "4.2.8";
+  };
+  rails-deprecated_sanitizer = {
+    dependencies = ["activesupport"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0qxymchzdxww8bjsxj05kbf86hsmrjx40r41ksj0xsixr2gmhbbj";
+      type = "gem";
+    };
+    version = "1.0.3";
+  };
+  rails-dom-testing = {
+    dependencies = ["activesupport" "nokogiri" "rails-deprecated_sanitizer"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0wssfqpn00byhvp2372p99mphkcj8qx6pf6646avwr9ifvq0q1x6";
+      type = "gem";
+    };
+    version = "1.0.9";
+  };
+  rails-html-sanitizer = {
+    dependencies = ["loofah"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1gv7vr5d9g2xmgpjfq4nxsqr70r9pr042r9ycqqnfvw5cz9c7jwr";
+      type = "gem";
+    };
+    version = "1.0.4";
+  };
+  railties = {
+    dependencies = ["actionpack" "activesupport" "rake" "thor"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0bavl4hj7bnl3ryqi9rvykm410kflplgingkcxasfv1gdilddh4g";
+      type = "gem";
+    };
+    version = "4.2.8";
+  };
+  rake = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1idi53jay34ba9j68c3mfr9wwkg3cd9qh0fn9cg42hv72c6q8dyg";
+      type = "gem";
+    };
+    version = "12.3.1";
+  };
+  rbpdf = {
+    dependencies = ["htmlentities" "rbpdf-font"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "021fda3gcz9pyydxnn40vs1nrkycwslb9ip4q0yg3hlip41k1b49";
+      type = "gem";
+    };
+    version = "1.19.5";
+  };
+  rbpdf-font = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0pxlr0l4vf785qpy55m439dyii63a26l0sd0yyhbwwcy9zm9hd1v";
+      type = "gem";
+    };
+    version = "1.19.1";
+  };
+  redcarpet = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0h9qz2hik4s9knpmbwrzb3jcp3vc5vygp9ya8lcpl7f1l9khmcd7";
+      type = "gem";
+    };
+    version = "3.4.0";
+  };
+  request_store = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1ky19wb6mpq6dxb81a0h4hnzx7a4ka99n9ay2syi68djbr4bkbbh";
+      type = "gem";
+    };
+    version = "1.0.5";
+  };
+  rmagick = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0m9x15cdlkcb9826s3s2jd97hxf50hln22p94x8hcccxi1lwklq6";
+      type = "gem";
+    };
+    version = "2.16.0";
+  };
+  roadie = {
+    dependencies = ["css_parser" "nokogiri"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0frp5yb07ib9y1k43shd4xjkb9a6wavhqq892l8yi9y73qi2cqbc";
+      type = "gem";
+    };
+    version = "3.2.2";
+  };
+  roadie-rails = {
+    dependencies = ["railties" "roadie"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1hxgl5marq2hi6lcc73f7g6afd7dz4w893rrgrbh7m3k8zrwjyk1";
+      type = "gem";
+    };
+    version = "1.1.1";
+  };
+  ruby-openid = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0yzaf2c1i88757554wk38rxqmj0xzgmwk2zx7gi98w2zx42d17pn";
+      type = "gem";
+    };
+    version = "2.3.0";
+  };
+  sprockets = {
+    dependencies = ["concurrent-ruby" "rack"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "182jw5a0fbqah5w9jancvfmjbk88h8bxdbwnl4d3q809rpxdg8ay";
+      type = "gem";
+    };
+    version = "3.7.2";
+  };
+  sprockets-rails = {
+    dependencies = ["actionpack" "activesupport" "sprockets"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0ab42pm8p5zxpv3sfraq45b9lj39cz9mrpdirm30vywzrwwkm5p1";
+      type = "gem";
+    };
+    version = "3.2.1";
+  };
+  thor = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0nmqpyj642sk4g16nkbq6pj856adpv91lp4krwhqkh2iw63aszdl";
+      type = "gem";
+    };
+    version = "0.20.0";
+  };
+  thread_safe = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0nmhcgq6cgz44srylra07bmaw99f5271l0dpsvl5f75m44l0gmwy";
+      type = "gem";
+    };
+    version = "0.3.6";
+  };
+  tzinfo = {
+    dependencies = ["thread_safe"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1fjx9j327xpkkdlxwmkl3a8wqj7i4l4jwlrv3z13mg95z9wl253z";
+      type = "gem";
+    };
+    version = "1.2.5";
+  };
+}
\ No newline at end of file
diff --git a/pkgs/applications/version-management/redmine/generate_nix_requirements.rb b/pkgs/applications/version-management/redmine/generate_nix_requirements.rb
deleted file mode 100644
index ed47d52c9c1b..000000000000
--- a/pkgs/applications/version-management/redmine/generate_nix_requirements.rb
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/usr/bin/env ruby
-
-require 'rubygems'
-require 'bundler'
-require 'fileutils'
-require 'net/http'
-require 'net/https'
-require 'uri'
-
-TMP_DIR = "/tmp/gems"
-
-FileUtils.rm_rf(TMP_DIR) if File.exists?(TMP_DIR)
-FileUtils.mkdir TMP_DIR
-
-GEMSERVER = "http://rubygems.org"
-
-# inspect Gemfile.lock
-lockfile = Bundler::LockfileParser.new(Bundler.read_file("Gemfile.lock"))
-
-to_mirror = {}
-
-uri = URI(GEMSERVER)
-http = Net::HTTP.new(uri.host, uri.port)
-http.use_ssl = uri.scheme == 'https'
-
-requirements = {}
-
-lockfile.specs.each do |s|
-  possible_gem_name = "#{s.name}-#{s.version.to_s}.gem"
-
-  Dir.chdir TMP_DIR do
-    filename = `gem fetch #{s.name} -v #{s.version.to_s}`.split()[1]
-    hash = `sha256sum #{filename}.gem`
-    url = "#{GEMSERVER}/downloads/#{filename}.gem"
-    puts url
-    requirements[s.name] = { :version => s.version.to_s, 
-                             :hash => hash.split().first,
-                             :url => url,}
-    
-  end
-end
-
-filename = 'Gemfile.nix'
-
-File.open(filename, 'w') do |file|
-  file.puts "["
-  requirements.each do |name, info|
-    file.puts "{"
-    file.puts ['name = ', '"', name, '";'].join('')
-    file.puts ['hash = ', '"', info[:hash], '";'].join('')
-    file.puts ['url = ', '"', info[:url], '";'].join('')
-    file.puts ['version = ', '"', info[:version], '";'].join('')
-    file.puts "}"
-  end
-  file.puts "]"
-end