From 41f64cf8809881b37d038bfaab70dadef7a404d2 Mon Sep 17 00:00:00 2001 From: Ray Andrew Date: Sat, 26 Oct 2024 21:38:00 -0500 Subject: [PATCH] add nix configuration --- flake.lock | 19 +++- flake.nix | 17 +--- src/home/default.nix | 2 +- src/home/{ => shell}/bash.nix | 0 src/home/shell/default.nix | 8 ++ src/home/shell/shell.nix | 32 +++++++ src/lib.nix | 58 ++++++++++++ src/nixos/default.nix | 50 ++++++++++- src/nixos/nix.nix | 163 ++++++++++++++++++++++++++++++++++ 9 files changed, 330 insertions(+), 19 deletions(-) rename src/home/{ => shell}/bash.nix (100%) create mode 100644 src/home/shell/default.nix create mode 100644 src/home/shell/shell.nix create mode 100644 src/nixos/nix.nix diff --git a/flake.lock b/flake.lock index a4c1454..14542cd 100644 --- a/flake.lock +++ b/flake.lock @@ -107,6 +107,22 @@ "type": "github" } }, + "nixpkgs-stable": { + "locked": { + "lastModified": 1729691686, + "narHash": "sha256-BAuPWW+9fa1moZTU+jFh+1cUtmsuF8asgzFwejM4wac=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "32e940c7c420600ef0d1ef396dc63b04ee9cad37", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-24.05", + "repo": "nixpkgs", + "type": "github" + } + }, "root": { "inputs": { "disko": "disko", @@ -114,7 +130,8 @@ "impermanence": "impermanence", "nix-index-database": "nix-index-database", "nixos-hardware": "nixos-hardware", - "nixpkgs": "nixpkgs" + "nixpkgs": "nixpkgs", + "nixpkgs-stable": "nixpkgs-stable" } } }, diff --git a/flake.nix b/flake.nix index 60e2591..73663c8 100644 --- a/flake.nix +++ b/flake.nix @@ -3,6 +3,7 @@ inputs = { nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-24.05"; disko.url = "github:nix-community/disko"; disko.inputs.nixpkgs.follows = "nixpkgs"; impermanence.url = "github:nix-community/impermanence"; @@ -54,20 +55,4 @@ inherit lib self; nixosConfigurations = (import ./src/hosts/default.nix commonArgs); }; - - # outputs = {nixpkgs, ...} @ inputs: - # { - # nixosConfigurations.pickwick = nixpkgs.lib.nixosSystem { - # specialArgs = { inherit inputs; }; - # modules = [ - # inputs.disko.nixosModules.default - # (import ./disko.nix { device = "/dev/nvme0n1"; }) - - # ./configuration.nix - # - # inputs.home-manager.nixosModules.default - # inputs.impermanence.nixosModules.impermanence - # ]; - # }; - # }; } diff --git a/src/home/default.nix b/src/home/default.nix index 0c3164e..f9cad80 100644 --- a/src/home/default.nix +++ b/src/home/default.nix @@ -8,11 +8,11 @@ { imports = [ - ./bash.nix ./emacs.nix ./impermanence.nix ./git.nix ./gui + ./shell ./ssh.nix ]; diff --git a/src/home/bash.nix b/src/home/shell/bash.nix similarity index 100% rename from src/home/bash.nix rename to src/home/shell/bash.nix diff --git a/src/home/shell/default.nix b/src/home/shell/default.nix new file mode 100644 index 0000000..cc90a79 --- /dev/null +++ b/src/home/shell/default.nix @@ -0,0 +1,8 @@ +{ config, lib, pkgs, ... }: + +{ + imports = [ + ./bash.nix + ./shell.nix + ]; +} diff --git a/src/home/shell/shell.nix b/src/home/shell/shell.nix new file mode 100644 index 0000000..c0abe57 --- /dev/null +++ b/src/home/shell/shell.nix @@ -0,0 +1,32 @@ +{ lib, pkgs, ... }: + +{ + options.custom = with lib; { + shell = { + packages = mkOption { + type = + with types; + attrsOf (oneOf [ + str + attrs + package + ]); + default = { }; + apply = custom.mkShellPackages; + description = '' + Attrset of shell packages to install and add to pkgs.custom overlay (for compatibility across multiple shells). + Both string and attr values will be passed as arguments to writeShellApplicationCompletions + ''; + example = '' + shell.packages = { + myPackage1 = "echo 'Hello, World!'"; + myPackage2 = { + runtimeInputs = [ pkgs.hello ]; + text = "hello --greeting 'Hi'"; + }; + } + ''; + }; + }; + }; +} diff --git a/src/lib.nix b/src/lib.nix index 9fb4299..cc4d4b4 100644 --- a/src/lib.nix +++ b/src/lib.nix @@ -1,4 +1,62 @@ { lib, pkgs, ... }: lib.extend (_: libprev: { + custom = rec { + # taken from https://github.com/iynaix/dotfiles/blob/main/lib.nix + # writeShellApplication with support for completions + writeShellApplicationCompletions = + { + name, + bashCompletion ? null, + zshCompletion ? null, + fishCompletion ? null, + ... + }@shellArgs: + let + inherit (pkgs) writeShellApplication writeTextFile symlinkJoin; + # get the needed arguments for writeShellApplication + app = writeShellApplication (lib.intersectAttrs (lib.functionArgs writeShellApplication) shellArgs); + completions = + lib.optional (bashCompletion != null) (writeTextFile { + name = "${name}.bash"; + destination = "/share/bash-completion/completions/${name}.bash"; + text = bashCompletion; + }) + ++ lib.optional (zshCompletion != null) (writeTextFile { + name = "${name}.zsh"; + destination = "/share/zsh/site-functions/_${name}"; + text = zshCompletion; + }) + ++ lib.optional (fishCompletion != null) (writeTextFile { + name = "${name}.fish"; + destination = "/share/fish/vendor_completions.d/${name}.fish"; + text = fishCompletion; + }); + in + if lib.length completions == 0 then + app + else + symlinkJoin { + inherit name; + inherit (app) meta; + paths = [ app ] ++ completions; + }; + + # taken from https://github.com/iynaix/dotfiles/blob/main/lib.nix + # produces an attrset shell package with completions from either a string / writeShellApplication attrset / package + mkShellPackages = lib.mapAttrs ( + name: value: + if lib.isString value then + pkgs.writeShellApplication { + inherit name; + text = value; + } + # packages + else if lib.isDerivation value then + value + # attrs to pass to writeShellApplication + else + writeShellApplicationCompletions (value // { inherit name; }) + ); + }; }) diff --git a/src/nixos/default.nix b/src/nixos/default.nix index 3fe9fb3..5817136 100644 --- a/src/nixos/default.nix +++ b/src/nixos/default.nix @@ -7,7 +7,55 @@ { imports = [ - ./users.nix ./impermanence.nix + ./nix.nix + ./users.nix ]; + + options.custom = with lib; { + shell = { + packages = mkOption { + type = + with types; + attrsOf (oneOf [ + str + attrs + package + ]); + apply = custom.mkShellPackages; + default = { }; + description = '' + Attrset of shell packages to install and add to pkgs.custom overlay (for compatibility across multiple shells). + Both string and attr values will be passed as arguments to writeShellApplicationCompletions + ''; + example = '' + shell.packages = { + myPackage1 = "echo 'Hello, World!'"; + myPackage2 = { + runtimeInputs = [ pkgs.hello ]; + text = "hello --greeting 'Hi'"; + }; + } + ''; + }; + }; + symlinks = mkOption { + type = types.attrsOf types.str; + default = { }; + description = "Symlinks to create in the format { dest = src;}"; + }; + }; + + config = { + environment = { + systemPackages = with pkgs; [ + curl + eza + neovim + yazi + ripgrep + htop + ] ++ (lib.attrValues config.custom.shell.packages); + }; + }; } diff --git a/src/nixos/nix.nix b/src/nixos/nix.nix new file mode 100644 index 0000000..08ff4a1 --- /dev/null +++ b/src/nixos/nix.nix @@ -0,0 +1,163 @@ +{ + config, + host, + inputs, + lib, + pkgs, + self, + user, + ... +}: +let + dots = "/persist${config.hm.home.homeDirectory}/Code/nix-config"; +in +{ + # execute shebangs that assume hardcoded shell paths + services.envfs.enable = true; + + # run unpatched binaries on nixos + programs.nix-ld.enable = true; + + environment = { + # for nixlang / nixpkgs + systemPackages = with pkgs; [ + nix-init + nix-update + nixfmt-rfc-style + ]; + }; + + # make a symlink of flake within the generation (e.g. /run/current-system/src) + system.extraSystemBuilderCmds = "ln -s ${self.sourceInfo.outPath} $out/src"; + + systemd.tmpfiles.rules = [ + # cleanup nixpkgs-review cache on boot + "D! ${config.hm.xdg.cacheHome}/nixpkgs-review 1755 ${user} users 1d" + # cleanup channels so nix stops complaining + "D! /nix/var/nix/profiles/per-user/root 1755 root root 1d" + ]; + + custom.shell.packages = + { + # list all installed packages + nix-list-packages = { + text = + let + allPkgs = map (p: p.name) ( + config.environment.systemPackages ++ config.users.users.${user}.packages ++ config.hm.home.packages + ); + in + ''sort -ui <<< "${lib.concatLines allPkgs}"''; + }; + }; + + nix = + let + nixPath = [ + "nixpkgs=flake:nixpkgs" + # "/nix/var/nix/profiles/per-user/root/channels" + ]; + in + { + channel.enable = false; + # required for nix-shell -p to work + inherit nixPath; + gc = { + # Automatic garbage collection + automatic = true; + dates = "daily"; + options = "--delete-older-than 7d"; + }; + package = pkgs.nixVersions.latest; + registry = { + nixpkgs-master = { + from = { + type = "indirect"; + id = "nixpkgs-master"; + }; + to = { + type = "github"; + owner = "NixOS"; + repo = "nixpkgs"; + }; + }; + nixpkgs-stable.flake = inputs.nixpkgs-stable; + }; + settings = { + auto-optimise-store = true; # Optimise symlinks + # re-evaluate on every rebuild instead of "cached failure of attribute" error + # eval-cache = false; + # required to be set, for some reason nix.nixPath does not write to nix.conf + nix-path = nixPath; + warn-dirty = false; + # removes ~/.nix-profile and ~/.nix-defexpr + use-xdg-base-directories = true; + + # use flakes + experimental-features = [ + "nix-command" + "flakes" + # "repl-flake" + ]; + substituters = [ + "https://hyprland.cachix.org" + "https://nix-community.cachix.org" + "https://ghostty.cachix.org" + ]; + # allow building and pushing of laptop config from desktop + trusted-users = [ user ]; + trusted-public-keys = [ + "hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc=" + "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" + "ghostty.cachix.org-1:QB389yTa6gTyneehvqG58y0WnHjQOqgnA+wBnpWWxns=" + ]; + }; + # // lib.optionalAttrs (config.nix.package.pname == "lix") { + # repl-overlays = [ ./repl-overlays.nix ]; + # }; + }; + + # better nixos generation label + # https://reddit.com/r/NixOS/comments/16t2njf/small_trick_for_people_using_nixos_with_flakes/k2d0sxx/ + system.nixos.label = lib.concatStringsSep "-" ( + (lib.sort (x: y: x < y) config.system.nixos.tags) + ++ [ "${config.system.nixos.version}.${self.sourceInfo.shortRev or "dirty"}" ] + ); + + # add nixos-option workaround for flakes + # https://github.com/NixOS/nixpkgs/issues/97855#issuecomment-1075818028 + nixpkgs.overlays = [ + (_: prev: { + nixos-option = + let + flake-compat = prev.fetchFromGitHub { + owner = "edolstra"; + repo = "flake-compat"; + rev = "12c64ca55c1014cdc1b16ed5a804aa8576601ff2"; + hash = "sha256-hY8g6H2KFL8ownSiFeMOjwPC8P0ueXpCVEbxgda3pko="; + }; + prefix = ''(import ${flake-compat} { src = ${dots}; }).defaultNix.nixosConfigurations.${host}''; + in + prev.runCommandNoCC "nixos-option" { buildInputs = [ prev.makeWrapper ]; } '' + makeWrapper ${lib.getExe prev.nixos-option} $out/bin/nixos-option \ + --add-flags --config_expr \ + --add-flags "\"${prefix}.config\"" \ + --add-flags --options_expr \ + --add-flags "\"${prefix}.options\"" + ''; + }) + ]; + + # enable man-db cache for fish to be able to find manpages + # https://discourse.nixos.org/t/fish-shell-and-manual-page-completion-nixos-home-manager/15661 + documentation.man.generateCaches = true; + + hm.custom.persist = { + home = { + cache.directories = [ + ".cache/nix" + ".cache/nixpkgs-review" + ]; + }; + }; +}