diff --git a/Current-Patch.md b/Current-Patch.md new file mode 100644 index 0000000..c4c50b9 --- /dev/null +++ b/Current-Patch.md @@ -0,0 +1,11 @@ +# Version 1.2.0 + +- Added **NixOS modules** support and made it the default +- Added **legacy support** for Homemanager-only imports +- Added **instructions** for using Homemanager-only imports +- Added **Nyx Info** to share upcoming changes easily +- Added **update tips** for Homemanager users +- Updated the **roadmap** + + + diff --git a/Documentation/How-to-Homemanager.md b/Documentation/How-to-Homemanager.md new file mode 100644 index 0000000..490c7f5 --- /dev/null +++ b/Documentation/How-to-Homemanager.md @@ -0,0 +1,89 @@ +# How-to: Home Manager → Legacy Nyx branch + +**Why:** Nyx is moving to a NixOS module. If you’re on Home Manager today and want stability, pin Nyx to the “legacy” state (by `rev`) or a local checkout. + +--- + +If you forgot how to setup the home.nix see the [Example](./Legacy/example-home.nix) + +--- + +## How to still use the Homemanager Import: + +### Option A — Pin Nyx to a specific revision + + +```nix +{ + description = "EXAMPLE-flake"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + home-manager.url = "github:nix-community/home-manager"; + home-manager.inputs.nixpkgs.follows = "nixpkgs"; + + # Old: + # nyx.url = "github:Peritia-System/Nyx-Tools"; + + # Legacy pin (replace rev with the legacy commit you want): + nyx.url = "github:Peritia-System/Nyx-Tools?rev=7f73899c918a09bae789306fe3fa73dbc2d83997"; + }; + + outputs = inputs @ { nixpkgs, home-manager, nyx, ... }: { + nixosConfigurations = { + default = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + specialArgs = { inherit inputs self; host = "default"; }; + modules = [ + ./Configurations/Hosts/Default/configuration.nix + ]; + }; + }; + }; +} +``` + + +### Option B — Pin to a local checkout + +This will **never** change unless you `git pull` inside the repo. + +1. Clone: + +```bash +git clone https://github.com/Peritia-System/Nyx-Tools /path/to/repo +cd /path/to/repo +git reset --hard 7f73899c918a09bae789306fe3fa73dbc2d83997 # or any other commit you want + +``` + +2. Point your flake at the local path: + +```nix +{ + description = "EXAMPLE-flake"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + home-manager.url = "github:nix-community/home-manager"; + home-manager.inputs.nixpkgs.follows = "nixpkgs"; + + # Local path (no updates unless you update the repo) + nyx.url = "/path/to/repo/"; + }; + + outputs = inputs @ { nixpkgs, home-manager, nyx, ... }: { + nixosConfigurations = { + default = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + specialArgs = { inherit inputs self; host = "default"; }; + modules = [ + ./Configurations/Hosts/Default/configuration.nix + ]; + }; + }; + }; +} +``` + + diff --git a/other/example/example-home.nix b/Documentation/Legacy/example-home.nix similarity index 100% rename from other/example/example-home.nix rename to Documentation/Legacy/example-home.nix diff --git a/Documentation/main.md b/Documentation/main.md index b70940d..528a6fc 100644 --- a/Documentation/main.md +++ b/Documentation/main.md @@ -16,6 +16,7 @@ ``` Nyx-Tools +├── legacy-nyx # will be removed ├── nyx │ ├── bash │ │ ├── nyx-cleanup.sh @@ -28,6 +29,8 @@ Nyx-Tools │ ├── nyx-tool.nix │ └── nyx-tui.nix └── other/ + ├── example # Example configurations + └── ... # Other ``` --- @@ -74,18 +77,19 @@ Nyx-Tools } ``` -### 2. Import Nyx into Home Manager +### 2. Import Nyx into configuration-nix ```nix -# home.nix +# configuration-nix { config, inputs, + # and all the others you have ... }: { imports = [ - inputs.nyx.homeManagerModules.default + inputs.nyx.nixosModules.default ]; } ``` @@ -97,7 +101,12 @@ Nyx-Tools nyx = { enable = true; - inherit username nixDirectory; + # Your username + username = "alex"; + # Set this to where you have your NixOS Configuration. Standard /etc/nixos + nixDirectory = "/home/${username}/my-nixos-config"; + # or inherit it + # inherit username nixDirectory; logDir = "/home/${username}/.nyx/logs"; autoPush = false; @@ -116,7 +125,7 @@ Nyx-Tools }; nyx-tool = { - enable = true; + enable = true; # must be enabled for others }; nyx-tui = { @@ -128,9 +137,9 @@ Nyx-Tools } ``` -> ⚠️ **Note**: `nixDirectory` must be a **full path** to your flake repo (e.g., `/home/${username}/NixOS/Nyx-Tools`). +> ⚠️ **Note**: `nixDirectory` must be a **full path** to your flake repo (e.g., `/home/${username}/NixOS`). -See `other/example/example-home.nix` for a working example. +See [Example-Configuration.nix](./../other/example/example-configuration.nix)/[Example-Flake.nix](./../other/example/example-flake.nix) for a working example. --- @@ -175,8 +184,6 @@ nyx-tui --pretty ``` - - --- ## Module Options diff --git a/README.md b/README.md index 3113bec..d25db20 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,6 @@ Nyx — NixOS System Management Toolkit | -------------------- | -------- | -------------------------------- | | NixOS / Nix | ✅ | Core platform | | `sudo` | ✅ | Needed for system changes | -| Home Manager | ✅ | For integration | | Git | ✅ | Required for `autoPush` features | | `nix-output-monitor` | ✅ | Installed automatically by Nyx | @@ -43,12 +42,12 @@ Nyx — NixOS System Management Toolkit } ``` -### 2. Import in Home Manager +### 2. Import in your Configuration ```nix -# home.nix +# configuration.nix { - imports = [ inputs.nyx.homeManagerModules.default ]; + imports = [ inputs.nyx.nixosModules.default ]; } ``` @@ -69,6 +68,8 @@ nyx = { }; ``` +Checkout the [Documentation](./Documentation/main.md) for a full Guide + --- ## Usage @@ -115,7 +116,6 @@ nyx-tui --pretty # TUI with animation * `nyx-tool` **must be enabled** for other modules. * `nixDirectory` must be a full Git repo path for `autoPush` to work. -* See `other/example/example-home.nix` for a full working setup. --- diff --git a/Roadmap.md b/Roadmap.md index 791057a..2c8e651 100644 --- a/Roadmap.md +++ b/Roadmap.md @@ -1,16 +1,21 @@ # Planned Features / Fixes -Request by [CommercialPug](https://www.reddit.com/r/NixOS/comments/1mncfvd/comment/n85214h/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button) -- Rename nixDirectory -> flakeDirectory or flakeRepoDir +### Ongoing / Planned -Request by [BizNameTaken](https://www.reddit.com/r/NixOS/comments/1mncfvd/comment/n8499d1/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button) -- add a nixosModule output +| Feature / Fix | Description | Requested By | +| ------------------------------------------------------------- | ------------------------------------------------------------ | -------------------------------------------------------------------------------- | +| **Rename** `nixDirectory` → `flakeDirectory` / `flakeRepoDir` | Update variable naming for clarity | [CommercialPug](https://www.reddit.com/r/NixOS/comments/1mncfvd/comment/n85214h) | +| **Expand nix command awareness** | Handle full range of `nix` commands and arguments | [no\_brains101](https://www.reddit.com/r/NixOS/comments/1mncfvd/comment/n86hc7b) | +| **Add** `nixOS-anywhere` / `sops` support | Integrate with these tools for deployment/secret management | [no\_brains101](https://www.reddit.com/r/NixOS/comments/1mncfvd/comment/n86hc7b) | +| **Update selection** | Allow choosing which inputs to update | [no\_brains101](https://www.reddit.com/r/NixOS/comments/1mncfvd/comment/n86hc7b) | +| **Opt-in commits** | Don’t commit changes automatically; make it optional | [no\_brains101](https://www.reddit.com/r/NixOS/comments/1mncfvd/comment/n86hc7b) | +| **Starter template initialization** | Provide a way to initialize a starter template for new users | [jellydn](https://www.reddit.com/r/NixOS/comments/1mncfvd/comment/n87hewi) | -Request by [no_brains101](https://www.reddit.com/r/NixOS/comments/1mncfvd/comment/n86hc7b/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button) -- It needs only to know about the full range of nix commands and arguments -- add nixOS-anywhere or sops support -- update should allow you to choose which inputs to update -- don't commit for User, that should be opt in +--- + +### Completed + +| Feature / Fix | Description | Requested By | +| ---------------------------- | ------------------------------------------ | ------------------------------------------------------------------------------- | +| **Add** `nixosModule` output | Support a NixOS module output in the flake | [BizNameTaken](https://www.reddit.com/r/NixOS/comments/1mncfvd/comment/n8499d1) | -Request by [jellydn](https://www.reddit.com/r/NixOS/comments/1mncfvd/comment/n87hewi/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button) -- Could you please have a way to initialize the starter template for new user \ No newline at end of file diff --git a/flake.nix b/flake.nix index 8731513..225ec82 100644 --- a/flake.nix +++ b/flake.nix @@ -6,6 +6,9 @@ }; outputs = { self, nixpkgs, ... }: { - homeManagerModules.default = import ./nyx; + homeManagerModules.default = import ./legacy-nyx; + homeManagerModules.legacy = import ./legacy-nyx; + + nixosModules.default = import ./nyx; }; } diff --git a/legacy-nyx/bash/nyx-cleanup.sh b/legacy-nyx/bash/nyx-cleanup.sh new file mode 100644 index 0000000..2bf0bdd --- /dev/null +++ b/legacy-nyx/bash/nyx-cleanup.sh @@ -0,0 +1,249 @@ +#!/usr/bin/env bash +# nyx-cleanup.sh — tokenized template +# Tokens replaced by Nix: +# @LOG_DIR@ @KEEP_GENERATIONS@ @AUTO_PUSH@ @GIT_BIN@ @VERSION@ + +nyx-cleanup() { + set -euo pipefail + + ######################################################################## + # CONFIG (injected by Nix) + ######################################################################## + log_dir="@LOG_DIR@" + keep_generations="@KEEP_GENERATIONS@" + auto_push="@AUTO_PUSH@" + git_bin="@GIT_BIN@" + version="@VERSION@" + + # Paths + log_dir_rebuild="${log_dir}/rebuild" + log_dir_cleanup="${log_dir}/cleanup" + timestamp=$(date '+%Y-%m-%d_%H-%M-%S') + summary_log="${log_dir_cleanup}/cleanup-${timestamp}.log" + + ######################################################################## + # COLORS + ######################################################################## + if [[ -t 1 ]]; then + RED=$'\e[31m'; GREEN=$'\e[32m'; YELLOW=$'\e[33m' + BLUE=$'\e[34m'; MAGENTA=$'\e[35m'; CYAN=$'\e[36m' + BOLD=$'\e[1m'; RESET=$'\e[0m' + else + RED=""; GREEN=""; YELLOW=""; BLUE=""; MAGENTA=""; CYAN=""; BOLD=""; RESET="" + fi + + ######################################################################## + # UTIL + ######################################################################## + say() { echo -e "$*"; } + action(){ say "${BOLD}${BLUE}➤ $*${RESET}"; } + ok() { say "${GREEN}✓${RESET} $*"; } + warn() { say "${YELLOW}!${RESET} $*"; } + nope() { say "${RED}✗${RESET} $*"; } + log() { echo -e "$*" | tee -a "$summary_log"; } + print_line() { log "\n${BOLD}==================================================${RESET}\n"; } + + # Lightweight git helpers (mirrors rebuild’s style) + g() { "$git_bin" "$@"; } + git_in_repo() { + local dir="$1" + [[ -d "$dir/.git" ]] || (cd "$dir" && g rev-parse --git-dir >/dev/null 2>&1) + } + git_commit_if_staged() { + if ! g diff --cached --quiet; then + g commit -m "$1" || true + return 0 + fi + return 1 + } + git_push_if_enabled() { + if [[ "$auto_push" == "true" ]]; then g push || true; fi + } + + ######################################################################## + # ARGS + ######################################################################## + DRYRUN=false + OVERRIDE_KEEP="" + while [[ $# -gt 0 ]]; do + case "$1" in + --dry-run) DRYRUN=true; shift;; + --keep) OVERRIDE_KEEP="${2:-}"; shift 2;; + -h|--help) + cat </dev/null 2>&1; then + nyx-tool "Nyx" "nyx-cleanup" "$version" \ + "Prune old NixOS generations, GC store, tidy logs" \ + "by Peritia-System" \ + "https://github.com/Peritia-System/Nyx-Tools" \ + "https://github.com/Peritia-System/Nyx-Tools/issues" \ + "Clean. Lean. Serene." + else + say "Nyx Tools — nyx-cleanup v${version}" + fi + + ######################################################################## + # PREP + ######################################################################## + mkdir -p "$log_dir_cleanup" + start_human=$(date '+%Y-%m-%d %H:%M:%S') + start_s=$(date +%s) + log "Started: ${start_human}" + print_line + + ######################################################################## + # STEP 1: Ensure sudo ticket + ######################################################################## + action "Checking sudo access…" + if sudo -n true 2>/dev/null; then + ok "Sudo already available." + else + say "Getting sudo ticket (you may be prompted)…" + if ! sudo -v; then nope "Cannot get sudo."; exit 1; fi + fi + + ######################################################################## + # STEP 2: Prune old *system* generations (keep newest K) + ######################################################################## + print_line + action "Pruning NixOS system generations (keeping ${keep_generations})…" + + # List generations oldest->newest + mapfile -t gens < <(sudo nix-env -p /nix/var/nix/profiles/system --list-generations | awk '{print $1}') + if (( ${#gens[@]} == 0 )); then + ok "No system generations found." + else + if (( ${#gens[@]} > keep_generations )); then + to_del_count=$(( ${#gens[@]} - keep_generations )) + to_del=( "${gens[@]:0:to_del_count}" ) + if [[ "$DRYRUN" == true ]]; then + log "[dry-run] sudo nix-env -p /nix/var/nix/profiles/system --delete-generations ${to_del[*]}" + else + sudo nix-env -p /nix/var/nix/profiles/system --delete-generations "${to_del[@]}" + ok "Removed ${to_del_count}; kept newest ${keep_generations}." + fi + else + ok "Generations (${#gens[@]}) ≤ keep (${keep_generations}); nothing to prune." + fi + fi + + ######################################################################## + # STEP 3: Garbage collect unreferenced store paths + ######################################################################## + print_line + action "Running Nix GC (and store optimise)…" + if [[ "$DRYRUN" == true ]]; then + log "[dry-run] sudo nix-collect-garbage -d" + log "[dry-run] sudo nix store optimise" + else + sudo nix-collect-garbage -d + # Optimise: dedup store (if subcommand exists) + if command -v nix >/dev/null 2>&1 && nix --help 2>&1 | grep -q 'store optimise'; then + sudo nix store optimise || true + fi + ok "GC complete." + fi + + ######################################################################## + # STEP 4: Tidy logs (rebuild + cleanup) + ######################################################################## + print_line + action "Tidying logs…" + + removed_any=false + + # (a) Remove unfinished rebuild logs + if [[ -d "$log_dir_rebuild" ]]; then + for pat in "rebuild-*.log" "Current-Error*.txt"; do + if compgen -G "${log_dir_rebuild}/${pat}" >/dev/null; then + if [[ "$DRYRUN" == true ]]; then + log "[dry-run] rm ${log_dir_rebuild}/${pat}" + else + rm -f ${log_dir_rebuild}/${pat} + removed_any=true + fi + fi + done + + # (b) Keep newest K final rebuild logs (nixos-gen_*-switch-*.log) + mapfile -t final_logs < <(ls -1 "${log_dir_rebuild}"/nixos-gen_*-switch-*.log 2>/dev/null | sort) + if (( ${#final_logs[@]} > keep_generations )); then + del_count=$(( ${#final_logs[@]} - keep_generations )) + to_del=( "${final_logs[@]:0:del_count}" ) + if [[ "$DRYRUN" == true ]]; then + log "[dry-run] rm ${to_del[*]}" + else + rm -f "${to_del[@]}" + removed_any=true + fi + ok "Rebuild logs: kept newest ${keep_generations}, removed ${del_count}." + else + ok "Rebuild logs count (${#final_logs[@]}) ≤ keep (${keep_generations}); nothing to delete." + fi + else + warn "Rebuild log dir not found: ${log_dir_rebuild}" + fi + + # (c) Keep cleanup dir itself trimmed (optional: keep last 10 summaries) + mapfile -t cleanup_logs < <(ls -1 "${log_dir_cleanup}"/cleanup-*.log 2>/dev/null | sort) + if (( ${#cleanup_logs[@]} > 10 )); then + del_count=$(( ${#cleanup_logs[@]} - 10 )) + to_del=( "${cleanup_logs[@]:0:del_count}" ) + if [[ "$DRYRUN" == true ]]; then + log "[dry-run] rm ${to_del[*]}" + else + rm -f "${to_del[@]}" + removed_any=true + fi + ok "Cleanup logs: kept newest 10, removed ${del_count}." + fi + + # (d) Commit/push log changes if logs live in a git repo + if [[ "$DRYRUN" == false && "$removed_any" == true ]]; then + log_root="$(dirname "$log_dir")" + if git_in_repo "$log_root"; then + ( + cd "$log_root" + g add "$(basename "$log_dir")" + git_commit_if_staged "cleanup: pruned logs & system generations" + git_push_if_enabled + ) + ok "Logged cleanup committed${auto_push:+ and pushed}." + fi + fi + + ######################################################################## + # SUMMARY + ######################################################################## + print_line + end_s=$(date +%s) + log "${BOLD}${CYAN}Cleanup Summary${RESET}" + log " Started: ${start_human}" + log " Duration: $(( end_s - start_s )) sec" + (( ${#gens[@]:-0} > 0 )) && log " Gens kept: ${keep_generations} (of ${#gens[@]})" + ok "Done." +} + +# Execute when sourced as a script +nyx-cleanup "$@" diff --git a/legacy-nyx/bash/nyx-info.sh b/legacy-nyx/bash/nyx-info.sh new file mode 100644 index 0000000..5de065a --- /dev/null +++ b/legacy-nyx/bash/nyx-info.sh @@ -0,0 +1,183 @@ +#!/usr/bin/env bash +nyx-info() { +############################################ +# CONFIG (injected by Nix) +############################################ +local info_dir="@LOG_DIR@/info" +local topic_name="Homemanager-Support" +local msg_file="${info_dir}/${topic_name}-message.txt" +local inform_enable=true +local sleeptimer=3 + + +# ⚠ IMPORTANT PROJECT UPDATE ⚠ + +local information=" +⚠ IMPORTANT PROJECT UPDATE ⚠ + +Please note that I will soon switch Nyx from a Home Manager module to a NixOS module. +You can still use the Home Manager module, but I will only continue developing it for Nyx at a specific legacy commit/revision. + +Please consider pinning Nyx to that commit: +https://github.com/Peritia-System/Nyx-Tools/blob/main/Documentation/How-to-Homemanager.md + +Or even better switch to the nixosmodule. Checkout the ReadMe for that: +https://github.com/Peritia-System/Nyx-Tools + +If you use this, you can keep the current version indefinitely but wont receive updates. +If you dont pin to that commit, I wont take any responsibility for breakage. +(Note: I dont take any responsibility regardless — this is a hobby project.) +If you want to ensure it works, help me develop it. + +Thank you for your understanding <3 + +This is not supposed to discourage you from using Nyx!!! I am so, so glad you use Nyx :) +But it is very early in development so things move quick and big changes will be common. +Plus as I said, it is a hobby project and at the moment I develop alone. +" + +############################################ +# Helpers +############################################ + +usage() { + cat <<'EOF' +Usage: nyx-info [--acknowledge] [--print-force] [--help] + + --acknowledge Record acknowledgment for the current notice and print it. + --print-force Print the current notice without reading/writing state. + --help Show this help. + +Notes: + - You'll be prompted again if the notice text changes. + - State is stored under @LOG_DIR@/info per topic, in this format: + + -----Acknowledged----- + $ack + -----BEGIN INFO----- + $information + -----END INFO----- + -----BEGIN SHA----- + $sha + -----END SHA----- +EOF +} + +ensure_storage() { + mkdir -p "${info_dir}" +} + +hash_text() { + if command -v sha256sum >/dev/null 2>&1; then + sha256sum | awk '{print $1}' + elif command -v shasum >/dev/null 2>&1; then + shasum -a 256 | awk '{print $1}' + else + echo "ERROR: Need sha256sum or shasum on PATH." >&2 + exit 1 + fi +} + +current_sha() { + printf '%s' "${information}" | hash_text +} + +save_state() { + # $1 = ack (true/false), $2 = sha + { + echo "-----Acknowledged-----" + echo "$1" + echo "-----BEGIN INFO-----" + printf '%s\n' "${information}" + echo "-----END INFO-----" + echo "-----BEGIN SHA-----" + echo "$2" + echo "-----END SHA-----" + } > "${msg_file}" +} + +load_state() { + # Sets globals: stored_ack, stored_sha, stored_info (empty if no file). + stored_ack="" + stored_sha="" + stored_info="" + + [[ -f "${msg_file}" ]] || return 0 + + stored_ack="$(awk '/^-----Acknowledged-----$/{getline; print; exit}' "${msg_file}" || true)" + + stored_info="$(awk ' + BEGIN{p=0} + /^-----BEGIN INFO-----$/ {p=1; next} + /^-----END INFO-----$/ {p=0} + p==1 {print} + ' "${msg_file}" || true)" + + stored_sha="$(awk ' + BEGIN{p=0} + /^-----BEGIN SHA-----$/ {p=1; next} + /^-----END SHA-----$/ {p=0} + p==1 {print} + ' "${msg_file}" || true)" +} + +print_notice() { + cat <&2; usage; exit 2 ;; + esac + shift + done + + [[ "${inform_enable}" == true ]] || exit 0 + ensure_storage + + local now_sha + now_sha="$(current_sha)" + + if [[ "${print_force}" == true ]]; then + print_notice + exit 0 + fi + + load_state + + if [[ "${acknowledge}" == true ]]; then + save_state "true" "${now_sha}" + print_notice + exit 0 + fi + + if should_skip_notice "${now_sha}"; then + echo "Notice already acknowledged. To reread: ${info_dir} -> ${msg_file}" + exit 0 + fi + + save_state "false" "${now_sha}" + print_notice +} + +nyx-info "$@" diff --git a/legacy-nyx/bash/nyx-rebuild.sh b/legacy-nyx/bash/nyx-rebuild.sh new file mode 100644 index 0000000..899e997 --- /dev/null +++ b/legacy-nyx/bash/nyx-rebuild.sh @@ -0,0 +1,387 @@ +#!/usr/bin/env bash +nyx-rebuild() { + set -euo pipefail + + ######################################################################## + # CONFIGURATION (injected by Nix) + ######################################################################## + nix_dir="@NIX_DIR@" + log_dir="@LOG_DIR@" + start_editor="@START_EDITOR@" + enable_formatting="@ENABLE_FORMATTING@" + editor_cmd="@EDITOR@" + formatter_cmd="@FORMATTER@" + git_bin="@GIT_BIN@" + nom_bin="@NOM_BIN@" + auto_push="@AUTO_PUSH@" + version="@VERSION@" + + ######################################################################## + # ARGUMENT PARSING + ######################################################################## + do_repair=false + do_update=false + while [[ $# -gt 0 ]]; do + case "$1" in + --repair) do_repair=true; shift;; + --update) do_update=true; shift;; + -h|--help) + cat <" + and remove any unfinished logs (Current-Error*.txt and rebuild-*.log + that are not final nixos-gen_* logs). + + --update Before rebuilding, update the flake in nix_dir using: + nix flake update +EOF + return 0 + ;; + *) echo "Unknown argument: $1" >&2; return 2;; + esac + done + + ######################################################################## + # COLORS (TTY only) + ######################################################################## + if [[ -t 1 ]]; then + RED=$'\e[31m'; GREEN=$'\e[32m'; YELLOW=$'\e[33m' + BLUE=$'\e[34m'; MAGENTA=$'\e[35m'; CYAN=$'\e[36m' + BOLD=$'\e[1m'; RESET=$'\e[0m' + else + RED=""; GREEN=""; YELLOW="" + BLUE=""; MAGENTA=""; CYAN="" + BOLD=""; RESET="" + fi + + ######################################################################## + # LIGHTWEIGHT GIT HELPERS + ######################################################################## + g() { "$git_bin" "$@"; } + + git_in_repo() { + local dir="$1" + [[ -d "$dir/.git" ]] || (cd "$dir" && g rev-parse --git-dir >/dev/null 2>&1) + } + + git_has_uncommitted_changes() { + # prints true if there are changes + [[ -n "$(g status --porcelain)" ]] + } + + git_pause_if_dirty() { + local attempts=0 + while git_has_uncommitted_changes; do + if (( attempts == 0 )); then + echo "${YELLOW}Uncommitted changes detected!${RESET}" + echo "${RED}Pausing for 5 seconds to allow cancel (Ctrl-C) before attempting repair...${RESET}" + sleep 5 + echo "Attempting repair..." + repair || true # never let a no-op commit kill the script + echo "repair ran" + ((attempts++)) || true + # loop will re-check cleanliness + else + echo "${YELLOW}Uncommitted changes still present after repair.${RESET}" + echo "${RED}Needs manual review. Continuing in 5 seconds...${RESET}" + sleep 5 + break + fi + done + } + + + + git_pull_rebase() { + g pull --rebase + } + + git_add_path() { + g add "$@" + } + + git_commit_if_staged() { + # commit if there is something staged; ignore empty + if ! g diff --cached --quiet; then + g commit -m "$1" || true + fi + } + + git_commit_message() { + local msg="$1" + g commit -m "$msg" + } + + git_push_if_enabled() { + if [[ "${auto_push}" == "true" ]]; then + g push + fi + } + + git_safe_add_commit_push() { + # Convenience: add paths, commit message, optional push + local msg="$1"; shift + git_add_path "$@" + if git_commit_if_staged "$msg"; then + git_push_if_enabled + fi + } + + + ######################################################################## + # REPAIR MODE + ######################################################################## + repair() { + cd "$nix_dir" || { echo "ERROR: Cannot cd into nix_dir: $nix_dir" >&2; return 1; } + + ts="$(date '+%Y-%m-%d_%H-%M-%S')" + echo "Starting repair at ${ts}..." + + # Remove unfinished logs (not final logs) + log_dir_rebuild="${log_dir}/rebuild" + if [[ -d "$log_dir_rebuild" ]]; then + echo "Checking for unfinished logs in: $log_dir_rebuild" + if find "$log_dir_rebuild" -type f \ + ! -name 'nixos-gen_*' \ + \( -name 'rebuild-*.log' -o -name 'Current-Error*.txt' \) | grep -q .; then + echo "Removing unfinished logs..." + find "$log_dir_rebuild" -type f \ + ! -name 'nixos-gen_*' \ + \( -name 'rebuild-*.log' -o -name 'Current-Error*.txt' \) \ + -exec rm -v {} + + echo "Unfinished logs removed." + else + echo "No unfinished logs found." + fi + else + echo "No rebuild log directory found." + fi + + echo "Staging all changes in $nix_dir..." + g add -A + + # Oed; avoid set nly commit if something is stag-e failure on empty commit + if ! g diff --cached --quiet --; then + echo "Committing repair changes..." + g commit -m "rebuild - repair ${ts}" + echo "Repair commit created." + else + echo "No changes to commit." + fi + + } + + + + + ######################################################################## + # LOGGING / COMMON HELPERS + ######################################################################## + start_time=$(date +%s) + start_human=$(date '+%Y-%m-%d %H:%M:%S') + stats_duration=0 + stats_gen="?" + stats_errors=0 + stats_last_error_lines="" + rebuild_success=false + exit_code=1 + + timestamp=$(date '+%Y-%m-%d_%H-%M-%S') + log_dir_rebuild="${log_dir}/rebuild" + build_log="${log_dir_rebuild}/rebuild-${timestamp}.log" + error_log="${log_dir_rebuild}/Current-Error-${timestamp}.txt" + + console-log() { echo -e "$@" | tee -a "$build_log"; } + print_line() { console-log ""; console-log "${BOLD}==================================================${RESET}"; console-log ""; } + + run_with_log() { + local tmp; tmp=$(mktemp) + ( "$@" 2>&1; echo $? > "$tmp" ) | tee -a "$build_log" + local s; s=$(<"$tmp"); rm "$tmp"; return "$s" + } + + run_with_log_rebuild() { + local tmp; tmp=$(mktemp) + ( "$@" 2>&1; echo $? > "$tmp" ) | tee -a "$build_log" | $nom_bin + local s; s=$(<"$tmp"); rm "$tmp"; return "$s" + } + + ######################################################################## + # EARLY REPAIR MODE CHECK + ######################################################################## + if [[ "$do_repair" == true ]]; then + ######################################################################## + # BANNER + ######################################################################## + echo + nyx-tool "Nyx" "nyx-rebuild --repair" "$version" \ + "Smart NixOS configuration repair" \ + "by Peritia-System" \ + "https://github.com/Peritia-System/Nyx-Tools" \ + "https://github.com/Peritia-System/Nyx-Tools/issues" \ + "Fixing our mistake... or yours" + echo + repair + rebuild_success=true + return 0 + fi + + finish_nyx_rebuild() { + stats_duration=$(( $(date +%s) - start_time )) + echo + if [[ "$rebuild_success" == true ]]; then + echo "${GREEN}${BOLD}NixOS Rebuild Complete${RESET}" + echo "${BOLD}${CYAN}Summary:${RESET}" + echo " Started: $start_human" + echo " Duration: ${stats_duration} sec" + echo " Generation: $stats_gen" + else + echo "${RED}${BOLD}NixOS Rebuild Failed${RESET}" + echo "${BOLD}${RED}Error Stats:${RESET}" + echo " Started: $start_human" + echo " Duration: ${stats_duration} sec" + echo " Error lines: ${stats_errors}" + [[ -n "$stats_last_error_lines" ]] && echo -e "${YELLOW}Last few errors:${RESET}$stats_last_error_lines" + fi + } + trap finish_nyx_rebuild EXIT + + ######################################################################## + # BANNER + ######################################################################## + echo + nyx-tool "Nyx" "nyx-rebuild" "$version" \ + "Smart NixOS configuration rebuilder" \ + "by Peritia-System" \ + "https://github.com/Peritia-System/Nyx-Tools" \ + "https://github.com/Peritia-System/Nyx-Tools/issues" \ + "Always up to date for you!" + echo + + ######################################################################## + # PREP + ######################################################################## + mkdir -p "$log_dir_rebuild" + cd "$nix_dir" || { echo "Cannot cd into nix_dir: $nix_dir" >&2; exit_code=1; return $exit_code; } + + ######################################################################## + # GIT DIRTY CHECK + ######################################################################## + echo -e "${BOLD}${BLUE}Checking Git status...${RESET}" + git_pause_if_dirty + + ######################################################################## + # NORMAL REBUILD FLOW... + ######################################################################## + + console-log "${BOLD}${BLUE}Pulling latest changes...${RESET}" + if ! run_with_log git pull --rebase; then + exit_code=1; return $exit_code + fi + + ######################################################################## + # OPTIONAL: editor + ######################################################################## + if [[ "$start_editor" == "true" ]]; then + console-log "${BOLD}${BLUE}Opening editor...${RESET}" + console-log "Started editing: $(date)" + run_with_log "$editor_cmd" + console-log "Finished editing: $(date)" + console-log "${BOLD}${CYAN}Changes summary:${RESET}" + run_with_log git diff --compact-summary + fi + + ######################################################################## + # OPTIONAL: formatter + ######################################################################## + if [[ "$enable_formatting" == "true" ]]; then + console-log "${BOLD}${MAGENTA}Running formatter...${RESET}" + run_with_log "$formatter_cmd" . + fi + + ######################################################################## + # REBUILD + ######################################################################## + + # Check if update: + print_line + if [[ "$do_update" == true ]]; then + console-log "${BOLD}${BLUE}Updating flake...${RESET}" + print_line + run_with_log nix flake update --verbose + if git_has_uncommitted_changes; then + git_add_path flake.lock + git_commit_if_staged "flake update: $(date '+%Y-%m-%d %H:%M:%S')" + fi + print_line + fi + + + console-log "${BOLD}${BLUE}Starting system rebuild...${RESET}" + + if find ~ -type f -name '*delme-HMbackup' | grep -q .; then + print_line + console-log "Removing old HM conf" + run_with_log find ~ -type f -name '*delme-HMbackup' -exec rm -v {} + + print_line + fi + + + if sudo -n true 2>/dev/null; then + console-log "Sudo rights already available" + else + console-log "Getting sudo ticket (please enter your password)" + run_with_log sudo whoami > /dev/null + fi + + print_line + console-log "Rebuild started: $(date)" + print_line + + run_with_log_rebuild sudo nixos-rebuild switch --flake "$nix_dir" + rebuild_status=$? + + if [[ $rebuild_status -ne 0 ]]; then + echo "${RED}Rebuild failed at $(date).${RESET}" > "$error_log" + stats_errors=$(grep -Ei -A 1 'error|failed' "$build_log" | tee -a "$error_log" | wc -l || true) + stats_last_error_lines=$(tail -n 10 "$error_log" || true) + + # capture and push error artifacts + git_add_path "$log_dir_rebuild" + g commit -m "Rebuild failed: errors logged" || true + git_push_if_enabled + + exit_code=1 + return $exit_code + fi + + ######################################################################## + # SUCCESS PATH + ######################################################################## + rebuild_success=true + exit_code=0 + + gen=$(nixos-rebuild list-generations | grep True | awk '{$1=$1};1' || true) + stats_gen=$(echo "$gen" | awk '{printf "%04d", $1}' || echo "0000") + + # Append summary to build log (before rotating file name) + finish_nyx_rebuild >> "$build_log" + + # Commit config changes (if any) + git_add_path -u + if git_commit_if_staged "Rebuild: $gen"; then + echo "${BLUE}Commit message:${RESET}${GREEN}Rebuild: $gen${RESET}" + fi + + # Move and add final log + final_log="$log_dir_rebuild/nixos-gen_${stats_gen}-switch-${timestamp}.log" + mv "$build_log" "$final_log" + git_add_path "$final_log" + git_commit_if_staged "log for $gen" || echo "${YELLOW}No changes in logs to commit.${RESET}" + + git_push_if_enabled && echo "${GREEN}Changes pushed to remote.${RESET}" || true +} + +# Execute when sourced as a script +nyx-rebuild "$@" diff --git a/legacy-nyx/bash/nyx-tool.sh b/legacy-nyx/bash/nyx-tool.sh new file mode 100644 index 0000000..8c5590e --- /dev/null +++ b/legacy-nyx/bash/nyx-tool.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env bash + +# nyx-tool: reusable metadata banner printer with Base16 theme +nyx-tool() { + local logo="${1:-Nyx}" + local name="${2:-nix-script}" + local version="${3:-Version Unknown - Please Open Issue}" + local description="${4:-A Nix utility}" + local credit="${5:-Peritia-System}" + local github="${6:-https://github.com/example/repo}" + local issues="${7:-${github}/issues}" + local message="${8:-Use responsibly}" + + # Base16 color palette (ANSI escape codes) + local RESET="\033[0m" + local BOLD="\033[1m" + local HEADER="\033[38;5;33m" # blue + local LABEL="\033[38;5;70m" # green + local VALUE="\033[38;5;250m" # gray + local EMPHASIS="\033[38;5;196m" # red + local CYAN="\033[38;5;51m" + local GREEN="\033[38;5;82m" + + local line + line=$(printf '=%.0s' $(seq 1 35)) + + echo "" + echo -e "${HEADER}${line}${RESET}" + echo -e "${HEADER}=====[ ${BOLD}Peritia System Tools${RESET}${HEADER} ]=====${RESET}" + echo -e "${VALUE}${BOLD}" + + # Figlet logo rendering + if command -v figlet &>/dev/null; then + figlet -f banner3 "$logo" | sed 's/#/█/g' + else + echo "$logo" + fi + + echo -e "${RESET}${HEADER}by Peritia-System${RESET}" + echo -e "${HEADER}${line}${RESET}" + echo "" + + echo -e "${LABEL}🛠️ Name: ${VALUE}${name}${RESET}" + echo -e "${LABEL}🏷️ Version: ${VALUE}${version}${RESET}" + echo -e "${LABEL}📝 Description: ${VALUE}${description}${RESET}" + echo -e "${LABEL}👤 Credit: ${VALUE}${credit}${RESET}" + echo -e "${LABEL}🌐 GitHub: ${VALUE}${github}${RESET}" + echo -e "${LABEL}🐛 Issues: ${VALUE}${issues}${RESET}" + echo "" + echo -e "${LABEL}📌 Message: ${BOLD}${message}${RESET}" + echo "" + nyx-info +} + +nyx-tool "$@" diff --git a/legacy-nyx/bash/nyx-tui.sh b/legacy-nyx/bash/nyx-tui.sh new file mode 100644 index 0000000..072aa84 --- /dev/null +++ b/legacy-nyx/bash/nyx-tui.sh @@ -0,0 +1,340 @@ +#!/usr/bin/env bash +# nyx-tui: interactive TUI for Nyx tasks + +if [ -z "${BASH_VERSION:-}" ]; then + echo "This script must be run with bash, not $SHELL" >&2 + exit 1 +fi + +set -euo pipefail + +######################################################################## +# CONFIGURATION (injected by Nix) +######################################################################## +log_dir="@LOG_DIR@" +nix_dir="@NIX_DIR@" +version="@VERSION@" +dialog_bin="${DIALOG_BIN:-@DIALOG_BIN@}" + +# Fallbacks if Nix didn't substitute +if [[ -z "${dialog_bin//@DIALOG_BIN@/}" ]]; then + # If placeholder remained, try common defaults + if command -v dialog >/dev/null 2>&1; then + dialog_bin="$(command -v dialog)" + elif command -v whiptail >/dev/null 2>&1; then + dialog_bin="$(command -v whiptail)" + else + echo "Error: neither 'dialog' nor 'whiptail' found. Please install one." >&2 + exit 1 + fi +fi + +if ! command -v "$dialog_bin" >/dev/null 2>&1; then + echo "Error: dialog binary '$dialog_bin' is not executable." >&2 + exit 1 +fi + +mkdir -p "$log_dir" + +######################################################################## +# CLI args +######################################################################## +do_startup=false + +print_help() { + cat <<'EOF' +nyx-tui [--pretty] [--help] + + --pretty Show a simple artificial startup screen (optional). + --help Show this help. +EOF +} + +while [[ $# -gt 0 ]]; do + case "$1" in + --pretty) do_startup=true; shift;; + -h|--help) print_help; exit 0;; + *) echo "Unknown argument: $1" >&2; exit 2;; + esac +done + +######################################################################## +# Colors (TTY only) +######################################################################## +if [[ -t 1 ]]; then + RED=$'\e[31m'; GREEN=$'\e[32m'; YELLOW=$'\e[33m' + BLUE=$'\e[34m'; MAGENTA=$'\e[35m'; CYAN=$'\e[36m' + BOLD=$'\e[1m'; RESET=$'\e[0m' +else + RED=""; GREEN=""; YELLOW=""; BLUE=""; MAGENTA=""; CYAN=""; BOLD=""; RESET="" +fi + +pause() { read -r -p "Press Enter to continue..." _; } + +######################################################################## +# Dialog wrappers +######################################################################## +d_msg() { + local msg="${1:-}" + "$dialog_bin" --title "Nyx TUI" --msgbox "$msg" 8 60 + clear +} + +d_textbox() { + local title="${1:-}"; local file="${2:-}" + "$dialog_bin" --title "$title" --textbox "$file" 20 100 + clear +} + +d_menu() { + local title="$1"; shift + local prompt="$1"; shift + local choice + choice=$("$dialog_bin" --title "$title" --menu "$prompt" 20 70 10 "$@" 3>&1 1>&2 2>&3) || return 1 + echo "$choice" +} + +######################################################################## +# Helpers +######################################################################## +run_with_spinner() { + local label="$1"; shift + echo "${CYAN}${BOLD}${label}${RESET}" + ( "$@" ) & + local pid=$! + local spin='|/-\'; local i=0 + while kill -0 "$pid" 2>/dev/null; do + i=$(( (i+1) % 4 )) + printf "\r%s" "${spin:$i:1}" + sleep 0.1 + done + wait "$pid"; local status=$?; printf "\r" + return $status +} + +######################################################################## +# Actions +######################################################################## +action_rebuild() { + clear + if command -v nyx-rebuild >/dev/null 2>&1; then + run_with_spinner "Rebuilding (nyx-rebuild)..." nyx-rebuild || true + if ! check_last_log_for_error; then + return + fi + d_msg "Rebuild finished." + elif command -v nixos-rebuild >/dev/null 2>&1; then + run_with_spinner "nixos-rebuild switch --flake ${nix_dir} ..." \ + sudo nixos-rebuild switch --flake "$nix_dir" || true + sleep 1 + d_msg "nixos-rebuild finished." + else + d_msg "No rebuild tool found (nyx-rebuild / nixos-rebuild). Skipping." + fi +} + +action_update() { + clear + if command -v nyx-rebuild >/dev/null 2>&1; then + run_with_spinner "Updating (nyx-rebuild --update)..." nyx-rebuild --update || true + if ! check_last_log_for_error; then + return + fi + d_msg "Update finished." + elif command -v nixos-rebuild >/dev/null 2>&1; then + ( + cd "$nix_dir" + run_with_spinner "nix flake update..." nix flake update || true + ) + run_with_spinner "nixos-rebuild switch --flake ${nix_dir} ..." \ + sudo nixos-rebuild switch --flake "$nix_dir" || true + sleep 1 + d_msg "nixos-rebuild finished." + else + d_msg "No update tool found. Skipping." + fi +} + +action_repair() { + clear + if command -v nyx-rebuild >/dev/null 2>&1; then + run_with_spinner "Repairing (nyx-rebuild --repair)..." nyx-rebuild --repair || true + if ! check_last_log_for_error; then + return + fi + d_msg "Repair finished." + else + d_msg "No repair tool found. Skipping." + fi +} + +action_cleanup() { + clear + if command -v nyx-cleanup >/dev/null 2>&1; then + run_with_spinner "Cleaning up..." nyx-cleanup || true + sleep 1 + d_msg "Cleanup finished." + else + d_msg "nyx-cleanup not found; nothing to do." + fi +} + +action_update_flake() { + clear + if command -v nix >/dev/null 2>&1 && [[ -d "$nix_dir" ]]; then + ( cd "$nix_dir" && run_with_spinner "nix flake update..." nix flake update ) || true + d_msg "Flake update finished." + else + d_msg "nix not installed or flake dir missing: ${nix_dir}" + fi +} + +action_git_pull() { + clear + if [[ -d "$nix_dir/.git" ]]; then + ( cd "$nix_dir" && run_with_spinner "git pull --rebase..." git pull --rebase ) || true + d_msg "Git pull completed." + else + d_msg "No git repo at: ${nix_dir}" + fi +} + +action_system_info() { + local tmp; tmp="$(mktemp)" + { + echo "Host: $(hostname)" + echo "Kernel: $(uname -srmo)" + echo "Uptime: $(uptime -p)" + echo + echo "Disk (root):" + df -h / + echo + if command -v nix >/dev/null 2>&1; then + echo "Nix profiles:" + nix profile list || true + else + echo "Nix not installed." + fi + } > "$tmp" + d_textbox "System Info" "$tmp" + rm -f "$tmp" +} + +action_view_logs() { + if [[ -d "$log_dir" ]]; then + local lastlog tmp + tmp="$(mktemp)" + lastlog="$(find "$log_dir" -type f -name '*.log' -printf '%T@ %p\n' 2>/dev/null | sort -nr | awk 'NR==1{print $2}')" + if [[ -n "${lastlog:-}" && -f "$lastlog" ]]; then + tail -n 300 "$lastlog" > "$tmp" + d_textbox "Last Rebuild Log: $(basename "$lastlog")" "$tmp" + else + d_msg "No logs found in ${log_dir}" + fi + rm -f "$tmp" + else + d_msg "Log directory not found: ${log_dir}" + fi +} + +check_last_log_for_error() { + local lastlog + lastlog="$(find "$log_dir" -type f -name '*.log' -printf '%T@ %p\n' 2>/dev/null | + sort -nr | awk 'NR==1{print $2}')" + if [[ -n "${lastlog:-}" && -f "$lastlog" ]]; then + if grep -qi "error" "$lastlog"; then + local tmp + tmp="$(mktemp)" + echo "Error detected in: $(basename "$lastlog")" > "$tmp" + echo >> "$tmp" + grep -A99999 -i "error" "$lastlog" >> "$tmp" + d_textbox "Last Build Error" "$tmp" + rm -f "$tmp" + return 1 + elif grep -qi "failed" "$lastlog"; then + local tmp + tmp="$(mktemp)" + echo "Error detected in: $(basename "$lastlog")" > "$tmp" + echo >> "$tmp" + grep -A99999 -i "error" "$lastlog" >> "$tmp" + d_textbox "Last Build Error" "$tmp" + rm -f "$tmp" + return 1 + fi + fi + return 0 +} + + + +startup() { + clear + if "$do_startup"; then + echo + nyx-tool "Nyx" "nyx-tui" "$version" \ + "A better way to nyx" \ + "by Peritia-System" \ + "https://github.com/Peritia-System/Nyx-Tools" \ + "https://github.com/Peritia-System/Nyx-Tools/issues" \ + "Because who doesn't love a good TUI" + echo "Loading Nyx TUI..." + echo + + local bar_length=25 + for ((i=0; i<=bar_length; i++)); do + local filled empty percent + filled=$(printf "%${i}s" | tr ' ' '#') + empty=$(printf "%$((bar_length - i))s" | tr ' ' ' ') + percent=$(( i * 100 / bar_length )) + printf "\r[%s%s] %d%%" "$filled" "$empty" "$percent" + sleep 0.2 + # Slow down after 70% (i > 17 when bar_length = 25) + if [[ $i -gt 17 ]]; then + sleep 0.1 + fi + done + echo -e "\nAll Loaded!\n" + read -r -p "Press Enter to continue..." + clear + else + echo + nyx-tool "Nyx" "nyx-tui" "$version" \ + "A better way to nyx" \ + "by Peritia-System" \ + "https://github.com/Peritia-System/Nyx-Tools" \ + "https://github.com/Peritia-System/Nyx-Tools/issues" \ + "Because who doesn't love a good TUI" + read -r -p "Press Enter to continue..." + clear + fi +} + + +######################################################################## +# Menu Loop +######################################################################## +startup +while true; do + choice=$(d_menu "Nyx TUI ${version}" "Select an action:" \ + 1 "Update" \ + 2 "Rebuild" \ + 3 "Repair" \ + 4 "Cleanup (nyx-cleanup)" \ + 5 "Flake: nix flake update" \ + 6 "Git pull (in nix dir)" \ + 7 "System info" \ + 8 "View latest rebuild log" \ + X "Exit") || { clear; exit 0; } + + case "$choice" in + 1) action_update ;; + 2) action_rebuild ;; + 3) action_repair ;; + 4) action_cleanup ;; + 5) action_update_flake ;; + 6) action_git_pull ;; + 7) action_system_info ;; + 8) action_view_logs ;; + X) clear; exit 0 ;; + esac +done diff --git a/legacy-nyx/default.nix b/legacy-nyx/default.nix new file mode 100644 index 0000000..b4391b8 --- /dev/null +++ b/legacy-nyx/default.nix @@ -0,0 +1,56 @@ +# nyx.nix +{ config, lib, ... }: +with lib; + +{ + ################################################################ + # Global Nyx Options + ################################################################ + options.nyx = { + enable = mkEnableOption "Enable all Nyx tools"; + + username = mkOption { + type = types.str; + description = "Username for Nyx tools"; + }; + + nixDirectory = mkOption { + type = types.path; + description = "Path to NixOS flake directory"; + }; + + logDir = mkOption { + type = types.path; + default = "/home/${config.nyx.username}/.nyx/logs"; + description = "Directory for Nyx logs"; + }; + + autoPush = mkOption { + type = types.bool; + default = false; + description = "Automatically push changes after rebuild/cleanup"; + }; + }; + + ################################################################ + # Import submodules + ################################################################ + imports = [ + ./nyx-rebuild.nix + ./nyx-cleanup.nix + ./nyx-tool.nix + ./nyx-tui.nix + + ]; + + ################################################################ + # Global disable logic + ################################################################ + config = mkIf (!config.nyx.enable) { + nyx.nyx-rebuild.enable = false; + nyx.nyx-cleanup.enable = false; + nyx.nyx-tui.enable = false; + nyx.nyx-tool.enable = false; + }; + +} diff --git a/legacy-nyx/nyx-cleanup.nix b/legacy-nyx/nyx-cleanup.nix new file mode 100644 index 0000000..571767b --- /dev/null +++ b/legacy-nyx/nyx-cleanup.nix @@ -0,0 +1,51 @@ +{ config, lib, pkgs, ... }: + +let + nyxCfg = config.nyx or {}; + cfg = nyxCfg."nyx-cleanup" or {}; + + # Read the cleanup script template and replace tokens + cleanupScript = + let + src = builtins.readFile ./bash/nyx-cleanup.sh; # Script with @TOKENS@ + in + builtins.replaceStrings + [ + "@LOG_DIR@" "@KEEP_GENERATIONS@" "@AUTO_PUSH@" "@GIT_BIN@" "@VERSION@" + ] + [ + (toString nyxCfg.logDir) + (toString (cfg.keepGenerations or 5)) + (if (nyxCfg.autoPush or false) then "true" else "false") + "${pkgs.git}/bin/git" + "1.2.0" + ] + src; +in +{ + options.nyx."nyx-cleanup" = { + enable = lib.mkEnableOption "Enable nyx-cleanup script"; + + keepGenerations = lib.mkOption { + type = lib.types.int; + default = 5; + description = "Number of NixOS *system* generations to keep."; + }; + + enableAlias = lib.mkOption { + type = lib.types.bool; + default = true; + description = "If true, add alias 'nc' for 'nyx-cleanup'."; + }; + }; + + config = lib.mkIf ((nyxCfg.enable or false) && (cfg.enable or false)) { + home.packages = [ + (pkgs.writeShellScriptBin "nyx-cleanup" cleanupScript) + ]; + + home.shellAliases = lib.mkIf (cfg.enableAlias or true) { + nc = "nyx-cleanup"; + }; + }; +} diff --git a/legacy-nyx/nyx-rebuild.nix b/legacy-nyx/nyx-rebuild.nix new file mode 100644 index 0000000..19d5601 --- /dev/null +++ b/legacy-nyx/nyx-rebuild.nix @@ -0,0 +1,54 @@ +{ config, lib, pkgs, ... }: + +let + nyxCfg = config.nyx; + cfg = nyxCfg."nyx-rebuild"; + + # Read template and inject values + rebuiltScript = + let + src = builtins.readFile ./bash/nyx-rebuild.sh; # uses @TOKENS@, not ${...} + in + builtins.replaceStrings + [ + "@NIX_DIR@" "@LOG_DIR@" "@START_EDITOR@" "@ENABLE_FORMATTING@" + "@EDITOR@" "@FORMATTER@" "@GIT_BIN@" "@NOM_BIN@" "@AUTO_PUSH@" "@VERSION@" + ] + [ + (toString nyxCfg.nixDirectory) + (toString nyxCfg.logDir) + (if cfg.startEditor then "true" else "false") + (if cfg.enableFormatting then "true" else "false") + cfg.editor + cfg.formatter + "${pkgs.git}/bin/git" + "${pkgs.nix-output-monitor}/bin/nom" + (if nyxCfg.autoPush then "true" else "false") + "1.2.0" + ] + src; +in +{ + options.nyx."nyx-rebuild" = { + enable = lib.mkEnableOption "Enable nyx-rebuild script"; + + editor = lib.mkOption { type = lib.types.str; default = "nvim"; }; + formatter = lib.mkOption { type = lib.types.str; default = "alejandra"; }; + startEditor = lib.mkOption { type = lib.types.bool; default = false; }; + enableFormatting = lib.mkOption { type = lib.types.bool; default = false; }; + enableAlias = lib.mkOption { type = lib.types.bool; default = true; }; + }; + + config = lib.mkIf (nyxCfg.enable && cfg.enable) { + home.packages = + lib.optionals (cfg.enableFormatting && cfg.formatter == "alejandra") [ pkgs.alejandra ] + ++ [ + # Ensure nyx-tool exists if you call it in the script + (pkgs.writeShellScriptBin "nyx-rebuild" rebuiltScript) + ]; + + home.shellAliases = lib.mkIf cfg.enableAlias { + nr = "nyx-rebuild"; + }; + }; +} diff --git a/legacy-nyx/nyx-tool.nix b/legacy-nyx/nyx-tool.nix new file mode 100644 index 0000000..03ddf1a --- /dev/null +++ b/legacy-nyx/nyx-tool.nix @@ -0,0 +1,31 @@ +{ config, lib, pkgs, ... }: + +let + nyxCfg = config.nyx; + cfg = config.nyx.nyx-tool; + infoScript = + let + src = builtins.readFile ./bash/nyx-info.sh; + in + builtins.replaceStrings + [ "@LOG_DIR@" ] + [ (toString nyxCfg.logDir) ] + src; +in +{ + options.nyx.nyx-tool = { + enable = lib.mkEnableOption "Enable nyx-tool banner script and the current info"; + }; + + config = lib.mkIf cfg.enable { + home.packages = [ + pkgs.figlet + (pkgs.writeShellScriptBin "nyx-tool" + (builtins.readFile ./bash/nyx-tool.sh) + ) + (pkgs.writeShellScriptBin "nyx-info" + infoScript + ) + ]; + }; +} diff --git a/legacy-nyx/nyx-tui.nix b/legacy-nyx/nyx-tui.nix new file mode 100644 index 0000000..23be242 --- /dev/null +++ b/legacy-nyx/nyx-tui.nix @@ -0,0 +1,45 @@ +{ config, lib, pkgs, ... }: + +let + nyxCfg = config.nyx or {}; + cfg = nyxCfg."nyx-tui" or {}; + + # Read the tui script template and replace tokens + tuiScript = + let + src = builtins.readFile ./bash/nyx-tui.sh; # Script with @TOKENS@ + in + builtins.replaceStrings + [ + "@LOG_DIR@" "@NIX_DIR@" "@VERSION@" "@DIALOG_BIN@" + ] + [ + (toString nyxCfg.logDir) + (toString nyxCfg.nixDirectory) + "1.2.0" + "${pkgs.dialog}/bin/dialog" + ] + src; +in +{ + options.nyx."nyx-tui" = { + enable = lib.mkEnableOption "Enable nyx-tui script"; + enableAlias = lib.mkOption { + type = lib.types.bool; + default = true; + description = "If true, add alias 'nyx' for 'nyx-tui'."; + }; + }; + + config = lib.mkIf ((nyxCfg.enable or false) && (cfg.enable or false)) { + home.packages = [ + (pkgs.writeShellScriptBin "nyx-tui" tuiScript) + ]; + + home.shellAliases = lib.mkIf (cfg.enableAlias or true) { + nyx = "nyx-tui"; + }; + }; +} + + diff --git a/nyx/bash/nyx-info.sh b/nyx/bash/nyx-info.sh new file mode 100644 index 0000000..ce9cd7b --- /dev/null +++ b/nyx/bash/nyx-info.sh @@ -0,0 +1,180 @@ +#!/usr/bin/env bash +nyx-info() { +############################################ +# CONFIG (injected by Nix) +############################################ +local info_dir="@LOG_DIR@/info" +local topic_name="Homemanager-Support" +local msg_file="${info_dir}/${topic_name}-message.txt" +local inform_enable=false +local sleeptimer=3 + + +# ⚠ IMPORTANT PROJECT UPDATE ⚠ + +local information=" +⚠ IMPORTANT PROJECT UPDATE ⚠ + +Please note that I will soon switch Nyx from a Home Manager module to a NixOS module. +You can still use the Home Manager module, but I will only continue developing it for Nyx at a specific legacy commit/revision. + +Please consider pinning Nyx to that commit: +[https://github.com/Peritia-System/Nyx-Tools/blob/main/Documentation/How-to-Homemanager.md](https://github.com/Peritia-System/Nyx-Tools/blob/main/Documentation/How-to-Homemanager.md) + +If you use this, you can keep the current version indefinitely but wont receive updates. +If you dont pin to that commit, I wont take any responsibility for breakage. +(Note: I dont take any responsibility regardless — this is a hobby project.) +If you want to ensure it works, help me develop it. + +Thank you for your understanding <3 + +This is not supposed to discourage you from using Nyx!!! I am so, so glad you use Nyx :) +But it is very early in development so things move quick and big changes will be common. +Plus as I said, it is a hobby project and at the moment I develop alone. +" + +############################################ +# Helpers +############################################ + +usage() { + cat <<'EOF' +Usage: nyx-info [--acknowledge] [--print-force] [--help] + + --acknowledge Record acknowledgment for the current notice and print it. + --print-force Print the current notice without reading/writing state. + --help Show this help. + +Notes: + - You'll be prompted again if the notice text changes. + - State is stored under @LOG_DIR@/info per topic, in this format: + + -----Acknowledged----- + $ack + -----BEGIN INFO----- + $information + -----END INFO----- + -----BEGIN SHA----- + $sha + -----END SHA----- +EOF +} + +ensure_storage() { + mkdir -p "${info_dir}" +} + +hash_text() { + if command -v sha256sum >/dev/null 2>&1; then + sha256sum | awk '{print $1}' + elif command -v shasum >/dev/null 2>&1; then + shasum -a 256 | awk '{print $1}' + else + echo "ERROR: Need sha256sum or shasum on PATH." >&2 + exit 1 + fi +} + +current_sha() { + printf '%s' "${information}" | hash_text +} + +save_state() { + # $1 = ack (true/false), $2 = sha + { + echo "-----Acknowledged-----" + echo "$1" + echo "-----BEGIN INFO-----" + printf '%s\n' "${information}" + echo "-----END INFO-----" + echo "-----BEGIN SHA-----" + echo "$2" + echo "-----END SHA-----" + } > "${msg_file}" +} + +load_state() { + # Sets globals: stored_ack, stored_sha, stored_info (empty if no file). + stored_ack="" + stored_sha="" + stored_info="" + + [[ -f "${msg_file}" ]] || return 0 + + stored_ack="$(awk '/^-----Acknowledged-----$/{getline; print; exit}' "${msg_file}" || true)" + + stored_info="$(awk ' + BEGIN{p=0} + /^-----BEGIN INFO-----$/ {p=1; next} + /^-----END INFO-----$/ {p=0} + p==1 {print} + ' "${msg_file}" || true)" + + stored_sha="$(awk ' + BEGIN{p=0} + /^-----BEGIN SHA-----$/ {p=1; next} + /^-----END SHA-----$/ {p=0} + p==1 {print} + ' "${msg_file}" || true)" +} + +print_notice() { + cat <&2; usage; exit 2 ;; + esac + shift + done + + [[ "${inform_enable}" == true ]] || exit 0 + ensure_storage + + local now_sha + now_sha="$(current_sha)" + + if [[ "${print_force}" == true ]]; then + print_notice + exit 0 + fi + + load_state + + if [[ "${acknowledge}" == true ]]; then + save_state "true" "${now_sha}" + print_notice + exit 0 + fi + + if should_skip_notice "${now_sha}"; then + echo "Notice already acknowledged. To reread: ${info_dir} -> ${msg_file}" + exit 0 + fi + + save_state "false" "${now_sha}" + print_notice +} + +nyx-info "$@" diff --git a/nyx/bash/nyx-tool.sh b/nyx/bash/nyx-tool.sh index f8b3140..8c5590e 100644 --- a/nyx/bash/nyx-tool.sh +++ b/nyx/bash/nyx-tool.sh @@ -49,6 +49,7 @@ nyx-tool() { echo "" echo -e "${LABEL}📌 Message: ${BOLD}${message}${RESET}" echo "" + nyx-info } nyx-tool "$@" diff --git a/nyx/nyx-cleanup.nix b/nyx/nyx-cleanup.nix index cabbe28..b474277 100644 --- a/nyx/nyx-cleanup.nix +++ b/nyx/nyx-cleanup.nix @@ -18,7 +18,7 @@ let (toString (cfg.keepGenerations or 5)) (if (nyxCfg.autoPush or false) then "true" else "false") "${pkgs.git}/bin/git" - "1.1.0" + "1.2.0" ] src; in @@ -40,11 +40,11 @@ in }; config = lib.mkIf ((nyxCfg.enable or false) && (cfg.enable or false)) { - home.packages = [ + environment.systemPackages = [ (pkgs.writeShellScriptBin "nyx-cleanup" cleanupScript) ]; - home.shellAliases = lib.mkIf (cfg.enableAlias or true) { + environment.shellAliases = lib.mkIf (cfg.enableAlias or true) { nc = "nyx-cleanup"; }; }; diff --git a/nyx/nyx-rebuild.nix b/nyx/nyx-rebuild.nix index 5e7a717..6967326 100644 --- a/nyx/nyx-rebuild.nix +++ b/nyx/nyx-rebuild.nix @@ -24,7 +24,7 @@ let "${pkgs.git}/bin/git" "${pkgs.nix-output-monitor}/bin/nom" (if nyxCfg.autoPush then "true" else "false") - "1.1.0" + "1.2.0" ] src; in @@ -40,14 +40,14 @@ in }; config = lib.mkIf (nyxCfg.enable && cfg.enable) { - home.packages = + environment.systemPackages = lib.optionals (cfg.enableFormatting && cfg.formatter == "alejandra") [ pkgs.alejandra ] ++ [ # Ensure nyx-tool exists if you call it in the script (pkgs.writeShellScriptBin "nyx-rebuild" rebuiltScript) ]; - home.shellAliases = lib.mkIf cfg.enableAlias { + environment.shellAliases = lib.mkIf cfg.enableAlias { nr = "nyx-rebuild"; }; }; diff --git a/nyx/nyx-tool.nix b/nyx/nyx-tool.nix index c27cb6f..4f277b3 100644 --- a/nyx/nyx-tool.nix +++ b/nyx/nyx-tool.nix @@ -1,20 +1,31 @@ { config, lib, pkgs, ... }: let + nyxCfg = config.nyx; cfg = config.nyx.nyx-tool; + infoScript = + let + src = builtins.readFile ./bash/nyx-info.sh; + in + builtins.replaceStrings + [ "@LOG_DIR@" ] + [ (toString nyxCfg.logDir) ] + src; in { options.nyx.nyx-tool = { - enable = lib.mkEnableOption "Enable nyx-tool banner script"; + enable = lib.mkEnableOption "Enable nyx-tool banner script and the current info"; }; config = lib.mkIf cfg.enable { - programs.zsh.enable = lib.mkDefault true; - home.packages = [ + environment.systemPackages = [ pkgs.figlet (pkgs.writeShellScriptBin "nyx-tool" (builtins.readFile ./bash/nyx-tool.sh) ) + (pkgs.writeShellScriptBin "nyx-info" + infoScript + ) ]; }; } diff --git a/nyx/nyx-tui.nix b/nyx/nyx-tui.nix index 03f7e69..c8f755b 100644 --- a/nyx/nyx-tui.nix +++ b/nyx/nyx-tui.nix @@ -16,7 +16,7 @@ let [ (toString nyxCfg.logDir) (toString nyxCfg.nixDirectory) - "1.1.1" + "1.2.0" "${pkgs.dialog}/bin/dialog" ] src; @@ -24,6 +24,7 @@ in { options.nyx."nyx-tui" = { enable = lib.mkEnableOption "Enable nyx-tui script"; + enableAlias = lib.mkOption { type = lib.types.bool; default = true; @@ -32,14 +33,12 @@ in }; config = lib.mkIf ((nyxCfg.enable or false) && (cfg.enable or false)) { - home.packages = [ + environment.systemPackages = [ (pkgs.writeShellScriptBin "nyx-tui" tuiScript) ]; - home.shellAliases = lib.mkIf (cfg.enableAlias or true) { + environment.shellAliases = lib.mkIf (cfg.enableAlias or true) { nyx = "nyx-tui"; }; }; } - - diff --git a/other/example/example-configuration.nix b/other/example/example-configuration.nix index 015779c..9cf4b05 100644 --- a/other/example/example-configuration.nix +++ b/other/example/example-configuration.nix @@ -9,27 +9,69 @@ in { ################################################################ imports = [ - # Home Manager integration - inputs.home-manager.nixosModules.home-manager + # Host-specific hardware configuration (autogenerated) + ./hardware-configuration.nix + + # Nyx + inputs.nyx.nixosModules.default + + # Other imports: + # ...... ]; + ################################################################ + # Nyx Tools Configuration + ################################################################ + nyx = { + # Global settings + enable = true; + username = username; + nixDirectory = nixDirectory; + logDir = "/home/${username}/.nyx/logs"; + autoPush = false; + + # Tool-specific settings + nyx-rebuild = { + enable = true; + formatter = "alejandra"; + enableFormatting = false; + editor = "nvim"; + startEditor = false; + enableAlias = false; + }; + + nyx-cleanup = { + enable = true; + keepGenerations = 5; + enableAlias = false; + }; + nyx-tui = { + enable = true; + enableAlias = false; + }; + nyx-tool = { + enable = true; # must be enabled for others + }; + }; + ################################################################ # Home Manager Configuration ################################################################ -home-manager = { - useGlobalPkgs = true; - useUserPackages = true; - backupFileExtension = "delme-HMbackup"; - # Please use this backup File Extension to ensure that the bug won't cause any problems - # nyx-rebuild deletes the backups on each rebuild before rebuilding - # HM Bug: https://discourse.nixos.org/t/nixos-rebuild-fails-on-backup-up-config-file-by-home-manager/45992 - users.${username} = import ./home.nix; - - extraSpecialArgs = { - inherit inputs nixDirectory username; - }; -}; +# you don't need this but i recommend using Homemanager: +# home-manager = { +# useGlobalPkgs = true; +# useUserPackages = true; +# backupFileExtension = "delme-HMbackup"; +# # Please use this backup File Extension to ensure that the bug won't cause any problems +# # nyx-rebuild deletes the backups on each rebuild before rebuilding +# # HM Bug: https://discourse.nixos.org/t/nixos-rebuild-fails-on-backup-up-config-file-by-home-manager/45992 +# users.${username} = import ./home.nix; +# +# extraSpecialArgs = { +# inherit inputs nixDirectory username; +# }; +# }; ################################################################ # System Version ################################################################ diff --git a/other/example/example-flake.nix b/other/example/example-flake.nix index 7b57c9a..bc28bf9 100644 --- a/other/example/example-flake.nix +++ b/other/example/example-flake.nix @@ -3,9 +3,15 @@ inputs = { nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; - home-manager.url = "github:nix-community/home-manager"; - home-manager.inputs.nixpkgs.follows = "nixpkgs"; + nyx.url = "github:Peritia-System/Nyx-Tools"; + nyx.inputs.nixpkgs.follows = "nixpkgs"; + + # Optional but i recommend it: + # home-manager.url = "github:nix-community/home-manager"; + # home-manager.inputs.nixpkgs.follows = "nixpkgs"; + + }; outputs = inputs @ { nixpkgs,