mirror of
https://github.com/nix-community/home-manager.git
synced 2026-01-11 17:39:37 +08:00
Compare commits
52 Commits
a97b0a0999
...
systemd-ad
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fb4c7e7ed2 | ||
|
|
ef0a84e496 | ||
|
|
0e4217b2c4 | ||
|
|
90e53291cb | ||
|
|
480b0b2b81 | ||
|
|
b52d47d670 | ||
|
|
f4bcc1ae1c | ||
|
|
297a085108 | ||
|
|
cd6e96d56e | ||
|
|
b1b1c68033 | ||
|
|
081234b704 | ||
|
|
2be878259a | ||
|
|
fa6de26b4d | ||
|
|
9fff37e6ff | ||
|
|
a2cc7b0bab | ||
|
|
37158e5267 | ||
|
|
cd74467526 | ||
|
|
72476602b9 | ||
|
|
e926e27968 | ||
|
|
db116ceb76 | ||
|
|
f7b2bdf042 | ||
|
|
a1a11393d9 | ||
|
|
802ce0a7b1 | ||
|
|
e69fbc243a | ||
|
|
ebab435f3e | ||
|
|
bacad23b8c | ||
|
|
6067be4770 | ||
|
|
12a723df97 | ||
|
|
40deed4ffe | ||
|
|
9500721e96 | ||
|
|
db105fadc4 | ||
|
|
609846bfd2 | ||
|
|
2db6bcc7ca | ||
|
|
a3ac4bb1f8 | ||
|
|
47db0fde35 | ||
|
|
3351348827 | ||
|
|
7688293f06 | ||
|
|
92394f9dea | ||
|
|
fb6a8404ee | ||
|
|
9afe77a70b | ||
|
|
246b8eaffb | ||
|
|
f9ce7c5234 | ||
|
|
d1da1de5c2 | ||
|
|
af7f14ddf7 | ||
|
|
46c9af8a92 | ||
|
|
a630bbdedd | ||
|
|
86e0f6f227 | ||
|
|
d4c406cfa8 | ||
|
|
4fee4bd14b | ||
|
|
c068188a8e | ||
|
|
bdaa374383 | ||
|
|
d28cc9f4a6 |
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -22,7 +22,7 @@ Also make sure to read the guidelines found at
|
||||
- [ ] Change is backwards compatible.
|
||||
|
||||
- [ ] Code formatted with `nix fmt` or
|
||||
`nix-shell -p treefmt nixfmt deadnix keep-sorted --run treefmt`.
|
||||
`nix-shell -p treefmt nixfmt deadnix keep-sorted nixf-diagnose --run treefmt`.
|
||||
|
||||
- [ ] Code tested through `nix run .#tests -- test-all` or
|
||||
`nix-shell --pure tests -A run.all`.
|
||||
|
||||
2
.github/labeler.yml
vendored
2
.github/labeler.yml
vendored
@@ -165,7 +165,7 @@
|
||||
"containers":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- modules/services/podman-linux/**/*
|
||||
- modules/services/podman/linux/**/*
|
||||
- modules/programs/distrobox.nix
|
||||
- modules/programs/docker-cli.nix
|
||||
"desktop-ui":
|
||||
|
||||
5
.github/workflows/validate-maintainers.yml
vendored
5
.github/workflows/validate-maintainers.yml
vendored
@@ -1,7 +1,10 @@
|
||||
name: Validate maintainers.nix
|
||||
on:
|
||||
pull_request:
|
||||
paths: ["modules/lib/maintainers.nix"]
|
||||
paths:
|
||||
- "modules/lib/maintainers.nix"
|
||||
- "flake.lock"
|
||||
- "all-maintainers.nix"
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
run_tests:
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017-2025 Home Manager contributors
|
||||
Copyright (c) 2017-2026 Home Manager contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
2
Makefile
2
Makefile
@@ -17,4 +17,4 @@ test-install:
|
||||
HOME=$(shell mktemp -d) NIX_PATH=${NIX_PATH} nix-shell . -A install
|
||||
|
||||
format:
|
||||
nix-shell -p treefmt nixfmt deadnix keep-sorted --run "treefmt --config-file ./treefmt.toml"
|
||||
nix-shell -p treefmt nixfmt deadnix keep-sorted nixf-diagnose --run "treefmt --config-file ./treefmt.toml"
|
||||
|
||||
@@ -19,6 +19,11 @@
|
||||
email = "da157@voidq.com";
|
||||
github = "0xda157";
|
||||
githubId = 153149335;
|
||||
keys = [
|
||||
{
|
||||
fingerprint = "5A66 FF95 36DE B501 DDD2 1647 B7AC 1B10 365D 45FF";
|
||||
}
|
||||
];
|
||||
matrix = "@da157:catgirl.cloud";
|
||||
name = "0xda157";
|
||||
source = "nixpkgs";
|
||||
@@ -65,14 +70,6 @@
|
||||
name = "Alex";
|
||||
source = "home-manager";
|
||||
};
|
||||
AndersonTorres = {
|
||||
email = "torres.anderson.85@protonmail.com";
|
||||
github = "AndersonTorres";
|
||||
githubId = 5954806;
|
||||
matrix = "@anderson_torres:matrix.org";
|
||||
name = "Anderson Torres";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
AndreasMager = {
|
||||
email = "andreas@mager.eu";
|
||||
github = "AndreasMager";
|
||||
@@ -1760,7 +1757,7 @@
|
||||
github = "nickthegroot";
|
||||
githubId = 1966472;
|
||||
name = "Nick DeGroot";
|
||||
source = "home-manager";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
nikp123 = {
|
||||
email = "nikp123@users.noreply.github.com";
|
||||
@@ -2012,7 +2009,7 @@
|
||||
github = "rrvsh";
|
||||
githubId = 20300874;
|
||||
name = "Mohammad Rafiq";
|
||||
source = "home-manager";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
rszamszur = {
|
||||
email = "radoslawszamszur@gmail.com";
|
||||
|
||||
@@ -110,8 +110,7 @@ let
|
||||
in
|
||||
pkgs.buildPackages.nixosOptionsDoc (
|
||||
{
|
||||
options =
|
||||
if includeModuleSystemOptions then options else builtins.removeAttrs options [ "_module" ];
|
||||
options = if includeModuleSystemOptions then options else removeAttrs options [ "_module" ];
|
||||
transformOptions =
|
||||
opt:
|
||||
opt
|
||||
@@ -133,7 +132,7 @@ let
|
||||
) opt.declarations;
|
||||
};
|
||||
}
|
||||
// builtins.removeAttrs args [
|
||||
// removeAttrs args [
|
||||
"modules"
|
||||
"includeModuleSystemOptions"
|
||||
]
|
||||
|
||||
@@ -17,8 +17,11 @@ way. In Bash and Z shell this can be done by adding
|
||||
to your `.profile` and `.zshrc` files, respectively. The
|
||||
`hm-session-vars.sh` file should work in most Bourne-like shells. For
|
||||
fish shell, it is possible to source it using [the foreign-env
|
||||
plugin](https://github.com/oh-my-fish/plugin-foreign-env)
|
||||
plugin](https://github.com/oh-my-fish/plugin-foreign-env) or using the builtin
|
||||
[babelfish](https://github.com/bouk/babelfish)-translated variables:
|
||||
|
||||
``` bash
|
||||
fenv source "$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh" > /dev/null
|
||||
# or
|
||||
source "$HOME/.nix-profile/etc/profile.d/hm-session-vars.fish"
|
||||
```
|
||||
|
||||
6
flake.lock
generated
6
flake.lock
generated
@@ -2,11 +2,11 @@
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1767640445,
|
||||
"narHash": "sha256-UWYqmD7JFBEDBHWYcqE6s6c77pWdcU/i+bwD6XxMb8A=",
|
||||
"lastModified": 1767767207,
|
||||
"narHash": "sha256-Mj3d3PfwltLmukFal5i3fFt27L6NiKXdBezC1EBuZs4=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "9f0c42f8bc7151b8e7e5840fb3bd454ad850d8c5",
|
||||
"rev": "5912c1772a44e31bf1c63c0390b90501e5026886",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
nixfmt
|
||||
deadnix
|
||||
keep-sorted
|
||||
nixf-diagnose
|
||||
];
|
||||
settings = pkgs.lib.importTOML ./treefmt.toml;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Project-Id-Version: Home Manager\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n"
|
||||
"POT-Creation-Date: 2025-07-22 10:59+0200\n"
|
||||
"PO-Revision-Date: 2025-11-30 14:00+0000\n"
|
||||
"PO-Revision-Date: 2026-01-07 17:01+0000\n"
|
||||
"Last-Translator: Brian E <brianellingsgaard9@gmail.com>\n"
|
||||
"Language-Team: Faroese <https://hosted.weblate.org/projects/home-manager/cli/"
|
||||
"fo/>\n"
|
||||
@@ -17,7 +17,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 5.15-dev\n"
|
||||
"X-Generator: Weblate 5.15.1\n"
|
||||
|
||||
#. translators: For example: "home-manager: missing argument for --cores"
|
||||
#: home-manager/home-manager:16
|
||||
@@ -41,10 +41,12 @@ msgid ""
|
||||
"Keeping your Home Manager %s in %s is deprecated,\n"
|
||||
"please move it to %s"
|
||||
msgstr ""
|
||||
"At hava Heimvørðurin %s í %s er fyrnast,\n"
|
||||
"vinarliga flyt hann til %s"
|
||||
|
||||
#: home-manager/home-manager:99
|
||||
msgid "No configuration file found. Please create one at %s"
|
||||
msgstr ""
|
||||
msgstr "Eingin samansetingsfíla funni. Vinarliga stovna ein hjá %s"
|
||||
|
||||
#: home-manager/home-manager:114
|
||||
msgid "Home Manager not found at %s."
|
||||
|
||||
@@ -31,7 +31,7 @@ let
|
||||
modules = [ configuration ] ++ hmModules;
|
||||
class = "homeManager";
|
||||
specialArgs = {
|
||||
modulesPath = builtins.toString ./.;
|
||||
modulesPath = toString ./.;
|
||||
}
|
||||
// extraSpecialArgs;
|
||||
};
|
||||
|
||||
@@ -192,7 +192,7 @@ in
|
||||
++ lib.optionals (cfg.quickPhraseFiles != { }) [
|
||||
(pkgs.linkFarm "quickPhraseFiles" (
|
||||
lib.mapAttrs' (
|
||||
name: value: lib.nameValuePair ("share/fcitx5/data/quickphrase.d/${name}.mb") value
|
||||
name: value: lib.nameValuePair "share/fcitx5/data/quickphrase.d/${name}.mb" value
|
||||
) cfg.quickPhraseFiles
|
||||
))
|
||||
];
|
||||
|
||||
@@ -13,12 +13,9 @@ let
|
||||
mergeDefinitions
|
||||
;
|
||||
inherit (builtins)
|
||||
map
|
||||
filter
|
||||
length
|
||||
deepSeq
|
||||
throw
|
||||
toString
|
||||
concatLists
|
||||
;
|
||||
inherit (lib.options) showDefs;
|
||||
|
||||
@@ -63,12 +63,12 @@ let
|
||||
intervalsString = lib.concatStringsSep ", " intervals;
|
||||
|
||||
assertInterval = option: interval: pkgs: {
|
||||
assertion = (!pkgs.stdenv.isDarwin) || (lib.elem interval intervals);
|
||||
message = "On Darwin ${option} must be one of: ${intervalsString}.";
|
||||
assertion = pkgs.stdenv.isDarwin -> lib.elem interval intervals;
|
||||
message = "On Darwin, ${option} must be one of: ${intervalsString}.";
|
||||
};
|
||||
|
||||
intervalDocumentation = ''
|
||||
On Darwin it must be one of: ${intervalsString}, which are implemented as defined in {manpage}`systemd.time(7)`.
|
||||
On Darwin, it must be one of: ${intervalsString}, which are implemented as defined in {manpage}`systemd.time(7)`.
|
||||
'';
|
||||
in
|
||||
{
|
||||
|
||||
@@ -175,6 +175,12 @@
|
||||
github = "exzombie";
|
||||
githubId = 11456290;
|
||||
};
|
||||
farberbrodsky = {
|
||||
name = "Michael Farber Brodsky";
|
||||
email = "misha@farberbrodsky.com";
|
||||
github = "farberbrodsky";
|
||||
githubId = 36243759;
|
||||
};
|
||||
fendse = {
|
||||
email = "46252070+Fendse@users.noreply.github.com";
|
||||
github = "Fendse";
|
||||
@@ -423,12 +429,6 @@
|
||||
github = "natecox";
|
||||
githubId = 2782695;
|
||||
};
|
||||
nickthegroot = {
|
||||
name = "Nick DeGroot";
|
||||
email = "nick@nickthegroot.com";
|
||||
github = "nickthegroot";
|
||||
githubId = 1966472;
|
||||
};
|
||||
nikp123 = {
|
||||
name = "nikp123";
|
||||
email = "nikp123@users.noreply.github.com";
|
||||
@@ -507,12 +507,6 @@
|
||||
github = "Rosuavio";
|
||||
githubId = 7164552;
|
||||
};
|
||||
rrvsh = {
|
||||
name = "Mohammad Rafiq";
|
||||
email = "rafiq@rrv.sh";
|
||||
github = "rrvsh";
|
||||
githubId = 20300874;
|
||||
};
|
||||
rszamszur = {
|
||||
name = "Radosław Szamszur";
|
||||
email = "radoslawszamszur@gmail.com";
|
||||
|
||||
@@ -278,7 +278,7 @@ in
|
||||
else if builtins.isString value then
|
||||
"<const>${value}</const>"
|
||||
else
|
||||
throw ("expected bool or string but got ${builtins.typeOf value}: ${toString value}");
|
||||
throw "expected bool or string but got ${builtins.typeOf value}: ${toString value}";
|
||||
in
|
||||
''
|
||||
<match target="font">
|
||||
@@ -338,7 +338,7 @@ in
|
||||
|
||||
xdg.configFile = lib.mapAttrs' (
|
||||
name: config:
|
||||
lib.nameValuePair "fontconfig/conf.d/${builtins.toString config.priority}-hm-${config.label}.conf" {
|
||||
lib.nameValuePair "fontconfig/conf.d/${toString config.priority}-hm-${config.label}.conf" {
|
||||
inherit (config) enable text;
|
||||
source = lib.mkIf (config.source != null) config.source;
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ let
|
||||
fileList ++ subdirFiles;
|
||||
|
||||
newsFiles = collectNixFiles ./news;
|
||||
newsEntries = builtins.map (
|
||||
newsEntries = map (
|
||||
newsFile:
|
||||
let
|
||||
imported = import newsFile;
|
||||
|
||||
34
modules/misc/news/2025/11/2025-11-04_16-44-03.nix
Normal file
34
modules/misc/news/2025/11/2025-11-04_16-44-03.nix
Normal file
@@ -0,0 +1,34 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
{
|
||||
time = "2025-11-04T15:44:03+00:00";
|
||||
condition = true;
|
||||
message = ''
|
||||
The 'services.podman' module now supports Darwin (macOS) with declarative
|
||||
machine management.
|
||||
|
||||
On Darwin, podman requires running containers inside a virtual machine.
|
||||
The new configuration options allow you to declaratively manage podman
|
||||
machines with automatic creation, configuration, and startup.
|
||||
|
||||
By default, a machine named 'podman-machine-default' will be created
|
||||
automatically. You can customize machines or disable the default with:
|
||||
|
||||
services.podman.useDefaultMachine = false;
|
||||
services.podman.machines = {
|
||||
"my-machine" = {
|
||||
cpus = 4;
|
||||
memory = 8192;
|
||||
diskSize = 100;
|
||||
autoStart = true;
|
||||
};
|
||||
};
|
||||
|
||||
The module includes a launchd-based watchdog service that automatically
|
||||
starts configured machines on login and keeps them running.
|
||||
'';
|
||||
}
|
||||
12
modules/misc/news/2026/01/2026-01-05_13-57-57.nix
Normal file
12
modules/misc/news/2026/01/2026-01-05_13-57-57.nix
Normal file
@@ -0,0 +1,12 @@
|
||||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
time = "2026-01-05T11:57:57+00:00";
|
||||
condition = pkgs.stdenv.hostPlatform.isLinux;
|
||||
message = ''
|
||||
A new module is available: 'programs.workstyle'.
|
||||
|
||||
Workstyle dynamically renames Sway/i3/Hyprland workspaces to indicate
|
||||
which programs are running in each one. For example, with a font icon.
|
||||
'';
|
||||
}
|
||||
@@ -47,9 +47,9 @@ in
|
||||
desktop: terminals:
|
||||
# Map desktop name such as GNOME to `.config/gnome-xdg-terminals.list`,
|
||||
# default to `.config/xdg-terminals.list`.
|
||||
lib.nameValuePair (
|
||||
"${if desktop == "default" then "" else "${lib.toLower desktop}-"}xdg-terminals.list"
|
||||
) { text = lib.concatLines terminals; }
|
||||
lib.nameValuePair "${
|
||||
if desktop == "default" then "" else "${lib.toLower desktop}-"
|
||||
}xdg-terminals.list" { text = lib.concatLines terminals; }
|
||||
) cfg.settings;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Project-Id-Version: Home Manager Modules\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n"
|
||||
"POT-Creation-Date: 2025-07-22 10:59+0200\n"
|
||||
"PO-Revision-Date: 2025-11-30 14:00+0000\n"
|
||||
"PO-Revision-Date: 2026-01-07 17:01+0000\n"
|
||||
"Last-Translator: Brian E <brianellingsgaard9@gmail.com>\n"
|
||||
"Language-Team: Faroese <https://hosted.weblate.org/projects/home-manager/"
|
||||
"modules/fo/>\n"
|
||||
@@ -17,7 +17,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 5.15-dev\n"
|
||||
"X-Generator: Weblate 5.15.1\n"
|
||||
|
||||
#: modules/files.nix:206
|
||||
msgid "Creating home file links in %s"
|
||||
@@ -33,7 +33,7 @@ msgstr "Stovni nýggjan profil ættarlið"
|
||||
|
||||
#: modules/home-environment.nix:650
|
||||
msgid "No change so reusing latest profile generation"
|
||||
msgstr ""
|
||||
msgstr "Eingin broyting. Seinastið umhvarv ættarlið er enn í brúk"
|
||||
|
||||
#: modules/home-environment.nix:699
|
||||
msgid ""
|
||||
|
||||
@@ -104,7 +104,7 @@ in
|
||||
};
|
||||
|
||||
stylesets = mkOption {
|
||||
type = with types; attrsOf (sectionsOrLines);
|
||||
type = with types; attrsOf sectionsOrLines;
|
||||
default = { };
|
||||
example = literalExpression ''
|
||||
{ default = { ui = { "tab.selected.reverse" = "toggle"; }; }; };
|
||||
|
||||
@@ -6,9 +6,7 @@
|
||||
}:
|
||||
let
|
||||
inherit (builtins)
|
||||
map
|
||||
toJSON
|
||||
toString
|
||||
substring
|
||||
stringLength
|
||||
;
|
||||
|
||||
@@ -54,7 +54,7 @@ in
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
||||
home.sessionVariables = lib.mkIf (cfg.settings != { }) {
|
||||
BEMENU_OPTS = lib.cli.toGNUCommandLineShell { } cfg.settings;
|
||||
BEMENU_OPTS = lib.cli.toCommandLineShellGNU { } cfg.settings;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -281,7 +281,7 @@ in
|
||||
) supportedBrowsers;
|
||||
|
||||
config = lib.mkMerge (
|
||||
builtins.map (browser: browserConfig browser config.programs.${browser}) (
|
||||
map (browser: browserConfig browser config.programs.${browser}) (
|
||||
builtins.attrNames supportedBrowsers
|
||||
)
|
||||
);
|
||||
|
||||
@@ -129,7 +129,7 @@ in
|
||||
enable = lib.mkDefault true;
|
||||
iniContent =
|
||||
let
|
||||
difftCommand = "${lib.getExe cfg.package} ${lib.cli.toGNUCommandLineShell { } cfg.options}";
|
||||
difftCommand = "${lib.getExe cfg.package} ${lib.cli.toCommandLineShellGNU { } cfg.options}";
|
||||
in
|
||||
mkMerge [
|
||||
{
|
||||
|
||||
@@ -16,8 +16,7 @@ let
|
||||
|
||||
generateConfig = lib.generators.toKeyValue {
|
||||
mkKeyValue =
|
||||
name: value:
|
||||
if lib.isString value then ''${name}="${value}"'' else "${name}=${builtins.toString value}";
|
||||
name: value: if lib.isString value then ''${name}="${value}"'' else "${name}=${toString value}";
|
||||
};
|
||||
|
||||
iniFormat = pkgs.formats.ini { listsAsDuplicateKeys = true; };
|
||||
|
||||
@@ -103,7 +103,7 @@ in
|
||||
{
|
||||
name = path;
|
||||
value = {
|
||||
source = jsonFormat.generate "config.json" (ctx);
|
||||
source = jsonFormat.generate "config.json" ctx;
|
||||
};
|
||||
}
|
||||
) cfg.contexts;
|
||||
|
||||
@@ -471,7 +471,7 @@ in
|
||||
|
||||
order = mkOption {
|
||||
type = with types; uniq (listOf str);
|
||||
apply = builtins.map migrateEngineNameToIdV7;
|
||||
apply = map migrateEngineNameToIdV7;
|
||||
default = [ ];
|
||||
example = [
|
||||
"ddg"
|
||||
|
||||
@@ -301,20 +301,13 @@ let
|
||||
let
|
||||
name = if isAttrs def && def.name != null then def.name else attrName;
|
||||
mods =
|
||||
lib.cli.toGNUCommandLineShell
|
||||
{
|
||||
mkOption =
|
||||
k: v:
|
||||
if v == null then
|
||||
[ ]
|
||||
else if k == "set-cursor" then
|
||||
[ "--${k}=${lib.generators.mkValueStringDefault { } v}" ]
|
||||
else
|
||||
[
|
||||
"--${k}"
|
||||
(lib.generators.mkValueStringDefault { } v)
|
||||
];
|
||||
}
|
||||
lib.cli.toCommandLineShell
|
||||
(optionName: {
|
||||
option = "--${optionName}";
|
||||
sep = if optionName == "set-cursor" then "=" else null;
|
||||
explicitBool = false;
|
||||
formatArg = lib.generators.mkValueStringDefault { };
|
||||
})
|
||||
{
|
||||
inherit (def)
|
||||
position
|
||||
@@ -395,12 +388,14 @@ let
|
||||
passAsFile = [ "text" ];
|
||||
} "env HOME=$(mktemp -d) fish_indent < $textPath > $out";
|
||||
|
||||
translatedSessionVariables = pkgs.runCommandLocal "hm-session-vars.fish" { } ''
|
||||
sessionVarsFile = "etc/profile.d/hm-session-vars.fish";
|
||||
sessionVarsPkg = pkgs.runCommandLocal "hm-session-vars.fish" { } ''
|
||||
mkdir -p "$(dirname $out/${sessionVarsFile})"
|
||||
(echo "function setup_hm_session_vars;"
|
||||
${pkgs.buildPackages.babelfish}/bin/babelfish \
|
||||
<${config.home.sessionVariablesPackage}/etc/profile.d/hm-session-vars.sh
|
||||
echo "end"
|
||||
echo "setup_hm_session_vars") > $out
|
||||
echo "setup_hm_session_vars") > $out/${sessionVarsFile}
|
||||
'';
|
||||
|
||||
in
|
||||
@@ -598,11 +593,25 @@ in
|
||||
<https://fishshell.com/docs/current/completions.html>.
|
||||
'';
|
||||
};
|
||||
|
||||
programs.fish.sessionVariablesPackage = mkOption {
|
||||
type = types.package;
|
||||
internal = true;
|
||||
description = ''
|
||||
The package containing the translated {file}`hm-session-vars.fish` file.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable (
|
||||
lib.mkMerge [
|
||||
{ home.packages = [ cfg.package ]; }
|
||||
{
|
||||
home.packages = [
|
||||
cfg.package
|
||||
cfg.sessionVariablesPackage
|
||||
];
|
||||
programs.fish.sessionVariablesPackage = sessionVarsPkg;
|
||||
}
|
||||
|
||||
(mkIf cfg.generateCompletions (
|
||||
let
|
||||
@@ -618,7 +627,7 @@ in
|
||||
package
|
||||
]
|
||||
++ lib.filter (p: p != null) (
|
||||
builtins.map (outName: package.${outName} or null) config.home.extraOutputsToInstall
|
||||
map (outName: package.${outName} or null) config.home.extraOutputsToInstall
|
||||
);
|
||||
nativeBuildInputs = [ pkgs.python3 ];
|
||||
buildInputs = [ cfg.package ];
|
||||
@@ -715,7 +724,7 @@ in
|
||||
set -q __fish_home_manager_config_sourced; and exit
|
||||
set -g __fish_home_manager_config_sourced 1
|
||||
|
||||
source ${translatedSessionVariables}
|
||||
source ${cfg.sessionVariablesPackage}/${sessionVarsFile}
|
||||
|
||||
${cfg.shellInit}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ let
|
||||
tomlFormat = pkgs.formats.toml { };
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.hm.maintainers.rrvsh ];
|
||||
meta.maintainers = [ lib.maintainers.rrvsh ];
|
||||
|
||||
options.programs.gemini-cli = {
|
||||
enable = lib.mkEnableOption "gemini-cli";
|
||||
|
||||
@@ -204,7 +204,7 @@ in
|
||||
|
||||
xdg.dataFile."gh/extensions" = mkIf (cfg.extensions != [ ]) {
|
||||
source = pkgs.linkFarm "gh-extensions" (
|
||||
builtins.map (p: {
|
||||
map (p: {
|
||||
name = p.pname;
|
||||
path = "${p}/bin";
|
||||
}) cfg.extensions
|
||||
|
||||
@@ -225,13 +225,18 @@ in
|
||||
}
|
||||
];
|
||||
|
||||
xdg.configFile."systemd/user/app-com.mitchellh.ghostty.service".source =
|
||||
"${cfg.package}/share/systemd/user/app-com.mitchellh.ghostty.service";
|
||||
|
||||
xdg.configFile."systemd/user/app-com.mitchellh.ghostty.service.d/overrides.conf".text = ''
|
||||
[Unit]
|
||||
X-SwitchMethod=keep-old
|
||||
'';
|
||||
systemd.user.services."app-com.mitchellh.ghostty" = {
|
||||
Unit = {
|
||||
X-Base = "${cfg.package}/share/systemd/user/app-com.mitchellh.ghostty.service";
|
||||
X-SwitchMethod = "keep-old";
|
||||
X-Reload-Triggers =
|
||||
let
|
||||
storePathOf = name: config.xdg.configFile.${name}.source;
|
||||
in
|
||||
lib.optionals (cfg.settings != { }) [ (storePathOf "ghostty/config") ]
|
||||
++ lib.mapAttrsToList (name: _: storePathOf "ghostty/themes/${name}") cfg.themes;
|
||||
};
|
||||
};
|
||||
|
||||
dbus.packages = [ cfg.package ];
|
||||
})
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
let
|
||||
tomlFormat = pkgs.formats.toml { };
|
||||
cfg = config.programs.gurk-rs;
|
||||
configDir =
|
||||
if pkgs.stdenv.hostPlatform.isDarwin then "Library/Application Support" else config.xdg.configHome;
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.da157 ];
|
||||
@@ -46,9 +48,8 @@ in
|
||||
config = lib.mkIf cfg.enable {
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
||||
home.file."${
|
||||
if pkgs.stdenv.hostPlatform.isDarwin then "Library/Application Support" else config.xdg.configHome
|
||||
}/gurk/gurk.toml".source =
|
||||
lib.mkIf (cfg.settings != { }) (tomlFormat.generate "gurk-config" cfg.settings);
|
||||
home.file."${configDir}/gurk/gurk.toml" = lib.mkIf (cfg.settings != { }) {
|
||||
source = tomlFormat.generate "gurk-config" cfg.settings;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ let
|
||||
iniFormat = pkgs.formats.ini { };
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [ ];
|
||||
meta.maintainers = [ ];
|
||||
|
||||
options.programs.havoc = {
|
||||
enable = lib.mkEnableOption "Havoc terminal";
|
||||
|
||||
@@ -70,7 +70,7 @@ in
|
||||
"mako"
|
||||
];
|
||||
in
|
||||
builtins.map (name: {
|
||||
map (name: {
|
||||
assertion = !config.services.${name}.enable;
|
||||
message = ''
|
||||
Only one notification daemon can be enabled at once. You have enabled
|
||||
|
||||
@@ -139,7 +139,7 @@ in
|
||||
in
|
||||
lib.hm.dag.entryAfter [ "linkGeneration" ] ''
|
||||
# Ensure that settings.json exists.
|
||||
mkdir -p ${builtins.dirOf configPath}
|
||||
mkdir -p ${dirOf configPath}
|
||||
touch ${configPath}
|
||||
# Config has to be written to temporary variable because jq cannot edit files in place.
|
||||
config="$(jq -s '.[0] + .[1]' ${configPath} ${newConfig})"
|
||||
|
||||
@@ -14,7 +14,7 @@ let
|
||||
renderSettings =
|
||||
with lib.generators;
|
||||
toINI {
|
||||
mkKeyValue = mkKeyValueDefault rec {
|
||||
mkKeyValue = mkKeyValueDefault {
|
||||
mkValueString =
|
||||
v:
|
||||
if lib.isList v then
|
||||
@@ -139,7 +139,7 @@ in
|
||||
let
|
||||
makePath =
|
||||
baseDir: subDir:
|
||||
builtins.toString (
|
||||
toString (
|
||||
/.
|
||||
+ lib.concatStringsSep "/" [
|
||||
baseDir
|
||||
|
||||
@@ -341,15 +341,12 @@ in
|
||||
# See https://sw.kovidgoyal.net/kitty/conf.html
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
}
|
||||
// lib.optionalAttrs pkgs.stdenv.hostPlatform.isLinux {
|
||||
onChange = ''
|
||||
${pkgs.procps}/bin/pkill -USR1 -u $USER kitty || true
|
||||
'';
|
||||
}
|
||||
// lib.optionalAttrs pkgs.stdenv.hostPlatform.isDarwin {
|
||||
onChange = ''
|
||||
/usr/bin/pkill -USR1 -u $USER kitty || true
|
||||
onChange =
|
||||
let
|
||||
prefix = if pkgs.stdenv.hostPlatform.isDarwin then "/usr" else pkgs.procps;
|
||||
in
|
||||
''
|
||||
${prefix}/bin/pkill -USR1 -u $USER kitty || true
|
||||
'';
|
||||
};
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ let
|
||||
|
||||
cfg = config.programs.kubecolor;
|
||||
yamlFormat = pkgs.formats.yaml { };
|
||||
inherit (pkgs.stdenv.hostPlatform) isDarwin;
|
||||
|
||||
in
|
||||
{
|
||||
@@ -50,18 +49,20 @@ in
|
||||
|
||||
config =
|
||||
let
|
||||
preferXdgDirectories = config.home.preferXdgDirectories && (!isDarwin || config.xdg.enable);
|
||||
preferXdgDirectories =
|
||||
config.home.preferXdgDirectories && (!pkgs.stdenv.hostPlatform.isDarwin || config.xdg.enable);
|
||||
configDir =
|
||||
if preferXdgDirectories then
|
||||
"${config.xdg.configHome}/kube"
|
||||
else if pkgs.stdenv.hostPlatform.isDarwin then
|
||||
"Library/Application Support/kube"
|
||||
else
|
||||
".kube";
|
||||
|
||||
# https://github.com/kubecolor/kubecolor/pull/145
|
||||
configPathSuffix =
|
||||
if
|
||||
cfg.package.pname == "kubecolor"
|
||||
&& lib.strings.toInt (lib.versions.major cfg.package.version) == 0
|
||||
&& lib.strings.toInt (lib.versions.minor cfg.package.version) < 4
|
||||
then
|
||||
"kube/"
|
||||
else
|
||||
"kube/color.yaml";
|
||||
configPathSuffix = lib.optionalString (
|
||||
cfg.package.pname == "kubecolor" && lib.versionOlder (lib.getVersion cfg.package) "0.4"
|
||||
) "color.yaml";
|
||||
|
||||
in
|
||||
mkIf cfg.enable {
|
||||
@@ -73,32 +74,11 @@ in
|
||||
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
||||
home.sessionVariables =
|
||||
if preferXdgDirectories then
|
||||
{
|
||||
KUBECOLOR_CONFIG = "${config.xdg.configHome}/${configPathSuffix}";
|
||||
}
|
||||
else if isDarwin then
|
||||
{
|
||||
KUBECOLOR_CONFIG = "${config.home.homeDirectory}/Library/Application Support/${configPathSuffix}";
|
||||
}
|
||||
else
|
||||
{ };
|
||||
home.sessionVariables.KUBECOLOR_CONFIG = "${configDir}/${configPathSuffix}";
|
||||
|
||||
xdg.configFile = mkIf preferXdgDirectories {
|
||||
"kube/color.yaml" = mkIf (cfg.settings != { }) {
|
||||
home.file."${configDir}/color.yaml" = mkIf (cfg.settings != { }) {
|
||||
source = yamlFormat.generate "kubecolor-settings" cfg.settings;
|
||||
};
|
||||
};
|
||||
|
||||
home.file = mkIf (!preferXdgDirectories) {
|
||||
"Library/Application Support/kube/color.yaml" = mkIf (isDarwin && cfg.settings != { }) {
|
||||
source = yamlFormat.generate "kubecolor-settings" cfg.settings;
|
||||
};
|
||||
".kube/color.yaml" = mkIf (!isDarwin && cfg.settings != { }) {
|
||||
source = yamlFormat.generate "kubecolor-settings" cfg.settings;
|
||||
};
|
||||
};
|
||||
|
||||
home.shellAliases = lib.mkIf (cfg.enableAlias && (cfg.package != null)) {
|
||||
kubectl = lib.getExe cfg.package;
|
||||
|
||||
@@ -201,7 +201,7 @@ let
|
||||
plugins:
|
||||
pkgs.linkFarm "lapce-plugins" (
|
||||
builtins.listToAttrs (
|
||||
builtins.map (
|
||||
map (
|
||||
{
|
||||
author,
|
||||
name,
|
||||
|
||||
@@ -11,7 +11,11 @@ let
|
||||
|
||||
yamlFormat = pkgs.formats.yaml { };
|
||||
|
||||
inherit (pkgs.stdenv.hostPlatform) isDarwin;
|
||||
configDir =
|
||||
if pkgs.stdenv.hostPlatform.isDarwin && !config.xdg.enable then
|
||||
"Library/Application Support/jesseduffield"
|
||||
else
|
||||
config.xdg.configHome;
|
||||
|
||||
in
|
||||
{
|
||||
@@ -51,15 +55,7 @@ in
|
||||
config = lib.mkIf cfg.enable {
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
||||
home.file."Library/Application Support/jesseduffield/lazydocker/config.yml" =
|
||||
lib.mkIf (cfg.settings != { } && (isDarwin && !config.xdg.enable))
|
||||
{
|
||||
source = yamlFormat.generate "lazydocker-config" cfg.settings;
|
||||
};
|
||||
|
||||
xdg.configFile."lazydocker/config.yml" =
|
||||
lib.mkIf (cfg.settings != { } && !(isDarwin && !config.xdg.enable))
|
||||
{
|
||||
home.file."${configDir}/lazydocker/config.yml" = lib.mkIf (cfg.settings != { }) {
|
||||
source = yamlFormat.generate "lazydocker-config" cfg.settings;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -11,8 +11,11 @@ let
|
||||
|
||||
yamlFormat = pkgs.formats.yaml { };
|
||||
|
||||
inherit (pkgs.stdenv.hostPlatform) isDarwin;
|
||||
|
||||
configDir =
|
||||
if pkgs.stdenv.hostPlatform.isDarwin && !config.xdg.enable then
|
||||
"Library/Application Support"
|
||||
else
|
||||
config.xdg.configHome;
|
||||
in
|
||||
{
|
||||
meta.maintainers = [
|
||||
@@ -71,15 +74,8 @@ in
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
||||
home.file."Library/Application Support/lazygit/config.yml" =
|
||||
mkIf (cfg.settings != { } && (isDarwin && !config.xdg.enable))
|
||||
{
|
||||
source = yamlFormat.generate "lazygit-config" cfg.settings;
|
||||
};
|
||||
|
||||
xdg.configFile."lazygit/config.yml" =
|
||||
mkIf (cfg.settings != { } && !(isDarwin && !config.xdg.enable))
|
||||
{
|
||||
home.file."${configDir}/lazygit/config.yml" = {
|
||||
enable = cfg.settings != { };
|
||||
source = yamlFormat.generate "lazygit-config" cfg.settings;
|
||||
};
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ in
|
||||
];
|
||||
attrs = attrsOf (either scalar (listOf scalar));
|
||||
in
|
||||
coercedTo attrs (lib.cli.toGNUCommandLine { }) (listOf str);
|
||||
coercedTo attrs (lib.cli.toCommandLineGNU { }) (listOf str);
|
||||
default = [ ];
|
||||
description = "Options to be set via {env}`$LESS`.";
|
||||
example = {
|
||||
|
||||
@@ -82,7 +82,7 @@ in
|
||||
package = lib.mkPackageOption pkgs "meli" { };
|
||||
|
||||
includes = mkOption {
|
||||
type = with types; listOf (str);
|
||||
type = with types; listOf str;
|
||||
description = "Paths of the various meli configuration files to include.";
|
||||
default = [ ];
|
||||
};
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
let
|
||||
cfg = config.programs.mullvad-vpn;
|
||||
jsonFormat = pkgs.formats.json { };
|
||||
configDir =
|
||||
if pkgs.stdenv.hostPlatform.isDarwin then "Library/Application Support" else config.xdg.configHome;
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.da157 ];
|
||||
@@ -42,10 +44,7 @@ in
|
||||
config = lib.mkIf cfg.enable {
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
||||
home.file."${
|
||||
if pkgs.stdenv.hostPlatform.isDarwin then "Library/Application Support" else config.xdg.configHome
|
||||
}/Mullvad VPN/gui_settings.json" =
|
||||
lib.mkIf (cfg.settings != { }) {
|
||||
home.file."${configDir}/Mullvad VPN/gui_settings.json" = lib.mkIf (cfg.settings != { }) {
|
||||
source = jsonFormat.generate "mullvad-gui-settings" cfg.settings;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -13,7 +13,7 @@ let
|
||||
|
||||
renderSettings = settings: lib.concatStringsSep ";" (lib.mapAttrsToList renderSetting settings);
|
||||
|
||||
pluginModule = types.submodule ({
|
||||
pluginModule = types.submodule {
|
||||
options = {
|
||||
src = mkOption {
|
||||
type = with types; nullOr path;
|
||||
@@ -46,7 +46,7 @@ let
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [ thiagokokada ];
|
||||
|
||||
@@ -254,7 +254,7 @@ in
|
||||
cssSnippets =
|
||||
let
|
||||
checkCssPath = path: lib.filesystem.pathIsRegularFile path && lib.strings.hasSuffix ".css" path;
|
||||
toCssName = path: lib.strings.removeSuffix ".css" (builtins.baseNameOf path);
|
||||
toCssName = path: lib.strings.removeSuffix ".css" (baseNameOf path);
|
||||
cssSnippetsOptions =
|
||||
{ config, ... }:
|
||||
{
|
||||
@@ -423,7 +423,7 @@ in
|
||||
source = (pkgs.formats.json { }).generate "appearance.json" (
|
||||
vault.settings.appearance
|
||||
// {
|
||||
enabledCssSnippets = builtins.map (snippet: snippet.name) enabledCssSnippets;
|
||||
enabledCssSnippets = map (snippet: snippet.name) enabledCssSnippets;
|
||||
}
|
||||
// lib.attrsets.optionalAttrs (activeTheme != null) {
|
||||
cssTheme = getManifest activeTheme;
|
||||
@@ -438,14 +438,14 @@ in
|
||||
{
|
||||
name = "${vault.target}/.obsidian/core-plugins.json";
|
||||
value.source = (pkgs.formats.json { }).generate "core-plugins.json" (
|
||||
builtins.map (plugin: plugin.name) vault.settings.corePlugins
|
||||
map (plugin: plugin.name) vault.settings.corePlugins
|
||||
);
|
||||
}
|
||||
{
|
||||
name = "${vault.target}/.obsidian/core-plugins-migration.json";
|
||||
value.source = (pkgs.formats.json { }).generate "core-plugins-migration.json" (
|
||||
builtins.listToAttrs (
|
||||
builtins.map (name: {
|
||||
map (name: {
|
||||
inherit name;
|
||||
value = builtins.any (plugin: name == plugin.name && plugin.enable) vault.settings.corePlugins;
|
||||
}) corePlugins
|
||||
@@ -453,7 +453,7 @@ in
|
||||
);
|
||||
}
|
||||
]
|
||||
++ builtins.map (plugin: {
|
||||
++ map (plugin: {
|
||||
name = "${vault.target}/.obsidian/${plugin.name}.json";
|
||||
value.source = (pkgs.formats.json { }).generate "${plugin.name}.json" plugin.settings;
|
||||
}) (builtins.filter (plugin: plugin.settings != { }) vault.settings.corePlugins);
|
||||
@@ -464,25 +464,25 @@ in
|
||||
{
|
||||
name = "${vault.target}/.obsidian/community-plugins.json";
|
||||
value.source = (pkgs.formats.json { }).generate "community-plugins.json" (
|
||||
builtins.map getManifest (builtins.filter (plugin: plugin.enable) vault.settings.communityPlugins)
|
||||
map getManifest (builtins.filter (plugin: plugin.enable) vault.settings.communityPlugins)
|
||||
);
|
||||
}
|
||||
]
|
||||
++ builtins.map (plugin: {
|
||||
++ map (plugin: {
|
||||
name = "${vault.target}/.obsidian/plugins/${getManifest plugin}";
|
||||
value = {
|
||||
source = plugin.pkg;
|
||||
recursive = true;
|
||||
};
|
||||
}) vault.settings.communityPlugins
|
||||
++ builtins.map (plugin: {
|
||||
++ map (plugin: {
|
||||
name = "${vault.target}/.obsidian/plugins/${getManifest plugin}/data.json";
|
||||
value.source = (pkgs.formats.json { }).generate "data.json" plugin.settings;
|
||||
}) (builtins.filter (plugin: plugin.settings != { }) vault.settings.communityPlugins);
|
||||
|
||||
mkCssSnippets =
|
||||
vault:
|
||||
builtins.map (snippet: {
|
||||
map (snippet: {
|
||||
name = "${vault.target}/.obsidian/snippets/${snippet.name}.css";
|
||||
value =
|
||||
if snippet.source != null then
|
||||
@@ -497,7 +497,7 @@ in
|
||||
|
||||
mkThemes =
|
||||
vault:
|
||||
builtins.map (theme: {
|
||||
map (theme: {
|
||||
name = "${vault.target}/.obsidian/themes/${getManifest theme}";
|
||||
value.source = theme.pkg;
|
||||
}) vault.settings.themes;
|
||||
@@ -509,7 +509,7 @@ in
|
||||
|
||||
mkExtraFiles =
|
||||
vault:
|
||||
builtins.map (file: {
|
||||
map (file: {
|
||||
name = "${vault.target}/.obsidian/${file.target}";
|
||||
value =
|
||||
if file.source != null then
|
||||
@@ -524,7 +524,7 @@ in
|
||||
in
|
||||
builtins.listToAttrs (
|
||||
lib.lists.flatten (
|
||||
builtins.map (vault: [
|
||||
map (vault: [
|
||||
(mkApp vault)
|
||||
(mkAppearance vault)
|
||||
(mkCorePlugins vault)
|
||||
@@ -540,7 +540,7 @@ in
|
||||
|
||||
xdg.configFile."obsidian/obsidian.json".source = (pkgs.formats.json { }).generate "obsidian.json" {
|
||||
vaults = builtins.listToAttrs (
|
||||
builtins.map (vault: {
|
||||
map (vault: {
|
||||
name = builtins.hashString "md5" vault.target;
|
||||
value = {
|
||||
path = "${config.home.homeDirectory}/${vault.target}";
|
||||
|
||||
@@ -126,14 +126,22 @@ in
|
||||
};
|
||||
|
||||
commands = lib.mkOption {
|
||||
type = lib.types.attrsOf (lib.types.either lib.types.lines lib.types.path);
|
||||
type = lib.types.either (lib.types.attrsOf (lib.types.either lib.types.lines lib.types.path)) lib.types.path;
|
||||
default = { };
|
||||
description = ''
|
||||
Custom commands for opencode.
|
||||
The attribute name becomes the command filename, and the value is either:
|
||||
- Inline content as a string
|
||||
- A path to a file containing the command content
|
||||
Commands are stored in {file}`$XDG_CONFIG_HOME/opencode/command/` directory.
|
||||
|
||||
This option can either be:
|
||||
- An attribute set defining commands
|
||||
- A path to a directory containing multiple command files
|
||||
|
||||
If an attribute set is used, the attribute name becomes the command filename,
|
||||
and the value is either:
|
||||
- Inline content as a string (creates `opencode/command/<name>.md`)
|
||||
- A path to a file (creates `opencode/command/<name>.md`)
|
||||
|
||||
If a path is used, it is expected to contain command files.
|
||||
The directory is symlinked to {file}`$XDG_CONFIG_HOME/opencode/command/`.
|
||||
'';
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
@@ -155,14 +163,22 @@ in
|
||||
};
|
||||
|
||||
agents = lib.mkOption {
|
||||
type = lib.types.attrsOf (lib.types.either lib.types.lines lib.types.path);
|
||||
type = lib.types.either (lib.types.attrsOf (lib.types.either lib.types.lines lib.types.path)) lib.types.path;
|
||||
default = { };
|
||||
description = ''
|
||||
Custom agents for opencode.
|
||||
The attribute name becomes the agent filename, and the value is either:
|
||||
- Inline content as a string
|
||||
- A path to a file containing the agent content
|
||||
Agents are stored in {file}`$XDG_CONFIG_HOME/opencode/agent/` directory.
|
||||
|
||||
This option can either be:
|
||||
- An attribute set defining agents
|
||||
- A path to a directory containing multiple agent files
|
||||
|
||||
If an attribute set is used, the attribute name becomes the agent filename,
|
||||
and the value is either:
|
||||
- Inline content as a string (creates `opencode/agent/<name>.md`)
|
||||
- A path to a file (creates `opencode/agent/<name>.md`)
|
||||
|
||||
If a path is used, it is expected to contain agent files.
|
||||
The directory is symlinked to {file}`$XDG_CONFIG_HOME/opencode/agent/`.
|
||||
'';
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
@@ -227,26 +243,94 @@ in
|
||||
};
|
||||
|
||||
themes = mkOption {
|
||||
type = lib.types.attrsOf (lib.types.either jsonFormat.type lib.types.path);
|
||||
type = lib.types.either (lib.types.attrsOf (lib.types.either jsonFormat.type lib.types.path)) lib.types.path;
|
||||
default = { };
|
||||
description = ''
|
||||
Custom themes for opencode. The attribute name becomes the theme
|
||||
filename, and the value is either:
|
||||
- An attribute set, that is converted to a json
|
||||
- A path to a file containing the content
|
||||
Themes are stored in {file}`$XDG_CONFIG_HOME/opencode/themes/` directory.
|
||||
Custom themes for opencode.
|
||||
|
||||
This option can either be:
|
||||
- An attribute set defining themes
|
||||
- A path to a directory containing multiple theme files
|
||||
|
||||
If an attribute set is used, the attribute name becomes the theme filename,
|
||||
and the value is either:
|
||||
- An attribute set that is converted to a JSON file (creates `opencode/themes/<name>.json`)
|
||||
- A path to a file (creates `opencode/themes/<name>.json`)
|
||||
|
||||
If a path is used, it is expected to contain theme files.
|
||||
The directory is symlinked to {file}`$XDG_CONFIG_HOME/opencode/themes/`.
|
||||
|
||||
Set `programs.opencode.settings.theme` to enable the custom theme.
|
||||
See <https://opencode.ai/docs/themes/> for the documentation.
|
||||
'';
|
||||
};
|
||||
|
||||
tools = lib.mkOption {
|
||||
type = lib.types.either (lib.types.attrsOf (lib.types.either lib.types.lines lib.types.path)) lib.types.path;
|
||||
default = { };
|
||||
description = ''
|
||||
Custom tools for opencode.
|
||||
|
||||
This option can either be:
|
||||
- An attribute set defining tools
|
||||
- A path to a directory containing multiple tool files
|
||||
|
||||
If an attribute set is used, the attribute name becomes the tool filename,
|
||||
and the value is either:
|
||||
- Inline content as a string (creates `opencode/tool/<name>.ts`)
|
||||
- A path to a file (creates `opencode/tool/<name>.ts` or `opencode/tool/<name>.js`)
|
||||
|
||||
If a path is used, it is expected to contain tool files.
|
||||
The directory is symlinked to {file}`$XDG_CONFIG_HOME/opencode/tool/`.
|
||||
|
||||
See <https://opencode.ai/docs/tools/> for the documentation.
|
||||
'';
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
database-query = '''
|
||||
import { tool } from "@opencode-ai/plugin"
|
||||
|
||||
export default tool({
|
||||
description: "Query the project database",
|
||||
args: {
|
||||
query: tool.schema.string().describe("SQL query to execute"),
|
||||
},
|
||||
async execute(args) {
|
||||
// Your database logic here
|
||||
return `Executed query: ''${args.query}`
|
||||
},
|
||||
})
|
||||
''';
|
||||
|
||||
# Or reference an existing file
|
||||
api-client = ./tools/api-client.ts;
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = !lib.isPath cfg.commands || lib.pathIsDirectory cfg.commands;
|
||||
message = "`programs.opencode.commands` must be a directory when set to a path";
|
||||
}
|
||||
{
|
||||
assertion = !lib.isPath cfg.agents || lib.pathIsDirectory cfg.agents;
|
||||
message = "`programs.opencode.agents` must be a directory when set to a path";
|
||||
}
|
||||
{
|
||||
assertion = !lib.isPath cfg.tools || lib.pathIsDirectory cfg.tools;
|
||||
message = "`programs.opencode.tools` must be a directory when set to a path";
|
||||
}
|
||||
{
|
||||
assertion = !lib.isPath cfg.skills || lib.pathIsDirectory cfg.skills;
|
||||
message = "`programs.opencode.skills` must be a directory when set to a path";
|
||||
}
|
||||
{
|
||||
assertion = !lib.isPath cfg.themes || lib.pathIsDirectory cfg.themes;
|
||||
message = "`programs.opencode.themes` must be a directory when set to a path";
|
||||
}
|
||||
];
|
||||
|
||||
home.packages = mkIf (cfg.package != null) [ cfg.package ];
|
||||
@@ -278,23 +362,55 @@ in
|
||||
})
|
||||
);
|
||||
|
||||
"opencode/command" = mkIf (lib.isPath cfg.commands) {
|
||||
source = cfg.commands;
|
||||
recursive = true;
|
||||
};
|
||||
|
||||
"opencode/agent" = mkIf (lib.isPath cfg.agents) {
|
||||
source = cfg.agents;
|
||||
recursive = true;
|
||||
};
|
||||
|
||||
"opencode/tool" = mkIf (lib.isPath cfg.tools) {
|
||||
source = cfg.tools;
|
||||
recursive = true;
|
||||
};
|
||||
|
||||
"opencode/skill" = mkIf (lib.isPath cfg.skills) {
|
||||
source = cfg.skills;
|
||||
recursive = true;
|
||||
};
|
||||
|
||||
"opencode/themes" = mkIf (lib.isPath cfg.themes) {
|
||||
source = cfg.themes;
|
||||
recursive = true;
|
||||
};
|
||||
}
|
||||
// lib.mapAttrs' (
|
||||
// lib.optionalAttrs (builtins.isAttrs cfg.commands) (
|
||||
lib.mapAttrs' (
|
||||
name: content:
|
||||
lib.nameValuePair "opencode/command/${name}.md" (
|
||||
if lib.isPath content then { source = content; } else { text = content; }
|
||||
)
|
||||
) cfg.commands
|
||||
// lib.mapAttrs' (
|
||||
)
|
||||
// lib.optionalAttrs (builtins.isAttrs cfg.agents) (
|
||||
lib.mapAttrs' (
|
||||
name: content:
|
||||
lib.nameValuePair "opencode/agent/${name}.md" (
|
||||
if lib.isPath content then { source = content; } else { text = content; }
|
||||
)
|
||||
) cfg.agents
|
||||
)
|
||||
// lib.optionalAttrs (builtins.isAttrs cfg.tools) (
|
||||
lib.mapAttrs' (
|
||||
name: content:
|
||||
lib.nameValuePair "opencode/tool/${name}.ts" (
|
||||
if lib.isPath content then { source = content; } else { text = content; }
|
||||
)
|
||||
) cfg.tools
|
||||
)
|
||||
// lib.mapAttrs' (
|
||||
name: content:
|
||||
if lib.isPath content && lib.pathIsDirectory content then
|
||||
@@ -307,7 +423,8 @@ in
|
||||
if lib.isPath content then { source = content; } else { text = content; }
|
||||
)
|
||||
) (if builtins.isAttrs cfg.skills then cfg.skills else { })
|
||||
// lib.mapAttrs' (
|
||||
// lib.optionalAttrs (builtins.isAttrs cfg.themes) (
|
||||
lib.mapAttrs' (
|
||||
name: content:
|
||||
lib.nameValuePair "opencode/themes/${name}.json" (
|
||||
if lib.isPath content then
|
||||
@@ -324,6 +441,7 @@ in
|
||||
);
|
||||
}
|
||||
)
|
||||
) cfg.themes;
|
||||
) cfg.themes
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ let
|
||||
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.hm.maintainers.nickthegroot ];
|
||||
meta.maintainers = [ lib.maintainers.nickthegroot ];
|
||||
|
||||
options.programs.pgcli = {
|
||||
enable = mkEnableOption "pgcli";
|
||||
|
||||
@@ -9,6 +9,9 @@ let
|
||||
|
||||
cfg = config.programs.pistol;
|
||||
|
||||
configDir =
|
||||
if pkgs.stdenv.hostPlatform.isDarwin then "Library/Preferences" else config.xdg.configHome;
|
||||
|
||||
configFile = lib.concatStringsSep "\n" (
|
||||
map (
|
||||
{
|
||||
@@ -74,9 +77,7 @@ in
|
||||
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable (
|
||||
lib.mkMerge [
|
||||
{
|
||||
config = mkIf cfg.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = lib.all (
|
||||
@@ -90,15 +91,9 @@ in
|
||||
];
|
||||
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
}
|
||||
|
||||
(mkIf (cfg.associations != [ ] && pkgs.stdenv.hostPlatform.isDarwin) {
|
||||
home.file."Library/Preferences/pistol/pistol.conf".text = configFile;
|
||||
})
|
||||
|
||||
(mkIf (cfg.associations != [ ] && !pkgs.stdenv.hostPlatform.isDarwin) {
|
||||
xdg.configFile."pistol/pistol.conf".text = configFile;
|
||||
})
|
||||
]
|
||||
);
|
||||
home.file."${configDir}/pistol/pistol.conf" = mkIf (cfg.associations != [ ]) {
|
||||
text = configFile;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -19,11 +19,11 @@ let
|
||||
valueToString =
|
||||
value:
|
||||
if builtins.isList value then
|
||||
builtins.concatStringsSep "," (builtins.map valueToString value)
|
||||
builtins.concatStringsSep "," (map valueToString value)
|
||||
else if builtins.isAttrs value then
|
||||
valueToString (lib.mapAttrsToList (key: val: "${valueToString key}=${valueToString val}") value)
|
||||
else
|
||||
builtins.toString value;
|
||||
toString value;
|
||||
|
||||
modulesArgument = optionalString (cfg.modules != null) " -modules ${valueToString cfg.modules}";
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ let
|
||||
else if builtins.isList v then
|
||||
"[${concatStringsSep ", " (map pythonize v)}]"
|
||||
else
|
||||
builtins.toString v;
|
||||
toString v;
|
||||
|
||||
formatDictLine =
|
||||
o: n: v:
|
||||
@@ -336,22 +336,20 @@ in
|
||||
greasemonkeyDir = lib.optionals (
|
||||
cfg.greasemonkey != [ ]
|
||||
) pkgs.linkFarmFromDrvs "greasemonkey-userscripts" cfg.greasemonkey;
|
||||
|
||||
configDir =
|
||||
if pkgs.stdenv.hostPlatform.isDarwin then
|
||||
".qutebrowser"
|
||||
else
|
||||
"${config.xdg.configHome}/qutebrowser";
|
||||
in
|
||||
mkIf cfg.enable {
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
||||
home.file.".qutebrowser/config.py" = mkIf pkgs.stdenv.hostPlatform.isDarwin {
|
||||
text = qutebrowserConfig;
|
||||
};
|
||||
|
||||
home.file.".qutebrowser/quickmarks" =
|
||||
mkIf (cfg.quickmarks != { } && pkgs.stdenv.hostPlatform.isDarwin)
|
||||
{
|
||||
text = quickmarksFile;
|
||||
};
|
||||
|
||||
xdg.configFile."qutebrowser/config.py" = mkIf pkgs.stdenv.hostPlatform.isLinux {
|
||||
home.file."${configDir}/config.py" = {
|
||||
text = qutebrowserConfig;
|
||||
}
|
||||
// lib.optionalAttrs pkgs.stdenv.hostPlatform.isLinux {
|
||||
onChange = ''
|
||||
hash="$(echo -n "$USER" | md5sum | cut -d' ' -f1)"
|
||||
socket="''${XDG_RUNTIME_DIR:-/run/user/$UID}/qutebrowser/ipc-$hash"
|
||||
@@ -371,21 +369,11 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
xdg.configFile."qutebrowser/quickmarks" =
|
||||
mkIf (cfg.quickmarks != { } && pkgs.stdenv.hostPlatform.isLinux)
|
||||
{
|
||||
home.file."${configDir}/quickmarks" = mkIf (cfg.quickmarks != { }) {
|
||||
text = quickmarksFile;
|
||||
};
|
||||
|
||||
home.file.".qutebrowser/greasemonkey" =
|
||||
mkIf (cfg.greasemonkey != [ ] && pkgs.stdenv.hostPlatform.isDarwin)
|
||||
{
|
||||
source = greasemonkeyDir;
|
||||
};
|
||||
|
||||
xdg.configFile."qutebrowser/greasemonkey" =
|
||||
mkIf (cfg.greasemonkey != [ ] && pkgs.stdenv.hostPlatform.isLinux)
|
||||
{
|
||||
home.file."${configDir}/greasemonkey" = mkIf (cfg.greasemonkey != [ ]) {
|
||||
source = greasemonkeyDir;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -168,7 +168,7 @@ in
|
||||
}
|
||||
{
|
||||
assertion = cfg.uri.web-rad.enable -> cfg.uri.web-rad.browser != null;
|
||||
message = "Could not detect preferred browser. Please set `${builtins.toString opt.uri.web-rad.browser}`.";
|
||||
message = "Could not detect preferred browser. Please set `${toString opt.uri.web-rad.browser}`.";
|
||||
}
|
||||
{
|
||||
assertion =
|
||||
|
||||
@@ -71,7 +71,7 @@ in
|
||||
|
||||
home.file.".rbenv/plugins" = mkIf (cfg.plugins != [ ]) {
|
||||
source = pkgs.linkFarm "rbenv-plugins" (
|
||||
builtins.map (p: {
|
||||
map (p: {
|
||||
name = p.name;
|
||||
path = p.src;
|
||||
}) cfg.plugins
|
||||
|
||||
@@ -10,7 +10,6 @@ let
|
||||
jsonFormat = pkgs.formats.json { };
|
||||
|
||||
inherit (lib) mkOption types;
|
||||
inherit (pkgs.stdenv.hostPlatform) isDarwin;
|
||||
|
||||
settingsModule = types.submodule {
|
||||
freeformType = jsonFormat.type;
|
||||
@@ -62,6 +61,9 @@ let
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
configDir =
|
||||
if pkgs.stdenv.hostPlatform.isDarwin then "Library/Application Support" else config.xdg.configHome;
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [ ambroisie ];
|
||||
@@ -93,21 +95,11 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable (
|
||||
lib.mkMerge [
|
||||
{
|
||||
config = lib.mkIf cfg.enable {
|
||||
home.packages = [ cfg.package ];
|
||||
}
|
||||
|
||||
# Only manage configuration if not empty
|
||||
(lib.mkIf (cfg.settings != null && !isDarwin) {
|
||||
xdg.configFile."rbw/config.json".source = jsonFormat.generate "rbw-config.json" cfg.settings;
|
||||
})
|
||||
|
||||
(lib.mkIf (cfg.settings != null && isDarwin) {
|
||||
home.file."Library/Application Support/rbw/config.json".source =
|
||||
jsonFormat.generate "rbw-config.json" cfg.settings;
|
||||
})
|
||||
]
|
||||
);
|
||||
home.file."${configDir}/rbw/config.json" = lib.mkIf (cfg.settings != null) {
|
||||
source = jsonFormat.generate "rbw-config.json" cfg.settings;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ let
|
||||
modes = map (mode: if isString mode then mode else "${mode.name}:${mode.path}") cfg.modes;
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [ ];
|
||||
meta.maintainers = [ ];
|
||||
|
||||
options.programs.rofi = {
|
||||
enable = lib.mkEnableOption "Rofi: A window switcher, application launcher and dmenu replacement";
|
||||
|
||||
@@ -11,6 +11,9 @@ let
|
||||
|
||||
iniFormat = pkgs.formats.ini { };
|
||||
|
||||
configDir =
|
||||
if pkgs.stdenv.hostPlatform.isDarwin then "Library/Preferences" else config.xdg.configHome;
|
||||
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.pbar ];
|
||||
@@ -55,32 +58,22 @@ in
|
||||
{
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
||||
programs.sapling.iniContent.ui = {
|
||||
username = cfg.userName + " <" + cfg.userEmail + ">";
|
||||
programs.sapling.iniContent = {
|
||||
alias = mkIf (cfg.aliases != { }) cfg.aliases;
|
||||
ui.username = cfg.userName + " <" + cfg.userEmail + ">";
|
||||
};
|
||||
|
||||
home.file."${configDir}/sapling/sapling.conf" = mkIf (cfg.iniContent != { }) {
|
||||
source = iniFormat.generate "sapling.conf" cfg.iniContent;
|
||||
};
|
||||
}
|
||||
|
||||
(mkIf (!pkgs.stdenv.isDarwin) {
|
||||
xdg.configFile."sapling/sapling.conf".source = iniFormat.generate "sapling.conf" cfg.iniContent;
|
||||
})
|
||||
(mkIf (pkgs.stdenv.isDarwin) {
|
||||
home.file."Library/Preferences/sapling/sapling.conf".source =
|
||||
iniFormat.generate "sapling.conf" cfg.iniContent;
|
||||
})
|
||||
|
||||
(mkIf (cfg.aliases != { }) {
|
||||
programs.sapling.iniContent.alias = cfg.aliases;
|
||||
})
|
||||
|
||||
(mkIf (lib.isAttrs cfg.extraConfig) {
|
||||
programs.sapling.iniContent = cfg.extraConfig;
|
||||
})
|
||||
|
||||
(mkIf (lib.isString cfg.extraConfig && !pkgs.stdenv.isDarwin) {
|
||||
xdg.configFile."sapling/sapling.conf".text = cfg.extraConfig;
|
||||
})
|
||||
(mkIf (lib.isString cfg.extraConfig && pkgs.stdenv.isDarwin) {
|
||||
home.file."Library/Preferences/sapling/sapling.conf".text = cfg.extraConfig;
|
||||
(mkIf (lib.isString cfg.extraConfig) {
|
||||
home.file."${configDir}/sapling/sapling.conf".text = cfg.extraConfig;
|
||||
})
|
||||
]
|
||||
);
|
||||
|
||||
@@ -40,6 +40,12 @@ let
|
||||
description = "The remote path to mount.";
|
||||
};
|
||||
|
||||
mountDestPath = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "The path on the current machine where the remote path would be mounted.";
|
||||
};
|
||||
|
||||
authType = mkOption {
|
||||
type = types.enum [
|
||||
"password"
|
||||
@@ -47,6 +53,7 @@ let
|
||||
"hostbased"
|
||||
"keyboard-interactive"
|
||||
"gssapi-with-mic"
|
||||
"authentication-agent"
|
||||
];
|
||||
default = "publickey";
|
||||
description = "The authentication method to use.";
|
||||
|
||||
@@ -158,7 +158,7 @@ in
|
||||
prjConf =
|
||||
lib.attrsets.mapAttrs' (
|
||||
name: value:
|
||||
(lib.attrsets.nameValuePair (if name == "beforeStart" then "before_start" else name) (value))
|
||||
(lib.attrsets.nameValuePair (if name == "beforeStart" then "before_start" else name) value)
|
||||
) v
|
||||
// {
|
||||
session = k;
|
||||
|
||||
@@ -9,6 +9,11 @@ let
|
||||
|
||||
cfg = config.programs.streamlink;
|
||||
|
||||
configDir =
|
||||
if pkgs.stdenv.hostPlatform.isDarwin then "Library/Application Support" else config.xdg.configHome;
|
||||
dataDir =
|
||||
if pkgs.stdenv.hostPlatform.isDarwin then "Library/Application Support" else config.xdg.dataHome;
|
||||
|
||||
renderSettings =
|
||||
settings:
|
||||
lib.concatLines (
|
||||
@@ -18,9 +23,9 @@ let
|
||||
if (builtins.isBool value) then
|
||||
if value then name else ""
|
||||
else if (builtins.isList value) then
|
||||
lib.concatStringsSep "\n" (builtins.map (item: "${name}=${builtins.toString item}") value)
|
||||
lib.concatStringsSep "\n" (map (item: "${name}=${toString item}") value)
|
||||
else
|
||||
"${name}=${builtins.toString value}"
|
||||
"${name}=${toString value}"
|
||||
) settings
|
||||
)
|
||||
);
|
||||
@@ -130,51 +135,17 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable (
|
||||
lib.mkMerge [
|
||||
{ home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; }
|
||||
config = lib.mkIf cfg.enable {
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
||||
(lib.mkIf pkgs.stdenv.hostPlatform.isLinux {
|
||||
xdg.configFile = {
|
||||
"streamlink/config" = lib.mkIf (cfg.settings != { }) {
|
||||
text = renderSettings cfg.settings;
|
||||
};
|
||||
}
|
||||
// (lib.mapAttrs' (
|
||||
name: value:
|
||||
lib.nameValuePair "streamlink/config.${name}" (
|
||||
lib.mkIf (value.settings != { }) {
|
||||
text = renderSettings value.settings;
|
||||
}
|
||||
)
|
||||
) cfg.plugins);
|
||||
|
||||
xdg.dataFile = lib.mapAttrs' (
|
||||
name: value:
|
||||
lib.nameValuePair "streamlink/plugins/${name}.py" (
|
||||
lib.mkIf (value.src != null) (
|
||||
if (builtins.isPath value.src) then
|
||||
{
|
||||
source = value.src;
|
||||
}
|
||||
else
|
||||
{
|
||||
text = value.src;
|
||||
}
|
||||
)
|
||||
)
|
||||
) cfg.plugins;
|
||||
})
|
||||
|
||||
(lib.mkIf pkgs.stdenv.hostPlatform.isDarwin {
|
||||
home.file = {
|
||||
"Library/Application Support/streamlink/config" = lib.mkIf (cfg.settings != { }) {
|
||||
"${configDir}/streamlink/config" = lib.mkIf (cfg.settings != { }) {
|
||||
text = renderSettings cfg.settings;
|
||||
};
|
||||
}
|
||||
// (lib.mapAttrs' (
|
||||
name: value:
|
||||
lib.nameValuePair "Library/Application Support/streamlink/config.${name}" (
|
||||
lib.nameValuePair "${configDir}/streamlink/config.${name}" (
|
||||
lib.mkIf (value.settings != { }) {
|
||||
text = renderSettings value.settings;
|
||||
}
|
||||
@@ -182,7 +153,7 @@ in
|
||||
) cfg.plugins)
|
||||
// (lib.mapAttrs' (
|
||||
name: value:
|
||||
lib.nameValuePair "Library/Application Support/streamlink/plugins/${name}.py" (
|
||||
lib.nameValuePair "${dataDir}/streamlink/plugins/${name}.py" (
|
||||
lib.mkIf (value.src != null) (
|
||||
if (builtins.isPath value.src) then
|
||||
{
|
||||
@@ -195,7 +166,5 @@ in
|
||||
)
|
||||
)
|
||||
) cfg.plugins);
|
||||
})
|
||||
]
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -85,8 +85,7 @@ in
|
||||
if v == false then
|
||||
""
|
||||
else
|
||||
(if v == true then n else n + "=" + (if builtins.isPath v then "${v}" else builtins.toString v))
|
||||
+ "\n"
|
||||
(if v == true then n else n + "=" + (if builtins.isPath v then "${v}" else toString v)) + "\n"
|
||||
) cfg.settings
|
||||
);
|
||||
};
|
||||
|
||||
@@ -183,14 +183,12 @@ let
|
||||
3;
|
||||
"mail.smtpserver.smtp_${id}.username" = account.userName;
|
||||
}
|
||||
// builtins.foldl' (a: b: a // b) { } (
|
||||
builtins.map (address: toThunderbirdSMTP account address) addresses
|
||||
)
|
||||
// builtins.foldl' (a: b: a // b) { } (map (address: toThunderbirdSMTP account address) addresses)
|
||||
// optionalAttrs (account.smtp != null && account.primary) {
|
||||
"mail.smtp.defaultserver" = "smtp_${id}";
|
||||
}
|
||||
// builtins.foldl' (a: b: a // b) { } (
|
||||
builtins.map (address: toThunderbirdIdentity account address) addresses
|
||||
map (address: toThunderbirdIdentity account address) addresses
|
||||
)
|
||||
// account.thunderbird.settings id;
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ in
|
||||
let
|
||||
conf =
|
||||
optional (cfg.host != null) ''set -g tmate-server-host "${cfg.host}"''
|
||||
++ optional (cfg.port != null) "set -g tmate-server-port ${builtins.toString cfg.port}"
|
||||
++ optional (cfg.port != null) "set -g tmate-server-port ${toString cfg.port}"
|
||||
++ optional (
|
||||
cfg.dsaFingerprint != null
|
||||
) ''set -g tmate-server-ed25519-fingerprint "${cfg.dsaFingerprint}"''
|
||||
|
||||
@@ -92,9 +92,12 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable (
|
||||
let
|
||||
config =
|
||||
let
|
||||
configDir =
|
||||
if pkgs.stdenv.hostPlatform.isDarwin then "Library/Application Support" else config.xdg.configHome;
|
||||
|
||||
configFiles =
|
||||
lib.attrsets.unionOfDisjoint
|
||||
{
|
||||
"vesktop/settings.json" = lib.mkIf (cfg.settings != { }) {
|
||||
@@ -117,16 +120,11 @@ in
|
||||
) cfg.vencord.themes
|
||||
);
|
||||
in
|
||||
lib.mkMerge [
|
||||
{
|
||||
lib.mkIf cfg.enable {
|
||||
home.packages = [
|
||||
(cfg.package.override { withSystemVencord = cfg.vencord.useSystem; })
|
||||
];
|
||||
}
|
||||
(lib.mkIf (!pkgs.stdenv.hostPlatform.isDarwin) { xdg.configFile = config; })
|
||||
(lib.mkIf pkgs.stdenv.hostPlatform.isDarwin {
|
||||
home.file = lib.mapAttrs' (n: v: lib.nameValuePair "Library/Application Support/${n}" v) config;
|
||||
})
|
||||
]
|
||||
);
|
||||
|
||||
home.file = lib.mapAttrs' (n: lib.nameValuePair "${configDir}/${n}") configFiles;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -240,7 +240,7 @@ in
|
||||
|
||||
dataFile =
|
||||
builtins.listToAttrs (
|
||||
builtins.map (item: {
|
||||
map (item: {
|
||||
name = "vicinae/extensions/${item.name}";
|
||||
value.source = item;
|
||||
}) cfg.extensions
|
||||
@@ -263,7 +263,7 @@ in
|
||||
KillMode = "process";
|
||||
EnvironmentFile = lib.mkIf (!versionPost0_17) (
|
||||
pkgs.writeText "vicinae-env" ''
|
||||
USE_LAYER_SHELL=${if cfg.useLayerShell then builtins.toString 1 else builtins.toString 0}
|
||||
USE_LAYER_SHELL=${if cfg.useLayerShell then toString 1 else toString 0}
|
||||
''
|
||||
);
|
||||
};
|
||||
|
||||
@@ -517,7 +517,7 @@ in
|
||||
else
|
||||
{ };
|
||||
# Merge MCP servers: transformed servers + user servers, with user servers taking precedence
|
||||
mergedServers = transformedMcpServers // ((v.userMcp.servers or { }));
|
||||
mergedServers = transformedMcpServers // (v.userMcp.servers or { });
|
||||
# Merge all MCP config
|
||||
mergedMcpConfig =
|
||||
v.userMcp // (lib.optionalAttrs (mergedServers != { }) { servers = mergedServers; });
|
||||
|
||||
@@ -301,7 +301,7 @@ in
|
||||
{
|
||||
assertions = [
|
||||
(lib.hm.assertions.assertPlatform "programs.waybar" pkgs lib.platforms.linux)
|
||||
({
|
||||
{
|
||||
assertion =
|
||||
if lib.versionAtLeast config.home.stateVersion "22.05" then
|
||||
all (x: !hasAttr "modules" x || x.modules == null) settings
|
||||
@@ -311,7 +311,7 @@ in
|
||||
The `programs.waybar.settings.[].modules` option has been removed.
|
||||
It is now possible to declare modules in the configuration without nesting them under the `modules` option.
|
||||
'';
|
||||
})
|
||||
}
|
||||
];
|
||||
|
||||
home.packages = [ cfg.package ];
|
||||
|
||||
@@ -58,7 +58,7 @@ in
|
||||
xdg.configFile."waylogout/config" = lib.mkIf (cfg.settings != { }) {
|
||||
text = lib.concatStrings (
|
||||
lib.mapAttrsToList (
|
||||
n: v: if v == false then "" else (if v == true then n else n + "=" + builtins.toString v) + "\n"
|
||||
n: v: if v == false then "" else (if v == true then n else n + "=" + toString v) + "\n"
|
||||
) cfg.settings
|
||||
);
|
||||
};
|
||||
|
||||
94
modules/programs/workstyle.nix
Normal file
94
modules/programs/workstyle.nix
Normal file
@@ -0,0 +1,94 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib) literalExpression mkOption mkEnableOption;
|
||||
inherit (lib.modules) mkIf;
|
||||
|
||||
cfg = config.programs.workstyle;
|
||||
|
||||
tomlFormat = pkgs.formats.toml { };
|
||||
|
||||
configFile = tomlFormat.generate "config.toml" cfg.settings;
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.hm.maintainers; [ farberbrodsky ];
|
||||
|
||||
options.programs.workstyle = {
|
||||
enable = mkEnableOption "Workstyle";
|
||||
|
||||
package = lib.mkPackageOption pkgs "workstyle" { };
|
||||
|
||||
systemd = {
|
||||
enable = mkEnableOption "Workstyle systemd integration";
|
||||
|
||||
debug = mkEnableOption "Workstyle debug logs";
|
||||
|
||||
target = mkOption {
|
||||
type = lib.types.str;
|
||||
default = config.wayland.systemd.target;
|
||||
defaultText = literalExpression "config.wayland.systemd.target";
|
||||
example = "sway-session.target";
|
||||
description = ''
|
||||
The systemd target that will automatically start the Workstyle service.
|
||||
|
||||
When setting this value to `"sway-session.target"`,
|
||||
make sure to also enable {option}`wayland.windowManager.sway.systemd.enable`,
|
||||
otherwise the service may never be started.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
settings = lib.mkOption {
|
||||
inherit (tomlFormat) type;
|
||||
default = { };
|
||||
description = "Configuration for workstyle";
|
||||
example = literalExpression ''
|
||||
{
|
||||
# Config for workstyle
|
||||
# Format: "pattern" = "icon";
|
||||
# The pattern will be used to match against the application name, class_id or WM_CLASS.
|
||||
# The icon will be used to represent that application.
|
||||
# Note if multiple patterns are present in the same application name,
|
||||
# precedence is given in order of apparition in this file.
|
||||
kitty = "T";
|
||||
firefox = "B";
|
||||
other = {
|
||||
fallback_icon = "F";
|
||||
deduplicate_icons = false;
|
||||
separator = ": ";
|
||||
};
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
assertions = [
|
||||
(lib.hm.assertions.assertPlatform "programs.workstyle" pkgs lib.platforms.linux)
|
||||
];
|
||||
|
||||
home.packages = [ cfg.package ];
|
||||
xdg.configFile."workstyle/config.toml" = mkIf (cfg.settings != { }) { source = configFile; };
|
||||
systemd.user.services.workstyle = mkIf cfg.systemd.enable {
|
||||
Unit = {
|
||||
Description = "workstyle autostart";
|
||||
BindsTo = [ cfg.systemd.target ];
|
||||
# This is not necessary: workstyle reloads the config file after every window event.
|
||||
# It might become necessary in the future.
|
||||
# X-Restart-Triggers = mkIf (cfg.settings != { }) [ "${configFile}" ];
|
||||
};
|
||||
Service = {
|
||||
ExecStart = "${cfg.package}/bin/workstyle";
|
||||
Restart = "always";
|
||||
RestartSec = 3;
|
||||
Environment = mkIf (cfg.systemd.debug) "RUST_LOG=debug";
|
||||
};
|
||||
Install.WantedBy = [ cfg.systemd.target ];
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -35,7 +35,7 @@ let
|
||||
'';
|
||||
}
|
||||
else
|
||||
builtins.dirOf value;
|
||||
dirOf value;
|
||||
|
||||
makePluginSearchPath = p: "${p}/?/init.lua;${p}/?.lua";
|
||||
|
||||
@@ -46,9 +46,9 @@ let
|
||||
searchPaths = map makePluginSearchPath wrappedPlugins;
|
||||
pluginSearchPath = lib.concatStringsSep ";" searchPaths;
|
||||
in
|
||||
(''
|
||||
''
|
||||
package.path = "${pluginSearchPath};" .. package.path
|
||||
'')
|
||||
''
|
||||
else
|
||||
"\n";
|
||||
|
||||
|
||||
@@ -127,7 +127,7 @@ in
|
||||
};
|
||||
|
||||
Service = {
|
||||
Environment = with pkgs; "PATH=${makeBinPath cfg.extraPackages}";
|
||||
Environment = "PATH=${makeBinPath cfg.extraPackages}";
|
||||
ExecStart = "${cfg.package}/bin/fusuma";
|
||||
};
|
||||
|
||||
|
||||
@@ -64,7 +64,10 @@ in
|
||||
|
||||
importantPrefixes = lib.mkOption {
|
||||
type = with lib.types; listOf str;
|
||||
default = [ "$" ];
|
||||
default = [
|
||||
"$"
|
||||
"monitor"
|
||||
];
|
||||
example = [ "$" ];
|
||||
description = ''
|
||||
List of prefix of attributes to source at the top of the config.
|
||||
|
||||
@@ -117,7 +117,7 @@ in
|
||||
args = lib.lists.forEach cfg.wallpapers (
|
||||
each:
|
||||
lib.concatStringsSep " " (
|
||||
lib.cli.toGNUCommandLine { } {
|
||||
lib.cli.toCommandLineGNU { } {
|
||||
screen-root = each.monitor;
|
||||
inherit (each) scaling fps;
|
||||
inherit (each.audio) silent;
|
||||
@@ -125,9 +125,11 @@ in
|
||||
no-audio-processing = !each.audio.processing;
|
||||
}
|
||||
++ each.extraOptions
|
||||
++ [
|
||||
"--bg"
|
||||
each.wallpaperId
|
||||
]
|
||||
)
|
||||
# This has to be the last argument in each group
|
||||
+ " --bg ${each.wallpaperId}"
|
||||
);
|
||||
in
|
||||
{
|
||||
|
||||
@@ -166,10 +166,14 @@ in
|
||||
mkIf cfg.enable {
|
||||
home = {
|
||||
packages = [ cfg.package ];
|
||||
sessionVariables = mkIf cfg.enableSessionVariables {
|
||||
MPD_HOST = mkIf (cfg.network.listenAddress != "any") cfg.network.listenAddress;
|
||||
MPD_PORT = builtins.toString cfg.network.port;
|
||||
};
|
||||
sessionVariables = mkIf cfg.enableSessionVariables (
|
||||
{
|
||||
MPD_PORT = toString cfg.network.port;
|
||||
}
|
||||
// lib.optionalAttrs (cfg.network.listenAddress != "any") {
|
||||
MPD_HOST = cfg.network.listenAddress;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
services.mpd = lib.mkMerge [
|
||||
|
||||
23
modules/services/podman/assertions.nix
Normal file
23
modules/services/podman/assertions.nix
Normal file
@@ -0,0 +1,23 @@
|
||||
{ lib }:
|
||||
|
||||
{
|
||||
assertPlatform =
|
||||
module: config: pkgs: platforms:
|
||||
let
|
||||
modulePath = lib.splitString "." module;
|
||||
isEmpty = x: x == false || x == null || x == { } || x == [ ] || x == "";
|
||||
in
|
||||
{
|
||||
assertion =
|
||||
(isEmpty (lib.attrByPath modulePath null config))
|
||||
|| (lib.elem pkgs.stdenv.hostPlatform.system platforms);
|
||||
message =
|
||||
let
|
||||
platformsStr = lib.concatStringsSep "\n" (map (p: " - ${p}") (lib.sort (a: b: a < b) platforms));
|
||||
in
|
||||
''
|
||||
The module ${module} does not support your platform. It only supports
|
||||
|
||||
${platformsStr}'';
|
||||
};
|
||||
}
|
||||
301
modules/services/podman/darwin.nix
Normal file
301
modules/services/podman/darwin.nix
Normal file
@@ -0,0 +1,301 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib)
|
||||
attrNames
|
||||
concatStringsSep
|
||||
filterAttrs
|
||||
mapAttrs'
|
||||
mkIf
|
||||
mkOption
|
||||
mkMerge
|
||||
nameValuePair
|
||||
optionalString
|
||||
types
|
||||
;
|
||||
assertions = import ./assertions.nix { inherit lib; };
|
||||
|
||||
cfg = config.services.podman;
|
||||
|
||||
machineDefinitionType = types.submodule {
|
||||
options = {
|
||||
cpus = mkOption {
|
||||
type = types.nullOr types.ints.positive;
|
||||
default = null;
|
||||
example = 2;
|
||||
description = "Number of CPUs to allocate to the machine. If null, uses podman's default.";
|
||||
};
|
||||
|
||||
diskSize = mkOption {
|
||||
type = types.nullOr types.ints.positive;
|
||||
default = null;
|
||||
example = 200;
|
||||
description = "Disk size in GB for the machine. If null, uses podman's default.";
|
||||
};
|
||||
|
||||
image = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Bootable image to use for the machine. If null, uses podman's default.";
|
||||
};
|
||||
|
||||
memory = mkOption {
|
||||
type = types.nullOr types.ints.positive;
|
||||
default = null;
|
||||
example = 8192;
|
||||
description = "Memory in MB to allocate to the machine. If null, uses podman's default.";
|
||||
};
|
||||
|
||||
rootful = mkOption {
|
||||
type = types.nullOr types.bool;
|
||||
default = null;
|
||||
example = true;
|
||||
description = ''
|
||||
Whether to run the machine in rootful mode. If null, uses podman's default.
|
||||
Rootful mode runs containers as root inside the VM.
|
||||
'';
|
||||
};
|
||||
|
||||
swap = mkOption {
|
||||
type = types.nullOr types.ints.positive;
|
||||
default = null;
|
||||
example = 2048;
|
||||
description = "Swap size in MB for the machine. If null, uses podman's default.";
|
||||
};
|
||||
|
||||
timezone = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "UTC";
|
||||
description = "Timezone to set in the machine. If null, uses podman's default.";
|
||||
};
|
||||
|
||||
username = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "user";
|
||||
description = "Username used in the machine image. If null, uses podman's default.";
|
||||
};
|
||||
|
||||
volumes = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
example = [
|
||||
"/Users:/Users"
|
||||
"/private:/private"
|
||||
"/var/folders:/var/folders"
|
||||
];
|
||||
description = ''
|
||||
Volumes to mount in the machine, specified as source:target pairs.
|
||||
If empty, podman will use its default volume mounts.
|
||||
'';
|
||||
};
|
||||
|
||||
autoStart = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
example = false;
|
||||
description = "Whether to automatically start this machine on login.";
|
||||
};
|
||||
|
||||
watchdogInterval = mkOption {
|
||||
type = types.ints.positive;
|
||||
default = 30;
|
||||
example = 60;
|
||||
description = "Interval in seconds to check if the machine is running";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mkWatchdogScript =
|
||||
name: machine:
|
||||
pkgs.writeShellScript "podman-machine-watchdog-${name}" ''
|
||||
set -euo pipefail
|
||||
|
||||
MACHINE_NAME="${name}"
|
||||
INTERVAL=${toString machine.watchdogInterval}
|
||||
PODMAN="${lib.getExe cfg.package}"
|
||||
|
||||
log() {
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >&2
|
||||
}
|
||||
|
||||
check_and_start() {
|
||||
local state
|
||||
state=$($PODMAN machine inspect "$MACHINE_NAME" --format '{{.State}}' 2>/dev/null || echo "unknown")
|
||||
|
||||
case "$state" in
|
||||
running)
|
||||
return 0
|
||||
;;
|
||||
stopped|unknown)
|
||||
log "Machine '$MACHINE_NAME' is starting..."
|
||||
if $PODMAN machine start "$MACHINE_NAME" 2>&1 | while IFS= read -r line; do log "$line"; done; then
|
||||
log "Machine '$MACHINE_NAME' started successfully"
|
||||
return 0
|
||||
else
|
||||
log "Failed to start machine '$MACHINE_NAME'"
|
||||
return 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
log "Machine '$MACHINE_NAME' is $state"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
log "Starting watchdog for machine '$MACHINE_NAME' (check interval: ''${INTERVAL}s)"
|
||||
|
||||
while true; do
|
||||
check_and_start || true
|
||||
sleep "$INTERVAL"
|
||||
done
|
||||
'';
|
||||
in
|
||||
{
|
||||
options.services.podman = {
|
||||
useDefaultMachine = mkOption {
|
||||
type = types.bool;
|
||||
default = pkgs.stdenv.hostPlatform.isDarwin;
|
||||
description = ''
|
||||
Whether to create and use the default podman machine.
|
||||
|
||||
The default machine will be named `podman-machine-default` and configured with podmans default values.
|
||||
'';
|
||||
readOnly = pkgs.stdenv.hostPlatform.isLinux;
|
||||
};
|
||||
|
||||
machines = mkOption {
|
||||
type = types.attrsOf machineDefinitionType;
|
||||
default = { };
|
||||
description = "Declarative podman machine configurations.";
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
"dev-machine" = {
|
||||
cpus = 4;
|
||||
diskSize = 100;
|
||||
memory = 8192;
|
||||
swap = 2048;
|
||||
timezone = "UTC";
|
||||
volumes = [
|
||||
"/Users:/Users"
|
||||
"/private:/private"
|
||||
];
|
||||
autoStart = true;
|
||||
watchdogInterval = 30;
|
||||
};
|
||||
"testing" = {
|
||||
cpus = 2;
|
||||
diskSize = 50;
|
||||
image = "ghcr.io/your-org/custom-image:latest";
|
||||
memory = 4096;
|
||||
username = "podman";
|
||||
autoStart = false;
|
||||
};
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config =
|
||||
let
|
||||
podmanCmd = lib.getExe cfg.package;
|
||||
allMachines =
|
||||
cfg.machines
|
||||
// (
|
||||
if cfg.useDefaultMachine then
|
||||
{
|
||||
"podman-machine-default" = {
|
||||
cpus = null;
|
||||
diskSize = null;
|
||||
image = null;
|
||||
memory = null;
|
||||
rootful = null;
|
||||
swap = null;
|
||||
timezone = null;
|
||||
username = null;
|
||||
volumes = [ ];
|
||||
autoStart = true;
|
||||
watchdogInterval = 30;
|
||||
};
|
||||
}
|
||||
else
|
||||
{ }
|
||||
);
|
||||
autoStartMachines = filterAttrs (_name: machine: machine.autoStart) allMachines;
|
||||
in
|
||||
mkIf cfg.enable (mkMerge [
|
||||
{
|
||||
assertions = [
|
||||
(assertions.assertPlatform "services.podman.useDefaultMachine" config pkgs lib.platforms.darwin)
|
||||
(assertions.assertPlatform "services.podman.machines" config pkgs lib.platforms.darwin)
|
||||
];
|
||||
}
|
||||
|
||||
(mkIf pkgs.stdenv.isDarwin {
|
||||
home.activation.podmanMachines =
|
||||
let
|
||||
mkMachineInitScript =
|
||||
name: machine:
|
||||
let
|
||||
# Automatically mount host's container config into the VM
|
||||
username = if isNull machine.username then "core" else machine.username;
|
||||
configVolume = "$HOME/.config/containers:/home/${username}/.config/containers";
|
||||
allVolumes = [ configVolume ] ++ machine.volumes;
|
||||
in
|
||||
''
|
||||
if ! ${podmanCmd} machine list --format '{{.Name}}' 2>/dev/null | sed 's/\*$//' | grep -q '^${name}$'; then
|
||||
echo "Creating podman machine: ${name}"
|
||||
${podmanCmd} machine init ${name} \
|
||||
${optionalString (machine.cpus != null) "--cpus ${toString machine.cpus}"} \
|
||||
${optionalString (machine.diskSize != null) "--disk-size ${toString machine.diskSize}"} \
|
||||
${optionalString (machine.image != null) "--image ${machine.image}"} \
|
||||
${optionalString (machine.memory != null) "--memory ${toString machine.memory}"} \
|
||||
${optionalString ((machine.rootful != null) && machine.rootful) "--rootful"} \
|
||||
${optionalString (machine.swap != null) "--swap ${toString machine.swap}"} \
|
||||
${optionalString (machine.timezone != null) "--timezone \"${machine.timezone}\""} \
|
||||
${optionalString (machine.username != null) "--username \"${machine.username}\""} \
|
||||
${concatStringsSep " " (map (v: "--volume \"${v}\"") allVolumes)}
|
||||
fi
|
||||
'';
|
||||
in
|
||||
lib.hm.dag.entryAfter [ "writeBoundary" ] ''
|
||||
PATH="${cfg.package}/bin:$PATH"
|
||||
|
||||
${concatStringsSep "\n" (lib.mapAttrsToList mkMachineInitScript allMachines)}
|
||||
|
||||
MANAGED_MACHINES="${concatStringsSep " " (attrNames allMachines)}"
|
||||
EXISTING_MACHINES=$(${podmanCmd} machine list --format '{{.Name}}' 2>/dev/null | sed 's/\*$//' || echo "")
|
||||
|
||||
for machine in $EXISTING_MACHINES; do
|
||||
if [[ ! " $MANAGED_MACHINES " =~ " $machine " ]]; then
|
||||
echo "Removing unmanaged podman machine: $machine"
|
||||
${podmanCmd} machine stop "$machine" 2>/dev/null || true
|
||||
${podmanCmd} machine rm -f "$machine"
|
||||
fi
|
||||
done
|
||||
'';
|
||||
|
||||
launchd.agents = mapAttrs' (
|
||||
name: machine:
|
||||
nameValuePair "podman-machine-${name}" {
|
||||
enable = true;
|
||||
config = {
|
||||
ProgramArguments = [ "${mkWatchdogScript name machine}" ];
|
||||
KeepAlive = {
|
||||
Crashed = true;
|
||||
SuccessfulExit = false;
|
||||
};
|
||||
ProcessType = "Background";
|
||||
RunAtLoad = true;
|
||||
};
|
||||
}
|
||||
) autoStartMachines;
|
||||
})
|
||||
]);
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
@@ -12,21 +12,19 @@ in
|
||||
meta.maintainers = [
|
||||
lib.hm.maintainers.bamhm182
|
||||
lib.maintainers.n-hass
|
||||
lib.maintainers.delafthi
|
||||
];
|
||||
|
||||
imports = [
|
||||
./builds.nix
|
||||
./containers.nix
|
||||
./images.nix
|
||||
./install-quadlet.nix
|
||||
./networks.nix
|
||||
./services.nix
|
||||
./volumes.nix
|
||||
./linux/default.nix
|
||||
./darwin.nix
|
||||
];
|
||||
|
||||
options.services.podman = {
|
||||
enable = lib.mkEnableOption "Podman, a daemonless container engine";
|
||||
|
||||
package = lib.mkPackageOption pkgs "podman" { };
|
||||
|
||||
settings = {
|
||||
containers = lib.mkOption {
|
||||
type = toml.type;
|
||||
@@ -94,14 +92,14 @@ in
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
assertions = [ (lib.hm.assertions.assertPlatform "podman" pkgs lib.platforms.linux) ];
|
||||
|
||||
home.packages = [ cfg.package ];
|
||||
|
||||
services.podman.settings.storage = {
|
||||
storage.driver = lib.mkDefault "overlay";
|
||||
};
|
||||
services.podman.settings.storage.storage.driver = lib.mkDefault "overlay";
|
||||
|
||||
# Configuration files are written to `$XDG_CONFIG_HOME/.config/containers`
|
||||
# On Linux: podman reads them directly from this location
|
||||
# On Darwin: these files are automatically mounted into the podman machine VM
|
||||
# (see darwin.nix for the volume mount configuration)
|
||||
xdg.configFile = {
|
||||
"containers/policy.json".source =
|
||||
if cfg.settings.policy != { } then
|
||||
@@ -5,7 +5,13 @@
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) mkOption types;
|
||||
inherit (lib)
|
||||
mkIf
|
||||
mkOption
|
||||
mkMerge
|
||||
types
|
||||
;
|
||||
assertions = import ../assertions.nix { inherit lib; };
|
||||
|
||||
cfg = config.services.podman;
|
||||
|
||||
@@ -182,10 +188,17 @@ in
|
||||
let
|
||||
buildQuadlets = lib.mapAttrsToList toQuadletInternal cfg.builds;
|
||||
in
|
||||
lib.mkIf cfg.enable {
|
||||
mkIf cfg.enable (mkMerge [
|
||||
{
|
||||
assertions = [
|
||||
(assertions.assertPlatform "services.podman.builds" config pkgs lib.platforms.linux)
|
||||
];
|
||||
}
|
||||
(mkIf pkgs.stdenv.hostPlatform.isLinux {
|
||||
services.podman.internal.quadletDefinitions = buildQuadlets;
|
||||
assertions = lib.flatten (map (build: build.assertions) buildQuadlets);
|
||||
|
||||
xdg.configFile."podman/images.manifest".text = podman-lib.generateManifestText buildQuadlets;
|
||||
};
|
||||
})
|
||||
]);
|
||||
}
|
||||
@@ -5,7 +5,13 @@
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) mkOption types;
|
||||
inherit (lib)
|
||||
mkIf
|
||||
mkOption
|
||||
mkMerge
|
||||
types
|
||||
;
|
||||
assertions = import ../assertions.nix { inherit lib; };
|
||||
|
||||
cfg = config.services.podman;
|
||||
|
||||
@@ -401,12 +407,19 @@ in
|
||||
let
|
||||
containerQuadlets = lib.mapAttrsToList toQuadletInternal cfg.containers;
|
||||
in
|
||||
lib.mkIf cfg.enable {
|
||||
mkIf cfg.enable (mkMerge [
|
||||
{
|
||||
assertions = [
|
||||
(assertions.assertPlatform "services.podman.containers" config pkgs lib.platforms.linux)
|
||||
];
|
||||
}
|
||||
(mkIf pkgs.stdenv.hostPlatform.isLinux {
|
||||
services.podman.internal.quadletDefinitions = containerQuadlets;
|
||||
assertions = lib.flatten (map (container: container.assertions) containerQuadlets);
|
||||
|
||||
# manifest file
|
||||
xdg.configFile."podman/containers.manifest".text =
|
||||
podman-lib.generateManifestText containerQuadlets;
|
||||
};
|
||||
})
|
||||
]);
|
||||
}
|
||||
12
modules/services/podman/linux/default.nix
Normal file
12
modules/services/podman/linux/default.nix
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
imports = [
|
||||
./options.nix
|
||||
./builds.nix
|
||||
./containers.nix
|
||||
./images.nix
|
||||
./install-quadlet.nix
|
||||
./networks.nix
|
||||
./services.nix
|
||||
./volumes.nix
|
||||
];
|
||||
}
|
||||
@@ -5,7 +5,13 @@
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) mkOption types;
|
||||
inherit (lib)
|
||||
mkIf
|
||||
mkOption
|
||||
mkMerge
|
||||
types
|
||||
;
|
||||
assertions = import ../assertions.nix { inherit lib; };
|
||||
|
||||
cfg = config.services.podman;
|
||||
|
||||
@@ -165,8 +171,15 @@ in
|
||||
let
|
||||
imageQuadlets = lib.mapAttrsToList toQuadletInternal cfg.images;
|
||||
in
|
||||
lib.mkIf cfg.enable {
|
||||
mkIf cfg.enable (mkMerge [
|
||||
{
|
||||
assertions = [
|
||||
(assertions.assertPlatform "services.podman.images" config pkgs lib.platforms.linux)
|
||||
];
|
||||
}
|
||||
(mkIf pkgs.stdenv.hostPlatform.isLinux {
|
||||
services.podman.internal.quadletDefinitions = imageQuadlets;
|
||||
assertions = lib.flatten (map (image: image.assertions) imageQuadlets);
|
||||
};
|
||||
})
|
||||
]);
|
||||
}
|
||||
@@ -99,7 +99,7 @@ in
|
||||
{
|
||||
imports = [ ./options.nix ];
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
config = lib.mkIf (cfg.enable && pkgs.stdenv.hostPlatform.isLinux) {
|
||||
home.file = generateSystemdFileLinks allUnitFiles;
|
||||
|
||||
# if the length of builtQuadlets is 0, then we don't need register the activation script
|
||||
@@ -5,7 +5,13 @@
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) mkOption types;
|
||||
inherit (lib)
|
||||
mkIf
|
||||
mkOption
|
||||
mkMerge
|
||||
types
|
||||
;
|
||||
assertions = import ../assertions.nix { inherit lib; };
|
||||
|
||||
cfg = config.services.podman;
|
||||
|
||||
@@ -180,10 +186,17 @@ in
|
||||
let
|
||||
networkQuadlets = lib.mapAttrsToList toQuadletInternal cfg.networks;
|
||||
in
|
||||
lib.mkIf cfg.enable {
|
||||
mkIf cfg.enable (mkMerge [
|
||||
{
|
||||
assertions = [
|
||||
(assertions.assertPlatform "services.podman.networks" config pkgs lib.platforms.linux)
|
||||
];
|
||||
}
|
||||
(mkIf pkgs.stdenv.hostPlatform.isLinux {
|
||||
services.podman.internal.quadletDefinitions = networkQuadlets;
|
||||
assertions = lib.flatten (map (network: network.assertions) networkQuadlets);
|
||||
|
||||
xdg.configFile."podman/networks.manifest".text = podman-lib.generateManifestText networkQuadlets;
|
||||
};
|
||||
})
|
||||
]);
|
||||
}
|
||||
@@ -1,37 +1,47 @@
|
||||
{ lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib) mkEnableOption mkIf mkOption;
|
||||
assertions = import ../assertions.nix { inherit lib; };
|
||||
|
||||
cfg = config.services.podman;
|
||||
|
||||
# Define the systemd service type
|
||||
quadletInternalType = lib.types.submodule {
|
||||
options = {
|
||||
assertions = lib.mkOption {
|
||||
assertions = mkOption {
|
||||
type = with lib.types; listOf unspecified;
|
||||
default = [ ];
|
||||
internal = true;
|
||||
description = "List of Nix type assertions.";
|
||||
};
|
||||
|
||||
dependencies = lib.mkOption {
|
||||
dependencies = mkOption {
|
||||
type = with lib.types; listOf package;
|
||||
default = [ ];
|
||||
internal = true;
|
||||
description = "List of systemd service dependencies.";
|
||||
};
|
||||
|
||||
resourceType = lib.mkOption {
|
||||
resourceType = mkOption {
|
||||
type = lib.types.str;
|
||||
default = "";
|
||||
internal = true;
|
||||
description = "The type of the podman Quadlet resource.";
|
||||
};
|
||||
|
||||
serviceName = lib.mkOption {
|
||||
serviceName = mkOption {
|
||||
type = lib.types.str;
|
||||
internal = true;
|
||||
description = "The name of the systemd service.";
|
||||
};
|
||||
|
||||
source = lib.mkOption {
|
||||
source = mkOption {
|
||||
type = lib.types.str;
|
||||
internal = true;
|
||||
description = "The quadlet source file content.";
|
||||
@@ -42,13 +52,13 @@ in
|
||||
{
|
||||
options.services.podman = {
|
||||
internal = {
|
||||
quadletDefinitions = lib.mkOption {
|
||||
quadletDefinitions = mkOption {
|
||||
type = lib.types.listOf quadletInternalType;
|
||||
default = { };
|
||||
internal = true;
|
||||
description = "List of quadlet source file content and service names.";
|
||||
};
|
||||
builtQuadlets = lib.mkOption {
|
||||
builtQuadlets = mkOption {
|
||||
type = with lib.types; attrsOf package;
|
||||
default = { };
|
||||
internal = true;
|
||||
@@ -56,8 +66,11 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
package = lib.mkPackageOption pkgs "podman" { };
|
||||
|
||||
enableTypeChecks = lib.mkEnableOption "type checks for podman quadlets";
|
||||
enableTypeChecks = mkEnableOption "type checks for podman quadlets";
|
||||
};
|
||||
config = mkIf cfg.enable {
|
||||
assertions = [
|
||||
(assertions.assertPlatform "services.podman.enableTypeChecks" config pkgs lib.platforms.linux)
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -23,9 +23,9 @@ let
|
||||
|
||||
${k}='' (mapAttrsToList normalizeKeyValue v))
|
||||
else
|
||||
builtins.toString v;
|
||||
toString v;
|
||||
in
|
||||
if builtins.isNull v then "" else "${k}=${v'}";
|
||||
if isNull v then "" else "${k}=${v'}";
|
||||
|
||||
primitiveAttrs = with types; attrsOf (either primitive (listOf primitive));
|
||||
primitiveList = with types; listOf primitive;
|
||||
@@ -5,20 +5,23 @@
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) mkIf mkOption mkMerge;
|
||||
assertions = import ../assertions.nix { inherit lib; };
|
||||
|
||||
cfg = config.services.podman;
|
||||
in
|
||||
{
|
||||
options.services.podman = {
|
||||
autoUpdate = {
|
||||
enable = lib.mkOption {
|
||||
enable = mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
default = pkgs.stdenv.hostPlatform.isLinux;
|
||||
description = "Automatically update the podman images.";
|
||||
};
|
||||
|
||||
onCalendar = lib.mkOption {
|
||||
onCalendar = mkOption {
|
||||
type = lib.types.str;
|
||||
default = "Sun *-*-* 00:00";
|
||||
default = lib.optionalString pkgs.stdenv.hostPlatform.isLinux "Sun *-*-* 00:00";
|
||||
description = ''
|
||||
The systemd `OnCalendar` expression for the update. See
|
||||
{manpage}`systemd.time(7)` for a description of the format.
|
||||
@@ -27,9 +30,14 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable (
|
||||
lib.mkMerge [
|
||||
(lib.mkIf cfg.autoUpdate.enable {
|
||||
config = mkIf cfg.enable (mkMerge [
|
||||
{
|
||||
assertions = [
|
||||
(assertions.assertPlatform "services.podman.networks" config pkgs lib.platforms.linux)
|
||||
];
|
||||
}
|
||||
(mkIf pkgs.stdenv.hostPlatform.isLinux (mkMerge [
|
||||
(mkIf cfg.autoUpdate.enable {
|
||||
systemd.user.services."podman-auto-update" = {
|
||||
Unit = {
|
||||
Description = "Podman auto-update service";
|
||||
@@ -86,6 +94,6 @@ in
|
||||
}:/bin
|
||||
'';
|
||||
}
|
||||
]
|
||||
);
|
||||
]))
|
||||
]);
|
||||
}
|
||||
@@ -5,7 +5,13 @@
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) mkOption types;
|
||||
inherit (lib)
|
||||
mkIf
|
||||
mkOption
|
||||
mkMerge
|
||||
types
|
||||
;
|
||||
assertions = import ../assertions.nix { inherit lib; };
|
||||
|
||||
cfg = config.services.podman;
|
||||
|
||||
@@ -192,10 +198,17 @@ in
|
||||
let
|
||||
volumeQuadlets = lib.mapAttrsToList toQuadletInternal cfg.volumes;
|
||||
in
|
||||
lib.mkIf cfg.enable {
|
||||
mkIf cfg.enable (mkMerge [
|
||||
{
|
||||
assertions = [
|
||||
(assertions.assertPlatform "services.podman.volumes" config pkgs lib.platforms.linux)
|
||||
];
|
||||
}
|
||||
(mkIf pkgs.stdenv.hostPlatform.isLinux {
|
||||
services.podman.internal.quadletDefinitions = volumeQuadlets;
|
||||
assertions = lib.flatten (map (volume: volume.assertions) volumeQuadlets);
|
||||
|
||||
xdg.configFile."podman/volumes.manifest".text = podman-lib.generateManifestText volumeQuadlets;
|
||||
};
|
||||
})
|
||||
]);
|
||||
}
|
||||
@@ -15,7 +15,7 @@ let
|
||||
''}
|
||||
|
||||
USE_BACKUP="${if cfg.useBackup then "yes" else "no"}"
|
||||
BACKUP_LIMIT=${builtins.toString cfg.backupLimit}
|
||||
BACKUP_LIMIT=${toString cfg.backupLimit}
|
||||
'';
|
||||
in
|
||||
{
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
let
|
||||
cfg = config.services.pueue;
|
||||
yamlFormat = pkgs.formats.yaml { };
|
||||
configDir =
|
||||
if pkgs.stdenv.hostPlatform.isDarwin then "Library/Application Support" else config.xdg.configHome;
|
||||
configFile = yamlFormat.generate "pueue.yaml" ({ shared = { }; } // cfg.settings);
|
||||
pueuedBin = "${cfg.package}/bin/pueued";
|
||||
in
|
||||
@@ -38,7 +40,7 @@ in
|
||||
config = lib.mkIf cfg.enable {
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
||||
xdg.configFile."pueue/pueue.yml" = lib.mkIf pkgs.stdenv.isLinux { source = configFile; };
|
||||
home.file."${configDir}/pueue/pueue.yml".source = configFile;
|
||||
|
||||
systemd.user = lib.mkIf (cfg.package != null) {
|
||||
services.pueued = {
|
||||
@@ -55,12 +57,6 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
# This is the default configuration file location for pueue on
|
||||
# darwin (https://github.com/Nukesor/pueue/wiki/Configuration)
|
||||
home.file."Library/Application Support/pueue/pueue.yml" = lib.mkIf pkgs.stdenv.isDarwin {
|
||||
source = configFile;
|
||||
};
|
||||
|
||||
launchd.agents.pueued = lib.mkIf (cfg.package != null) {
|
||||
enable = true;
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ in
|
||||
StopWhenUnneeded = cfg.node.lazy.enable;
|
||||
ConditionPathExists = radicleKeyPair;
|
||||
};
|
||||
Service = mkMerge ([
|
||||
Service = mkMerge [
|
||||
{
|
||||
Slice = "session.slice";
|
||||
ExecStart = "${getExe' cfg.node.package "radicle-node"} ${cfg.node.args}";
|
||||
@@ -182,7 +182,7 @@ in
|
||||
"~@setuid"
|
||||
];
|
||||
}
|
||||
]);
|
||||
];
|
||||
};
|
||||
"radicle-node-proxy" = mkIf cfg.node.lazy.enable {
|
||||
Unit = {
|
||||
|
||||
@@ -239,7 +239,7 @@ in
|
||||
configFullPath = config.xdg.configHome + "/${xdgConfigFilePath}";
|
||||
in
|
||||
"${cfg.package}/bin/${command} "
|
||||
+ lib.cli.toGNUCommandLineShell { } {
|
||||
+ lib.cli.toCommandLineShellGNU { } {
|
||||
v = cfg.enableVerboseLogging;
|
||||
c = configFullPath;
|
||||
};
|
||||
|
||||
@@ -37,6 +37,17 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
pkcs11Whitelist = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
example = lib.literalExpression ''[ "''${pkgs.tpm2-pkcs11}/lib/*" ]'';
|
||||
description = ''
|
||||
Specify a list of approved path patterns for PKCS#11 and FIDO authenticator middleware libraries. When using the -s or -S options with {manpage}`ssh-add(1)`, only libraries matching these patterns will be accepted.
|
||||
|
||||
See {manpage}`ssh-agent(1)`.
|
||||
'';
|
||||
};
|
||||
|
||||
enableBashIntegration = lib.hm.shell.mkBashIntegrationOption { inherit config; };
|
||||
|
||||
enableZshIntegration = lib.hm.shell.mkZshIntegrationOption { inherit config; };
|
||||
@@ -101,6 +112,10 @@ in
|
||||
lib.optionalString (
|
||||
cfg.defaultMaximumIdentityLifetime != null
|
||||
) " -t ${toString cfg.defaultMaximumIdentityLifetime}"
|
||||
}${
|
||||
lib.optionalString (
|
||||
cfg.pkcs11Whitelist != [ ]
|
||||
) " -P '${lib.concatStringsSep "," cfg.pkcs11Whitelist}'"
|
||||
}";
|
||||
};
|
||||
|
||||
@@ -114,6 +129,10 @@ in
|
||||
lib.optionalString (
|
||||
cfg.defaultMaximumIdentityLifetime != null
|
||||
) " -t ${toString cfg.defaultMaximumIdentityLifetime}"
|
||||
}${
|
||||
lib.optionalString (
|
||||
cfg.pkcs11Whitelist != [ ]
|
||||
) " -P '${lib.concatStringsSep "," cfg.pkcs11Whitelist}'"
|
||||
}''
|
||||
];
|
||||
KeepAlive = {
|
||||
@@ -124,7 +143,5 @@ in
|
||||
RunAtLoad = true;
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -130,6 +130,7 @@ in
|
||||
- `HYPRLAND_INSTANCE_SIGNATURE`
|
||||
- `WAYLAND_DISPLAY`
|
||||
- `XDG_CURRENT_DESKTOP`
|
||||
- `XDG_SESSION_TYPE`
|
||||
'';
|
||||
};
|
||||
|
||||
@@ -140,6 +141,7 @@ in
|
||||
"HYPRLAND_INSTANCE_SIGNATURE"
|
||||
"WAYLAND_DISPLAY"
|
||||
"XDG_CURRENT_DESKTOP"
|
||||
"XDG_SESSION_TYPE"
|
||||
];
|
||||
example = [ "--all" ];
|
||||
description = ''
|
||||
@@ -359,7 +361,7 @@ in
|
||||
) cfg.submaps;
|
||||
|
||||
submapWarnings = lib.mapAttrsToList (submapName: nonBinds: ''
|
||||
wayland.windowManager.hyprland.submaps."${submapName}".settings: found non-bind entries: [${builtins.toString nonBinds}], which will have no effect in a submap
|
||||
wayland.windowManager.hyprland.submaps."${submapName}".settings: found non-bind entries: [${toString nonBinds}], which will have no effect in a submap
|
||||
'') (lib.filterAttrs (n: v: v != [ ]) submapWarningsAttrset);
|
||||
in
|
||||
submapWarnings ++ lib.optional inconsistent warning;
|
||||
|
||||
@@ -98,7 +98,7 @@ let
|
||||
attrName = builtins.substring 1 999 k; # Remove "@" prefix
|
||||
attrValue = value.${k};
|
||||
in
|
||||
" ${attrName}=\"${escape (builtins.toString attrValue)}\""
|
||||
" ${attrName}=\"${escape (toString attrValue)}\""
|
||||
) attrKeys
|
||||
);
|
||||
|
||||
@@ -125,7 +125,7 @@ let
|
||||
|
||||
# All other primitive values: wrap in start/end tag
|
||||
else
|
||||
"<${name}>${escape (builtins.toString value)}</${name}>";
|
||||
"<${name}>${escape (toString value)}</${name}>";
|
||||
|
||||
generateXML = name: config: extraConfig: ''
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
@@ -139,7 +139,7 @@ let
|
||||
else if name == "labwc_config" then
|
||||
lib.mapAttrsToList generateRc
|
||||
else
|
||||
builtins.throw "error ${name} is neither openbox_menu nor labwc_config"
|
||||
throw "error ${name} is neither openbox_menu nor labwc_config"
|
||||
)
|
||||
config
|
||||
)
|
||||
|
||||
@@ -134,7 +134,7 @@ in
|
||||
Service = {
|
||||
ExecStart =
|
||||
let
|
||||
args = lib.cli.toGNUCommandLineShell { } {
|
||||
args = lib.cli.toCommandLineShellGNU { } {
|
||||
t = cfg.temperature.night;
|
||||
T = cfg.temperature.day;
|
||||
g = cfg.gamma;
|
||||
|
||||
@@ -12,12 +12,14 @@ let
|
||||
inherit (lib)
|
||||
any
|
||||
attrValues
|
||||
filterAttrs
|
||||
hm
|
||||
isBool
|
||||
literalExpression
|
||||
mapAttrs
|
||||
mkEnableOption
|
||||
mkIf
|
||||
mkMerge
|
||||
mkEnableOption
|
||||
mkOption
|
||||
types
|
||||
;
|
||||
@@ -28,7 +30,7 @@ let
|
||||
mkPathSafeName = lib.replaceStrings [ "@" ":" "\\" "[" "]" ] [ "-" "-" "-" "" "" ];
|
||||
|
||||
removeIfEmpty =
|
||||
attrs: names: lib.filterAttrs (name: value: !(builtins.elem name names) || value != "") attrs;
|
||||
attrs: names: filterAttrs (name: value: !(builtins.elem name names) || value != "") attrs;
|
||||
|
||||
toSystemdIni = lib.generators.toINI {
|
||||
listsAsDuplicateKeys = true;
|
||||
@@ -46,36 +48,70 @@ let
|
||||
filename = "${name}.${style}";
|
||||
pathSafeName = mkPathSafeName filename;
|
||||
|
||||
# The actual unit content (or unit override content if a base is
|
||||
# specified).
|
||||
finalConfig =
|
||||
let
|
||||
# Filters out fields that are set to `null` or empty list. Also
|
||||
# make sure the `Unit.X-Base` field is skipped.
|
||||
shouldKeepField =
|
||||
section: key: value:
|
||||
value != null && value != [ ] && !(section == "Unit" && key == "X-Base");
|
||||
|
||||
# Filters out empty sections.
|
||||
shouldKeepSection = _: value: value != { };
|
||||
|
||||
filteredFields = mapAttrs (section: filterAttrs (shouldKeepField section)) serviceCfg;
|
||||
filteredSections = filterAttrs shouldKeepSection filteredFields;
|
||||
in
|
||||
filteredSections;
|
||||
|
||||
finalConfigIni = toSystemdIni finalConfig;
|
||||
|
||||
# Needed because systemd derives unit names from the ultimate
|
||||
# link target.
|
||||
source =
|
||||
generatedSource =
|
||||
pkgs.writeTextFile {
|
||||
name = pathSafeName;
|
||||
text = toSystemdIni (
|
||||
lib.filterAttrs (_: v: v != { }) (
|
||||
lib.mapAttrs (_: lib.filterAttrs (_: v: v != null && v != [ ])) serviceCfg
|
||||
)
|
||||
);
|
||||
text = finalConfigIni;
|
||||
destination = "/${filename}";
|
||||
}
|
||||
+ "/${filename}";
|
||||
|
||||
hasBaseSource = serviceCfg.Unit.X-Base != null;
|
||||
|
||||
source = if hasBaseSource then serviceCfg.Unit.X-Base else generatedSource;
|
||||
|
||||
install = variant: target: {
|
||||
name = "systemd/user/${target}.${variant}/${filename}";
|
||||
value = { inherit source; };
|
||||
};
|
||||
in
|
||||
lib.singleton {
|
||||
[
|
||||
{
|
||||
name = "systemd/user/${filename}";
|
||||
value = { inherit source; };
|
||||
}
|
||||
# Produce the overrides file if the main unit file is produced by X-Base.
|
||||
# Note, we always create an overrides file even if no overrides are
|
||||
# present. This simplifies the implementation somewhat as we don't have to
|
||||
# check whether the unit settings attribute set is empty. The check would
|
||||
# force the attribute set which may cause infinite recursion if it
|
||||
# contains references to `config`.
|
||||
{
|
||||
name = "systemd/user/${filename}.d/overrides.conf";
|
||||
value = lib.mkIf hasBaseSource {
|
||||
source = generatedSource;
|
||||
};
|
||||
}
|
||||
]
|
||||
++ map (install "wants") (serviceCfg.Install.WantedBy or [ ])
|
||||
++ map (install "requires") (serviceCfg.Install.RequiredBy or [ ]);
|
||||
|
||||
buildServices =
|
||||
style: serviceCfgs: lib.concatLists (lib.mapAttrsToList (buildService style) serviceCfgs);
|
||||
|
||||
servicesStartTimeoutMs = builtins.toString cfg.servicesStartTimeoutMs;
|
||||
servicesStartTimeoutMs = toString cfg.servicesStartTimeoutMs;
|
||||
|
||||
unitBaseType =
|
||||
unitKind: mod:
|
||||
@@ -98,6 +134,53 @@ let
|
||||
imports = [
|
||||
{
|
||||
options.Unit = {
|
||||
X-Base = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
example = literalExpression "\${pkgs.example}/share/systemd/user/example.service";
|
||||
description = ''
|
||||
::: {.warning}
|
||||
This is an experimental option, it may be removed or its
|
||||
behavior changed at any time!
|
||||
:::
|
||||
|
||||
Path to unit file that should be used as a base definition. This
|
||||
unit file will be copied to the Nix store (if not already there)
|
||||
and linked into the user's environment. Any other fields
|
||||
specified for this unit will be placed in an overrides file.
|
||||
|
||||
The `Unit.X-Base` field is filtered out from when the output
|
||||
files are generated.
|
||||
|
||||
The filename of the base unit file _must_ be the same as the
|
||||
unit name. That is, if you specify a base file for
|
||||
`systemd.user.services."foo"`, then the base file must be
|
||||
`foo.service`.
|
||||
|
||||
As a specific example, consider the following configuration:
|
||||
|
||||
``` nix
|
||||
systemd.user.services.example = {
|
||||
Unit.X-Base = "''${pkgs.example}/share/systemd/user/example.service";
|
||||
Service.ExecStartPre = "''${pkgs.coreutils}/bin/sleep 1m"
|
||||
};
|
||||
```
|
||||
|
||||
After activation the user will have two new managed files in
|
||||
their home directory:
|
||||
|
||||
`.config/systemd/user/example.service`
|
||||
: This will point to the `X-Base` file.
|
||||
|
||||
`.config/systemd/user/example.service.d/overrides.conf`
|
||||
: This will contain the specified overrides, in this case
|
||||
``` ini
|
||||
[Service]
|
||||
ExecStartPre=/nix/store/...-coreutils/bin/sleep 1m
|
||||
```
|
||||
'';
|
||||
};
|
||||
|
||||
Description = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
|
||||
@@ -18,13 +18,14 @@ stdenv.mkDerivation {
|
||||
src = ./.;
|
||||
patchPhase = ''
|
||||
substituteInPlace non-nixos-gpu* \
|
||||
--replace '@@resources@@' "$out/resources" \
|
||||
--replace '@@statedir@@' '${nixStateDirectory}' \
|
||||
--replace '@@env@@' "${nonNixosGpuEnv}"
|
||||
--replace-quiet '@@resources@@' "$out/resources" \
|
||||
--replace-quiet '@@statedir@@' '${nixStateDirectory}' \
|
||||
--replace-quiet '@@systemddir@@' "$out/lib/systemd/system" \
|
||||
--replace-quiet '@@env@@' "${nonNixosGpuEnv}"
|
||||
'';
|
||||
installPhase = ''
|
||||
mkdir -p $out/{bin,resources}
|
||||
mkdir -p $out/{bin,resources,lib/systemd/system}
|
||||
cp non-nixos-gpu-setup $out/bin
|
||||
cp non-nixos-gpu.service $out/resources
|
||||
cp non-nixos-gpu.service $out/lib/systemd/system
|
||||
'';
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user