{ pkgs, lib, ... }: rec { escapeTmpFileContents = contents: builtins.replaceStrings ["\n"] ["\\n"] contents; mkTmpFile = { type ? "f", target, mode ? "0700", user, group, contents }: "${type} \"${target}\" ${mode} ${user} ${group} - ${escapeTmpFileContents contents}"; mkRmTmpFile = { type ? "f", target }: "${if type == "d" then "R" else "r"} ${target}"; tmpFileType = lib.types.submodule ({ config, ... }: { options = { enable = lib.mkOption { type = lib.types.bool; default = true; }; type = lib.mkOption { type = lib.types.str; default = "f"; }; mode = lib.mkOption { type = lib.types.str; default = "0400"; }; user = lib.mkOption { type = lib.types.nullOr lib.types.str; default = null; }; group = lib.mkOption { type = lib.types.nullOr lib.types.str; default = null; }; executable = lib.mkOption { type = lib.types.bool; default = false; }; target = lib.mkOption { type = lib.types.str; }; source = lib.mkOption { type = lib.types.nullOr lib.types.path; default = null; }; text = lib.mkOption { type = lib.types.nullOr lib.types.lines; default = null; }; }; }); homeFileType = lib.types.attrsOf (lib.types.submodule ({ config, name, ... }: { options = { enable = lib.mkOption { type = lib.types.bool; default = true; }; type = lib.mkOption { type = lib.types.str; default = "f"; }; mode = lib.mkOption { type = lib.types.str; default = "0400"; }; user = lib.mkOption { type = lib.types.nullOr lib.types.str; default = null; }; group = lib.mkOption { type = lib.types.nullOr lib.types.str; default = null; }; executable = lib.mkOption { type = lib.types.bool; default = false; }; target = lib.mkOption { type = lib.types.str; }; source = lib.mkOption { type = lib.types.nullOr lib.types.path; default = null; }; text = lib.mkOption { type = lib.types.nullOr lib.types.lines; default = null; }; }; config = { target = lib.mkDefault name; source = lib.mkIf (config.text != null) (lib.mkDefault (pkgs.writeTextFile { inherit (config) text; executable = config.executable == true; name = storeFileName config.target; })); }; })); # 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 = [ "+" "." "_" "?" "=" ] ++ lib.lowerChars ++ lib.upperChars ++ lib.stringToCharacters "0123456789"; empties = l: lib.genList (x: "") (lib.length l); unsafeInName = lib.stringToCharacters (lib.replaceStrings safeChars (empties safeChars) path); safeName = lib.replaceStrings unsafeInName (empties unsafeInName) path; in "home_" + safeName; }