From c0f39d649737ac754a8f9f35cb105233c345c86a Mon Sep 17 00:00:00 2001
From: Eike Kettner <eike.kettner@posteo.de>
Date: Wed, 22 Jan 2020 23:11:02 +0100
Subject: [PATCH] Improve nix files

List available versions; refactor modules to reuse default values.
---
 nix/configuration-test.nix |   4 +-
 nix/module-joex.nix        | 169 ++++++++++++++++++-------------------
 nix/module-server.nix      |   6 +-
 nix/pkg.nix                |  26 ++----
 nix/release.nix            |  43 +++++++---
 5 files changed, 129 insertions(+), 119 deletions(-)

diff --git a/nix/configuration-test.nix b/nix/configuration-test.nix
index 5859f84e..037ec249 100644
--- a/nix/configuration-test.nix
+++ b/nix/configuration-test.nix
@@ -20,7 +20,7 @@ in
         let
           callPackage = pkgs.lib.callPackageWith(custom // pkgs);
           custom = {
-            docspell = callPackage (docspell.pkg "0.2.0") {};
+            docspell = callPackage docspell.currentPkg {};
           };
         in custom;
     };
@@ -39,6 +39,8 @@ in
     urls = ["http://localhost:7880/api/v1/open/upload/item/blabla"];
   };
 
+  environment.systemPackages = [ pkgs.docspell.tools pkgs.jq ];
+
   services.xserver = {
     enable = false;
   };
diff --git a/nix/module-joex.nix b/nix/module-joex.nix
index 020a65e7..516947fa 100644
--- a/nix/module-joex.nix
+++ b/nix/module-joex.nix
@@ -9,6 +9,54 @@ let
        ${builtins.toJSON cfg}
   }}
   '';
+  defaults = {
+    app-id = "joex1";
+    base-url = "http://localhost:7878";
+    bind = {
+      address = "localhost";
+      port = 7878;
+    };
+    jdbc = {
+      url = "jdbc:h2:///tmp/docspell-demo.db;MODE=PostgreSQL;DATABASE_TO_LOWER=TRUE;AUTO_SERVER=TRUE";
+      user = "sa";
+      password = "";
+    };
+    scheduler = {
+      pool-size = 2;
+      counting-scheme = "4,1";
+      retries = 5;
+      retry-delay = "1 minute";
+      log-buffer-size = 500;
+      wakeup-period = "30 minutes";
+    };
+    extraction = {
+      page-range = {
+        begin = 10;
+      };
+      ghostscript =  {
+        working-dir = "/tmp/docspell-extraction";
+        command = {
+          program = "${pkgs.ghostscript}/bin/gs";
+          args = [ "-dNOPAUSE" "-dBATCH" "-dSAFER" "-sDEVICE=tiffscaled8" "-sOutputFile={{outfile}}" "{{infile}}" ];
+          timeout = "5 minutes";
+        };
+      };
+      unpaper = {
+        command = {
+          program = "${pkgs.unpaper}/bin/unpaper";
+          args = [ "{{infile}}" "{{outfile}}" ];
+          timeout = "5 minutes";
+        };
+      };
+      tesseract = {
+        command= {
+          program = "${pkgs.tesseract4}/bin/tesseract";
+          args = ["{{file}}" "stdout" "-l" "{{lang}}" ];
+          timeout = "5 minutes";
+        };
+      };
+    };
+  };
 in {
 
   ## interface
@@ -30,13 +78,13 @@ in {
 
       app-id = mkOption {
         type = types.str;
-        default = "docspell-joex1";
+        default = defaults.app-id;
         description = "The node id. Must be unique across all docspell nodes.";
       };
 
       base-url = mkOption {
         type = types.str;
-        default = "http://localhost:7878";
+        default = defaults.base-url;
         description = "The base url where attentive is deployed.";
       };
 
@@ -45,20 +93,17 @@ in {
           options = {
             address = mkOption {
               type = types.str;
-              default = "localhost";
+              default = defaults.bind.address;
               description = "The address to bind the REST server to.";
             };
             port = mkOption {
               type = types.int;
-              default = 7878;
+              default = defaults.bind.port;
               description = "The port to bind the REST server";
             };
           };
         });
-        default = {
-          address = "localhost";
-          port = 7878;
-        };
+        default = defaults.bind;
         description = "Address and port bind the rest server.";
       };
 
