From ceb0d409eacee969071c96aba8df5ed505d7dcdf Mon Sep 17 00:00:00 2001 From: Rutherther Date: Mon, 15 Apr 2024 19:32:39 +0200 Subject: [PATCH] feat: many updates --- lib/default.nix | 54 +++++++++++++++++++++++- modules/default.nix | 1 + modules/desktop-items.nix | 40 ++++++++++++++++++ modules/home.nix | 14 ++++++- modules/systemd.nix | 86 +++++++++++++++++++++++---------------- 5 files changed, 157 insertions(+), 38 deletions(-) create mode 100644 modules/desktop-items.nix diff --git a/lib/default.nix b/lib/default.nix index 8abc5ad..5388d6c 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -1,6 +1,58 @@ { pkgs, lib, ... }: rec { + mkWrapper = { basePackage, prependFlags ? [], appendFlags ? [], pathAdd ? [], environment ? {}, extraPackages ? [] }: pkgs.symlinkJoin ({ + name = "wrapper-${basePackage.name}"; + paths = [ basePackage ] ++ extraPackages; + nativeBuildInputs = [ pkgs.makeWrapper ]; + postBuild = let + + envToWrapperArg = name: config: let + optionStr = attr: lib.showOption ["env" name attr]; + unsetArg = + if !config.force + then + (lib.warn '' + ${optionStr "value"} is null (indicating unsetting the variable), but ${optionStr "force"} is false. This option will have no effect + '' []) + else ["--unset" config.name]; + setArg = let + arg = + if config.force + then "--set" + else "--set-default"; + in [arg config.name config.value]; + in + if config.value == null + then unsetArg + else setArg; + + envArgs = lib.mapAttrsToList envToWrapperArg environment; + # Yes, the arguments are escaped later, yes, this is intended to "double escape", + # so that they are escaped for wrapProgram and for the final binary too. + prependFlagArgs = map (args: ["--add-flags" (lib.escapeShellArg args)]) prependFlags; + appendFlagArgs = map (args: ["--append-flags" (lib.escapeShellArg args)]) appendFlags; + pathArgs = map (p: ["--prefix" "PATH" ":" "${p}/bin"]) pathAdd; + allArgs = lib.flatten (envArgs ++ prependFlagArgs ++ appendFlagArgs ++ pathArgs); + in '' + for file in $out/bin/*; do + wrapProgram \ + "$file" \ + ${lib.escapeShellArgs allArgs} + done + + ${ + lib.concatMapStringsSep "\n" + (p: + if lib.hasAttr "man" p + then "${pkgs.xorg.lndir}/bin/lndir -silent ${p.man} $out" + else "#") + ([basePackage] ++ extraPackages) + } + ''; + passthru = (basePackage.passhtru or {}) // {unwrapped = basePackage;}; + }); + escapeTmpFileContents = contents: builtins.replaceStrings ["\n"] ["\\n"] contents; mkTmpFile = { type ? "f", target, mode ? "0700", user, group, contents }: "${type} \"${target}\" ${mode} ${user} ${group} - ${escapeTmpFileContents contents}"; mkRmTmpFile = { type ? "f", target }: "${if type == "d" then "R" else "r"} ${target}"; @@ -36,7 +88,7 @@ rec { }; }); - homeFileType = lib.types.attrsOf (lib.types.submodule ({ config, name, ... }: { + homeFileType = (lib.types.submodule ({ config, name, ... }: { options = { enable = lib.mkOption { type = lib.types.bool; diff --git a/modules/default.nix b/modules/default.nix index 3cda1b5..cc2ffd3 100644 --- a/modules/default.nix +++ b/modules/default.nix @@ -5,6 +5,7 @@ ./tmpfiles.nix ./home.nix ./systemd.nix + ./desktop-items.nix ]; _module.args = { diff --git a/modules/desktop-items.nix b/modules/desktop-items.nix new file mode 100644 index 0000000..946a841 --- /dev/null +++ b/modules/desktop-items.nix @@ -0,0 +1,40 @@ +{ pkgs, lib, config, ... }: + +let + mkStrOption = lib.mkOption { type = lib.types.str; }; + mkStrNullOption = lib.mkOption { type = lib.types.nullOr lib.types.str; default = null; }; + + desktopItems = lib.mapAttrs (name: conf: (pkgs.makeDesktopItem { + inherit name; + inherit (conf) desktopName exec icon path; + }) + "/share/applications/${name}.desktop") config.desktopItems.items; +in { + options = { + desktopItems = { + enable = lib.mkEnableOption "desktop items"; + + items = lib.mkOption { + type = lib.types.attrsOf (lib.types.submodule ({ config, ... }: { + options = { + desktopName = mkStrOption; + exec = mkStrOption; + icon = mkStrNullOption; + path = mkStrNullOption; + }; + })); + default = []; + }; + }; + }; + + config = lib.mkIf config.desktopItems.enable { + + home.file = lib.mapAttrs' + (name: conf: + lib.nameValuePair + ".local/share/applications/${name}.desktop" + { source = conf; } + ) + desktopItems; + }; +} diff --git a/modules/home.nix b/modules/home.nix index 548f643..fbb7c36 100644 --- a/modules/home.nix +++ b/modules/home.nix @@ -30,10 +30,15 @@ in { }; file = lib.mkOption { - type = tmpLib.homeFileType; + type = lib.types.attrsOf tmpLib.homeFileType; default = {}; }; + packages = lib.mkOption { + type = lib.types.listOf lib.types.package; + default = []; + }; + homeFilesPackage = lib.mkOption { type = lib.types.package; }; @@ -44,6 +49,13 @@ in { tmpfiles.defaultUser = config.home.user; tmpfiles.defaultGroup = config.home.group; + home.file = builtins.listToAttrs (builtins.map (pkg: + lib.nameValuePair (".local/bin/${pkg.meta.mainProgram}") { + source = (lib.getExe pkg); + executable = true; + }) + config.home.packages); + tmpfiles.files = (lib.attrValues (lib.mapAttrs (name: conf: { type = "L+"; mode = "-"; diff --git a/modules/systemd.nix b/modules/systemd.nix index b43216b..4efd894 100644 --- a/modules/systemd.nix +++ b/modules/systemd.nix @@ -14,42 +14,47 @@ let timerToUnit pathToUnit; - cfg = config.systemd; + cfg = config.systemd.user; + + wantedPaths = lib.unique (lib.flatten (lib.attrValues (lib.mapAttrs (name: conf: (builtins.map (wanted: "${wanted}.wants/${name}") (conf.wantedBy or []))) cfg.units))); + requiredPaths = lib.unique (lib.flatten (lib.attrValues (lib.mapAttrs (name: conf: (builtins.map (required: "${required}.requires/${name}") (conf.requiredBy or []))) cfg.units))); in { options = { systemd = { - units = lib.mkOption { - default = {}; - type = systemdUtils.types.units; - }; - services = lib.mkOption { - default = {}; - type = systemdUtils.types.services; - }; - slices = lib.mkOption { - default = {}; - type = systemdUtils.types.slices; - }; - paths = lib.mkOption { - default = {}; - type = systemdUtils.types.paths; - }; - sockets = lib.mkOption { - default = {}; - type = systemdUtils.types.sockets; - }; - targets = lib.mkOption { - default = {}; - type = systemdUtils.types.targets; - }; - timers = lib.mkOption { - default = {}; - type = systemdUtils.types.timers; - }; + user = { + units = lib.mkOption { + default = {}; + type = systemdUtils.types.units; + }; + services = lib.mkOption { + default = {}; + type = systemdUtils.types.services; + }; + slices = lib.mkOption { + default = {}; + type = systemdUtils.types.slices; + }; + paths = lib.mkOption { + default = {}; + type = systemdUtils.types.paths; + }; + sockets = lib.mkOption { + default = {}; + type = systemdUtils.types.sockets; + }; + targets = lib.mkOption { + default = {}; + type = systemdUtils.types.targets; + }; + timers = lib.mkOption { + default = {}; + type = systemdUtils.types.timers; + }; - unitsPackage = lib.mkOption { - type = lib.types.package; + unitsPackage = lib.mkOption { + type = lib.types.package; + }; }; package = lib.mkOption { @@ -60,10 +65,11 @@ in { }; }; + a.wantedServices = lib.mkOption { type = lib.types.listOf lib.types.str; }; }; config = { - systemd.units = with lib; + systemd.user.units = with lib; mapAttrs' (n: v: nameValuePair "${n}.path" (pathToUnit n v)) cfg.paths // mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit n v)) cfg.services // mapAttrs' (n: v: nameValuePair "${n}.slice" (sliceToUnit n v)) cfg.slices @@ -71,7 +77,7 @@ in { // mapAttrs' (n: v: nameValuePair "${n}.target" (targetToUnit n v)) cfg.targets // mapAttrs' (n: v: nameValuePair "${n}.timer" (timerToUnit n v)) cfg.timers; - systemd.unitsPackage = generateUnits { + systemd.user.unitsPackage = generateUnits { type = "user"; inherit (cfg) units; upstreamUnits = []; @@ -85,8 +91,16 @@ in { # inherit (cfg) units; # }; # - home.file = lib.mapAttrs' (name: conf: (lib.nameValuePair ".config/systemd/user/${name}" { - source = "${config.systemd.unitsPackage}/${name}"; - })) config.systemd.units; + home.file = lib.mkMerge [ + (lib.mapAttrs' (name: conf: (lib.nameValuePair ".config/systemd/user/${name}" { + source = "${cfg.unitsPackage}/${name}"; + })) cfg.units) + + (lib.listToAttrs (builtins.map (path: + (lib.nameValuePair + ".config/systemd/user/${path}" + { source = "${cfg.unitsPackage}/${path}"; }) + ) (wantedPaths ++ requiredPaths))) + ]; }; } -- 2.48.1