~ruther/nix-tmpactivator

ref: 8fa85e7ab5259c2807913f9aa888fed4d2aa92a5 nix-tmpactivator/modules/home.nix -rw-r--r-- 4.8 KiB
8fa85e7a — Rutherther feat: add nix registry management from nixos modules 11 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
{ pkgs, tmpLib, lib, config, ... }:

let
  homeFiles = lib.filterAttrs (name: conf: conf.enable) config.home.file;

  sourceStorePath = file:
    let
      sourcePath = toString file.source;
      sourceName = tmpLib.storeFileName (baseNameOf sourcePath);
    in
      if builtins.hasContext sourcePath
      then file.source
      else builtins.path { path = file.source; name = sourceName; };
in {
  options = {
    home = {
      user = lib.mkOption {
        type = lib.types.nullOr lib.types.str;
        default = null;
      };

      group = lib.mkOption {
        type = lib.types.nullOr lib.types.str;
        default = null;
      };

      homeDirectory = lib.mkOption {
        type = lib.types.str;
        default = "/home/${config.home.user}";
      };

      file = lib.mkOption {
        type = lib.types.attrsOf tmpLib.homeFileType;
        default = {};
      };

      packages = lib.mkOption {
        type = lib.types.listOf lib.types.package;
        default = [];
      };

      homeFilesPackage = lib.mkOption {
        type = lib.types.package;
      };

      path = lib.mkOption {
        type = lib.types.package;
      };
    };
  };

  config = lib.mkIf (config.home.user != null) {
    # tmpfiles.selfManagement.targetDir = "${config.home.homeDirectory}/.local/share/user-tmpfiles.d";
    tmpfiles.defaultUser = config.home.user;
    tmpfiles.defaultGroup = config.home.group;

    home.path = pkgs.buildEnv {
      name = "tmpactivator-profile";
      paths = config.home.packages;
    };

    tmpfiles.instances.home.files = [
      {
        type = "L+";
        mode = "-";
        user = "-";
        group = "-";
        text = "${config.home.path}";
        target = "${config.home.homeDirectory}/.tmpactivator-profile";
      }
    ] ++ (lib.attrValues (lib.mapAttrs (name: conf: {
      type = "L+";
      mode = "-";
      user = "-";
      group = "-";
      text = "${config.home.homeFilesPackage}/${name}";
      target = "${config.home.homeDirectory}/${name}";
    }) homeFiles)) ++ (lib.attrValues (lib.mapAttrs (name: conf: {
      type = "r";
      mode = "-";
      user = "-";
      group = "-";
      text = "-";
      target = "${config.home.homeDirectory}/${name}";
    }) homeFiles));

    home.homeFilesPackage = pkgs.runCommandLocal "home-files" {
      nativeBuildInputs = [ pkgs.xorg.lndir ];
    }
    (''
        mkdir -p $out

        # Needed in case /nix is a symbolic link.
        realOut="$(realpath -m "$out")"

        function insertFile() {
          local source="$1"
          local relTarget="$2"
          local executable="$3"
          local recursive="$4"

          # If the target already exists then we have a collision. Note, this
          # should not happen due to the assertion found in the 'files' module.
          # We therefore simply log the conflict and otherwise ignore it, mainly
          # to make the `files-target-config` test work as expected.
          if [[ -e "$realOut/$relTarget" ]]; then
            echo "File conflict for file '$relTarget'" >&2
            return
          fi

          # Figure out the real absolute path to the target.
          local target
          target="$(realpath -m "$realOut/$relTarget")"

          # Target path must be within $HOME.
          if [[ ! $target == $realOut* ]] ; then
            echo "Error installing file '$relTarget' outside \$HOME" >&2
            exit 1
          fi

          mkdir -p "$(dirname "$target")"
          if [[ -d $source ]]; then
            if [[ $recursive ]]; then
              mkdir -p "$target"
              lndir -silent "$source" "$target"
            else
              ln -s "$source" "$target"
            fi
          else
            [[ -x $source ]] && isExecutable=1 || isExecutable=""

            # Link the file into the home file directory if possible,
            # i.e., if the executable bit of the source is the same we
            # expect for the target. Otherwise, we copy the file and
            # set the executable bit to the expected value.
            if [[ $executable == inherit || $isExecutable == $executable ]]; then
              ln -s "$source" "$target"
            else
              cp "$source" "$target"

              if [[ $executable == inherit ]]; then
                # Don't change file mode if it should match the source.
                :
              elif [[ $executable ]]; then
                chmod +x "$target"
              else
                chmod -x "$target"
              fi
            fi
          fi
        }
      '' + lib.concatStrings (
        lib.mapAttrsToList (n: v: ''
          insertFile ${
            lib.escapeShellArgs [
              (sourceStorePath v)
              n
              (if v.executable == null
               then "inherit"
               else toString v.executable)
               "false"
            ]}
        '') homeFiles
      ));
  };
}
Do not follow this link