diff --git a/nix/configModule/alacritty.nix b/nix/configModule/alacritty.nix new file mode 100644 index 0000000..e69f9b2 --- /dev/null +++ b/nix/configModule/alacritty.nix @@ -0,0 +1,50 @@ +{ config +, proj_root +, myLib +, ... +}: +let + inherit (myLib) fromYaml; + actualConfig = fromYaml (builtins.readFile "${proj_root}//alacritty/alacritty.yml"); + cfg = config.base.alacritty; +in +{ + options.base.alacritty = + { + font.family = myLib.mkOption { + type = myLib.types.singleLineStr; + default = actualConfig.font.normal.family; + description = '' + The font family for Alacritty + ''; + example = "DroidSansMono NF"; + }; + enable = myLib.mkOption { + type = myLib.types.bool; + default = true; + description = '' + Enables alacritty + ''; + example = true; + }; + _actualConfig = myLib.mkOption { + type = myLib.types.attrs; + visible = false; + default = actualConfig; + description = "underlying default config"; + }; + additionalConfigPath = myLib.mkOption { + type = myLib.types.nullOr myLib.types.path; + visible = false; + default = null; + description = "impurely write our alacritty.yml to this path"; + }; + }; + + config.programs.alacritty = { + enable = cfg.enable; + settings = myLib.recursiveUpdate actualConfig { + font.normal.family = cfg.font.family; + }; + }; +} diff --git a/nix/configModule/default.nix b/nix/configModule/default.nix new file mode 100644 index 0000000..5621907 --- /dev/null +++ b/nix/configModule/default.nix @@ -0,0 +1,12 @@ +{ + mkModuleArgs = import ./mkModuleArgs.nix; + modules = [ + ./alacritty.nix + ./git.nix + ./ssh.nix + ./shells.nix + { + config.programs.home-manager.enable = true; + } + ]; +} diff --git a/nix/configModule/git.nix b/nix/configModule/git.nix new file mode 100644 index 0000000..8db840b --- /dev/null +++ b/nix/configModule/git.nix @@ -0,0 +1,80 @@ +{ config +, myLib +, ... +}: +let + cfg = config.base.git; + baseAliases = { + a = "add"; + c = "commit"; + ca = "commit --amend"; + cm = "commit -m"; + lol = "log --graph --decorate --pretty=oneline --abbrev-commit"; + lola = "log --graph --decorate --pretty=oneline --abbrev-commit --all"; + sts = "status"; + co = "checkout"; + b = "branch"; + }; +in +{ + options.base.git = { + aliases = myLib.mkOption { + type = myLib.types.attrs; + default = { }; + example = baseAliases; + description = '' + Additional git aliases. This settings comes with base configuration. + Redeclaring the base config will override the values. + ''; # TODO: Add baseAliases as string here (builtins.toString doesn't work) + }; + name = myLib.mkOption { + type = myLib.types.str; + default = "Pegasust"; + description = "Git username that appears on commits"; + example = "Pegasust"; + }; + email = myLib.mkOption { + type = myLib.types.str; + default = "pegasucksgg@gmail.com"; + example = "peagsucksgg@gmail.com"; + description = "Git email that appears on commits"; + }; + ignores = myLib.mkOption { + type = myLib.types.listOf myLib.types.str; + default = [ + ".vscode" # vscode settings + ".direnv" # .envrc cached outputs + ]; + description = '' + .gitignore patterns that are applied in every repository. + This is useful for IDE-specific settings. + ''; + example = [ ".direnv" "node_modules" ]; + }; + enable = myLib.mkOption { + type = myLib.types.bool; + default = true; + description = '' + Enables git + ''; + example = false; + }; + credentialCacheTimeoutSeconds = myLib.mkOption { + type = myLib.types.int; + default = 3000; + description = "Credential cache (in-memory store) for Git in seconds."; + example = 3000; + }; + }; +# TODO : anyway to override configuration? + config.programs.git = { + inherit (cfg) enable ignores; + userName = cfg.name; + userEmail = cfg.email; + aliases = baseAliases // cfg.aliases; + extraConfig = { + credential.helper = "cache --timeout=${builtins.toString cfg.credentialCacheTimeoutSeconds}"; + }; + lfs.enable = true; + }; +} diff --git a/nix/configModule/gitea.service.nix b/nix/configModule/gitea.service.nix new file mode 100644 index 0000000..e69de29 diff --git a/nix/configModule/mkModuleArgs.nix b/nix/configModule/mkModuleArgs.nix new file mode 100644 index 0000000..358470f --- /dev/null +++ b/nix/configModule/mkModuleArgs.nix @@ -0,0 +1,16 @@ +# This shows the config fields that these modules are expected to have +# usage: [extra]specialArgs = mkModuleArgs {pkgs, lib,...} @ inputs +# Note that mkModuleArgs also recursively merges `inputs` +{ pkgs +, lib ? pkgs.lib +, ... +}@inputs: +let + recursiveUpdate = lib.recursiveUpdate; + _lib = recursiveUpdate lib (import ../../lib { inherit pkgs lib; }); +in +# TODO: Unpollute inputs +recursiveUpdate inputs { + proj_root = builtins.toString ./../../..; + myLib = _lib; +} diff --git a/nix/configModule/neovim.nix b/nix/configModule/neovim.nix new file mode 100644 index 0000000..e69de29 diff --git a/nix/configModule/shells.nix b/nix/configModule/shells.nix new file mode 100644 index 0000000..8f034d2 --- /dev/null +++ b/nix/configModule/shells.nix @@ -0,0 +1,89 @@ +# Configurations for shell stuffs. +# Should probably be decoupled even more +{ config +, proj_root +, myLib +, ... +}: +let cfg = config.base.shells; +in +{ + options.base.shells = { + enable = myLib.mkOption { + type = myLib.types.bool; + description = "Enable umbrella shell configuration"; + default = true; + example = false; + }; + # TODO: Support shell-specific init + shellInitExtra = myLib.mkOption { + type = myLib.types.str; + description = "Extra shell init. The syntax should be sh-compliant"; + default = ""; + example = '' + # X11 support for WSL + export DISPLAY=$(ip route list default | awk '{print $3}'):0 + export LIBGL_ALWAYS_INDIRECT=1 + ''; + }; + shellAliases = myLib.mkOption { + type = myLib.types.attrs; + description = "Shell command aliases"; + default = { }; + example = { + nixGL = "nixGLIntel"; + }; + }; + }; + config = myLib.mkIf cfg.enable { + xdg.configFile."starship.toml".source = "${proj_root}//starship/starship.toml"; + # nix: Propagates the environment with packages and vars when enter (children of) + # a directory with shell.nix-compatible and .envrc + programs.direnv = { + enable = true; + nix-direnv.enable = true; + # nix-direnv.enableFlakes = true; # must remove. this will always be supported. + }; + # z as smarter cd + programs.zoxide = { + enable = true; + enableZshIntegration = true; + }; + programs.tmux = { + enable = true; + extraConfig = builtins.readFile "${proj_root}/tmux/tmux.conf"; + }; + programs.exa = { + enable = true; + enableAliases = true; + }; + programs.starship = { + enable = true; + enableZshIntegration = true; + }; + programs.fzf.enable = true; + programs.bash = { + enable = true; + enableCompletion = true; + initExtra = cfg.shellInitExtra or ""; + }; + programs.zsh = { + enable = true; + enableCompletion = true; + enableAutosuggestions = true; + shellAliases = { + nix-rebuild = "sudo nixos-rebuild switch"; + hm-switch = "home-manager switch --flake"; + } // (cfg.shellAliases or { }); + history = { + size = 10000; + path = "${config.xdg.dataHome}/zsh/history"; + }; + oh-my-zsh = { + enable = true; + plugins = [ "git" "sudo" "command-not-found" "gitignore" "ripgrep" "rust" ]; + }; + initExtra = cfg.shellInitExtra or ""; + }; + }; +} diff --git a/nix/configModule/ssh.nix b/nix/configModule/ssh.nix new file mode 100644 index 0000000..aedb1e3 --- /dev/null +++ b/nix/configModule/ssh.nix @@ -0,0 +1,23 @@ +{ config +, proj_root +, myLib +, ... +}: +let cfg = config.base.ssh; +in +{ + options.base.ssh.enable = myLib.mkOption { + type = myLib.types.bool; + default = true; + example = false; + description = '' + Enables SSH + ''; + }; + config.programs.ssh = { + inherit (cfg) enable; + forwardAgent = true; + extraConfig = builtins.readFile "${proj_root}/ssh/config"; + }; +} + diff --git a/nix/configModule/tailscale.service.nix b/nix/configModule/tailscale.service.nix new file mode 100644 index 0000000..e69de29 diff --git a/nix/configModule/vault.service.nix b/nix/configModule/vault.service.nix new file mode 100644 index 0000000..e69de29 diff --git a/nix/configModule/vaultops.nix b/nix/configModule/vaultops.nix new file mode 100644 index 0000000..e69de29 diff --git a/nix/flake.nix b/nix/flake.nix new file mode 100644 index 0000000..e2bf7b7 --- /dev/null +++ b/nix/flake.nix @@ -0,0 +1,36 @@ +{ + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + home-manager = { + url = "github:nix-community/home-manager"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + # useful only when packaging, not really within config zone + flake-utils-plus.url = "github:gytis-ivaskevicius/flake-utils-plus"; + nixgl.url = "github:guibou/nixGL"; + rust-overlay.url = "github:oxalica/rust-overlay"; + # Allows default.nix to call onto flake.nix. Useful for nix eval and automations + flake-compat = { + url = "github:edolstra/flake-compat"; + flake = false; + }; + naersk.url = "gihub:nix-community/naersk"; + }; + outputs = { nixpkgs, ... } @ inputs: + let + # init config + overlays = [ nixgl.overlay rust-overlay.overlays.default ]; + pkgs = import nixpkgs { inherit overlays; }; + _lib = pkgs.lib; + lib = _lib.recursiveUpdate _lib import ./lib { inherit pkgs; }; + + # module collecting + hosts = import ./hosts { inherit pkgs lib; }; + users = import ./users { inherit pkgs lib; }; + in + { + inherit pkgs lib overlays; + nixosConfigurations = hosts; + homeConfigurations = users; + }; +} diff --git a/nix/hardwareConfig/Felia.nix b/nix/hardwareConfig/Felia.nix new file mode 100644 index 0000000..97c93fb --- /dev/null +++ b/nix/hardwareConfig/Felia.nix @@ -0,0 +1,80 @@ +# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ config, lib, pkgs, modulesPath, ... }: + +{ + imports = [ ]; + + boot.initrd.availableKernelModules = [ ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ ]; + boot.extraModulePackages = [ ]; + + ## NOTE: These filesystems are mounted by a wrapper script from nix-wsl + + # fileSystems."/" = + # { + # device = "/dev/sdc"; + # fsType = "ext4"; + # }; + # + # fileSystems."/mnt/wsl" = + # { + # device = "tmpfs"; + # fsType = "tmpfs"; + # }; + # + # fileSystems."/mnt/wsl/docker-desktop/shared-sockets/guest-services" = + # { + # device = "none"; + # fsType = "tmpfs"; + # }; + # + # fileSystems."/usr/lib/wsl/drivers" = + # { + # device = "drivers"; + # fsType = "drvfs"; + # }; + # + # fileSystems."/usr/lib/wsl/lib" = + # { + # device = "lib"; + # fsType = "drvfs"; + # }; + + fileSystems."/mnt/c" = + { + device = "C:"; + fsType = "drvfs"; + }; + + fileSystems."/mnt/d" = + { + device = "D:"; + fsType = "drvfs"; + }; + + fileSystems."/mnt/f" = + { + device = "F:"; + fsType = "drvfs"; + }; + + swapDevices = [ ]; + + # Enables DHCP on each ethernet and wireless interface. In case of scripted networking + # (the default) this is the recommended approach. When using systemd-networkd it's + # still possible to use this option, but it's recommended to use it in conjunction + # with explicit per-interface declarations with `networking.interfaces..useDHCP`. + networking.useDHCP = lib.mkDefault true; + # networking.interfaces.bond0.useDHCP = lib.mkDefault true; + # networking.interfaces.bonding_masters.useDHCP = lib.mkDefault true; + # networking.interfaces.dummy0.useDHCP = lib.mkDefault true; + # networking.interfaces.eth0.useDHCP = lib.mkDefault true; + # networking.interfaces.sit0.useDHCP = lib.mkDefault true; + # networking.interfaces.tunl0.useDHCP = lib.mkDefault true; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; +} diff --git a/nix/hardwareConfig/default.nix b/nix/hardwareConfig/default.nix new file mode 100644 index 0000000..3fd6629 --- /dev/null +++ b/nix/hardwareConfig/default.nix @@ -0,0 +1,18 @@ +{ lib # require extended lib +, config +, pkgs +, modulePaths +, ... +}@inputs: +# Yields {nix = import ./nyx.nix inputs; ...} +# TODO: use something that can detect .nix into a list for auto adding. Remember to filter out default.nix +lib.exportWithInputs ( + [ + ./nyx.nix + ./Felia.nix + ./lizzi.nix + ./prince.nix + ] + inputs +) + diff --git a/nix/hardwareConfig/lizzi.nix b/nix/hardwareConfig/lizzi.nix new file mode 100644 index 0000000..2a955e9 --- /dev/null +++ b/nix/hardwareConfig/lizzi.nix @@ -0,0 +1,49 @@ +# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ config, lib, pkgs, modulesPath, ... }: +{ + imports = + [ + (modulesPath + "/profiles/qemu-guest.nix") + ]; + + boot.initrd.availableKernelModules = [ "virtio_pci" "virtio_scsi" "ahci" "sd_mod" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelParams = [ "console=ttyS0,19200n8" ]; + boot.loader.grub.extraConfig = '' + serial --speed=19200 --unit=0 --word=8 --parity=no --stop=1 + terminal_input serial; + terminal_output serial + ''; + boot.loader.grub.forceInstall = true; + boot.loader.grub.device = "nodev"; + boot.loader.timeout = 10; + boot.kernelModules = [ ]; + boot.extraModulePackages = [ ]; + + fileSystems = { + "/" = { + device = "/dev/sda"; + fsType = "ext4"; + }; + # Assume Linode volume "gitea" exists, mount it to '/gitea"' + "/gitea" = { + device = "/dev/disk/by-id/scsi-0Linode_Volume_gitea"; + fsType = "ext4"; + }; + }; + + swapDevices = + [{ device = "/dev/sdb"; }]; + + # Enables DHCP on each ethernet and wireless interface. In case of scripted networking + # (the default) this is the recommended approach. When using systemd-networkd it's + # still possible to use this option, but it's recommended to use it in conjunction + # with explicit per-interface declarations with `networking.interfaces..useDHCP`. + networking.useDHCP = lib.mkDefault true; + # networking.interfaces.enp0s5.useDHCP = lib.mkDefault true; + + hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; +} + diff --git a/nix/hardwareConfig/nyx.nix b/nix/hardwareConfig/nyx.nix new file mode 100644 index 0000000..36b63dd --- /dev/null +++ b/nix/hardwareConfig/nyx.nix @@ -0,0 +1,42 @@ +# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ config, lib, pkgs, modulesPath, ... }: + +{ + imports = + [ (modulesPath + "/profiles/qemu-guest.nix") + ]; + + boot.initrd.availableKernelModules = [ "virtio_pci" "virtio_scsi" "ahci" "sd_mod" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ ]; + boot.extraModulePackages = [ ]; + + boot.kernelParams = ["console=ttyS0,19200n8"]; + boot.loader.grub.extraConfig = '' + serial --speed=19200 --unit=0 --word=8 --parity=no --stop=1 + terminal_input serial; + terminal_output serial; + ''; + boot.loader.grub.forceInstall = true; + boot.loader.grub.device = "nodev"; + boot.loader.timeout = 10; + fileSystems."/" = + { device = "/dev/sda"; + fsType = "ext4"; + }; + + swapDevices = + [ { device = "/dev/sdb"; } + ]; + + # Enables DHCP on each ethernet and wireless interface. In case of scripted networking + # (the default) this is the recommended approach. When using systemd-networkd it's + # still possible to use this option, but it's recommended to use it in conjunction + # with explicit per-interface declarations with `networking.interfaces..useDHCP`. + networking.useDHCP = lib.mkDefault true; + # networking.interfaces.enp0s5.useDHCP = lib.mkDefault true; + + hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; +} diff --git a/nix/hardwareConfig/prince.nix b/nix/hardwareConfig/prince.nix new file mode 100644 index 0000000..9fe8c60 --- /dev/null +++ b/nix/hardwareConfig/prince.nix @@ -0,0 +1 @@ +inputs: {} diff --git a/nix/hosts/default.nix b/nix/hosts/default.nix new file mode 100644 index 0000000..75bee19 --- /dev/null +++ b/nix/hosts/default.nix @@ -0,0 +1,9 @@ +{ flake-utils-plus +, lib # extended lib from ../lib +, ... +} @inputs: +lib.exportWithInputs [ + ./prince + ./hwtr +] inputs + diff --git a/nix/hosts/hwtr/default.nix b/nix/hosts/hwtr/default.nix new file mode 100644 index 0000000..e69de29 diff --git a/nix/hosts/hwtr/nix.conf b/nix/hosts/hwtr/nix.conf new file mode 100644 index 0000000..e69de29 diff --git a/nix/hosts/prince/default.nix b/nix/hosts/prince/default.nix new file mode 100644 index 0000000..e69de29 diff --git a/nix/lib/default.nix b/nix/lib/default.nix new file mode 100644 index 0000000..e75bdef --- /dev/null +++ b/nix/lib/default.nix @@ -0,0 +1,20 @@ +# Contains all of the utilities to help build this monorepo +# NOTE: lib is evaluated after overlays, but before import of mypkgs +# since mypkgs is dependent on ./lib +# In the future, if we need to develop utilities on top of mypkgs, +# use public_lib instead +{ pkgs +, lib ? pkgs.lib +, ... +}@flake_import: +let + moduleUtils = import ./moduleUtils flake_import; + inherit (moduleUtils.exportWithInputs [ ./serde ] flake_import) serde; + + recursiveUpdate = lib.recursiveUpdate; +in +recursiveUpdate (recursiveUpdate pkgs.lib lib) { + fromYaml = serde.fromYaml; + fromYamlPath = serde.fromYamlPath; + inherit (moduleUtils) exportWithInputs; +} diff --git a/nix/lib/moduleUtils.nix b/nix/lib/moduleUtils.nix new file mode 100644 index 0000000..879d977 --- /dev/null +++ b/nix/lib/moduleUtils.nix @@ -0,0 +1,10 @@ +{ flake-utils-plus +, lib +, ... +}: { + # exportWithInputs [./a.nix ./b.nix] {my = "inputs";} + # -> {a = import ./a.nix {my = "inputs";}, b = import ./b.nix {my = "inputs";}} + exportWithInputs = modules: inputs: ( + lib.mapAttrs (name: value: (value inputs)) + (flake-utils-plus.lib.exportModules modules)); +} diff --git a/nix/lib/serde/default.nix b/nix/lib/serde/default.nix new file mode 100644 index 0000000..f0bba84 --- /dev/null +++ b/nix/lib/serde/default.nix @@ -0,0 +1,29 @@ +# Takes care of serializing and deserializing to some formats +# Blame: Pegasust +# TODO: Add to* formats from pkgs.formats.* +{ pkgs +, lib +, ... +} @ inputs: +let + yamlToJsonDrv = yamlContent: outputPath: pkgs.callPackage + ({ runCommand }: + # runCommand source: https://github.com/NixOS/nixpkgs/blob/master/pkgs/build-support/trivial-builders.nix#L33 + runCommand outputPath { inherit yamlContent; nativeBuildInputs = [ pkgs.yq ]; } + # run yq which outputs '.' (no filter) on file at yamlPath + # note that $out is passed onto the bash/sh script for execution + '' + echo "$yamlContent" | yq >$out + '') + { }; +in { + # Takes in a yaml string and produces a derivation with translated JSON at $outputPath + # similar to builtins.fromJSON, turns a YAML string to nix attrset + fromYaml = yamlContent: builtins.fromJSON (builtins.readFile (yamlToJsonDrv yamlContent "any_output.json")); + fromYamlPath = yamlPath: builtins.fromJSON ( + builtins.readFile ( + yamlToJsonDrv ( + builtins.readFile yamlPath) + "any-output.json")); + # TODO: fromToml? +} diff --git a/nix/pkgs/cargo-bacon.nix b/nix/pkgs/cargo-bacon.nix new file mode 100644 index 0000000..df5b0e3 --- /dev/null +++ b/nix/pkgs/cargo-bacon.nix @@ -0,0 +1,9 @@ +{ pkgs +, lib +, naersk +,... +}@pkgs_input: { + deriv = pkgs.rustPlatform.buildRustPackage rec { + pname = "bacon"; + }; +} diff --git a/nix/pkgs/default.nix b/nix/pkgs/default.nix new file mode 100644 index 0000000..c9accdd --- /dev/null +++ b/nix/pkgs/default.nix @@ -0,0 +1,14 @@ +# This module aims to be merge (not inject/override) with top-level pkgs to provide +# personalized/custom packages +# For utility functions that aids with development of this whole monorepo, +# go into ../lib. +{ pkgs +, lib # extended lib from ../lib +, naersk # rust packages +, ... +}@pkgs_input: +lib.exportWithInputs [ + ./nixgl + ./neovim + ./cargo-bacon +] pkgs_input diff --git a/nix/pkgs/neovim.nix b/nix/pkgs/neovim.nix new file mode 100644 index 0000000..9629cb9 --- /dev/null +++ b/nix/pkgs/neovim.nix @@ -0,0 +1 @@ +inputs: null diff --git a/nix/pkgs/nixgl.nix b/nix/pkgs/nixgl.nix new file mode 100644 index 0000000..9629cb9 --- /dev/null +++ b/nix/pkgs/nixgl.nix @@ -0,0 +1 @@ +inputs: null diff --git a/nix/users/default.nix b/nix/users/default.nix new file mode 100644 index 0000000..ad4b3f0 --- /dev/null +++ b/nix/users/default.nix @@ -0,0 +1,10 @@ +{ home-manager +, lib # extended lib from ../lib +, pkgs +, ... }@inputs: +lib.exportWithInputs [ + ./hwtr + ./prince + ./hungtr +] inputs + diff --git a/nix/users/hungtr.nix b/nix/users/hungtr.nix new file mode 100644 index 0000000..ee08ddd --- /dev/null +++ b/nix/users/hungtr.nix @@ -0,0 +1,8 @@ +{ ... }@inputs: { + users.users.hungtr = { + isNormalUser = true; + home = "/home/hungtr"; + description = "pegasust/hungtr"; + extraGroups = [ "wheel" "networkmanager" ]; + }; +} diff --git a/nix/users/hwtr.nix b/nix/users/hwtr.nix new file mode 100644 index 0000000..73a83a9 --- /dev/null +++ b/nix/users/hwtr.nix @@ -0,0 +1,28 @@ +{ home-manager, lib, pkgs }@inputs: { + # end result: homeConfigurations.hwtr = home-manager... + homeConfig = home-manager.lib.homeManagerConfiguration { + inherit pkgs; + modules = base.modules ++ [ + ./home.nix + { + base.alacritty.font.family = "BitstreamVeraSansMono Nerd Font"; + base.shells = { + shellAliases = { + nixGL = "nixGLIntel"; + }; + }; + } + ]; + extraSpecialArgs = mkModuleArgs { + inherit pkgs; + myHome = { + username = "hwtr"; + homeDirectory = "/home/hwtr"; + packages = [ + pkgs.nixgl.nixGLIntel + pkgs.postman + ]; + }; + }; + }; +} diff --git a/nix/users/prince.nix b/nix/users/prince.nix new file mode 100644 index 0000000..e69de29