summaryrefslogtreecommitdiffstats
path: root/docs/inputs/index.md
blob: 9aff0257cb69f55b607b89f27d66a3e4c3c0b1a0 (plain)
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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# Index

## Preface {#preface}

Welcome to the Hjem documentation. This online manual aims to describe how to
get started with, use, and extend Hjem per your needs.

> [!TIP]
> We also provide a short [module option reference](/options.html). Hjem does
> not vendor any modules similar to Home-Manager and Nix-Darwin, but there
> exists a companion project that aims to bridge the gap between Hjem and
> per-program modules. If you are interested in such a setup, we encourage you
> to take a look at [Hjem Rum](https://github.com/snugnug/hjem-rum)

This page is still in early beta. If you think some things should be better
explained, or find bugs in the site please report them
[over at our issue tracker](https://github.com/feel-co/hjem/issues).

## Installing Hjem

[Nix Flakes]: https://nix.dev/concepts/flakes.html

The primary method of installing Hjem is through [Nix Flakes]. To get started,
you must first add Hjem as a flake input in your `flake.nix`.

```nix
# flake.nix
{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";

    # ↓  Add here in the 'inputs' section. The name is arbitrary.
    hjem = {
      url = "github:feel-co/hjem";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };
}
```

Then add the corresponding module for your system to your
system configuration.


Hjem is distributed as a **NixOS module**, **nix-darwin** or **finix** module
for the time being, and you must import it as such.
For the sake of brevity, this guide will demonstrate how to
import it from inside the `nixosSystem` call.

```nix
# flake.nix
{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";

    hjem = {
      url = "github:feel-co/hjem";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs = inputs: {
    nixosConfigurations."<your_configuration>" = inputs.nixpkgs.lib.nixosSystem {
      # ...
      modules = [
        inputs.hjem.nixosModules.default # <- needed for 'config.hjem' options
        # ...
      ];
      # ...
    };
  };
}
```

Alternatively, if you use nix-darwin:

```nix
# flake.nix
{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";

    nix-darwin = {
      url = "github:nix-darwin/nix-darwin";
      inputs.nixpkgs.follows = "nixpkgs";
    };

    hjem = {
      url = "github:feel-co/hjem";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs = inputs: {
    darwinConfigurations."<your_configuration>" = inputs.nix-darwin.lib.darwinSystem {
      # ...
      modules = [
        inputs.hjem.darwinModules.default # <- needed for 'config.hjem' options
        # ...
      ];
      # ...
    };
  };
}
```

or if you use finix:

```nix
# flake.nix
{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";

    finix.url = "github:finix-community/finix";

    hjem = {
      url = "github:feel-co/hjem";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs = inputs: {
    nixosConfigurations."<your_configuration>" = inputs.finix.lib.finixSystem {
      # ...
      modules = [
        inputs.hjem.finixModules.default # <- needed for 'config.hjem' options
        # ...
      ];
      # ...
    };
  };
}
```

> [!WARNING]
> nix-darwin and finix support is currently experimental;
> please report any issues to [the tracker](https://github.com/feel-co/hjem/issues).

## Usage

Hjem achieves its signature simplicity and robustness by shaving off the
unnecessary complexity and the boilerplate. Instead we expose a simple interface
used to link files: {option}`hjem.users.<username>.files`. This is the core of
Hjem―file linking.

### `hjem.users`

{option}`hjem.users` is the main entry point used to declare individual users
for Hjem. It contains several sub-options that may be used to control Hjem's
behaviour per user. You may refer to the option documentation for more details
on each bell and whistle. Important options to be aware of are as follows:

- {option}`hjem.users.<username>.enable` allows toggling file linking for individual
  users. Set to `true` by default, but can be used to toggle off file linking
  for individual users on a multi-tenant system.
- {option}`hjem.users.<username>.user` is the name of the user that will be defined.
  Set to `<username>` by default.
- {option}`hjem.users.<username>.directory` is your home directory. Files in
  `hjem.users.<username>.files` will always be relative to this directory.
- {option}`hjem.users.<username>.clobberFiles` decides whether Hjem should override
  if a file already exists at a target location. This default to `false`, but
  this can be enabled for all users by setting {option}`hjem.clobberByDefault`
  to `true`.

#### Example

Now, let's go over an example. In this case we have a user named "alice" whose
home directory we are looking to manage. Alice's home directory is
`/home/alice`, so we should first tell Hjem to look there in the configuration.
Since defined users are enabled by default, no need to set `enable` explicitly.

```nix
{
  hjem.users = {
    alice = {
      # enable = true; # This is not necessary, since enable is 'true' by default
      user = "alice"; # this is the name of the user
      directory = "/home/alice"; # where the user's $HOME resides
    };
  };
}
```

Once Hjem has some information about the user, i.e., the username and the user's
home directory, we can give Hjem some files to manage. Let's go over Hjem's file
linking capabilities with some basic examples.

1. You can use `files."<path/to/file>".text` to create a file at a given
   location with the `text` attribute as its contents. For example we can set
   `files.".config/foo".text = "Hello World!` to create
   `/home/alice/.config/foo` and it's contents will read "Hello World".
2. Similar to NixOS's `environment.etc`, Hjem files support a `.source` option
   which accepts a store path. For example:

   ```nix
   ".config/bar".source = pkgs.writeTextFile {
     name = "file-foo";
     text = ''
       file contents
     '';
   }
   ```

   Here, Hjem will link the store path `(pkgs.writeTextFile { ... }).outPath` to
   `$HOME/.config/bar`, and the store path will have the contents "file contents".

3. The most recent addition to Hjem's file linking interface is the `generator`
   attribute. It allows feeding a generator by which your values will be
   transformed. Consider the following example:

   ```nix
   ".config/baz" = {
    generator = lib.generators.toJSON {};
      value = {
        some = "contents";
      };
    };
   ```

   The result in `/home/alice/.config/baz` will be the JSON representation of
   the attribute set provided in `value`. This is helpful when you are writing
   files in specific formats expected by your programs. You could, say, use
   `(pkgs.formats.toml { }).generate` to write a TOML configuration file in
   `/home/alice/.config/jj/config.toml`

   ```nix
   ".config/baz" = {
      generator = (pkgs.formats.toml {}).generate "baz";
      value = {
        "ui.graph".style = "curved";
        "ui.movement".edit = true;
      };
    };
   ```

   This, of course, works with other formats and generators as well.

#### Bringing it together

Now that we have gone over individual examples, here is a more _complete_
example to give an idea of the bigger picture. By using (or abusing, up to you)
the `files` submodule you can write files and/or folders anywhere in your home directory.

```nix
{
  pkgs,
  lib,
  ...
}: {
  hjem.users.alice = {
    directory = "/home/alice"; # Alice's $HOME
    files = {
      # Write a text file in '/home/alice/.config/foo'
      # with the contents 'bar'
      ".config/foo".text = "bar";

      # Alternatively, create the file source using a writer. This can be used
      # to generate config files with various formats expected by different
      # programs such as but not limited to JSON and YAML.
      ".config/bar".source = pkgs.writeTextFile "file-foo" "file contents";

      # Generators can also be used to transform Nix values directly as an
      # alternative to passing the generator result to 'source'.
      ".config/baz" = {
        # 'generator' works with `pkgs.formats` too!
        generator = lib.generators.toJSON {};
        value = {
          some = "contents";
        };
      };

      # Write a folder in '/home/alice/.config/qux'
      ".config/qux".source = ./qux-folder;
    };
  };
}
```

With such a configuration, we can expect three files and one directory:

1. `~/.config/foo` with the contents "bar"
2. `~/.config/bar` with the contents "file contents"
3. `~/.config/baz` with the contents `"{\"some\":\"contents\"}"`
4. `~/.config/qux` with the contents of `./qux-folder`

#### Using Hjem To Install Packages {#installing-packages}

Hjem exposes an experimental interface for managing packages of individual
users. At its core, `hjem.users.<username>.packages` is identical to
`users.users.<username>.packages` as found in Nixpkgs. In fact, to avoid creating
additional environments Hjem maps your `hjem.users.<username>.packages` to
`users.users.<username>.packages`. This is provided as a convenient alias to manage
users in one place, but **this may be subject to change!**. Please report any
issues.