From e95838d16080a859126bb80415a7268701f24c00 Mon Sep 17 00:00:00 2001 From: Mike Priscella Date: Wed, 18 Jun 2025 23:43:41 -0400 Subject: [PATCH 1/5] Commit current install script as well as default nix --- .config/home-manager/hosts/default.nix | 21 +-- install.sh | 205 ++++++++++++++++++------- 2 files changed, 150 insertions(+), 76 deletions(-) diff --git a/.config/home-manager/hosts/default.nix b/.config/home-manager/hosts/default.nix index 2f1ff11..683fc23 100644 --- a/.config/home-manager/hosts/default.nix +++ b/.config/home-manager/hosts/default.nix @@ -1,25 +1,15 @@ { config, pkgs, lib, ... }: let - # Automatically detect username from environment + # Automatically detect username from environment. username = builtins.getEnv "USER"; - # Construct home directory based on detected username and OS + # Construct home directory based on detected username and OS. homeDirectory = if pkgs.stdenv.isDarwin then "/Users/${username}" else "/home/${username}"; - - # Detect hostname for configuration path - hostname = - let - envHostname = builtins.getEnv "HOSTNAME"; - in - if envHostname != "" then envHostname - else if builtins.pathExists /etc/hostname then builtins.readFile /etc/hostname - else "unknown"; in - { imports = [ ../common.nix @@ -37,11 +27,4 @@ in # Default GPG key (optional - can be left null for no signing) gpgSigningKey = null; # Set to your default key ID if desired }; - - # Optional: Add some debug info to session variables - home.sessionVariables = { - HM_DETECTED_USER = username; - HM_DETECTED_HOME = homeDirectory; - HM_DETECTED_HOST = hostname; - }; } diff --git a/install.sh b/install.sh index f86f622..9a08b0b 100755 --- a/install.sh +++ b/install.sh @@ -44,16 +44,6 @@ detect_os() { Linux*) OS="linux" log_info "Running on Linux" - # Detect Linux distribution - if [[ -f /etc/os-release ]]; then - # shellcheck source=/dev/null - source /etc/os-release - DISTRO="$ID" - log_info "Detected Linux distribution: $PRETTY_NAME" - else - DISTRO="unknown" - log_warning "Could not detect Linux distribution" - fi ;; *) log_error "Unsupported operating system: $(uname -s)" @@ -61,52 +51,85 @@ detect_os() { exit 1 ;; esac + + # Detect if we're in a container environment + if [[ -f /.dockerenv ]] || [[ -n "${CODESPACES:-}" ]] || [[ -n "${DEVCONTAINER:-}" ]] || grep -qi 'docker\|lxc\|container' /proc/1/cgroup 2>/dev/null; then + IN_CONTAINER=true + log_info "Container environment detected" + else + IN_CONTAINER=false + fi } # Check prerequisites based on OS check_prerequisites() { - case "$OS" in - linux) - # Check if curl is available - if ! command -v curl >/dev/null 2>&1; then - log_error "curl is required but not installed" - log_info "Please install curl first:" - case "$DISTRO" in - ubuntu | debian) - log_info " sudo apt update && sudo apt install curl" - ;; - fedora | rhel | centos) - log_info " sudo dnf install curl" - ;; - arch | manjaro) - log_info " sudo pacman -S curl" - ;; - *) - log_info " Please install curl using your distribution's package manager" - ;; - esac - exit 1 + if ! command -v curl >/dev/null 2>&1; then + log_error "curl is required but not installed" + exit 1 + fi +} + +# Install Nix if not already installed +# TODO: +# - If this script is run and nix is installed, then the script is run again, it's failing because path is not updated. +install_nix() { + # Check for permission issues in devcontainer first + if command -v nix >/dev/null 2>&1 && [[ "$IN_CONTAINER" == true ]]; then + # Test if we can actually use nix commands that require write access to both db and store + write_test_failed=false + + if [[ ! -w /nix/var/nix/db/big-lock ]] 2>/dev/null || ! touch /nix/var/nix/test-write 2>/dev/null; then + write_test_failed=true fi + rm -f /nix/var/nix/test-write 2>/dev/null # Clean up test file - # Check if systemd is available for multi-user install - if command -v systemctl >/dev/null 2>&1; then - log_info "systemd detected - will use multi-user installation" - else - log_warning "systemd not detected - will use single-user installation" + # Also test if we can write to the store (where the real issues often occur) + if ! touch /nix/store/test-write 2>/dev/null; then + write_test_failed=true fi - ;; - macos) - # macOS specific checks - if ! command -v curl >/dev/null 2>&1; then - log_error "curl is required but not installed" - exit 1 + rm -f /nix/store/test-write 2>/dev/null # Clean up test file + + if [[ "$write_test_failed" == true ]]; then + log_warning "Detected Nix permission issues in devcontainer" + log_error "Nix database permissions issue detected" + log_info "This usually happens when Nix was installed as root in devcontainer" + log_info "" + log_info "Solutions:" + echo " 1. Fix database permissions (quick fix):" + echo " sudo chown -R $(whoami):$(whoami) /nix/var/nix/" + echo "" + echo " 2. Reinstall as single-user (recommended for devcontainers):" + echo " sudo rm -rf /nix /etc/nix" + echo " curl -L https://nixos.org/nix/install | sh -s -- --no-daemon" + echo " source ~/.bashrc" + + read -p "Choose option (1/2) or cancel (N): " -n 1 -r + echo + if [[ $REPLY == "1" ]]; then + log_info "Attempting to fix Nix database permissions..." + if sudo chown -R "$(whoami):$(whoami)" /nix/var/nix/ 2>/dev/null; then + log_success "Fixed Nix database permissions!" + log_warning "Note: You may still encounter issues with /nix/store. Consider option 2 for a complete fix." + else + log_error "Failed to fix permissions." + exit 1 + fi + elif [[ $REPLY == "2" ]]; then + log_info "Reinstalling Nix as single-user..." + if sudo rm -rf /nix /etc/nix /etc/profile.d/nix.sh 2>/dev/null; then + log_info "Removed existing Nix installation" + # Fall through to the installation section below + else + log_error "Failed to remove existing Nix installation" + exit 1 + fi + else + log_error "Cannot continue with permission issues. Please fix manually." + exit 1 + fi fi - ;; - esac -} + fi -# Install Nix if not already installed -install_nix() { if command -v nix >/dev/null 2>&1; then log_success "Nix is already installed: $(nix --version)" @@ -135,17 +158,26 @@ install_nix() { case "$OS" in macos) - # Use the official Nix installer for macOS with daemon support - install_args="--daemon" + if [[ "$IN_CONTAINER" == true ]]; then + log_info "Container detected on macOS - using single-user installation" + install_args="--no-daemon" + else + # Use the official Nix installer for macOS with daemon support + install_args="--daemon" + fi ;; linux) - # Check if we should use multi-user or single-user install - if command -v systemctl >/dev/null 2>&1 && [[ "$EUID" -ne 0 ]]; then + # In containers, always use single-user to avoid permission issues + if [[ "$IN_CONTAINER" == true ]]; then + log_info "Container environment detected - using single-user installation" + install_args="--no-daemon" + # Check if we should use multi-user or single-user install on bare metal + elif command -v systemctl >/dev/null 2>&1 && [[ "$EUID" -ne 0 ]]; then log_info "Using multi-user installation (recommended)" install_args="--daemon" else log_info "Using single-user installation" - install_args="" + install_args="--no-daemon" fi ;; esac @@ -190,13 +222,13 @@ install_nix() { # Install home-manager install_home_manager() { - # Check if home-manager is already installed + # Check if home-manager is already installed. if command -v home-manager >/dev/null 2>&1; then log_success "home-manager is already installed: $(home-manager --version)" return 0 fi - # Ensure nix commands are available + # Ensure nix-channel command is available. if ! command -v nix-channel >/dev/null 2>&1; then log_error "nix-channel command not found. Nix may not be properly installed or sourced." log_info "Try restarting your terminal or manually sourcing Nix profile." @@ -256,6 +288,7 @@ setup_home_manager() { local config_dir="$HOME/.config/home-manager" local dotfiles_config_dir dotfiles_config_dir="$(pwd)/.config/home-manager" + local config_file if [[ -d "$config_dir" ]]; then log_info "home-manager config directory already exists" @@ -271,13 +304,15 @@ setup_home_manager() { # Suggest appropriate configuration file based on OS case "$OS" in macos) - log_info "You can now run: home-manager switch --file .config/home-manager/hosts/work-macbook-pro.nix" + config_file="work-macbook-pro.nix" + # log_info "You can now run: home-manager switch --file .config/home-manager/hosts/work-macbook-pro.nix" ;; linux) - log_info "You can now run: home-manager switch --file .config/home-manager/hosts/linux-machine.nix" - log_warning "Note: You may need to create a Linux-specific configuration file" + config_file="default.nix" + # log_info "You can now run: home-manager switch --file .config/home-manager/hosts/linux-machine.nix" ;; esac + log_info "You can now run: home-manager switch --file .config/home-manager/hosts/$config_file" else log_warning "No home-manager configuration found in dotfiles" log_info "You may need to create a home-manager configuration" @@ -351,6 +386,59 @@ test_and_apply_config() { fi } +# Check and fix Nix permissions in devcontainer +check_devcontainer_nix() { + if [[ "$IN_CONTAINER" != true ]]; then + return 0 + fi + + # Check if Nix is installed but has permission issues + if [[ -d /nix ]] && ! nix-channel --list >/dev/null 2>&1; then + log_warning "Detected Nix permission issues in devcontainer" + + # Check if we're running as root + if [[ "$EUID" -eq 0 ]]; then + log_error "Running as root in devcontainer. This script should run as the target user." + log_info "To fix this, ensure your devcontainer runs this script as the 'vscode' user:" + echo " \"postCreateCommand\": \"su - vscode -c 'cd /workspaces/dotfiles && ./install.sh'\"" + exit 1 + fi + + # Check if big-lock file has permission issues + if [[ ! -w /nix/var/nix/db/big-lock ]] 2>/dev/null; then + log_error "Nix database permissions issue detected" + log_info "This usually happens when Nix was installed as root in devcontainer" + log_info "" + log_info "Solutions:" + echo " 1. Fix permissions (run as root):" + echo " sudo chown -R $(whoami):$(whoami) /nix/var/nix/" + echo "" + echo " 2. Or reinstall Nix as single-user:" + echo " sudo rm -rf /nix /etc/nix" + echo " curl -L https://nixos.org/nix/install | sh -s -- --no-daemon" + echo " source ~/.bashrc" + echo "" + echo " 3. Or run this script with sudo to fix ownership:" + echo " sudo ./install.sh" + + read -p "Would you like to automatically fix the permissions? (y/N): " -n 1 -r + echo + if [[ $REPLY =~ ^[Yy]$ ]]; then + log_info "Attempting to fix Nix permissions..." + if sudo chown -R "$(whoami):$(whoami)" /nix/var/nix/ 2>/dev/null; then + log_success "Fixed Nix permissions!" + else + log_error "Failed to fix permissions. You may need to reinstall Nix." + exit 1 + fi + else + log_error "Cannot continue with permission issues. Please fix manually." + exit 1 + fi + fi + fi +} + # Main installation process main() { log_info "Starting dotfiles installation..." @@ -358,6 +446,9 @@ main() { # Detect operating system detect_os + # Check devcontainer Nix setup + check_devcontainer_nix + # Check prerequisites check_prerequisites From 1ea4afe7dfccb16fb432dcd878b56aaa7a5d5187 Mon Sep 17 00:00:00 2001 From: Michael Priscella Date: Fri, 20 Jun 2025 01:24:06 -0400 Subject: [PATCH 2/5] Attempting to move to nix flakes --- .config/home-manager/common-flake.nix | 206 ++++++++ .config/home-manager/common.nix | 207 -------- .config/home-manager/hosts/default-flake.nix | 14 + .config/home-manager/hosts/default.nix | 30 -- .../home-manager/hosts/macbook-air-flake.nix | 19 + .config/home-manager/hosts/macbook-air.nix | 18 - .../hosts/work-macbook-pro-flake.nix | 19 + .../home-manager/hosts/work-macbook-pro.nix | 18 - .../modules/machine-config-flake.nix | 66 +++ .../home-manager/modules/machine-config.nix | 39 -- .envrc | 4 +- .gitignore | 4 + README.md | 469 +++++++++++++++++- flake.lock | 48 ++ flake.nix | 128 +++++ 15 files changed, 954 insertions(+), 335 deletions(-) create mode 100644 .config/home-manager/common-flake.nix delete mode 100644 .config/home-manager/common.nix create mode 100644 .config/home-manager/hosts/default-flake.nix delete mode 100644 .config/home-manager/hosts/default.nix create mode 100644 .config/home-manager/hosts/macbook-air-flake.nix delete mode 100644 .config/home-manager/hosts/macbook-air.nix create mode 100644 .config/home-manager/hosts/work-macbook-pro-flake.nix delete mode 100644 .config/home-manager/hosts/work-macbook-pro.nix create mode 100644 .config/home-manager/modules/machine-config-flake.nix delete mode 100644 .config/home-manager/modules/machine-config.nix create mode 100644 flake.lock create mode 100644 flake.nix diff --git a/.config/home-manager/common-flake.nix b/.config/home-manager/common-flake.nix new file mode 100644 index 0000000..3e4349d --- /dev/null +++ b/.config/home-manager/common-flake.nix @@ -0,0 +1,206 @@ +{ config, pkgs, lib, inputs, ... }: + +let + # Get GPG signing key from host configuration, with fallback + gpgSigningKey = config.myConfig.gpgSigningKey or null; +in + +{ + # Allow unfree packages (like some proprietary tools) + nixpkgs.config.allowUnfree = true; + + home.packages = [ + pkgs.ack + pkgs.act + pkgs.awscli2 + pkgs.dive + pkgs.fd + pkgs.fzf + pkgs.gh + pkgs.git + pkgs.gnupg + pkgs.jq + pkgs.kind + pkgs.k9s + pkgs.kubectl + pkgs.kubernetes-helm + pkgs.lazydocker + pkgs.lazygit + pkgs.neovim + pkgs.pinentry-curses # For GPG password prompts in terminal + pkgs.ripgrep + pkgs.tmux + pkgs.yq + pkgs.yt-dlp + ]; + + home.file = { + ".ackrc".text = '' + --pager=less -R + --ignore-case + ''; + + ".tmux.conf".source = ../../tmux.conf; + + ".config/atuin".source = ../atuin; + ".config/ghostty".source = ../ghostty; + ".config/k9s".source = ../k9s; + ".config/nvim".source = ../nvim; + }; + + # Common session variables + home.sessionVariables = { + AWS_CLI_AUTO_PROMPT = "on-partial"; + EDITOR = "nvim"; + PAGER = "less"; + LESS = "-R"; + }; + + # Direnv integration + programs.direnv = { + enable = true; + nix-direnv.enable = true; + }; + + # Fish shell configuration + # https://nixos.wiki/wiki/Fish + programs.fish = { + enable = true; + + shellInit = '' + # Set up direnv if available + if command -v direnv >/dev/null + direnv hook fish | source + end + + fish_vi_key_bindings + ''; + + functions = { + # AWS profile switcher + aws-ps = { + description = "Switch AWS profiles"; + body = '' + set -l profile $argv[1] + if test -z "$profile" + echo "Available profiles:" + aws configure list-profiles + return + end + set -gx AWS_PROFILE $profile + echo "Switched to AWS profile: $profile" + ''; + }; + }; + + shellAliases = { + ll = "ls -la"; + la = "ls -la"; + l = "ls -l"; + ".." = "cd .."; + "..." = "cd ../.."; + + # Git aliases + g = "git"; + gs = "git status"; + gd = "git diff"; + ga = "git add"; + gc = "git commit"; + gp = "git push"; + gl = "git pull"; + + # Docker aliases + d = "docker"; + dc = "docker-compose"; + + # Kubernetes aliases + k = "kubectl"; + h = "helm"; + + # Modern replacements + cat = "bat --style=plain"; + find = "fd"; + grep = "rg"; + }; + + plugins = [ + { + name = "pure"; + src = pkgs.fishPlugins.pure.src; + } + ]; + }; + + # Git configuration + programs.git = { + enable = true; + userName = "Mike Priscella"; + userEmail = "mpriscella@gmail.com"; + + extraConfig = { + init.defaultBranch = "main"; + pull.rebase = true; + push.autoSetupRemote = true; + core.editor = "nvim"; + + # GPG signing configuration (conditional) + user.signingkey = lib.mkIf (gpgSigningKey != null) gpgSigningKey; + commit.gpgsign = lib.mkIf (gpgSigningKey != null) true; + tag.gpgsign = lib.mkIf (gpgSigningKey != null) true; + }; + + ignores = [ + ".DS_Store" + "*.swp" + "*.swo" + "*~" + ".direnv/" + "result" + "result-*" + ]; + + aliases = { + st = "status"; + co = "checkout"; + br = "branch"; + ci = "commit"; + di = "diff"; + unstage = "reset HEAD --"; + last = "log -1 HEAD"; + visual = "!gitk"; + graph = "log --oneline --graph --decorate --all"; + # Show files ignored by git + ign = "ls-files -o -i --exclude-standard"; + }; + }; + + # GPG configuration + programs.gpg = { + enable = true; + settings = { + # Use a long keyid format + keyid-format = "long"; + # Show fingerprints + with-fingerprint = true; + # Disable greeting message + no-greeting = true; + # Use the GPG agent + use-agent = true; + }; + }; + + # Home Manager needs a bit of information about you and the + # paths it should manage. + programs.home-manager.enable = true; + + # Enable man page support + programs.man.enable = true; + + services.gpg-agent = { + enable = true; + enableFishIntegration = true; + pinentry.package = pkgs.pinentry-curses; + defaultCacheTtl = 28800; # 8 hours + maxCacheTtl = 86400; # 24 hours + }; +} diff --git a/.config/home-manager/common.nix b/.config/home-manager/common.nix deleted file mode 100644 index 0965278..0000000 --- a/.config/home-manager/common.nix +++ /dev/null @@ -1,207 +0,0 @@ -{ config, pkgs, lib, ... }: - -let - # Get GPG signing key from host configuration, with fallback - gpgSigningKey = config.myConfig.gpgSigningKey or null; -in - -{ - home.packages = [ - pkgs.ack - pkgs.act - pkgs.awscli2 - pkgs.dive - pkgs.fd - pkgs.fzf - pkgs.gh - pkgs.git - pkgs.gnupg - pkgs.jq - pkgs.kind - pkgs.k9s - pkgs.kubectl - pkgs.kubernetes-helm - pkgs.lazydocker - pkgs.lazygit - pkgs.neovim - pkgs.pinentry-curses # For GPG password prompts in terminal - pkgs.ripgrep - pkgs.tmux - pkgs.yq - pkgs.yt-dlp - ]; - - home.file = { - ".ackrc".text = '' - --pager=less -R - --ignore-case - ''; - - ".tmux.conf".source = ../../tmux.conf; - - ".config/atuin".source = ../atuin; - ".config/ghostty".source = ../ghostty; - ".config/k9s".source = ../k9s; - ".config/nvim".source = ../nvim; - }; - - # Common session variables - home.sessionVariables = { - AWS_CLI_AUTO_PROMPT = "on-partial"; - EDITOR = "nvim"; - KUBE_EDITOR = "nvim"; - }; - - # Enable and configure Fish shell - programs.fish = { - enable = true; - - plugins = [ - { - name = "pure"; - src = pkgs.fishPlugins.pure.src; - } - ]; - - functions = { - aws-ps = '' - set profile $(aws configure list-profiles | fzf --height=30% --layout=reverse) - if set --query profile - set -gx AWS_PROFILE $profile - echo "AWS profile $AWS_PROFILE now active." - end - ''; - }; - - # Fish shell configuration - shellInit = '' - # Commands to run when fish starts (non-interactive) - set PATH $PATH /opt/homebrew/bin - set PATH $HOME/.orbstack/bin $PATH - ''; - - interactiveShellInit = '' - # Commands to run in interactive sessions - # Initialize atuin if available - if command -q atuin - atuin init fish | source - end - ''; - - # Fish shell aliases - shellAliases = { - lg = "lazygit"; - - # Quick reload aliases - rl = "exec fish"; - src = "source ~/.config/fish/config.fish"; - - # Home Manager aliases - hm = "home-manager"; - hms = "home-manager switch"; - hmb = "home-manager build --no-out-link"; - - # GPG aliases for easier key management - gpg-list = "gpg --list-secret-keys --keyid-format=long"; - gpg-export = "gpg --armor --export"; - gpg-restart = "gpg-connect-agent reloadagent /bye"; - }; - }; - - # Configure direnv with nix-direnv for automatic Nix environment loading - programs.direnv = { - enable = true; - nix-direnv.enable = true; - }; - - programs.git = { - enable = true; - userName = "Mike Priscella"; - userEmail = "mpriscella@gmail.com"; - - extraConfig = { - core.editor = "nvim"; - color.ui = "auto"; - init.defaultBranch = "main"; - pull.rebase = false; - push.default = "simple"; - - # GPG signing configuration - commit.gpgsign = true; - tag.gpgsign = true; - }; - - aliases = { - chb = "checkout -b"; - empty = "commit --allow-empty -n -m 'Empty-Commit'"; - }; - - ignores = [ - # OS generated files - ".DS_Store" - ".DS_Store?" - "._*" - ".Spotlight-V100" - ".Trashes" - "ehthumbs.db" - "Thumbs.db" - - # IDE files - ".vscode/" - ".idea/" - "*.swp" - "*.swo" - "*~" - - # Build artifacts - "node_modules/" - "target/" - "dist/" - "build/" - - # Environment files - ".env" - ".env.local" - ]; - } // lib.optionalAttrs (gpgSigningKey != null) { - signing = { - key = gpgSigningKey; - signByDefault = true; - }; - }; - - # Configure GPG for commit signing - programs.gpg = { - enable = true; - - # Configure GPG settings - settings = { - # Use agent for key management - use-agent = true; - # Default key preferences - personal-digest-preferences = "SHA512"; - cert-digest-algo = "SHA512"; - default-preference-list = "SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed"; - }; - }; - - # Configure GPG agent for automatic key management - services.gpg-agent = { - enable = true; - - # Cache settings for convenience - defaultCacheTtl = 43200; # 12 hours (longer default) - maxCacheTtl = 86400; # 24 hours - - # Enable SSH support (optional, useful for SSH key management) - enableSshSupport = false; - - # Pin entry program for password prompts - pinentry = { - package = pkgs.pinentry-curses; # Use curses for terminal, or pkgs.pinentry-gtk2 for GUI - }; - }; - - # Let Home Manager install and manage itself. - programs.home-manager.enable = true; -} diff --git a/.config/home-manager/hosts/default-flake.nix b/.config/home-manager/hosts/default-flake.nix new file mode 100644 index 0000000..e5edc77 --- /dev/null +++ b/.config/home-manager/hosts/default-flake.nix @@ -0,0 +1,14 @@ +{ config, pkgs, inputs, ... }: + +{ + imports = [ + ../common-flake.nix + ../modules/machine-config-flake.nix + ]; + + # Custom configuration using our module + myConfig = { + configPath = "${config.home.homeDirectory}/.config/home-manager/hosts/default-flake.nix"; + gpgSigningKey = null; # No default GPG key + }; +} diff --git a/.config/home-manager/hosts/default.nix b/.config/home-manager/hosts/default.nix deleted file mode 100644 index 683fc23..0000000 --- a/.config/home-manager/hosts/default.nix +++ /dev/null @@ -1,30 +0,0 @@ -{ config, pkgs, lib, ... }: - -let - # Automatically detect username from environment. - username = builtins.getEnv "USER"; - - # Construct home directory based on detected username and OS. - homeDirectory = - if pkgs.stdenv.isDarwin - then "/Users/${username}" - else "/home/${username}"; -in -{ - imports = [ - ../common.nix - ../modules/machine-config.nix - ]; - - # Automatically inferred values - home.username = username; - home.homeDirectory = homeDirectory; - home.stateVersion = "25.05"; - - # Custom configuration using our module - myConfig = { - configPath = "${homeDirectory}/.config/home-manager/hosts/default.nix"; - # Default GPG key (optional - can be left null for no signing) - gpgSigningKey = null; # Set to your default key ID if desired - }; -} diff --git a/.config/home-manager/hosts/macbook-air-flake.nix b/.config/home-manager/hosts/macbook-air-flake.nix new file mode 100644 index 0000000..d470e05 --- /dev/null +++ b/.config/home-manager/hosts/macbook-air-flake.nix @@ -0,0 +1,19 @@ +{ config, pkgs, inputs, ... }: + +{ + imports = [ + ../common-flake.nix + ../modules/machine-config-flake.nix + ]; + + # Custom configuration using our module + myConfig = { + configPath = "${config.home.homeDirectory}/.config/home-manager/hosts/macbook-air-flake.nix"; + gpgSigningKey = null; # Set your personal GPG key here if needed + }; + + # You can add MacBook Air specific configurations here + home.packages = with pkgs; [ + # Add any MacBook Air specific tools here + ]; +} diff --git a/.config/home-manager/hosts/macbook-air.nix b/.config/home-manager/hosts/macbook-air.nix deleted file mode 100644 index ce2fe17..0000000 --- a/.config/home-manager/hosts/macbook-air.nix +++ /dev/null @@ -1,18 +0,0 @@ -{ config, pkgs, ... }: - -{ - imports = [ - ../common.nix - ../modules/machine-config.nix - ]; - - home.username = "mpriscella"; - home.homeDirectory = "/Users/mpriscella"; - home.stateVersion = "25.05"; - - # Custom configuration using our module - myConfig = { - configPath = "${config.home.homeDirectory}/.config/home-manager/hosts/macbook-air.nix"; - gpgSigningKey = "PERSONAL_GPG_KEY_ID_HERE"; # Personal MacBook Air GPG key - }; -} diff --git a/.config/home-manager/hosts/work-macbook-pro-flake.nix b/.config/home-manager/hosts/work-macbook-pro-flake.nix new file mode 100644 index 0000000..b261671 --- /dev/null +++ b/.config/home-manager/hosts/work-macbook-pro-flake.nix @@ -0,0 +1,19 @@ +{ config, pkgs, inputs, ... }: + +{ + imports = [ + ../common-flake.nix + ../modules/machine-config-flake.nix + ]; + + # Custom configuration using our module + myConfig = { + configPath = "${config.home.homeDirectory}/.config/home-manager/hosts/work-macbook-pro-flake.nix"; + gpgSigningKey = "799887D03FE96FD0"; # Work-specific GPG key + }; + + # You can add work-specific packages or configurations here + home.packages = with pkgs; [ + # Add any work-specific tools here + ]; +} diff --git a/.config/home-manager/hosts/work-macbook-pro.nix b/.config/home-manager/hosts/work-macbook-pro.nix deleted file mode 100644 index 89b4104..0000000 --- a/.config/home-manager/hosts/work-macbook-pro.nix +++ /dev/null @@ -1,18 +0,0 @@ -{ config, pkgs, ... }: - -{ - imports = [ - ../common.nix - ../modules/machine-config.nix - ]; - - home.username = "michaelpriscella"; - home.homeDirectory = "/Users/michaelpriscella"; - home.stateVersion = "25.05"; - - # Custom configuration using our module - myConfig = { - configPath = "${config.home.homeDirectory}/.config/home-manager/hosts/work-macbook-pro.nix"; - gpgSigningKey = "799887D03FE96FD0"; # Work-specific GPG key - }; -} diff --git a/.config/home-manager/modules/machine-config-flake.nix b/.config/home-manager/modules/machine-config-flake.nix new file mode 100644 index 0000000..b5feb48 --- /dev/null +++ b/.config/home-manager/modules/machine-config-flake.nix @@ -0,0 +1,66 @@ +{ config, lib, pkgs, inputs, ... }: + +with lib; + +{ + options.myConfig = { + configPath = mkOption { + type = types.str; + default = "${config.home.homeDirectory}/.config/home-manager/home.nix"; + description = "Path to the home-manager configuration file for this machine"; + }; + + gpgSigningKey = mkOption { + type = types.nullOr types.str; + default = null; + description = "GPG key ID for signing git commits on this machine"; + example = "ABC123DEF456"; + }; + }; + + config = { + # Use your custom options here + home.packages = with pkgs; [ + # Custom build script for flake + (writeShellScriptBin "home-manager-build" '' + echo "Building Home Manager flake configuration..." + echo "Using config: ${config.myConfig.configPath}" + cd ${config.home.homeDirectory}/.config/home-manager/../../.. + exec home-manager build --flake .#$(hostname -s || echo "default") "$@" + '') + + # Custom switch script for flake + (writeShellScriptBin "home-manager-switch" '' + echo "Switching Home Manager flake configuration..." + echo "Using config: ${config.myConfig.configPath}" + cd ${config.home.homeDirectory}/.config/home-manager/../../.. + exec home-manager switch --flake .#$(hostname -s || echo "default") "$@" + '') + + # Helper script to show available flake configurations + (writeShellScriptBin "home-manager-list" '' + echo "Available Home Manager flake configurations:" + cd ${config.home.homeDirectory}/.config/home-manager/../../.. + nix flake show . 2>/dev/null | grep homeConfigurations || echo "No configurations found" + '') + + # Update flake script + (writeShellScriptBin "home-manager-update" '' + echo "Updating Home Manager flake inputs..." + cd ${config.home.homeDirectory}/.config/home-manager/../../.. + nix flake update + echo "Flake inputs updated!" + '') + ]; + + # Add some useful shell aliases for flake management + programs.fish.shellAliases = lib.mkMerge [ + { + hmb = "home-manager-build"; + hms = "home-manager-switch"; + hml = "home-manager-list"; + hmu = "home-manager-update"; + } + ]; + }; +} diff --git a/.config/home-manager/modules/machine-config.nix b/.config/home-manager/modules/machine-config.nix deleted file mode 100644 index 693326c..0000000 --- a/.config/home-manager/modules/machine-config.nix +++ /dev/null @@ -1,39 +0,0 @@ -{ config, lib, pkgs, ... }: - -with lib; - -{ - options.myConfig = { - configPath = mkOption { - type = types.str; - default = "${config.home.homeDirectory}/.config/home-manager/home.nix"; - description = "Path to the home-manager configuration file for this machine"; - }; - - gpgSigningKey = mkOption { - type = types.nullOr types.str; - default = null; - description = "GPG key ID for signing git commits on this machine"; - example = "ABC123DEF456"; - }; - }; - - config = { - # Use your custom options here - home.packages = with pkgs; [ - # Custom build script - (writeShellScriptBin "home-manager-build" '' - echo "Building Home Manager configuration..." - echo "Using config: ${config.myConfig.configPath}" - exec home-manager build --file "${config.myConfig.configPath}" "$@" - '') - - # Custom switch script - (writeShellScriptBin "home-manager-switch" '' - echo "Switching Home Manager configuration..." - echo "Using config: ${config.myConfig.configPath}" - exec home-manager switch --file "${config.myConfig.configPath}" "$@" - '') - ]; - }; -} diff --git a/.envrc b/.envrc index 1d953f4..988d72b 100644 --- a/.envrc +++ b/.envrc @@ -1 +1,3 @@ -use nix +if has nix; then + use flake +fi diff --git a/.gitignore b/.gitignore index 92b2793..2ea2a09 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,5 @@ .direnv + +.DS_Store + +result diff --git a/README.md b/README.md index 01582a9..ee7e08a 100644 --- a/README.md +++ b/README.md @@ -1,39 +1,464 @@ # Dotfiles -[![Open in Dev Containers](https://img.shields.io/static/v1?label=Dev%20Containers&message=Open&color=blue&logo=visualstudiocode)](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/mpriscella/dotfiles) +Cross-platform dotfiles managed with Nix and Home Manager, supporting macOS and +Linux with host-specific configurations. -My personal dotfiles. Feel free to borrow from or use them, but your mileage -may vary. +## Components -## Installation +This dotfiles repository includes: -```shell -./dotfiles.sh install +- **Home Manager**: User-level packages, dotfiles, and shell configuration +- **nix-darwin** (macOS only): System-level macOS configuration and Homebrew management +- **GPG Configuration**: Git commit signing setup with per-host key support + +## Quick Setup + +### Using Nix Flakes (Recommended) + +This repository uses Nix flakes for reproducible, multi-system configurations: + +```bash +# 1. Install Nix with flake support +curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install + +# 2. Clone this repository +git clone https://github.com/mpriscella/dotfiles.git ~/.config/dotfiles +cd ~/.config/dotfiles + +# 3. Enter the development shell (optional, provides helpful tools) +nix develop + +# 4. Apply your configuration (choose your host) +# For work MacBook Pro: +home-manager switch --flake .#work-macbook-pro + +# For default/devcontainer setup: +home-manager switch --flake .#default + +# For generic MacBook Air: +home-manager switch --flake .#macbook-air + +# For Linux user: +home-manager switch --flake .#linux-user +``` + +### Legacy Setup (Non-Flake) + +#### macOS with nix-darwin + +For complete macOS system management: + +```bash +# 1. Install Nix (if not already installed) +curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install + +# 2. Clone this repository +git clone https://github.com/mpriscella/dotfiles.git ~/.config + +# 3. Install nix-darwin (includes Home Manager) +cd ~/.config/nix-darwin +./install.sh + +# 4. Restart your terminal or reload shell +exec $SHELL +``` + +#### Home Manager Only + +For user-level configuration only: + +```bash +# 1. Install Nix and Home Manager +# 2. Clone repository +git clone https://github.com/mpriscella/dotfiles.git ~/.config + +# 3. Apply Home Manager configuration +home-manager switch --file ~/.config/home-manager/hosts/default.nix +``` + +## Management Commands + +### Nix Flake Commands (Recommended) + +```bash +# Apply configuration changes +home-manager switch --flake .# + +# Build configuration without applying (test first) +home-manager build --flake .# + +# Update flake inputs (nixpkgs, home-manager, etc.) +nix flake update + +# Show available configurations +nix flake show + +# Check flake validity +nix flake check + +# Enter development shell with tools +nix develop + +# Format Nix code +nix fmt +``` + +**Available configurations:** +- `work-macbook-pro` - Work MacBook Pro (Apple Silicon) +- `default` - Default/devcontainer setup +- `macbook-air` - Generic MacBook Air +- `linux-user` - Alternative Linux setup + +### Legacy Commands + +#### nix-darwin (macOS System) +- `dr` - Apply system configuration changes +- `drb` - Build configuration without applying +- `drc` - Check configuration validity + +#### Home Manager (User Configuration) +- `hms` - Apply user configuration changes +- `hmb` - Build user configuration without applying +- `hm` - Home Manager command + +## Nix Flakes Configuration + +This repository uses Nix flakes for reproducible, declarative configuration management across multiple systems and architectures. + +### Flake Structure + +The flake configuration supports: +- **Multiple systems**: x86_64-linux, aarch64-linux, x86_64-darwin, aarch64-darwin +- **Multiple hosts**: Different configurations for work, personal, and development environments +- **Reproducible builds**: Locked dependency versions via `flake.lock` +- **Development environment**: Built-in dev shell with helpful tools + +### Available Configurations + +| Configuration | System | Username | Use Case | +|---------------|---------|----------|----------| +| `work-macbook-pro` | aarch64-darwin | michaelpriscella | Work MacBook Pro (Apple Silicon) | +| `macbook-air` | aarch64-darwin | user | Personal MacBook Air | +| `default` | x86_64-linux | vscode | Devcontainers, CI/CD | +| `linux-user` | x86_64-linux | user | General Linux setup | + +### Switching Configurations + +```bash +# Switch to work setup +home-manager switch --flake .#work-macbook-pro + +# Switch to personal setup +home-manager switch --flake .#macbook-air + +# Switch to development/container setup +home-manager switch --flake .#default ``` -## Usage in Development Containers +### Updating Dependencies + +```bash +# Update all flake inputs (nixpkgs, home-manager, etc.) +nix flake update -Add the following value to your VSCode's `settings.json` file. +# Update specific input +nix flake lock --update-input nixpkgs -```json -{ - "dotfiles.repository": "mpriscella/dotfiles" -} +# View current lock file info +nix flake metadata ``` -## Troubleshooting +### Testing Changes -### zsh startup taking an abnormally long time +```bash +# Build without applying (test configuration) +home-manager build --flake .#work-macbook-pro -If `zsh` is taking a long time to start up, the startup script can be profiled -using [zprof](https://zsh.sourceforge.io/Doc/Release/Zsh-Modules.html#The-zsh_002fzprof-Module). -Add the following lines to the beginning and end of `.zshrc`. The next time `zsh` -runs, the profiling results will be printed to standard output. +# Check flake for errors +nix flake check -```shell -zmodload zsh/zprof +# Show what would be installed/removed +home-manager switch --flake .#work-macbook-pro --dry-run +``` + +### Development Environment -# zsh script +The flake includes a development shell with helpful tools: -zprof +```bash +# Enter development shell +nix develop + +# Or with direnv (if .envrc is present) +direnv allow # automatically loads when entering directory ``` + +The development shell includes: +- Home Manager binary +- Git +- Nix Language Server (nil) +- Helpful command examples + +### Customizing Configurations + +Each host configuration is in a separate file: +- `hosts/work-macbook-pro-flake.nix` - Work-specific settings +- `hosts/macbook-air-flake.nix` - Personal settings +- `hosts/default-flake.nix` - Development/container settings + +Common configuration is shared via: +- `common-flake.nix` - Shared packages and settings +- `modules/machine-config-flake.nix` - Reusable options and helper scripts + +### Migrating from Legacy Setup + +If you're currently using the non-flake setup: + +```bash +# 1. Backup current generation (optional) +home-manager generations + +# 2. Switch to flake version +home-manager switch --flake .#work-macbook-pro + +# 3. Verify everything works as expected +``` + +The flake configurations are compatible with the legacy ones but provide additional benefits: +- Reproducible builds across machines +- Easy switching between different setups +- Locked dependency versions +- Better development experience + +## GPG Setup for Git Signing + +This repository includes GPG commit signing configuration. Follow these steps to +set up GPG keys for signing your Git commits. + +### Prerequisites + +Ensure you have GPG installed: +```bash +# Check if GPG is available +gpg --version + +# If using this dotfiles setup, GPG is included in the Nix packages +``` + +### 1. Generate a New GPG Key + +```bash +# Start the key generation process +gpg --full-generate-key +``` + +Follow the prompts: + +1. **Key type**: Select `RSA and RSA` (option 1) +2. **Key size**: Enter `4096` for maximum security +3. **Expiration**: Choose based on your security policy: + - `0` = key does not expire (not recommended) + - `2y` = expires in 2 years (recommended) + - `1y` = expires in 1 year +4. **Real name**: Enter your full name (e.g., "Mike Priscella") +5. **Email**: Enter the email associated with your Git commits +6. **Comment**: Optional, can leave blank +7. **Passphrase**: Choose a strong passphrase (you'll need this for signing) + +### 2. List Your GPG Keys + +```bash +# List all secret keys with long format key IDs +gpg --list-secret-keys --keyid-format=long + +# Or use the provided alias +gpg-list +``` + +Output will look like: +``` +sec rsa4096/ABC123DEF456 2025-06-18 [SC] [expires: 2027-06-18] + 1234567890ABCDEF1234567890ABCDEF12345678 +uid [ultimate] Mike Priscella +ssb rsa4096/XYZ789UVW012 2025-06-18 [E] [expires: 2027-06-18] +``` + +Your **GPG Key ID** is `ABC123DEF456` (the part after `rsa4096/`). + +### 3. Export Your Public Key + +```bash +# Export your public key (replace with your actual key ID) +gpg --armor --export ABC123DEF456 + +# Or use the provided alias +gpg-export ABC123DEF456 +``` + +Copy the entire output (including `-----BEGIN PGP PUBLIC KEY BLOCK-----` and `-----END PGP PUBLIC KEY BLOCK-----`). + +### 4. Add Public Key to GitHub + +1. Go to [GitHub Settings → SSH and GPG keys](https://github.com/settings/keys) +2. Click **"New GPG key"** +3. Paste your public key +4. Click **"Add GPG key"** + +### 5. Configure Your Dotfiles + +Update your host-specific configuration file with your GPG key ID: + +#### For Flake Setup (Recommended) + +**For work machine** (`.config/home-manager/hosts/work-macbook-pro-flake.nix`): +```nix +myConfig = { + configPath = "${config.home.homeDirectory}/.config/home-manager/hosts/work-macbook-pro-flake.nix"; + gpgSigningKey = "ABC123DEF456"; # Replace with your work key ID +}; +``` + +**For personal machine** (`.config/home-manager/hosts/macbook-air-flake.nix`): +```nix +myConfig = { + configPath = "${config.home.homeDirectory}/.config/home-manager/hosts/macbook-air-flake.nix"; + gpgSigningKey = "XYZ789UVW012"; # Replace with your personal key ID +}; +``` + +#### For Legacy Setup + +**For work machine** (`.config/home-manager/hosts/work-macbook-pro.nix`): +```nix +myConfig = { + configPath = "${config.home.homeDirectory}/.config/home-manager/hosts/work-macbook-pro.nix"; + gpgSigningKey = "ABC123DEF456"; # Replace with your work key ID +}; +``` + +**For personal machine** (`.config/home-manager/hosts/macbook-air.nix`): +```nix +myConfig = { + configPath = "${config.home.homeDirectory}/.config/home-manager/hosts/macbook-air.nix"; + gpgSigningKey = "XYZ789UVW012"; # Replace with your personal key ID +}; +``` + +### 6. Apply Configuration + +#### Using Flakes (Recommended) +```bash +# Apply flake configuration +home-manager switch --flake .#work-macbook-pro + +# Or for other configurations +home-manager switch --flake .#macbook-air +home-manager switch --flake .#default +``` + +#### Using Legacy Setup +```bash +# Rebuild and apply your Home Manager configuration +home-manager switch + +# Or if using a specific host file +home-manager switch --file .config/home-manager/hosts/work-macbook-pro.nix +``` + +### 7. Test GPG Signing + +```bash +# Test GPG functionality +echo "test" | gpg --clearsign + +# Make a test commit +git commit --allow-empty -m "Test GPG signing" + +# Verify the commit is signed +git log --show-signature -1 +``` + +You should see output like: +``` +gpg: Signature made Wed Jun 18 10:30:00 2025 PDT +gpg: using RSA key ABC123DEF456 +gpg: Good signature from "Mike Priscella " +``` + +### Multiple Keys for Different Contexts + +This dotfiles setup supports different GPG keys for different machines: + +- **Work Machine**: Use your work email and work GPG key +- **Personal Machine**: Use your personal email and personal GPG key +- **Default/Testing**: Can be set to `null` to disable signing + +### GPG Key Management Commands + +The dotfiles include helpful aliases: + +```bash +# List all secret keys +gpg-list + +# Export a public key +gpg-export KEY_ID + +# Restart GPG agent (if having issues) +gpg-restart + +# Edit a key (change expiration, add email, etc.) +gpg --edit-key KEY_ID +``` + +### Troubleshooting + +**GPG agent not starting:** +```bash +# Restart the GPG agent +gpg-restart + +# Or manually +gpg-connect-agent reloadagent /bye +``` + +**Passphrase prompts:** +- The configuration caches your passphrase for 12 hours +- You'll only need to enter it once per session + +**Commits not showing as verified:** +- Ensure your email in Git config matches the email in your GPG key +- Check that your public key is added to GitHub +- Verify the key ID is correct in your configuration + +**Key expiration:** +```bash +# Extend key expiration +gpg --edit-key KEY_ID +gpg> expire +gpg> save + +# Re-export and update on GitHub +gpg-export KEY_ID +``` + +### Security Best Practices + +1. **Use a strong passphrase** for your GPG key +2. **Set key expiration** (1-2 years recommended) +3. **Backup your keys securely**: + ```bash + # Export private key for backup (store securely!) + gpg --export-secret-keys --armor KEY_ID > private-key-backup.asc + ``` +4. **Use different keys** for work and personal contexts +5. **Revoke compromised keys** immediately: + ```bash + gpg --gen-revoke KEY_ID > revocation-cert.asc + ``` + +### References + +- [GitHub GPG Documentation](https://docs.github.com/en/authentication/managing-commit-signature-verification) +- [GnuPG Documentation](https://gnupg.org/documentation/) +- [Git Signing Documentation](https://git-scm.com/book/en/v2/Git-Tools-Signing-Your-Work) diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..9658f54 --- /dev/null +++ b/flake.lock @@ -0,0 +1,48 @@ +{ + "nodes": { + "home-manager": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1750304462, + "narHash": "sha256-Mj5t4yX05/rXnRqJkpoLZTWqgStB88Mr/fegTRqyiWc=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "863842639722dd12ae9e37ca83bcb61a63b36f6c", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "home-manager", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1750134718, + "narHash": "sha256-v263g4GbxXv87hMXMCpjkIxd/viIF7p3JpJrwgKdNiI=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "9e83b64f727c88a7711a2c463a7b16eedb69a84c", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "home-manager": "home-manager", + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..b48ee49 --- /dev/null +++ b/flake.nix @@ -0,0 +1,128 @@ +{ + description = "Personal dotfiles configuration with Home Manager"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + + home-manager = { + url = "github:nix-community/home-manager"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + # Optionally, you can pin to specific commits for reproducibility + # nixpkgs.url = "github:NixOS/nixpkgs/c16a6c8efedb65e10d565633e3f45f73bbbdf8ab"; + }; + + outputs = { self, nixpkgs, home-manager, ... }@inputs: + let + # Define supported systems + systems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ]; + + # Helper to generate configurations for each system + forAllSystems = nixpkgs.lib.genAttrs systems; + + # Helper function to create home-manager configuration + mkHomeConfiguration = { system, username, homeDirectory, modules ? [], extraSpecialArgs ? {} }: + home-manager.lib.homeManagerConfiguration { + pkgs = nixpkgs.legacyPackages.${system}; + + modules = [ + { + home.username = username; + home.homeDirectory = homeDirectory; + home.stateVersion = "25.05"; + } + ] ++ modules; + + extraSpecialArgs = { + inherit inputs; + } // extraSpecialArgs; + }; + in + { + # Home Manager configurations + homeConfigurations = { + # Default configuration for Linux (devcontainers, etc.) + "default" = mkHomeConfiguration { + system = "x86_64-linux"; + username = "vscode"; # Common devcontainer username + homeDirectory = "/home/vscode"; + modules = [ + ./.config/home-manager/hosts/default-flake.nix + ]; + }; + + # Work MacBook Pro configuration + "work-macbook-pro" = mkHomeConfiguration { + system = "aarch64-darwin"; # Apple Silicon + username = "michaelpriscella"; + homeDirectory = "/Users/michaelpriscella"; + modules = [ + ./.config/home-manager/hosts/work-macbook-pro-flake.nix + ]; + }; + + # Generic MacBook Air configuration + "macbook-air" = mkHomeConfiguration { + system = "aarch64-darwin"; # Adjust if you have Intel MacBook Air + username = "user"; # Change this to your actual username + homeDirectory = "/Users/user"; # Change this to your actual home directory + modules = [ + ./.config/home-manager/hosts/macbook-air-flake.nix + ]; + }; + + # Alternative Linux configuration for different username + "linux-user" = mkHomeConfiguration { + system = "x86_64-linux"; + username = "user"; # Change this to your preferred username + homeDirectory = "/home/user"; + modules = [ + ./.config/home-manager/hosts/default-flake.nix + ]; + }; + }; + + # Development shells for each system + devShells = forAllSystems (system: { + default = nixpkgs.legacyPackages.${system}.mkShell { + buildInputs = with nixpkgs.legacyPackages.${system}; [ + home-manager.packages.${system}.default + git + nil # Nix language server + ]; + + shellHook = '' + echo "🏠 Home Manager Flake Development Shell" + echo "Available commands:" + echo " home-manager switch --flake .#" + echo " home-manager build --flake .#" + echo "" + echo "Available configurations:" + echo " default, work-macbook-pro, macbook-air, linux" + echo "" + echo "Example: home-manager switch --flake .#work-macbook-pro" + ''; + }; + }); + + # Packages for each system (useful for CI/CD) + packages = forAllSystems (system: { + default = self.homeConfigurations.default.activationPackage; + work-macbook-pro = self.homeConfigurations.work-macbook-pro.activationPackage; + macbook-air = self.homeConfigurations.macbook-air.activationPackage; + linux-user = self.homeConfigurations.linux-user.activationPackage; + }); + + # Formatter for `nix fmt` + formatter = forAllSystems (system: nixpkgs.legacyPackages.${system}.nixpkgs-fmt); + + # Checks for `nix flake check` + checks = forAllSystems (system: { + default = self.packages.${system}.default; + work-macbook-pro = self.packages.${system}.work-macbook-pro; + macbook-air = self.packages.${system}.macbook-air; + linux-user = self.packages.${system}.linux-user; + }); + }; +} From b28994a7aec42d0409923e2af97c7da05eff44a1 Mon Sep 17 00:00:00 2001 From: Mike Priscella Date: Sat, 21 Jun 2025 23:40:58 -0400 Subject: [PATCH 3/5] Add terraform and terraform-docs --- .config/home-manager/common-flake.nix | 32 ++++++--------------- flake.lock | 6 ++-- flake.nix | 40 +++++++++++++++++++-------- 3 files changed, 39 insertions(+), 39 deletions(-) diff --git a/.config/home-manager/common-flake.nix b/.config/home-manager/common-flake.nix index 3e4349d..1a6a750 100644 --- a/.config/home-manager/common-flake.nix +++ b/.config/home-manager/common-flake.nix @@ -29,6 +29,8 @@ in pkgs.neovim pkgs.pinentry-curses # For GPG password prompts in terminal pkgs.ripgrep + pkgs.terraform + pkgs.terraform-docs pkgs.tmux pkgs.yq pkgs.yt-dlp @@ -94,33 +96,15 @@ in }; shellAliases = { - ll = "ls -la"; - la = "ls -la"; - l = "ls -l"; - ".." = "cd .."; - "..." = "cd ../.."; - - # Git aliases - g = "git"; - gs = "git status"; - gd = "git diff"; - ga = "git add"; - gc = "git commit"; - gp = "git push"; - gl = "git pull"; - - # Docker aliases - d = "docker"; - dc = "docker-compose"; - - # Kubernetes aliases - k = "kubectl"; - h = "helm"; - # Modern replacements cat = "bat --style=plain"; find = "fd"; grep = "rg"; + + # Nix flake aliases + nfc = "nix flake check"; + nfu = "nix flake update"; + nfs = "nix flake show"; }; plugins = [ @@ -139,7 +123,7 @@ in extraConfig = { init.defaultBranch = "main"; - pull.rebase = true; + pull.rebase = false; push.autoSetupRemote = true; core.editor = "nvim"; diff --git a/flake.lock b/flake.lock index 9658f54..1e582b7 100644 --- a/flake.lock +++ b/flake.lock @@ -22,11 +22,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1750134718, - "narHash": "sha256-v263g4GbxXv87hMXMCpjkIxd/viIF7p3JpJrwgKdNiI=", + "lastModified": 1750365781, + "narHash": "sha256-XE/lFNhz5lsriMm/yjXkvSZz5DfvKJLUjsS6pP8EC50=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "9e83b64f727c88a7711a2c463a7b16eedb69a84c", + "rev": "08f22084e6085d19bcfb4be30d1ca76ecb96fe54", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index b48ee49..4d12bf1 100644 --- a/flake.nix +++ b/flake.nix @@ -107,22 +107,38 @@ }); # Packages for each system (useful for CI/CD) - packages = forAllSystems (system: { - default = self.homeConfigurations.default.activationPackage; - work-macbook-pro = self.homeConfigurations.work-macbook-pro.activationPackage; - macbook-air = self.homeConfigurations.macbook-air.activationPackage; - linux-user = self.homeConfigurations.linux-user.activationPackage; - }); + packages = forAllSystems (system: + let + # Only include packages that match the target system + linuxConfigs = nixpkgs.lib.optionalAttrs (nixpkgs.lib.hasInfix "linux" system) { + default = self.homeConfigurations.default.activationPackage; + linux-user = self.homeConfigurations.linux-user.activationPackage; + }; + darwinConfigs = nixpkgs.lib.optionalAttrs (nixpkgs.lib.hasInfix "darwin" system) { + work-macbook-pro = self.homeConfigurations.work-macbook-pro.activationPackage; + macbook-air = self.homeConfigurations.macbook-air.activationPackage; + }; + in + linuxConfigs // darwinConfigs + ); # Formatter for `nix fmt` formatter = forAllSystems (system: nixpkgs.legacyPackages.${system}.nixpkgs-fmt); # Checks for `nix flake check` - checks = forAllSystems (system: { - default = self.packages.${system}.default; - work-macbook-pro = self.packages.${system}.work-macbook-pro; - macbook-air = self.packages.${system}.macbook-air; - linux-user = self.packages.${system}.linux-user; - }); + checks = forAllSystems (system: + let + # Only include checks that match the target system + linuxChecks = nixpkgs.lib.optionalAttrs (nixpkgs.lib.hasInfix "linux" system) { + default = self.packages.${system}.default or null; + linux-user = self.packages.${system}.linux-user or null; + }; + darwinChecks = nixpkgs.lib.optionalAttrs (nixpkgs.lib.hasInfix "darwin" system) { + work-macbook-pro = self.packages.${system}.work-macbook-pro or null; + macbook-air = self.packages.${system}.macbook-air or null; + }; + in + nixpkgs.lib.filterAttrs (_: v: v != null) (linuxChecks // darwinChecks) + ); }; } From 9ab591506ea0c8296c3942120d73e1e7bcefd7c0 Mon Sep 17 00:00:00 2001 From: Mike Priscella Date: Sun, 22 Jun 2025 00:06:07 -0400 Subject: [PATCH 4/5] Update test workflow --- .github/workflows/test-home-manager.yml | 113 +++++++++++------------- 1 file changed, 54 insertions(+), 59 deletions(-) diff --git a/.github/workflows/test-home-manager.yml b/.github/workflows/test-home-manager.yml index b863e3e..d9368f1 100644 --- a/.github/workflows/test-home-manager.yml +++ b/.github/workflows/test-home-manager.yml @@ -6,37 +6,43 @@ on: - main paths: - '.config/home-manager/**' + - 'flake.nix' + - 'flake.lock' pull_request: branches: - main paths: - '.config/home-manager/**' + - 'flake.nix' + - 'flake.lock' workflow_dispatch: jobs: test-configs: - name: Test ${{ matrix.host }} on ${{ matrix.os }} + name: Test ${{ matrix.config }} on ${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: include: - # Test default.nix on both platforms (auto-detects) - - host: default + # Test configurations from flake + - config: default os: ubuntu-latest platform: linux - - host: default - os: macos-latest - platform: darwin - - # Test specific host configs on their target platforms - - host: work-macbook-pro + system: x86_64-linux + - config: linux-user + os: ubuntu-latest + platform: linux + system: x86_64-linux + - config: work-macbook-pro os: macos-latest platform: darwin - - host: macbook-air + system: aarch64-darwin + - config: macbook-air os: macos-latest platform: darwin + system: aarch64-darwin steps: - name: Checkout repository @@ -46,7 +52,8 @@ jobs: uses: cachix/install-nix-action@v24 with: github_access_token: ${{ secrets.GITHUB_TOKEN }} - nix_path: nixpkgs=channel:nixos-unstable + extra_nix_config: | + experimental-features = nix-command flakes # - name: Setup Cachix (optional - speeds up builds) # uses: cachix/cachix-action@v12 @@ -55,40 +62,37 @@ jobs: # name: ${{ vars.CACHIX_NAME }} # authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' - - name: Install Home Manager - run: | - # Use the standard installation method with proper environment setup - nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager - nix-channel --update - - # Ensure the channel is in NIX_PATH for this session - export NIX_PATH="nixpkgs=channel:nixos-unstable:home-manager=$HOME/.nix-defexpr/channels/home-manager" - - # Install home-manager using the updated NIX_PATH - nix-shell '' -A install - - name: Set test environment variables run: | - # Set test username but keep the real HOME directory + # Set test username for configurations that need it echo "USER=testuser" >> $GITHUB_ENV # Keep the existing HOME directory (GitHub runner's home) echo "REAL_HOME=$HOME" >> $GITHUB_ENV # Set hostname for testing echo "HOSTNAME=github-runner" >> $GITHUB_ENV - # Set proper NIX_PATH for all subsequent steps - echo "NIX_PATH=nixpkgs=channel:nixos-unstable:home-manager=$HOME/.nix-defexpr/channels/home-manager" >> $GITHUB_ENV + - name: Test flake evaluation + run: | + cd ${{ github.workspace }} + echo "Testing flake configuration: ${{ matrix.config }}" + + # Check that the flake is valid + nix flake check --show-trace + + # Show available configurations + echo "Available configurations:" + nix flake show - name: Test configuration build run: | cd ${{ github.workspace }} - echo "Testing configuration: ${{ matrix.host }}.nix" + echo "Building Home Manager configuration: ${{ matrix.config }}" - # Build the configuration using home-manager - home-manager build \ - --file .config/home-manager/hosts/${{ matrix.host }}.nix \ - --no-out-link \ - --show-trace + # Build the specific configuration from the flake + nix build .#homeConfigurations.${{ matrix.config }}.activationPackage \ + --no-link \ + --show-trace \ + --print-build-logs - name: Test configuration evaluation run: | @@ -96,22 +100,14 @@ jobs: echo "Evaluating configuration for detailed analysis..." # Test that the configuration evaluates without errors - nix-instantiate \ - --eval \ - --strict \ - --show-trace \ - --expr " - let - pkgs = import {}; - home-manager = import {}; - config = import ./.config/home-manager/hosts/${{ matrix.host }}.nix { - inherit pkgs; - config = {}; - lib = pkgs.lib; - }; - in - config.home.stateVersion or \"unknown\" - " + nix eval .#homeConfigurations.${{ matrix.config }}.config.home.stateVersion \ + --show-trace + + # Test that packages are available + echo "Testing package availability..." + nix eval .#homeConfigurations.${{ matrix.config }}.config.home.packages \ + --apply "builtins.length" \ + --show-trace - name: Check for common issues run: | @@ -119,18 +115,15 @@ jobs: echo "Checking for common configuration issues..." # Check if all imported files exist - echo "Checking imports..." + echo "Checking Nix syntax..." if ! find .config/home-manager -name "*.nix" -exec nix-instantiate --parse {} \; > /dev/null; then echo "❌ Syntax errors found in nix files" exit 1 fi - # Check for missing files referenced in configs - echo "Checking file references..." - if grep -r "source.*\.\." .config/home-manager/hosts/${{ matrix.host }}.nix; then - echo "Found relative path references - ensuring they exist..." - # This is just informational, actual test is in the build step - fi + # Check flake syntax + echo "Checking flake syntax..." + nix flake check --dry-run echo "✅ Basic checks passed" @@ -139,8 +132,9 @@ jobs: run: | cd ${{ github.workspace }} echo "## Configuration Test Results" >> $GITHUB_STEP_SUMMARY - echo "- **Host**: ${{ matrix.host }}" >> $GITHUB_STEP_SUMMARY + echo "- **Configuration**: ${{ matrix.config }}" >> $GITHUB_STEP_SUMMARY echo "- **Platform**: ${{ matrix.platform }}" >> $GITHUB_STEP_SUMMARY + echo "- **System**: ${{ matrix.system }}" >> $GITHUB_STEP_SUMMARY echo "- **OS**: ${{ matrix.os }}" >> $GITHUB_STEP_SUMMARY echo "- **Status**: ${{ job.status }}" >> $GITHUB_STEP_SUMMARY @@ -174,6 +168,7 @@ jobs: echo "" >> $GITHUB_STEP_SUMMARY echo "### Tested Configurations:" >> $GITHUB_STEP_SUMMARY - echo "- default.nix (Linux & macOS)" >> $GITHUB_STEP_SUMMARY - echo "- work-macbook-pro.nix (macOS)" >> $GITHUB_STEP_SUMMARY - echo "- macbook-air.nix (macOS)" >> $GITHUB_STEP_SUMMARY + echo "- default (Linux)" >> $GITHUB_STEP_SUMMARY + echo "- linux-user (Linux)" >> $GITHUB_STEP_SUMMARY + echo "- work-macbook-pro (macOS)" >> $GITHUB_STEP_SUMMARY + echo "- macbook-air (macOS)" >> $GITHUB_STEP_SUMMARY From 268811afb9374e124aa4b71d6615093d5902225c Mon Sep 17 00:00:00 2001 From: Mike Priscella Date: Sun, 22 Jun 2025 00:20:49 -0400 Subject: [PATCH 5/5] Remove --dry-run flag --- .github/workflows/test-home-manager.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-home-manager.yml b/.github/workflows/test-home-manager.yml index d9368f1..65b0656 100644 --- a/.github/workflows/test-home-manager.yml +++ b/.github/workflows/test-home-manager.yml @@ -123,7 +123,7 @@ jobs: # Check flake syntax echo "Checking flake syntax..." - nix flake check --dry-run + nix flake check echo "✅ Basic checks passed"