Move programs to modules

This commit is contained in:
Jordan Holt 2023-01-02 22:08:18 +00:00
parent 046eb42dd3
commit e45609ea4b
Signed by: jordan
GPG Key ID: B8CFFF61F1CCF520
23 changed files with 586 additions and 250 deletions

1
README.md Normal file
View File

@ -0,0 +1 @@
# nix-config

View File

@ -9,20 +9,38 @@
};
};
outputs = inputs@{ nixpkgs, home-manager, ... }: {
nixosConfigurations = {
atlas = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
outputs = inputs @ { nixpkgs, home-manager, ... }:
let
inherit (lib) attrValues;
inherit (lib.my) mapModules mapModulesRec;
modules = [
./hosts/atlas/configuration.nix
home-manager.nixosModules.home-manager {
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.users.jordan = import ./users/jordan/home.nix;
}
];
mkPkgs = pkgs:
import pkgs {
config.allowUnfree = true;
};
pkgs = mkPkgs nixpkgs;
lib = nixpkgs.lib.extend (self: super: {
my = import ./lib {
inherit pkgs inputs;
lib = self;
};
});
in {
lib = lib.my;
nixosModules = mapModulesRec ./modules import;
nixosConfigurations = {
atlas = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
inputs.home-manager.nixosModules.home-manager
(import ./modules)
./hosts/atlas
];
specialArgs = { inherit lib inputs; };
};
};
};
};
}

View File

@ -1,132 +0,0 @@
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running nixos-help).
{ config, pkgs, ... }:
{
imports =
[ # Include the results of the hardware scan.
./hardware-configuration.nix
];
# Bootloader.
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
boot.loader.efi.efiSysMountPoint = "/boot/efi";
networking.hostName = "atlas"; # Define your hostname.
# networking.wireless.enable = true; # Enables wireless support via wpa_supplicant.
# Configure network proxy if necessary
# networking.proxy.default = "http://user:password@proxy:port/";
# networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";
# Enable networking
networking.networkmanager.enable = true;
# Set your time zone.
time.timeZone = "Europe/London";
# Select internationalisation properties.
i18n.defaultLocale = "en_GB.UTF-8";
i18n.extraLocaleSettings = {
LC_ADDRESS = "en_GB.UTF-8";
LC_IDENTIFICATION = "en_GB.UTF-8";
LC_MEASUREMENT = "en_GB.UTF-8";
LC_MONETARY = "en_GB.UTF-8";
LC_NAME = "en_GB.UTF-8";
LC_NUMERIC = "en_GB.UTF-8";
LC_PAPER = "en_GB.UTF-8";
LC_TELEPHONE = "en_GB.UTF-8";
LC_TIME = "en_GB.UTF-8";
};
# Enable the X11 windowing system.
services.xserver.enable = true;
# Enable the GNOME Desktop Environment.
services.xserver.displayManager.gdm.enable = true;
services.xserver.desktopManager.gnome.enable = true;
# Configure keymap in X11
services.xserver = {
layout = "gb";
xkbVariant = "";
};
# Configure console keymap
console.keyMap = "uk";
# Enable CUPS to print documents.
services.printing.enable = true;
# Enable sound with pipewire.
sound.enable = true;
hardware.pulseaudio.enable = false;
security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
# If you want to use JACK applications, uncomment this
#jack.enable = true;
# use the example session manager (no others are packaged yet so this is enabled by default,
# no need to redefine it in your config for now)
#media-session.enable = true;
};
nix.package = pkgs.nixFlakes;
nix.extraOptions = ''
experimental-features = nix-command flakes
'';
# Enable touchpad support (enabled default in most desktopManager).
# services.xserver.libinput.enable = true;
users.defaultUserShell = pkgs.zsh;
# Define a user account. Don't forget to set a password with passwd.
users.users.jordan = {
isNormalUser = true;
description = "Jordan Holt";
extraGroups = [ "networkmanager" "wheel" ];
useDefaultShell = true;
};
# Allow unfree packages
nixpkgs.config.allowUnfree = true;
# List packages installed in system profile. To search, run:
# $ nix search wget
environment.systemPackages = with pkgs; [
# vim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default.
# wget
];
# Some programs need SUID wrappers, can be configured further or are
# started in user sessions.
# programs.mtr.enable = true;
# List services that you want to enable:
# Enable the OpenSSH daemon.
# services.openssh.enable = true;
# Open ports in the firewall.
# networking.firewall.allowedTCPPorts = [ ... ];
# networking.firewall.allowedUDPPorts = [ ... ];
# Or disable the firewall altogether.
# networking.firewall.enable = false;
# This value determines the NixOS release from which the default
# settings for stateful data, like file locations and database versions
# on your system were taken. Its perfectly fine and recommended to leave
# this value at the release version of the first install of this system.
# Before changing this value read the documentation for this option
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
system.stateVersion = "22.11"; # Did you read the comment?
}