@@ -67,7 +112,7 @@ in {
           options = {
             url = mkOption {
               type = types.str;
-              default = "jdbc:h2:///tmp/docspell-demo.db;MODE=PostgreSQL;DATABASE_TO_LOWER=TRUE;AUTO_SERVER=TRUE";
+              default = defaults.jdbc.url;
               description = ''
                 The URL to the database. By default a file-based database is
                 used. It should also work with mariadb and postgresql.
@@ -81,21 +126,17 @@ in {
             };
             user = mkOption {
               type = types.str;
-              default = "sa";
+              default = defaults.jdbc.user;
               description = "The user name to connect to the database.";
             };
             password = mkOption {
               type = types.str;
-              default = "";
+              default = defaults.jdbc.password;
               description = "The password to connect to the database.";
             };
           };
         });
-        default = {
-          url = "jdbc:h2:///tmp/docspell-demo.db;MODE=PostgreSQL;DATABASE_TO_LOWER=TRUE;AUTO_SERVER=TRUE";
-          user = "sa";
-          password = "";
-        };
+        default = defaults.jdbc;
         description = "Database connection settings";
       };
 
@@ -104,12 +145,12 @@ in {
           options = {
             pool-size = mkOption {
               type = types.int;
-              default = 2;
+              default = defaults.scheduler.pool-size;
               description = "Number of processing allowed in parallel.";
             };
             counting-scheme = mkOption {
               type = types.str;
-              default = "4,1";
+              default = defaults.scheduler.counting-scheme;
               description = ''
                 A counting scheme determines the ratio of how high- and low-prio
                 jobs are run. For example: 4,1 means run 4 high prio jobs, then
@@ -118,7 +159,7 @@ in {
             };
             retries = mkOption {
               type = types.int;
-              default = 5;
+              default = defaults.scheduler.retries;
               description = ''
                 How often a failed job should be retried until it enters failed
                 state. If a job fails, it becomes "stuck" and will be retried
@@ -127,7 +168,7 @@ in {
             };
             retry-delay = mkOption {
               type = types.str;
-              default = "1 minute";
+              default = defaults.scheduler.retry-delay;
               description = ''
                 The delay until the next try is performed for a failed job. This
                 delay is increased exponentially with the number of retries.
@@ -135,14 +176,14 @@ in {
             };
             log-buffer-size = mkOption {
               type = types.int;
-              default = 500;
+              default = defaults.scheduler.log-buffer-size;
               description = ''
                 The queue size of log statements from a job.
               '';
             };
             wakeup-period = mkOption {
               type = types.str;
-              default = "30 minutes";
+              default = defaults.scheduler.wakeup-period;
               description = ''
                 If no job is left in the queue, the scheduler will wait until a
                 notify is requested (using the REST interface). To also retry
@@ -151,36 +192,11 @@ in {
             };
           };
         });
-        default = {
-          pool-size = 2;
-          counting-scheme = "4,1";
-          retries = 5;
-          retry-delay = "1 minute";
-          log-buffer-size = 500;
-          wakeup-period = "30 minutes";
-        };
+        default = defaults.scheduler;
         description = "Settings for the scheduler";
       };
 
-      extraction =
-        let
-          gsdefaults =  {
-            program = "${pkgs.ghostscript}/bin/gs";
-            args = [ "-dNOPAUSE" "-dBATCH" "-dSAFER" "-sDEVICE=tiffscaled8" "-sOutputFile={{outfile}}" "{{infile}}" ];
-            timeout = "5 minutes";
-          };
-          unpaperdefaults = {
-            program = "${pkgs.unpaper}/bin/unpaper";
-            args = [ "{{infile}}" "{{outfile}}" ];
-            timeout = "5 minutes";
-          };
-          tesseractdefaults = {
-            program = "${pkgs.tesseract4}/bin/tesseract";
-            args = ["{{file}}" "stdout" "-l" "{{lang}}" ];
-            timeout = "5 minutes";
-          };
-        in
-        mkOption {
+      extraction = mkOption {
         type = types.submodule({
           options = {
             page-range = mkOption {
@@ -188,14 +204,12 @@ in {
                 options = {
                   begin = mkOption {
                     type = types.int;
-                    default = 10;
+                    default = defaults.extraction.page-range.begin;
                     description = "Specifies the first N pages of a file to process.";
                   };
                 };
               });
-              default = {
-                begin = 10;
-              };
+              default = defaults.extraction.page-range;
               description = ''
                 Defines what pages to process. If a PDF with 600 pages is
                 submitted, it is probably not necessary to scan through all of
@@ -215,7 +229,7 @@ in {
                 options = {
                   working-dir = mkOption {
                     type = types.str;
-                    default = "/tmp/docspell-extraction";
+                    default = defaults.extraction.ghostscript.working-dir;
                     description = "Directory where the extraction processes can put their temp files";
                   };
                   command = mkOption {
@@ -223,30 +237,27 @@ in {
                       options = {
                         program = mkOption {
                           type = types.str;
-                          default = gsdefaults.program;
+                          default = defaults.extraction.ghostscript.command.program;
                           description = "The path to the executable.";
                         };
                         args = mkOption {
                           type = types.listOf types.str;
-                          default = gsdefaults.args;
+                          default = defaults.extraction.ghostscript.command.args;
                           description = "The arguments to the program";
                         };
                         timeout = mkOption {
                           type = types.str;
-                          default = gsdefaults.timeout;
+                          default = defaults.extraction.ghostscript.command.timeout;
                           description = "The timeout when executing the command";
                         };
                       };
                     });
-                    default = gsdefaults;
+                    default = defaults.extraction.ghostscript.command;
                     description = "The system command";
                   };
                 };
               });
-              default = {
-                command = gsdefaults;
-                working-dir = "/tmp/docspell-extraction";
-              };
+              default = defaults.extraction.ghostscript;
               description = "The ghostscript command.";
             };
             unpaper = mkOption {
@@ -257,29 +268,27 @@ in {
                       options = {
                         program = mkOption {
                           type = types.str;
-                          default = unpaperdefaults.program;
+                          default = defaults.extraction.unpaper.command.program;
                           description = "The path to the executable.";
                         };
                         args = mkOption {
                           type = types.listOf types.str;
-                          default = unpaperdefaults.args;
+                          default = defaults.extraction.unpaper.command.args;
                           description = "The arguments to the program";
                         };
                         timeout = mkOption {
                           type = types.str;
-                          default = unpaperdefaults.timeout;
+                          default = defaults.extraction.unpaper.command.timeout;
                           description = "The timeout when executing the command";
                         };
                       };
                     });
-                    default = unpaperdefaults;
+                    default = defaults.extraction.unpaper.command;
                     description = "The system command";
                   };
                 };
               });
