From e8e437fa62ee8652bf2f6d46d598b462c624332b 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 | 45 +++++++++++++++++++++++++++++++++++ module.nix | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++ smooooth.sh | 44 +++++++++++++++++++++++++++++++++++ 4 files changed, 199 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..f76ea1c --- /dev/null +++ b/flake.nix @@ -0,0 +1,45 @@ +{ + 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 = pkgs.writeShellApplication { + name = "smooooth"; + runtimeInputs = builtins.attrValues { + inherit (pkgs) + polkit + gnugrep + coreutils + libnotify + inotify-tools + nix + ; + }; + text = builtins.readFile ./smooooth.sh; + }; + }); + nixosModules.smooooth = + { + config, + options, + pkgs, + lib, + ... + }: + { + imports = [ ./module.nix ]; + services.smooooth.package = self.packages.${pkgs.system}.default; + }; + }; +} diff --git a/module.nix b/module.nix new file mode 100644 index 0000000..0ba373e --- /dev/null +++ b/module.nix @@ -0,0 +1,67 @@ +{ + 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 { + systemd.user = { + services.smooooth = { + path = [ + cfg.package + cfg.nixPackage + ]; + serviceConfig = { + 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..ffcc384 --- /dev/null +++ b/smooooth.sh @@ -0,0 +1,44 @@ +SACRED_SPACE="$1" +BLOCKERS="$2" +PERIOD="$3" + +scrapePids() { + for pid in /proc/*; do + if [[ "$pid" =~ ^[0-9]*$ ]]; then + if grep -E "$BLOCKERS" -q /proc/"$pid"/comm; then + if [[ "$(readlink /proc/"$pid"/cwd)" == "$SACRED_SPACE"* ]]; then + echo "$pid with name $(cat /proc/"$pid"/comm) is blocking" + return 0 + fi + fi + fi + done + return 1 +} + +while true; do + + inotifywait -r "$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 - attempting to activate system" + notify-send "smooooth" "activating your new config" + switch="$(readlink "$build")/bin/switch-to-configuration" + pkexec "$switch" switch + + echo "cleaning up" + rm -r "$temp" + +done