From ce46d97d414d6f12aa2f15d95df6b6a6228c2d3a Mon Sep 17 00:00:00 2001 From: atagen Date: Wed, 21 May 2025 17:03:16 +1000 Subject: [PATCH] feat: init . . . . --- flake.lock | 43 ++++++++++++++++++++++++++++++++ flake.nix | 48 ++++++++++++++++++++++++++++++++++++ module.nix | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++ smooooth.sh | 46 +++++++++++++++++++++++++++++++++++ 4 files changed, 207 insertions(+) create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 module.nix create mode 100755 smooooth.sh diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..aa97b79 --- /dev/null +++ b/flake.lock @@ -0,0 +1,43 @@ +{ + "nodes": { + "nix-systems": { + "locked": { + "lastModified": 1689347949, + "narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=", + "owner": "nix-systems", + "repo": "default-linux", + "rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default-linux", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1747728033, + "narHash": "sha256-NnXFQu7g4LnvPIPfJmBuZF7LFy/fey2g2+LCzjQhTUk=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "2f9173bde1d3fbf1ad26ff6d52f952f9e9da52ea", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nix-systems": "nix-systems", + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..97ec1e7 --- /dev/null +++ b/flake.nix @@ -0,0 +1,48 @@ +{ + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; + nix-systems.url = "github:nix-systems/default-linux"; + }; + + outputs = + inputs: + with inputs; + let + forAllSystems = + function: + nixpkgs.lib.genAttrs (import nix-systems) (system: function nixpkgs.legacyPackages.${system}); + in + { + packages = forAllSystems (pkgs: { + default = + nix: + pkgs.writeShellApplication { + name = "smooooth"; + runtimeInputs = builtins.attrValues { + inherit (pkgs) + gnugrep + coreutils + libnotify + inotify-tools + git + ; + inherit nix; + }; + text = builtins.readFile ./smooooth.sh; + }; + }); + nixosModules.smooooth = + { + config, + pkgs, + lib, + ... + }: + { + imports = [ ./module.nix ]; + services.smooooth.package = ( + self.packages.${pkgs.system}.default config.services.smooooth.nixPackage + ); + }; + }; +} diff --git a/module.nix b/module.nix new file mode 100644 index 0000000..112817b --- /dev/null +++ b/module.nix @@ -0,0 +1,70 @@ +{ + pkgs, + lib, + config, + ... +}: +let + inherit (lib) types; + inherit (lib.options) mkEnableOption mkOption; + cfg = config.services.smooooth; +in +{ + options.services.smooooth = { + enable = mkEnableOption "the smooooth nixos hot reloader"; + blockers = mkOption { + description = "Names of processes that may block reloading when holding a flake (sub)path open."; + default = [ + "nano" + "nvim" + "vim" + "vi" + "hx" + ]; + example = '' + [ "hx" ] + ''; + type = types.listOf types.str; + }; + path = mkOption { + description = "Path to the root of your flake."; + type = types.str; + }; + pollingRate = mkOption { + description = "How frequently to poll for blockers when waiting on a reload."; + default = 10; + type = types.int; + }; + nixPackage = mkOption { + description = "Your preferred package providing a `nix` executable."; + default = pkgs.nix; + type = types.package; + }; + package = mkOption { + description = "smooooth package"; + type = types.package; + }; + }; + + config = lib.mkIf cfg.enable { + # idk probably need more soteria workarounds + security.polkit.enable = lib.mkIf (config.security.soteria.enable == false) true; + systemd.user = { + services.smooooth = { + enable = true; + path = [ + cfg.package + ]; + serviceConfig = { + Restart = "always"; + Type = "exec"; + ExecStart = + let + blockers = builtins.concatStringsSep "|" cfg.blockers; + in + "${lib.getExe cfg.package} ${cfg.path} ${blockers} ${toString cfg.pollingRate}"; + }; + }; + }; + }; +} diff --git a/smooooth.sh b/smooooth.sh new file mode 100755 index 0000000..f16af46 --- /dev/null +++ b/smooooth.sh @@ -0,0 +1,46 @@ +SACRED_SPACE="$1" +BLOCKERS="$2" +PERIOD="$3" + +scrapePids() { + for pid in /proc/*; do + if [[ "$pid" =~ .*[0-9]*$ ]]; then + if grep -E "$BLOCKERS" -q "$pid"/comm; then + if [[ "$(readlink "$pid"/cwd)" == "$SACRED_SPACE"* ]]; then + echo "$pid with name $(cat "$pid"/comm) is blocking" + return 0 + fi + fi + fi + done + return 1 +} + +echo "Starting up for $SACRED_SPACE with blockers $BLOCKERS and polling of $PERIOD" + +while true; do + + inotifywait -r -e modify -e move -e create -e delete "$SACRED_SPACE" + + + notify-send "smooooth" "config change detected. waiting for blockers to resolve.." + while scrapePids; do + echo "found blocker in $SACRED_SPACE, waiting.." + sleep "$PERIOD" + done + + echo "building system" + notify-send "smooooth" "rebuilding your nixos config - please stand by" + temp="$(mktemp -d)" + build="$temp/system" + nix build --out-link "$build" "$SACRED_SPACE"#nixosConfigurations."$HOSTNAME".config.system.build.toplevel + + echo "built and linked at $build - attempting to activate system" + notify-send "smooooth" "activating your new config" + switch="$build/bin/switch-to-configuration" + /run/wrappers/bin/pkexec "$switch" switch + + echo "cleaning up" + rm -r "$temp" + +done