45
hosts/atlas/default.nix Normal file
View File

@ -0,0 +1,45 @@
{ config, lib, pkgs, ... }:
with lib.my;
{
imports = [
./hardware-configuration.nix
../desktop.nix
];
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
boot.loader.efi.efiSysMountPoint = "/boot/efi";
networking.hostName = "atlas";
networking.networkmanager.enable = true;
nix.package = pkgs.nixFlakes;
nix.extraOptions = ''
experimental-features = nix-command flakes
'';
users.defaultUserShell = pkgs.zsh;
system.stateVersion = "22.11";
modules = {
desktop = {
firefox.enable = true;
};
editors = {
neovim.enable = true;
vscode.enable = true;
};
security = {
gpg.enable = true;
pass.enable = true;
};
shell = {
fzf.enable = true;
git.enable = true;
nnn.enable = true;
zsh.enable = true;
};
};
}

36
hosts/desktop.nix Normal file
View File

@ -0,0 +1,36 @@
{ config, lib, pkgs, ... }:
with lib;
with lib.my;
{
time.timeZone = "Europe/London";
i18n.defaultLocale = "en_GB.UTF-8";
i18n.extraLocaleSettings = {
LC_ADDRESS = "en_GB.UTF-8";
LC_IDENTIFICATION = "en_GB.UTF-8";
LC_MEASUREMENT = "en_GB.UTF-8";
LC_MONETARY = "en_GB.UTF-8";
LC_NAME = "en_GB.UTF-8";
LC_NUMERIC = "en_GB.UTF-8";
LC_PAPER = "en_GB.UTF-8";
LC_TELEPHONE = "en_GB.UTF-8";
LC_TIME = "en_GB.UTF-8";
};
console.keyMap = "uk";
services.printing.enable = true;
sound.enable = true;
hardware.pulseaudio.enable = false;
security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
};
modules.desktop.gnome.enable = true;
}

26
lib/attrs.nix Normal file
View File

