cc69486cead8

add flake.nix, nixos-module.nix; rewrite install.sh with ASCII banner, NixOS nix profile/nix-shell paths, and update reminder

time
2026-06-04 16:15 UTC · 4 months ago
machine
koh2
agent
claude-sonnet-4-6
session
install script and kepr setup
parent
c10740f41f1a
3 files flake.nix+59 −0install.sh+157 −50nixos-module.nix+43 −0
flake.nix+59 −0
@@ -0,0 +1,59 @@1+{2+  description = "nina — the nix helper";3+4+  inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";5+6+  outputs = { self, nixpkgs }:7+    let8+      systems = [ "x86_64-linux" "aarch64-linux" "aarch64-darwin" "x86_64-darwin" ];9+      forSystems = f: nixpkgs.lib.genAttrs systems f;10+      version = builtins.replaceStrings [ "\n" "\r" " " "\t" ] [ "" "" "" "" ]11+        (builtins.readFile ./VERSION);12+    in {13+      packages = forSystems (system:14+        let pkgs = nixpkgs.legacyPackages.${system};15+        in rec {16+          nina = pkgs.stdenv.mkDerivation {17+            pname = "nina";18+            inherit version;19+            src = self;20+            nativeBuildInputs = [ pkgs.zig_0_16 ];21+            dontConfigure = true;22+            buildPhase = ''23+              export ZIG_GLOBAL_CACHE_DIR="$TMPDIR/zig-cache"24+              zig build -Doptimize=ReleaseSafe25+            '';26+            installPhase = ''27+              install -Dm755 zig-out/bin/nina $out/bin/nina28+            '';29+            meta = with nixpkgs.lib; {30+              description = "The nix helper — manage your NixOS system from the command line";31+              mainProgram = "nina";32+              platforms = platforms.unix;33+              license = licenses.mit;34+            };35+          };36+          default = nina;37+        }38+      );39+40+      nixosModules.default = { config, pkgs, lib, ... }:41+        let cfg = config.programs.nina;42+        in {43+          options.programs.nina = {44+            enable = lib.mkEnableOption "nina, the NixOS helper";45+            package = lib.mkOption {46+              type = lib.types.package;47+              default = self.packages.${pkgs.system}.default;48+              defaultText = lib.literalExpression "nina.packages.\${pkgs.system}.default";49+              description = "The nina package to install.";50+            };51+          };52+          config = lib.mkIf cfg.enable {53+            environment.systemPackages = [ cfg.package ];54+          };55+        };56+57+      nixosModules.nina = self.nixosModules.default;58+    };59+}

view file

install.sh+157 −50
@@ -2,18 +2,14 @@22 # nina install script33 # Run:  curl -fsSL kepr.uk/nina/install.sh | sh44 # Or:   NINA_INSTALL_DIR=/usr/local/bin sh install.sh5-#6-# Downloads the pre-built binary from Kepr for your platform.7-# Falls back to building from source (requires Zig 0.16+) if unavailable.85 96 set -e107 8+FLAKE_URL="https://kepr.uk/nina/archive/HEAD.tar.gz"119 RELEASES_URL="https://kepr.uk/api/nina/releases/latest"12-SOURCE_URL="https://kepr.uk/nina/archive/HEAD.tar.gz"1310 INSTALL_DIR="${NINA_INSTALL_DIR:-$HOME/.local/bin}"1411 MIN_ZIG_MINOR=161512 16-# Detect platform1713 os="$(uname -s)"1814 arch="$(uname -m)"1915 case "${os}-${arch}" in@@ -22,28 +18,55 @@2218   Darwin-arm64)               platform="macos-aarch64" ;;2319   Darwin-x86_64)              platform="macos-x86_64"  ;;2420   *)25-    printf 'nina install: unsupported platform %s-%s\n' "$os" "$arch" >&226-    printf '  build from source with Zig 0.%s+:\n' "$MIN_ZIG_MINOR" >&227-    printf '    zig build -Doptimize=ReleaseSafe\n' >&221+    printf 'nina: unsupported platform %s-%s\n' "$os" "$arch" >&22822     exit 1 ;;2923 esac3024 31-have() { command -v "$1" >/dev/null 2>&1; }32-say()  { printf 'nina install: %s\n' "$1"; }33-die()  { say "error: $1" >&2; exit 1; }25+have()  { command -v "$1" >/dev/null 2>&1; }26+say()   { printf 'nina: %s\n' "$1"; }27+die()   { say "error: $1" >&2; exit 1; }28+blank() { printf '\n'; }29+is_nixos() { [ -e /etc/NIXOS ]; }3430 3531 fetch_text() {3632   if have curl;   then curl -fsSL "$1"3733   elif have wget; then wget -qO- "$1"38-  else die "curl or wget is required"; fi34+  else die "curl or wget required"; fi3935 }4036 4137 fetch_file() {4238   if have curl;   then curl -fsSL "$1" -o "$2"4339   elif have wget; then wget -qO  "$2" "$1"44-  else die "curl or wget is required"; fi40+  else die "curl or wget required"; fi4541 }4642 43+# ── banner ────────────────────────────────────────────────────────────────────44+45+banner() {46+  cat <<'BANNER'47+48+   _ __   _  _ __    __ _49+  | '_ \ (_)| '_ \  / _` |50+  | | | || || | | || (_| |51+  |_| |_||_||_| |_| \__,_|52+53+  the nix helper  ·  kepr.uk/nina54+55+BANNER56+}57+58+# ── fetch source archive ──────────────────────────────────────────────────────59+60+fetch_source() {61+  srcdir="$(mktemp -d /tmp/nina-src.XXXXXX)"62+  say "fetching source from Kepr..."63+  fetch_file "$FLAKE_URL" "${srcdir}/nina.tar.gz" \64+    || die "could not download source archive — check your connection"65+  tar -xzf "${srcdir}/nina.tar.gz" -C "$srcdir" --strip-components=1 \66+    || die "could not extract source archive"67+  printf '%s' "$srcdir"68+}69+4770 # ── binary install from Kepr ─────────────────────────────────────────────────4871 4972 install_binary() {@@ -75,7 +98,6 @@7598     cksum_raw="$(printf '%s' "$meta" | jq -r ".platforms.\"${platform}\".blake3 // .platforms.\"${platform}\".checksum // empty")"7699     cksum="${cksum_raw#blake3:}"77100   else78-    # Minimal grep/sed fallback for compact JSON79101     version="$(printf '%s' "$meta" | grep -o '"version":"[^"]*"' | sed 's/"version":"//;s/"//')"80102     plat_block="$(printf '%s' "$meta" | grep -o "\"${platform}\":{[^}]*}" | head -1)"81103     dl_url="$(printf '%s' "$plat_block" | grep -o '"url":"[^"]*"' | sed 's/"url":"//;s/"//')"@@ -92,7 +114,7 @@92114   if [ -n "$cksum" ] && have b3sum; then93115     actual="$(b3sum --no-names "$tmpfile" 2>/dev/null | awk '{print $1}')"94116     if [ "$actual" != "$cksum" ]; then95-      say "blake3 checksum mismatch — aborting"117+      say "checksum mismatch — aborting"96118       rm -f "$tmpfile"97119       return 198120     fi@@ -106,68 +128,128 @@106128   return 0107129 }108130 131+# ── NixOS: nix profile install (primary) ─────────────────────────────────────132+133+nixos_profile_install() {134+  have nix || return 1135+  say "installing via nix profile install..."136+  blank137+  if nix profile install "$FLAKE_URL"; then138+    return 0139+  fi140+  blank141+  say "nix profile install failed. Common causes:"142+  say "  flakes not enabled — add to /etc/nix/nix.conf or ~/.config/nix/nix.conf:"143+  say "    experimental-features = nix-command flakes"144+  say "  once nina is installed: nina setup enables this automatically"145+  blank146+  return 1147+}148+149+# ── NixOS: nix-shell source build (fallback) ──────────────────────────────────150+151+nixos_shell_build() {152+  have nix-shell || return 1153+  say "opening nix-shell with zig_0_16 and building nina from source..."154+  blank155+  srcdir="$(fetch_source)"156+  nix-shell -p zig_0_16 \157+    --run "cd '${srcdir}' && zig build -Doptimize=ReleaseSafe" \158+    || die "build failed — see output above"159+  mkdir -p "$INSTALL_DIR"160+  cp "${srcdir}/zig-out/bin/nina" "${INSTALL_DIR}/nina"161+  chmod +x "${INSTALL_DIR}/nina"162+  blank163+  say "installed from source → ${INSTALL_DIR}/nina"164+  say "note: this binary was built outside of nix — adopt ~/nina.nix into your"165+  say "configuration.nix to make it nix-managed."166+}167+168+# ── generate ~/nina.nix ───────────────────────────────────────────────────────169+170+generate_nixos_module() {171+  # Write ~/nina.nix without invoking shell substitution on the nix code inside.172+  cat > "$HOME/nina.nix" <<'NIXEOF'173+# ~/nina.nix — generated by the nina installer174+#175+# Declares nina as a NixOS system package.176+#177+# Add to /etc/nixos/configuration.nix:178+#   imports = [ /home/YOUR_USER/nina.nix ];179+# Then: sudo nixos-rebuild switch180+#181+# For flake-based configurations, add nina as a flake input instead:182+#   inputs.nina.url = "https://kepr.uk/nina/archive/HEAD.tar.gz";183+#   # in your modules: nina.nixosModules.default184+#   # then set: programs.nina.enable = true;185+#186+# To update nina: nina update187+{ ... }:188+{189+  imports = [190+    "${builtins.fetchTarball "https://kepr.uk/nina/archive/HEAD.tar.gz"}/nixos-module.nix"191+  ];192+  programs.nina.enable = true;193+}194+NIXEOF195+  blank196+  say "generated ~/nina.nix for system-wide installation:"197+  say "  1. add to /etc/nixos/configuration.nix:"198+  say "       imports = [ /home/$(id -un)/nina.nix ];"199+  say "  2. sudo nixos-rebuild switch"200+}201+109202 # ── Zig version check ─────────────────────────────────────────────────────────110203 111204 check_zig() {112205   if ! have zig; then113-    say ""114-    say "Zig not found. Building nina from source requires Zig 0.${MIN_ZIG_MINOR} or later."115-    say ""116-    say "  NixOS:"117-    say "    nix profile install 'nixpkgs#zig_0_16'   # if your channel has it"118-    say "    nix-shell -p zig_0_16 --run 'sh install.sh'"119-    say "    # or add 'pkgs.zig_0_16' to environment.systemPackages and rebuild"120-    say ""121-    say "  Direct download: https://ziglang.org/download/"122-    say ""123-    die "Zig 0.${MIN_ZIG_MINOR}+ required for source build"206+    blank207+    say "Zig not found. Building nina requires Zig 0.${MIN_ZIG_MINOR}+."208+    blank209+    say "  Download: https://ziglang.org/download/"210+    if is_nixos; then211+      say "  NixOS:    nix-shell -p zig_0_16 --run 'sh install.sh'"212+    fi213+    blank214+    die "Zig 0.${MIN_ZIG_MINOR}+ required"124215   fi125216 126217   zig_ver="$(zig version 2>/dev/null)"127218   major="$(printf '%s' "$zig_ver" | cut -d. -f1)"128219   minor="$(printf '%s' "$zig_ver" | cut -d. -f2)"129-130220   ok=0131221   [ "$major" -ge 1 ] 2>/dev/null && ok=1132222   [ "$major" -eq 0 ] 2>/dev/null && [ "$minor" -ge "$MIN_ZIG_MINOR" ] 2>/dev/null && ok=1133223 134224   if [ "$ok" -ne 1 ]; then135-    say ""136-    say "Found zig ${zig_ver}, but nina requires Zig 0.${MIN_ZIG_MINOR} or later."137-    say ""138-    say "  NixOS: the system 'zig' package is ${zig_ver}. To get 0.16:"139-    say "    nix profile install 'nixpkgs#zig_0_16'"140-    say "    nix-shell -p zig_0_16 --run 'sh install.sh'"141-    say "    # or check nixpkgs-unstable if your stable channel lacks zig_0_16"142-    say ""143-    say "  Direct download: https://ziglang.org/download/"144-    say ""225+    blank226+    say "found zig ${zig_ver}, but nina requires Zig 0.${MIN_ZIG_MINOR}+."227+    if is_nixos; then228+      say "  run: nix-shell -p zig_0_16 --run 'sh install.sh'"229+    else230+      say "  update: https://ziglang.org/download/"231+    fi232+    blank145233     die "Zig 0.${MIN_ZIG_MINOR}+ required; found ${zig_ver}"146234   fi147235 148236   say "zig ${zig_ver} found"149237 }150238 151-# ── source build fallback ─────────────────────────────────────────────────────239+# ── generic source build (non-NixOS) ─────────────────────────────────────────152240 153241 build_from_source() {154-  say "falling back to build from source..."242+  say "building from source..."155243   check_zig156244 157245   if [ -f "build.zig" ] && [ -f "src/main.zig" ]; then158246     srcdir="."159247   else160-    say "fetching source archive from Kepr..."161-    srcdir="$(mktemp -d /tmp/nina-src.XXXXXX)"162-    fetch_file "$SOURCE_URL" "${srcdir}/nina.tar.gz" \163-      || die "could not download source archive"164-    tar -xzf "${srcdir}/nina.tar.gz" -C "$srcdir" --strip-components=1 \165-      || die "could not extract source archive"248+    srcdir="$(fetch_source)"166249   fi167250 168-  say "building (this may take a moment)..."169251   (cd "$srcdir" && zig build -Doptimize=ReleaseSafe) \170-    || die "build failed — see output above for details"252+    || die "build failed — see output above"171253 172254   mkdir -p "$INSTALL_DIR"173255   cp "${srcdir}/zig-out/bin/nina" "${INSTALL_DIR}/nina"@@ -181,22 +263,47 @@181263   case ":${PATH}:" in182264     *":${INSTALL_DIR}:"*) ;;183265     *)184-      say ""266+      blank185267       say "${INSTALL_DIR} is not in your PATH. Add it:"186268       say "  export PATH=\"\${PATH}:${INSTALL_DIR}\""187269       say "  echo 'export PATH=\"\${PATH}:${INSTALL_DIR}\"' >> ~/.bashrc"188-      say "  # NixOS: add '${INSTALL_DIR}' to environment.sessionVariables in configuration.nix"270+      if is_nixos; then271+        say "  NixOS: add to environment.sessionVariables in configuration.nix"272+      fi189273       ;;190274   esac191275 }192276 193277 # ── main ──────────────────────────────────────────────────────────────────────194278 279+banner280+281+if is_nixos; then282+  say "NixOS detected"283+  if nixos_profile_install; then284+    generate_nixos_module285+    blank286+    say "to update nina: nina update"287+    exit 0288+  fi289+  nixos_shell_build290+  generate_nixos_module291+  check_path292+  blank293+  say "to update nina: nina update"294+  exit 0295+fi296+297+# macOS / generic Linux: download binary, fall back to source build195298 if install_binary; then196299   check_path300+  blank301+  say "to update nina: nina update"197302   exit 0198303 fi199304 200-say "pre-built binary unavailable for ${platform} — trying source build"305+say "no pre-built binary for ${platform} — falling back to source build"201306 build_from_source202307 check_path308+blank309+say "to update nina: nina update"

view file

nixos-module.nix+43 −0
@@ -0,0 +1,43 @@1+# Standalone NixOS module for nina — no flake inputs needed.2+# Generated by the installer into ~/nina.nix. Also importable directly.3+#4+# Usage (in configuration.nix):5+#   imports = [6+#     "${builtins.fetchTarball "https://kepr.uk/nina/archive/HEAD.tar.gz"}/nixos-module.nix"7+#   ];8+#   programs.nina.enable = true;9+#10+# For flake-based configs use the flake input instead — see flake.nix.11+{ config, pkgs, lib, ... }:12+let13+  nina-pkg = pkgs.stdenv.mkDerivation {14+    pname = "nina";15+    version = builtins.replaceStrings [ "\n" "\r" " " "\t" ] [ "" "" "" "" ]16+      (builtins.readFile ./VERSION);17+    src = ./.;18+    nativeBuildInputs = [ pkgs.zig_0_16 ];19+    dontConfigure = true;20+    buildPhase = ''21+      export ZIG_GLOBAL_CACHE_DIR="$TMPDIR/zig-cache"22+      zig build -Doptimize=ReleaseSafe23+    '';24+    installPhase = "install -Dm755 zig-out/bin/nina $out/bin/nina";25+    meta = {26+      description = "The nix helper — manage your NixOS system from the command line";27+      mainProgram = "nina";28+    };29+  };30+  cfg = config.programs.nina;31+in {32+  options.programs.nina = {33+    enable = lib.mkEnableOption "nina, the NixOS helper";34+    package = lib.mkOption {35+      type = lib.types.package;36+      default = nina-pkg;37+      description = "The nina package to install.";38+    };39+  };40+  config = lib.mkIf cfg.enable {41+    environment.systemPackages = [ cfg.package ];42+  };43+}

view file