From 4f842d9f1b137d98ad4e6393b16b038bbab2bad2 Mon Sep 17 00:00:00 2001 From: Robert Helgesson Date: Mon, 6 Nov 2017 10:28:54 +0100 Subject: [PATCH] files: extract type of `home.file` into own file --- modules/files.nix | 86 ++----------------------------- modules/lib/file-type.nix | 105 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+), 82 deletions(-) create mode 100644 modules/lib/file-type.nix diff --git a/modules/files.nix b/modules/files.nix index 66d715100..c61560c5b 100644 --- a/modules/files.nix +++ b/modules/files.nix @@ -9,27 +9,9 @@ let homeDirectory = config.home.homeDirectory; - # Figures out a valid Nix store name for the given path. - storeFileName = path: - let - # All characters that are considered safe. Note "-" is not - # included to avoid "-" followed by digit being interpreted as a - # version. - safeChars = - [ "+" "." "_" "?" "=" ] - ++ lowerChars - ++ upperChars - ++ stringToCharacters "0123456789"; - - empties = l: genList (x: "") (length l); - - unsafeInName = stringToCharacters ( - replaceStrings safeChars (empties safeChars) path - ); - - safeName = replaceStrings unsafeInName (empties unsafeInName) path; - in - "home_file_" + safeName; + fileType = (import lib/file-type.nix { + inherit homeDirectory lib pkgs; + }).fileType; # A symbolic link whose target path matches this pattern will be # considered part of a Home Manager generation. @@ -42,67 +24,7 @@ in home.file = mkOption { description = "Attribute set of files to link into the user home."; default = {}; - type = types.loaOf (types.submodule ( - { name, config, ... }: { - options = { - target = mkOption { - type = types.str; - apply = removePrefix (homeDirectory + "/"); - description = '' - Path to target file relative to HOME. - ''; - }; - - text = mkOption { - default = null; - type = types.nullOr types.lines; - description = "Text of the file."; - }; - - source = mkOption { - type = types.path; - description = '' - Path of the source file. The file name must not start - with a period since Nix will not allow such names in - the Nix store. - - This may refer to a directory. - ''; - }; - - mode = mkOption { - type = types.nullOr types.str; - default = null; - description = '' - The permissions to apply to the file. - - DEPRECATED: use home.file.<name?>.executable - instead. - ''; - }; - - executable = mkOption { - type = types.nullOr types.bool; - default = null; - description = '' - Set the execute bit. If null, defaults to the mode - of the source file or to false - for files created through the text option. - ''; - }; - }; - - config = { - target = mkDefault name; - source = mkIf (config.text != null) ( - mkDefault (pkgs.writeTextFile { - inherit (config) executable text; - name = storeFileName name; - }) - ); - }; - }) - ); + type = fileType "HOME" homeDirectory; }; home-files = mkOption { diff --git a/modules/lib/file-type.nix b/modules/lib/file-type.nix new file mode 100644 index 000000000..ebdcb7741 --- /dev/null +++ b/modules/lib/file-type.nix @@ -0,0 +1,105 @@ +{ homeDirectory, lib, pkgs }: + +with lib; + +let + + # Figures out a valid Nix store name for the given path. + storeFileName = path: + let + # All characters that are considered safe. Note "-" is not + # included to avoid "-" followed by digit being interpreted as a + # version. + safeChars = + [ "+" "." "_" "?" "=" ] + ++ lowerChars + ++ upperChars + ++ stringToCharacters "0123456789"; + + empties = l: genList (x: "") (length l); + + unsafeInName = stringToCharacters ( + replaceStrings safeChars (empties safeChars) path + ); + + safeName = replaceStrings unsafeInName (empties unsafeInName) path; + in + "home_file_" + safeName; + +in + +{ + # Constructs a type suitable for a `home.file` like option. The + # target path may be either absolute or relative, in which case it + # is relative the `basePath` argument (which itself must be an + # absolute path). + # + # Arguments: + # - basePathDesc docbook compatible description of the base path + # - basePath the file base path + fileType = basePathDesc: basePath: types.loaOf (types.submodule ( + { name, config, ... }: { + options = { + target = mkOption { + type = types.str; + apply = p: + let + absPath = if hasPrefix "/" p then p else "${basePath}/${p}"; + in + removePrefix (homeDirectory + "/") absPath; + description = '' + Path to target file relative to ${basePathDesc}. + ''; + }; + + text = mkOption { + default = null; + type = types.nullOr types.lines; + description = "Text of the file."; + }; + + source = mkOption { + type = types.path; + description = '' + Path of the source file. The file name must not start + with a period since Nix will not allow such names in + the Nix store. + + This may refer to a directory. + ''; + }; + + mode = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + The permissions to apply to the file. + + DEPRECATED: use home.file.<name?>.executable + instead. + ''; + }; + + executable = mkOption { + type = types.nullOr types.bool; + default = null; + description = '' + Set the execute bit. If null, defaults to the mode + of the source file or to false + for files created through the text option. + ''; + }; + }; + + config = { + target = mkDefault name; + source = mkIf (config.text != null) ( + mkDefault (pkgs.writeTextFile { + inherit (config) executable text; + name = storeFileName name; + }) + ); + }; + } + )); +}