From b256e3a44f9d9c10b1554c01cada888eb66312ab Mon Sep 17 00:00:00 2001
From: Robert Helgesson <robert@rycee.net>
Date: Mon, 6 May 2019 00:27:25 +0200
Subject: [PATCH] fontconfig: fix build error

This fixes a build error occurring when building a configuration
having fontconfig enabled and `home.packages` only containing one
package installing things to `/lib`.

Also adds a number of test cases to verify the fontconfig cache
generation functionality.

Fixes #703
---
 modules/misc/fontconfig.nix                   | 38 ++++++++++++++++---
 tests/default.nix                             |  1 +
 tests/modules/misc/fontconfig/default.nix     |  5 +++
 .../fontconfig/multiple-font-packages.nix     | 15 ++++++++
 .../misc/fontconfig/no-font-package.nix       | 17 +++++++++
 .../misc/fontconfig/single-font-package.nix   | 15 ++++++++
 6 files changed, 85 insertions(+), 6 deletions(-)
 create mode 100644 tests/modules/misc/fontconfig/default.nix
 create mode 100644 tests/modules/misc/fontconfig/multiple-font-packages.nix
 create mode 100644 tests/modules/misc/fontconfig/no-font-package.nix
 create mode 100644 tests/modules/misc/fontconfig/single-font-package.nix

diff --git a/modules/misc/fontconfig.nix b/modules/misc/fontconfig.nix
index 9f3def775..8dbcce53c 100644
--- a/modules/misc/fontconfig.nix
+++ b/modules/misc/fontconfig.nix
@@ -36,10 +36,29 @@ in
   };
 
   config = mkIf cfg.enable {
-    home.extraProfileCommands = ''
-      export FONTCONFIG_FILE=$(pwd)/fonts.conf
+    # Create two dummy files in /lib/fontconfig to make sure that
+    # buildEnv creates a real directory path. These files are removed
+    # in home.extraProfileCommands below so the packages will not
+    # become "runtime" dependencies.
+    home.packages = [
+      (pkgs.writeTextFile {
+        name = "hm-dummy1";
+        destination = "/lib/fontconfig/hm-dummy1";
+        text = "dummy";
+      })
 
-      cat > $FONTCONFIG_FILE << EOF
+      (pkgs.writeTextFile {
+        name = "hm-dummy2";
+        destination = "/lib/fontconfig/hm-dummy2";
+        text = "dummy";
+      })
+    ];
+
+    home.extraProfileCommands = ''
+      if [[ -d $out/lib/X11/fonts || -d $out/share/fonts ]]; then
+        export FONTCONFIG_FILE="$(pwd)/fonts.conf"
+
+        cat > $FONTCONFIG_FILE << EOF
       <?xml version='1.0'?>
       <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
       <fontconfig>
@@ -49,10 +68,17 @@ in
       </fontconfig>
       EOF
 
-      ${getBin pkgs.fontconfig}/bin/fc-cache -f
-      rm -f $out/lib/fontconfig/cache/CACHEDIR.TAG
+        ${getBin pkgs.fontconfig}/bin/fc-cache -f
+        rm -f $out/lib/fontconfig/cache/CACHEDIR.TAG
+        rmdir --ignore-fail-on-non-empty -p $out/lib/fontconfig/cache
 
-      unset FONTCONFIG_FILE
+        rm "$FONTCONFIG_FILE"
+        unset FONTCONFIG_FILE
+      fi
+
+      # Remove hacky dummy files.
+      rm $out/lib/fontconfig/hm-dummy?
+      rmdir --ignore-fail-on-non-empty -p $out/lib/fontconfig
     '';
 
     xdg.configFile = {
diff --git a/tests/default.nix b/tests/default.nix
index d186ee04d..91942a65a 100644
--- a/tests/default.nix
+++ b/tests/default.nix
@@ -35,6 +35,7 @@ import nmt {
     // import ./modules/systemd
   )
   // import ./modules/home-environment
+  // import ./modules/misc/fontconfig
   // import ./modules/programs/bash
   // import ./modules/programs/ssh
   // import ./modules/programs/tmux
diff --git a/tests/modules/misc/fontconfig/default.nix b/tests/modules/misc/fontconfig/default.nix
new file mode 100644
index 000000000..b669e1c34
--- /dev/null
+++ b/tests/modules/misc/fontconfig/default.nix
@@ -0,0 +1,5 @@
+{
+  fontconfig-no-font-package = ./no-font-package.nix;
+  fontconfig-single-font-package = ./single-font-package.nix;
+  fontconfig-multiple-font-packages = ./multiple-font-packages.nix;
+}
diff --git a/tests/modules/misc/fontconfig/multiple-font-packages.nix b/tests/modules/misc/fontconfig/multiple-font-packages.nix
new file mode 100644
index 000000000..3845b4ba4
--- /dev/null
+++ b/tests/modules/misc/fontconfig/multiple-font-packages.nix
@@ -0,0 +1,15 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+{
+  config = {
+    home.packages = [ pkgs.comic-relief pkgs.unifont ];
+
+    fonts.fontconfig.enable = true;
+
+    nmt.script = ''
+      assertDirectoryNotEmpty home-path/lib/fontconfig/cache
+    '';
+  };
+}
diff --git a/tests/modules/misc/fontconfig/no-font-package.nix b/tests/modules/misc/fontconfig/no-font-package.nix
new file mode 100644
index 000000000..c4c687a13
--- /dev/null
+++ b/tests/modules/misc/fontconfig/no-font-package.nix
@@ -0,0 +1,17 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+{
+  config = {
+    home.packages = [
+      # Look, no font!
+    ];
+
+    fonts.fontconfig.enable = true;
+
+    nmt.script = ''
+      assertPathNotExists home-path/lib/fontconfig/cache
+    '';
+  };
+}
diff --git a/tests/modules/misc/fontconfig/single-font-package.nix b/tests/modules/misc/fontconfig/single-font-package.nix
new file mode 100644
index 000000000..b70bdf8a9
--- /dev/null
+++ b/tests/modules/misc/fontconfig/single-font-package.nix
@@ -0,0 +1,15 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+{
+  config = {
+    home.packages = [ pkgs.comic-relief ];
+
+    fonts.fontconfig.enable = true;
+
+    nmt.script = ''
+      assertDirectoryNotEmpty home-path/lib/fontconfig/cache
+    '';
+  };
+}