From eb2f62d0de9997b2f73b409a2843ac5968e1a6f3 Mon Sep 17 00:00:00 2001 From: Emily Date: Thu, 3 Aug 2023 02:11:40 +0100 Subject: [PATCH 1/5] fonts: use non-standard path in test Ensure that #665 works correctly. --- tests/fonts.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/fonts.nix b/tests/fonts.nix index acd1b13..e92b3bc 100644 --- a/tests/fonts.nix +++ b/tests/fonts.nix @@ -2,8 +2,8 @@ let font = pkgs.runCommand "font-0.0.0" {} '' - mkdir -p $out/share/fonts - touch $out/share/fonts/Font.ttf + mkdir -p $out + touch $out/Font.ttf ''; in From 09e72ff9b9a2d888aac70bc8019e5a0696f4c24c Mon Sep 17 00:00:00 2001 From: Emily Date: Thu, 3 Aug 2023 02:28:06 +0100 Subject: [PATCH 2/5] fonts: remove `with lib` --- modules/fonts/default.nix | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/modules/fonts/default.nix b/modules/fonts/default.nix index 7140639..cde6148 100644 --- a/modules/fonts/default.nix +++ b/modules/fonts/default.nix @@ -1,19 +1,17 @@ { config, lib, pkgs, ... }: -with lib; - let cfg = config.fonts; in { imports = [ - (mkRenamedOptionModule [ "fonts" "enableFontDir" ] [ "fonts" "fontDir" "enable" ]) + (lib.mkRenamedOptionModule [ "fonts" "enableFontDir" ] [ "fonts" "fontDir" "enable" ]) ]; options = { - fonts.fontDir.enable = mkOption { - type = types.bool; + fonts.fontDir.enable = lib.mkOption { + type = lib.types.bool; default = false; description = '' Whether to enable font management and install configured fonts to @@ -23,10 +21,10 @@ in ''; }; - fonts.fonts = mkOption { - type = types.listOf types.path; + fonts.fonts = lib.mkOption { + type = lib.types.listOf lib.types.path; default = [ ]; - example = literalExpression "[ pkgs.dejavu_fonts ]"; + example = lib.literalExpression "[ pkgs.dejavu_fonts ]"; description = '' List of fonts to install. @@ -48,7 +46,7 @@ in done ''; - system.activationScripts.fonts.text = optionalString cfg.fontDir.enable '' + system.activationScripts.fonts.text = lib.optionalString cfg.fontDir.enable '' # Set up fonts. echo "configuring fonts..." >&2 find -L "$systemConfig/Library/Fonts" -type f -print0 | while IFS= read -rd "" l; do From 27517d2d182629cf32020b9c77cffdc462a34c01 Mon Sep 17 00:00:00 2001 From: Emily Date: Thu, 3 Aug 2023 02:11:40 +0100 Subject: [PATCH 3/5] fonts: refactor `system.build.fonts` Process substitution behaves better with variables and it's good practice to use `lib.escapeShellArgs`. --- modules/fonts/default.nix | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/modules/fonts/default.nix b/modules/fonts/default.nix index cde6148..8bf5f72 100644 --- a/modules/fonts/default.nix +++ b/modules/fonts/default.nix @@ -41,9 +41,14 @@ in '' mkdir -p $out/Library/Fonts font_regexp='.*\.\(ttf\|ttc\|otf\|dfont\)' - find -L ${toString cfg.fonts} -regex "$font_regexp" -type f -print0 | while IFS= read -rd "" f; do - ln -sf "$f" $out/Library/Fonts - done + while IFS= read -rd "" f; do + ln -sf "$f" "$out/Library/Fonts" + done < <( + find -L ${lib.escapeShellArgs cfg.fonts} \ + -type f \ + -regex "$font_regexp" \ + -print0 + ) ''; system.activationScripts.fonts.text = lib.optionalString cfg.fontDir.enable '' From adf578e398445f981a36ad919928f23a1dd5ee12 Mon Sep 17 00:00:00 2001 From: Emily Date: Thu, 3 Aug 2023 02:11:40 +0100 Subject: [PATCH 4/5] fonts: reimplement and rename to `fonts.packages` Fixes: #120 Fixes: #722 Fixes: #752 Closes: #692 --- modules/fonts/default.nix | 67 ++++++++++++++++----------------------- tests/fonts.nix | 10 +++--- 2 files changed, 31 insertions(+), 46 deletions(-) diff --git a/modules/fonts/default.nix b/modules/fonts/default.nix index 8bf5f72..9ecb6eb 100644 --- a/modules/fonts/default.nix +++ b/modules/fonts/default.nix @@ -7,6 +7,10 @@ in { imports = [ (lib.mkRenamedOptionModule [ "fonts" "enableFontDir" ] [ "fonts" "fontDir" "enable" ]) + (lib.mkRemovedOptionModule [ "fonts" "fonts" ] '' + This option has been renamed to `fonts.packages' for consistency with NixOS. + + Note that the implementation now keeps fonts in `/Library/Fonts/Nix Fonts' to allow them to coexist with fonts not managed by nix-darwin; existing fonts will be left directly in `/Library/Fonts' without getting updates and should be manually removed.'') ]; options = { @@ -15,21 +19,16 @@ in default = false; description = '' Whether to enable font management and install configured fonts to - {file}`/Library/Fonts`. - - NOTE: removes any manually-added fonts. + {file}`/Library/Fonts/Nix Fonts`. ''; }; - fonts.fonts = lib.mkOption { + fonts.packages = lib.mkOption { type = lib.types.listOf lib.types.path; default = [ ]; example = lib.literalExpression "[ pkgs.dejavu_fonts ]"; description = '' List of fonts to install. - - Fonts present in later entries override those with the same filenames - in previous ones. ''; }; }; @@ -40,48 +39,36 @@ in { preferLocalBuild = true; } '' mkdir -p $out/Library/Fonts - font_regexp='.*\.\(ttf\|ttc\|otf\|dfont\)' + store_dir=${lib.escapeShellArg builtins.storeDir} while IFS= read -rd "" f; do - ln -sf "$f" "$out/Library/Fonts" + dest="$out/Library/Fonts/Nix Fonts/''${f#"$store_dir/"}" + mkdir -p "''${dest%/*}" + ln -sf "$f" "$dest" done < <( - find -L ${lib.escapeShellArgs cfg.fonts} \ + find -L ${lib.escapeShellArgs cfg.packages} \ -type f \ - -regex "$font_regexp" \ + -regex '.*\.\(ttf\|ttc\|otf\|dfont\)' \ -print0 ) ''; system.activationScripts.fonts.text = lib.optionalString cfg.fontDir.enable '' - # Set up fonts. - echo "configuring fonts..." >&2 - find -L "$systemConfig/Library/Fonts" -type f -print0 | while IFS= read -rd "" l; do - font=''${l##*/} - f=$(readlink -f "$l") - if [ ! -e "/Library/Fonts/$font" ]; then - echo "updating font $font..." >&2 - ln -fn -- "$f" /Library/Fonts 2>/dev/null || { - echo "Could not create hard link. Nix is probably on another filesystem. Copying the font instead..." >&2 - rsync -az --inplace "$f" /Library/Fonts - } - fi - done + printf >&2 'setting up /Library/Fonts/Nix Fonts...\n' - if [[ "`sw_vers -productVersion`" < "13.0" ]]; then - fontrestore default -n 2>&1 | while read -r f; do - case $f in - /Library/Fonts/*) - font=''${f##*/} - if [ ! -e "$systemConfig/Library/Fonts/$font" ]; then - echo "removing font $font..." >&2 - rm "/Library/Fonts/$font" - fi - ;; - /*) - # ignoring unexpected fonts - ;; - esac - done - fi + # rsync uses the mtime + size of files to determine whether they + # need to be copied by default. This is inadequate for Nix store + # paths, but we don't want to use `--checksum` as it makes + # activation consistently slow when you have large fonts + # installed. Instead, we ensure that fonts are linked according to + # their full store paths in `system.build.fonts`, so that any + # given font path should only ever have one possible content. + ${pkgs.rsync}/bin/rsync \ + --archive \ + --copy-links \ + --delete-during \ + --delete-missing-args \ + "$systemConfig/Library/Fonts/Nix Fonts" \ + '/Library/Fonts/' ''; }; diff --git a/tests/fonts.nix b/tests/fonts.nix index e92b3bc..57d61dc 100644 --- a/tests/fonts.nix +++ b/tests/fonts.nix @@ -9,15 +9,13 @@ in { fonts.fontDir.enable = true; - fonts.fonts = [ font ]; + fonts.packages = [ font ]; test = '' - echo "checking fonts in /Library/Fonts" >&2 - test -e ${config.out}/Library/Fonts/Font.ttf + echo "checking fonts in /Library/Fonts/Nix Fonts" >&2 + test -e "${config.out}/Library/Fonts/Nix Fonts"/*/Font.ttf echo "checking activation of fonts in /activate" >&2 - grep "fontrestore default -n 2>&1" ${config.out}/activate - grep 'ln -fn ".*" /Library/Fonts' ${config.out}/activate || grep 'rsync -az --inplace ".*" /Library/Fonts' ${config.out}/activate - grep 'rm "/Library/Fonts/.*"' ${config.out}/activate + grep '/Library/Fonts/Nix Fonts' ${config.out}/activate ''; } From 7d4f8672101536674ca5d75d91161474739a83e2 Mon Sep 17 00:00:00 2001 From: Emily Date: Thu, 3 Aug 2023 02:11:40 +0100 Subject: [PATCH 5/5] fonts: remove `fonts.fontDir.enable` As far as I can tell, this isn't required to get fonts to work on NixOS, so we shouldn't require it on nix-darwin either, even if the implementations are superficially similar. --- modules/fonts/default.nix | 16 ++++------------ tests/fonts.nix | 1 - 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/modules/fonts/default.nix b/modules/fonts/default.nix index 9ecb6eb..b0bd63f 100644 --- a/modules/fonts/default.nix +++ b/modules/fonts/default.nix @@ -6,7 +6,8 @@ in { imports = [ - (lib.mkRenamedOptionModule [ "fonts" "enableFontDir" ] [ "fonts" "fontDir" "enable" ]) + (lib.mkRemovedOptionModule [ "fonts" "enableFontDir" ] "No nix-darwin equivalent to this NixOS option. This is not required to install fonts.") + (lib.mkRemovedOptionModule [ "fonts" "fontDir" "enable" ] "No nix-darwin equivalent to this NixOS option. This is not required to install fonts.") (lib.mkRemovedOptionModule [ "fonts" "fonts" ] '' This option has been renamed to `fonts.packages' for consistency with NixOS. @@ -14,21 +15,12 @@ in ]; options = { - fonts.fontDir.enable = lib.mkOption { - type = lib.types.bool; - default = false; - description = '' - Whether to enable font management and install configured fonts to - {file}`/Library/Fonts/Nix Fonts`. - ''; - }; - fonts.packages = lib.mkOption { type = lib.types.listOf lib.types.path; default = [ ]; example = lib.literalExpression "[ pkgs.dejavu_fonts ]"; description = '' - List of fonts to install. + List of fonts to install into {file}`/Library/Fonts/Nix Fonts`. ''; }; }; @@ -52,7 +44,7 @@ in ) ''; - system.activationScripts.fonts.text = lib.optionalString cfg.fontDir.enable '' + system.activationScripts.fonts.text = '' printf >&2 'setting up /Library/Fonts/Nix Fonts...\n' # rsync uses the mtime + size of files to determine whether they diff --git a/tests/fonts.nix b/tests/fonts.nix index 57d61dc..d60979c 100644 --- a/tests/fonts.nix +++ b/tests/fonts.nix @@ -8,7 +8,6 @@ let in { - fonts.fontDir.enable = true; fonts.packages = [ font ]; test = ''