-              default = {
-                command = unpaperdefaults;
-              };
+              default = defaults.extraction.unpaper;
               description = "The unpaper command.";
             };
             tesseract = mkOption {
@@ -290,42 +299,32 @@ in {
                       options = {
                         program = mkOption {
                           type = types.str;
-                          default = tesseractdefaults.program;
+                          default = defaults.extraction.tesseract.command.program;
                           description = "The path to the executable.";
                         };
                         args = mkOption {
                           type = types.listOf types.str;
-                          default = tesseractdefaults.args;
+                          default = defaults.extraction.tesseract.command.args;
                           description = "The arguments to the program";
                         };
                         timeout = mkOption {
                           type = types.str;
-                          default = tesseractdefaults.timeout;
+                          default = defaults.extraction.tesseract.command.timeout;
                           description = "The timeout when executing the command";
                         };
                       };
                     });
-                    default = tesseractdefaults;
+                    default = defaults.extraction.tesseract.command;
                     description = "The system command";
                   };
                 };
               });
-              default = {
-                command = tesseractdefaults;
-              };
+              default = defaults.extraction.tesseract;
               description = "The tesseract command.";
             };
           };
         });
-        default = {
-          page-range = {
-            begin = 10;
-          };
-          ghostscript = {
-            command = gsdefaults;
-            working-dir = "/tmp/docspell-extraction";
-          };
-        };
+        default = defaults.extraction;
         description = ''
           Configuration of text extraction
 
diff --git a/nix/module-server.nix b/nix/module-server.nix
index 47d1e7ad..7a160499 100644
--- a/nix/module-server.nix
+++ b/nix/module-server.nix
@@ -196,11 +196,7 @@ in {
                   };
                 };
               });