@ -0,0 +1,26 @@
{ lib, ... }:
with builtins;
with lib;
rec {
# attrsToList
attrsToList = attrs:
mapAttrsToList (name: value: { inherit name value; }) attrs;
# mapFilterAttrs ::
# (name -> value -> bool)
# (name -> value -> { name = any; value = any; })
# attrs
mapFilterAttrs = pred: f: attrs: filterAttrs pred (mapAttrs' f attrs);
# Generate an attribute set by mapping a function over a list of values.
genAttrs' = values: f: listToAttrs (map f values);
# anyAttrs :: (name -> value -> bool) attrs
anyAttrs = pred: attrs:
any (attr: pred attr.name attr.value) (attrsToList attrs);
# countAttrs :: (name -> value -> bool) attrs
countAttrs = pred: attrs:
count (attr: pred attr.name attr.value) (attrsToList attrs);
}

19
lib/default.nix Normal file
View File

@ -0,0 +1,19 @@
{ inputs, lib, pkgs, ... }:
let
inherit (lib) makeExtensible attrValues foldr;
inherit (modules) mapModules;
modules = import ./modules.nix {
inherit lib;
self.attrs = import ./attrs.nix { inherit lib; self = {}; };
};
mylib = makeExtensible (self:
with self; mapModules ./.
(file: import file { inherit self lib pkgs inputs; }));
in
mylib.extend
(self: super:
foldr (a: b: a // b) {} (attrValues super))

53
lib/modules.nix Normal file
View File

@ -0,0 +1,53 @@
{ self, lib, ... }:
let
inherit (builtins) attrValues readDir pathExists concatLists;
inherit (lib) id mapAttrsToList filterAttrs hasPrefix hasSuffix nameValuePair removeSuffix;
inherit (self.attrs) mapFilterAttrs;
in
rec {
mapModules = dir: fn:
mapFilterAttrs
(n: v:
v != null &&
!(hasPrefix "_" n))
(n: v:
let path = "${toString dir}/${n}"; in
if v == "directory" && pathExists "${path}/default.nix"
then nameValuePair n (fn path)
else if v == "regular" &&
n != "default.nix" &&
hasSuffix ".nix" n
then nameValuePair (removeSuffix ".nix" n) (fn path)
else nameValuePair "" null)
(readDir dir);
mapModules' = dir: fn:
attrValues (mapModules dir fn);
mapModulesRec = dir: fn:
mapFilterAttrs
(n: v:
v != null &&
!(hasPrefix "_" n))
(n: v:
let path = "${toString dir}/${n}"; in
if v == "directory"
then nameValuePair n (mapModulesRec path fn)
else if v == "regular" && n != "default.nix" && hasSuffix ".nix" n
then nameValuePair (removeSuffix ".nix" n) (fn path)
else nameValuePair "" null)
(readDir dir);
mapModulesRec' = dir: fn:
let
dirs =
mapAttrsToList
(k: _: "${dir}/${k}")
(filterAttrs
(n: v: v == "directory" && !(hasPrefix "_" n))
(readDir dir));
files = attrValues (mapModules dir id);
paths = files ++ concatLists (map (d: mapModulesRec' d id) dirs);
in map fn paths;
}

25
lib/nixos.nix Normal file
View File

@ -0,0 +1,25 @@
{ inputs, lib, pkgs, ... }:
with lib;
with lib.my;
let sys = "x86_64-linux";
in {
mkHost = path: attrs @ { system ? sys, ... }:
nixosSystem {
inherit system;
specialArgs = { inherit lib inputs system; };
modules = [
{
nixpkgs.pkgs = pkgs;
networking.hostName = mkDefault (removeSuffix ".nix" (baseNameOf path));
}
(filterAttrs (n: v: !elem n [ "system" ]) attrs)
../. # /default.nix
(import path)
];
};
mapHosts = dir: attrs @ { system ? system, ... }:
mapModules dir
(hostPath: mkHost hostPath attrs);
}

35
lib/options.nix Normal file
View File

@ -0,0 +1,35 @@
{ lib, ... }:
let
inherit (lib) mkOption types;
in
rec {
mkOpt = type: default:
mkOption { inherit type default; };
mkOpt' = type: default: description:
mkOption { inherit type default description; };
mkBoolOpt = default: mkOption {
inherit default;
type = types.bool;
example = true;
};
mkStringOpt = default: mkOption {
inherit default;
type = types.lines;
example = "";
};
mkListOfStringOpt = default: mkOption {
inherit default;
type = types.listOf types.lines;
example = [ "a" "b" "c" ];
};
mkPath = path:
if path != null
then toString path
else "";
}

15
modules/default.nix Normal file
View File

@ -0,0 +1,15 @@
{
imports = [
./options.nix
./desktop/firefox.nix
./desktop/gnome.nix
./editors/neovim.nix
./editors/vscode.nix
./security/gpg.nix
./security/pass.nix
./shell/fzf.nix
./shell/git.nix
./shell/nnn.nix
./shell/zsh.nix
];
}

View File

@ -0,0 +1,16 @@
{ config, lib, pkgs, ... }:
with lib;
with lib.my;
let cfg = config.modules.desktop.firefox;
in {
options.modules.desktop.firefox = {
enable = mkBoolOpt false;
};
config = mkIf cfg.enable {
home.programs.firefox = {
enable = true;
};
};
}

37
modules/desktop/gnome.nix Normal file
View File

@ -0,0 +1,37 @@
{ config, lib, pkgs, ... }:
with lib;
with lib.my;
let cfg = config.modules.desktop.gnome;
in {
options.modules.desktop.gnome = {
enable = mkBoolOpt false;
};
config = mkIf cfg.enable {
services.xserver = {
enable = true;
displayManager.gdm.enable = true;
desktopManager.gnome.enable = true;
};
fonts.fonts = with pkgs; [
noto-fonts
ubuntu_font_family
];
environment.systemPackages = with pkgs; [
bind
bmon
fd
ffmpeg
iotop
ripgrep
rsync
tcpdump
tokei
tree
wl-clipboard
];
};
}

View File

@ -0,0 +1,18 @@
{ config, lib, pkgs, ... }:
with lib;
with lib.my;
let cfg = config.modules.editors.neovim;
in {
options.modules.editors.neovim = {
enable = mkBoolOpt false;
};
config = mkIf cfg.enable {
home.programs.neovim = {
enable = true;
vimAlias = true;
vimdiffAlias = true;
};
};
}

View File

@ -0,0 +1,16 @@
{ config, lib, pkgs, ... }:
with lib;
with lib.my;
let cfg = config.modules.editors.vscode;
in {
options.modules.editors.vscode = {
enable = mkBoolOpt false;
};
config = mkIf cfg.enable {
home.programs.vscode = {
enable = true;
};
};
}

69
modules/options.nix Normal file
View File

@ -0,0 +1,69 @@
{ config, options, lib, home-manager, ... }:
with lib;
with lib.my;
{
options = with types; {
user = mkOpt attrs { };
home = {
configFile = mkOpt' attrs { } "Files to place in $XDG_CONFIG_HOME";
dataFile = mkOpt' attrs { } "Files to place in $XDG_DATA_HOME";
file = mkOpt' attrs { } "Files to place directly in $HOME";
packages = mkOpt' attrs { } "User-level installed packages";
programs = mkOpt' attrs { } "Programs managed directly from home-manager";
services = mkOpt' attrs { } "Services managed directly from home-manager";
};
env = mkOption {
type = attrsOf (oneOf [ str path (listOf (either str path)) ]);
apply = mapAttrs (n: v:
if isList v then
concatMapStringsSep ":" (x: toString x) v
else
(toString v));
default = { };
description = "";
};
};
config = {
user =
let user = builtins.getEnv "USER";
name = if elem user [ "" "root" ] then "jordan" else user;
in {
inherit name;
isNormalUser = true;
extraGroups = [ "networkmanager" "wheel" ];
description = "Jordan Holt";
useDefaultShell = true;
home = "/home/${name}";
group = "users";
uid = 1000;
};
home-manager = {
useGlobalPkgs = true;
useUserPackages = true;
users.${config.user.name} = {
home = {
file = mkAliasDefinitions options.home.file;
stateVersion = config.system.stateVersion;
};
home.packages = mkAliasDefinitions options.home.packages;
programs = mkAliasDefinitions options.home.programs;
services = mkAliasDefinitions options.home.services;
xdg = {
enable = true;
configFile = mkAliasDefinitions options.home.configFile;
dataFile = mkAliasDefinitions options.home.dataFile;
};
};
};
users.users.${config.user.name} = mkAliasDefinitions options.user;
nixpkgs.config.allowUnfree = true;
};
}

21
modules/security/gpg.nix Normal file
View File

@ -0,0 +1,21 @@
{ config, lib, pkgs, ... }:
with lib;
with lib.my;
let cfg = config.modules.security.gpg;
in {
options.modules.security.gpg = {
enable = mkBoolOpt false;
};
config = mkIf cfg.enable {
home.programs.gpg = {
enable = true;
};
home.services.gpg-agent = {
enable = true;
enableSshSupport = true;
};
};
}

17
modules/security/pass.nix Normal file
View File

@ -0,0 +1,17 @@
{ config, lib, pkgs, ... }:
with lib;
with lib.my;
let cfg = config.modules.security.pass;
in {
options.modules.security.pass = {
enable = mkBoolOpt false;
};
config = mkIf cfg.enable {
home.programs.password-store = {
enable = true;
package = pkgs.pass.withExtensions (exts: [ exts.pass-otp ]);
};
};
}

21
modules/shell/fzf.nix Normal file
View File

@ -0,0 +1,21 @@
{ config, lib, pkgs, ... }:
with lib;
with lib.my;
let cfg = config.modules.shell.fzf;
in {
options.modules.shell.fzf = {
enable = mkBoolOpt false;
};
config = mkIf cfg.enable {
home.packages = with pkgs; [
bind
];
home.programs.fzf = {
enable = true;
enableZshIntegration = true;
defaultCommand = "fd --type f --hidden --follow --exclude .git";
};
};
}

34
modules/shell/git.nix Normal file
View File

@ -0,0 +1,34 @@
{ config, lib, pkgs, ... }:
with lib;
with lib.my;
let cfg = config.modules.shell.git;
in {
options.modules.shell.git = {
enable = mkBoolOpt false;
};
config = mkIf cfg.enable {
home.programs.git = {
enable = true;
aliases = {
amend = "commit --amend";
lg = "log --color --graph --abbrev-commit --";
ls = "ls-files";
unadd = "reset HEAD";
undo-commit = "reset --soft \"HEAD^\"";
};
userEmail = "jordan@vimium.com";
userName = "Jordan Holt";
signing = {
key = "B8CFFF61F1CCF520";
signByDefault = true;
};
extraConfig = {
rebase.autosquash = true;
push.default = "current";
pull.rebase = true;
};
};
};
}

16
modules/shell/nnn.nix Normal file
View File

@ -0,0 +1,16 @@
{ config, lib, pkgs, ... }:
with lib;
with lib.my;
let cfg = config.modules.shell.nnn;
in {
options.modules.shell.nnn = {
enable = mkBoolOpt false;
};
config = mkIf cfg.enable {
home.programs.nnn = {
enable = true;
};
};
}

35
modules/shell/zsh.nix Normal file
View File

@ -0,0 +1,35 @@
{ config, lib, pkgs, ... }:
with lib;
with lib.my;
let cfg = config.modules.shell.zsh;
in {
options.modules.shell.zsh = {
enable = mkBoolOpt false;
};
config = mkIf cfg.enable {
home.packages = with pkgs; [
zsh-autosuggestions
zsh-fast-syntax-highlighting
zsh-history-substring-search
];
home.programs.zsh = {
enable = true;
enableCompletion = true;
shellAliases = {
cp = "cp -iv";
mv = "mv -iv";
rm = "rm -v";
mkdir = "mkdir -v";
ls = "ls -h --color=auto --group-directories-first";
e = "nvim";
f = "nnn";
g = "git";
n = "nnn";
v = "nvim";
};
};
};
}

View File

@ -1,105 +0,0 @@
{ config, pkgs, ... }:
{
programs.home-manager.enable = true;
home.username = "jordan";
home.homeDirectory = "/home/jordan";
home.stateVersion = "22.11";
home.packages = with pkgs; [
bind
bmon
fd
ffmpeg
iotop
noto-fonts
ripgrep
rsync
tcpdump
tokei
tree
ubuntu_font_family
wl-clipboard
zsh-autosuggestions
zsh-fast-syntax-highlighting
zsh-history-substring-search
];
programs.gpg.enable = true;
programs.firefox = {
enable = true;
};
programs.fzf = {
enable = true;
enableZshIntegration = true;
defaultCommand = "fd --type f --hidden --follow --exclude .git";
};
programs.git = {
enable = true;
aliases = {
amend = "commit --amend";
lg = "log --color --graph --abbrev-commit --";
ls = "ls-files";
unadd = "reset HEAD";
undo-commit = "reset --soft \"HEAD^\"";
};
userEmail = "jordan@vimium.com";
userName = "Jordan Holt";
signing = {
key = "B8CFFF61F1CCF520";
signByDefault = true;
};
extraConfig = {
rebase.autosquash = true;
push.default = "current";
pull.rebase = true;
};
};
programs.neovim = {
enable = true;
vimAlias = true;
vimdiffAlias = true;
};
programs.nnn = {
enable = true;
};
programs.password-store = {
enable = true;
package = pkgs.pass.withExtensions (exts: [ exts.pass-otp ]);
};
programs.yt-dlp = {
enable = true;
extraConfig = ''
--ignore-errors
-o ~/Videos/%(title)s.%(ext)s
'';
};
programs.zsh = {
enable = true;
enableCompletion = true;
shellAliases = {
cp = "cp -iv";
mv = "mv -iv";
rm = "rm -v";
mkdir = "mkdir -v";
ls = "ls -h --color=auto --group-directories-first";
e = "nvim";
f = "nnn";
g = "git";
n = "nnn";
v = "nvim";
};
};
xdg.enable = true;
}