Skip to content

Commit

Permalink
Add home-manager service module (#185)
Browse files Browse the repository at this point in the history
* Add home-manager service module

Resolves #159

* Add documentation for home-manager module
  • Loading branch information
rvl authored Nov 3, 2021
1 parent 71abc42 commit fd2d1cf
Show file tree
Hide file tree
Showing 3 changed files with 182 additions and 1 deletion.
62 changes: 62 additions & 0 deletions docs/tips/nix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Using on Nix/NixOS

Emanote can be easily built using the Nix expressions provided in its source repo.

You will need [Nix](https://nixos.org/download.html) version 2.4 or greater.

## Installing with Nix Flakes

This will provide the `emanote` command in your environment.

```sh-session
$ nix profile install github:srid/emanote
```

## Using Emanote as a Home Manager service

[Home Manager][home-manager] is a
Nix-based personal configuration manager. If you use Home Manager,
then Emanote has a [module][] that can be imported into your
configuration.

Merge or import this config into your `~/.config/nixpkgs/home.nix`:
```nix
{ config, ... }:
let
emanote = import (builtins.fetchTarball "https://github.com/srid/emanote/archive/master.tar.gz");
in {
imports = [ emanote.homeManagerModule ];
services.emanote = {
enable = true;
# host = "127.0.0.1"; # default listen address is 127.0.0.1
# port = 7000; # default http port is 7000
notes = [
"/home/user/notes" # add as many layers as you like
];
package = emanote.defaultPackage.${builtins.currentSystem};
};
}
```

Re-apply your home-manager configuration the usual way (e.g. `home-manager switch`).

You will then have an `emanote` command in your profile, and a systemd
user service running a live-preview of your notes.

```sh-session
$ home-manager switch
...
$ systemctl --user status emanote.service
● emanote.service - Emanote web server
Loaded: loaded (/nix/store/i1af5hdydwcf7y0r55n7fd67dnw5habd-home-manager-files/.config/systemd/user/emanote.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2021-11-02 17:17:04 AWST; 17h ago
Main PID: 1705303 (emanote)
Tasks: 26 (limit: 38220)
Memory: 38.3M
CPU: 2.884s
CGroup: /user.slice/user-1000.slice/[email protected]/app.slice/emanote.service
└─1705303 /nix/store/9hj2cwk1jakfws0d1hpwa221kcni3j45-emanote-0.3.12.1/bin/emanote --layers /nix/store/hr7wp1xvqn48b8gy16sdq6k2csrvr8c1-emanote-config;/home/user/notes
```

[home-manager]: https://github.com/nix-community/home-manager
[module]: https://github.com/srid/emanote/blob/master/home-manager-module.nix
5 changes: 4 additions & 1 deletion flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -80,5 +80,8 @@

# Used by `nix develop`
devShell = project true;
});
}) //
{
homeManagerModule = import ./home-manager-module.nix;
};
}
116 changes: 116 additions & 0 deletions home-manager-module.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
{ config, lib, pkgs, ... }: let

cfg = config.services.emanote;

yamlFormat = pkgs.formats.yaml { } // {
generateDir = name: path: value:
(yamlFormat.generate path value).overrideAttrs (attrs: {
inherit name;
buildCommand = ''
mkdir -p $out
out="$out/${path}"
${attrs.buildCommand}
'';
});
};

extraConfig = lib.recursiveUpdate cfg.extraConfig {
template.baseUrl = cfg.baseUrl;
};
configLayer = yamlFormat.generateDir "emanote-config" "/index.yaml" extraConfig;
layers = map toString ([configLayer] ++ cfg.notes);

in {
options = {
services.emanote = with lib; {
enable = mkEnableOption ''
Enable the Emanote service, to create beautiful websites --
such as your personal webpage, blog, wiki, Zettelkasten,
notebook, knowledge-base, documentation, etc. from
future-proof plain-text notes and arbitrary data -- with a
live preview that updates in real-time.
'';

package = mkOption {
type = types.package;
default = pkgs.emanote;
defaultText = "pkgs.emanote";
description = "Emanote derivation to use";
};

notes = mkOption {
type = types.nonEmptyListOf (types.either types.path types.str);
default = [ "${config.home.homeDirectory}/Documents/Notes" ];
defaultText = literalExample ''[ ''${config.home.homeDirectory}/Documents/Notes" ]'';
description = ''
List of notebook folders to 'union mount', with earlier
paths in the list taking priority over later paths.
'';
};

host = mkOption {
type = types.str;
default = "127.0.0.1";
description = "The hostname or IP address the HTTP server should listen to";
};

port = mkOption {
type = types.port;
default = 7000;
description = "The port on which the HTTP server listens.";
};

baseUrl = mkOption {
type = types.str;
description = "Base href for hyperlinks on the site.";
default = "/";
example = "/emanote/";
};

extraConfig = mkOption {
inherit (yamlFormat) type;
default = { };
example = {
template.urlStrategy = "pretty";
};
description = ''
Config that will be layered over the default notes configs.
See https://note.ema.srid.ca/demo/yaml-config for
information about the format.
'';
};

systemdTarget = mkOption {
type = types.str;
default = "graphical-session.target";
description = ''
The systemd user unit which
<literal>emanote.service<literal> should be a part of.
'';
};
};
};

config = lib.mkIf cfg.enable {
home.packages = [ cfg.package ];

systemd.user.services.emanote = {
Unit = {
Description = "Emanote web server";
PartOf = [ cfg.systemdTarget ];
After = [ cfg.systemdTarget ];
};
Install.WantedBy = [ cfg.systemdTarget ];
Service = {
Environment = [
"PORT=${builtins.toString cfg.port}"
"HOST=${cfg.host}"
];
ExecStart = ''
${cfg.package}/bin/emanote --layers "${lib.concatStringsSep ";" layers}"
'';
};
};
};
}

0 comments on commit fd2d1cf

Please sign in to comment.