-              default = {
-                mode = "closed";
-                newInvitePassword = "";
-                inviteTime = "3 days";
-              };
+              default = defaults.backend.signup;
               description = "Registration settings";
             };
             files = mkOption {
diff --git a/nix/pkg.nix b/nix/pkg.nix
index 24ac3e11..c0177c17 100644
--- a/nix/pkg.nix
+++ b/nix/pkg.nix
@@ -1,6 +1,5 @@
-version: {stdenv, fetchzip, file, curl, inotifyTools, fetchurl, jre8_headless, bash}:
+cfg: {stdenv, fetchzip, file, curl, inotifyTools, fetchurl, jre8_headless, bash}:
 let
-#  version = "0.2.0";
   meta = with stdenv.lib; {
     description = "Docspell helps to organize and archive your paper documents.";
     homepage = https://github.com/eikek/docspell;
@@ -9,12 +8,9 @@ let
   };
 in
 { server = stdenv.mkDerivation rec {
-    name = "docspell-server-${version}";
+    name = "docspell-server-${cfg.version}";
 
-     src = fetchzip {
-       url = "https://github.com/eikek/docspell/releases/download/v${version}/docspell-restserver-${version}.zip";
-       sha256 = "1mpyd66pcsd2q4wx9vszldqlamz9qgv6abrxh7xwzw23np61avy5";
-     };
+     src = fetchzip cfg.server;
 
     buildInputs = [ jre8_headless ];
 
@@ -34,12 +30,9 @@ in
   };
 
   joex = stdenv.mkDerivation rec {
-    name = "docspell-joex-${version}";
+    name = "docspell-joex-${cfg.version}";
 
-     src = fetchzip {
-       url = "https://github.com/eikek/docspell/releases/download/v${version}/docspell-joex-${version}.zip";
-       sha256 = "1ycfcfcv24vvkdbzvnahj500gb5l9vdls4bxq0jd1zn72p4z765f";
-     };
+    src = fetchzip cfg.joex;
 
     buildInputs = [ jre8_headless ];
 
@@ -58,13 +51,10 @@ in
     inherit meta;
   };
 
-  tools = stdenv.mkDerivation rec {
-    name = "docspell-tools-${version}";
+  tools = stdenv.mkDerivation {
+    name = "docspell-tools-${cfg.version}";
 
-    src = fetchzip {
-      url = "https://github.com/eikek/docspell/releases/download/v${version}/docspell-tools-${version}.zip";
-      sha256 = "0hd93rlnnrq8xj7knp38x1jj2mv4y5lvbcv968bzk5f1az51qsvg";
-    };
+    src = fetchzip cfg.tools;
 
     buildPhase = "true";
 
diff --git a/nix/release.nix b/nix/release.nix
index 35bbd2af..2f5b3edf 100644
--- a/nix/release.nix
+++ b/nix/release.nix
@@ -1,15 +1,38 @@
-let
-  currentVersion =
-    let
-      file = builtins.readFile ../version.sbt;
-      comps = builtins.split ":=" file;
-      last = builtins.head (builtins.tail (builtins.filter builtins.isString comps));
-    in
-      builtins.replaceStrings ["\"" "\n" " "] ["" "" ""] last;
-in
 rec {
+  cfg = {
+    v0_2_0 = rec {
+      version = "0.2.0";
+      server = {
+        url = "https://github.com/eikek/docspell/releases/download/v${version}/docspell-restserver-${version}.zip";
+        sha256 = "1mpyd66pcsd2q4wx9vszldqlamz9qgv6abrxh7xwzw23np61avy5";
+      };
+      joex = {
+        url = "https://github.com/eikek/docspell/releases/download/v${version}/docspell-joex-${version}.zip";
+        sha256 = "1ycfcfcv24vvkdbzvnahj500gb5l9vdls4bxq0jd1zn72p4z765f";
+      };
+      tools = {
+        url = "https://github.com/eikek/docspell/releases/download/v${version}/docspell-tools-${version}.zip";
+        sha256 = "0hd93rlnnrq8xj7knp38x1jj2mv4y5lvbcv968bzk5f1az51qsvg";
+      };
+    };
+    v0_1_0 = rec {
+      version = "0.1.0";
+      server = {
+        url = "https://github.com/eikek/docspell/releases/download/v${version}/docspell-restserver-${version}.zip";
+        sha256 = "19bmvrk07s4gsw4dszbilfv7jns7bp20lfr0ia73xdmn5w8kdhq0";
+      };
+      joex = {
+        url = "https://github.com/eikek/docspell/releases/download/v${version}/docspell-joex-${version}.zip";
+        sha256 = "175yz0lxra0qv63xjl90hh32idm13c1k1aah2hqc0ncpx22scp5v";
+      };
+      tools = {
+        url = "https://github.com/eikek/docspell/releases/download/v${version}/docspell-tools-${version}.zip";
+        sha256 = "03w5cxylk2yfkah15qrx5cl21gfly0vwa0czglb1swsri3808rdb";
+      };
+    };
+  };
   pkg = v: import ./pkg.nix v;
-  currentPkg = pkg currentVersion;
+  currentPkg = pkg cfg.v0_2_0;
   module-joex = ./module-joex.nix;
   module-restserver = ./module-server.nix;
   module-consumedir = ./module-consumedir.nix;