diff --git a/apps/aarch64-darwin/apply b/apps/aarch64-darwin/apply new file mode 100755 index 00000000..3db7bd1f --- /dev/null +++ b/apps/aarch64-darwin/apply @@ -0,0 +1,221 @@ +#!/usr/bin/env bash + +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +# Determine the operating system +export OS=$(uname) + +# Primary network interface +if [[ "$OS" != "Darwin" ]]; then + export PRIMARY_IFACE=$(ip -o -4 route show to default | awk '{print $5}') + echo -e "${GREEN}Found primary network interface $PRIMARY_IFACE${NC}" +fi + +# Custom print function +_print() { + if [[ "$OS" == "Darwin" ]]; then + echo -e "$1" + else + echo "$1" + fi +} + +# Custom prompt function +_prompt() { + local message="$1" + local variable="$2" + + _print "$message" + read -r $variable +} + +insert_secrets_output() { + local pattern="outputs = { self, darwin, nix-homebrew, homebrew-bundle, homebrew-core, homebrew-cask, home-manager, nixpkgs, disko, agenix } @inputs:" + local insert_text="secrets " + + awk -v pat="$pattern" -v insert="$insert_text" ' + $0 ~ pat { + sub(/} @inputs:/, ", " insert "} @inputs:"); # Replace the closing brace with the insert text followed by the brace + gsub(/ ,/, ","); # Correct any spaces before commas + print + next + } + { print } + ' flake.nix > flake.nix.tmp + + mv flake.nix.tmp flake.nix +} + +insert_secrets_input() { + # Define file path + FILE_PATH="flake.nix" + + # Backup the original file + cp "$FILE_PATH" "${FILE_PATH}.bak" + + # Temporary file for the text to insert + TEMP_FILE="temp_insert.txt" + + # Write the formatted text to the temporary file +cat > "$TEMP_FILE" << 'EOF' + secrets = { + url = "git+ssh://git@github.com/%GITHUB_USER%/%GITHUB_SECRETS_REPO%.git"; + flake = false; + }; +EOF + + # Check if the 'secrets' block already exists + if grep -q 'url = "git+ssh://git@github.com/%GITHUB_USER%/%GITHUB_SECRETS_REPO%.git"' "$FILE_PATH"; then + echo "The 'secrets' block already exists in the file." + rm "$TEMP_FILE" + rm "${FILE_PATH}.bak" + exit 0 + fi + + # Find the start and end line numbers of the 'disko' block + START_LINE=$(grep -n 'disko = {' "$FILE_PATH" | head -n 1 | cut -d: -f1) + END_LINE=$(tail -n +$START_LINE "$FILE_PATH" | grep -n '};' | head -n 1 | cut -d: -f1) + END_LINE=$((START_LINE + END_LINE - 1)) + + # Create a new file with the insertion + { + sed -n "1,${END_LINE}p" "$FILE_PATH" + cat "$TEMP_FILE" + sed -n "$((END_LINE + 1)),\$p" "$FILE_PATH" + } > "${FILE_PATH}.new" + + # Replace the original file with the new file + mv "${FILE_PATH}.new" "$FILE_PATH" + + # Clean up the temporary files + rm "$TEMP_FILE" + rm "${FILE_PATH}.bak" +} + +# Fetch username from the system +export USERNAME=$(whoami) + +# If the username is 'nixos' or 'root', ask the user for their username +if [[ "$USERNAME" == "nixos" ]] || [[ "$USERNAME" == "root" ]]; then + _prompt "${YELLOW}You're running as $USERNAME. Please enter your desired username: ${NC}" USERNAME +fi + +# Check if git is available +if command -v git >/dev/null 2>&1; then + # Fetch email and name from git config + export GIT_EMAIL=$(git config --get user.email) + export GIT_NAME=$(git config --get user.name) +else + _print "${RED}Git is not available on this system.${NC}" +fi + +# If git email is not found or git is not available, ask the user +if [[ -z "$GIT_EMAIL" ]]; then + _prompt "${YELLOW}Please enter your email: ${NC}" GIT_EMAIL +fi + +# If git name is not found or git is not available, ask the user +if [[ -z "$GIT_NAME" ]]; then + _prompt "${YELLOW}Please enter your name: ${NC}" GIT_NAME +fi + +_prompt "${YELLOW}Please enter your Github username: ${NC}" GITHUB_USER +_prompt "${YELLOW}Please enter your Github secrets repository name: ${NC}" GITHUB_SECRETS_REPO + +export GITHUB_USER +export GITHUB_SECRETS_REPO + +select_boot_disk() { + local disks + local _boot_disk + + _print "${YELLOW}Available disks:${NC}" + disks=$(lsblk -nd --output NAME,SIZE | grep -v loop) + echo "$disks" + + # Warning message for data deletion + _print "${RED}WARNING: All data on the chosen disk will be erased during the installation!${NC}" + _prompt "${YELLOW}Please choose your boot disk (e.g., nvme0n1, sda): ${NC}" _boot_disk + + # Confirmation for disk selection to prevent accidental data loss + _print "${YELLOW}You have selected $_boot_disk as the boot disk. This will delete everything on this disk. Are you sure? (Y/N): ${NC}" + read -r confirmation + if [[ "$confirmation" =~ ^[Yy]$ ]]; then + export BOOT_DISK=$_boot_disk + else + _print "${RED}Disk selection cancelled by the user. Please run the script again to select the correct disk.${NC}" + exit 1 + fi +} + +# Set hostname and find primary disk if this is NixOS +if [[ "$OS" != "Darwin" ]]; then + _prompt "${YELLOW}Please enter a hostname for the system: ${NC}" HOST_NAME + export HOST_NAME + select_boot_disk +fi + +# Confirmation step +confirm_details() { + _print "${GREEN}Username: $USERNAME" + _print "Email: $GIT_EMAIL" + _print "Name: $GIT_NAME${NC}" + + if([[ "$OS" != "Darwin" ]]); then + _print "${GREEN}Primary interface: $PRIMARY_IFACE" + _print "Boot disk: $BOOT_DISK" + _print "Hostname: $HOST_NAME${NC}" + fi + + _print "${GREEN}Secrets repository: $GITHUB_USER/$GITHUB_SECRETS_REPO${NC}" + + _prompt "${YELLOW}Is this correct? (Y/N): ${NC}" choice + + case "$choice" in + [Nn] ) _print "${RED}Exiting script.${NC}" && exit 1;; + [Yy] ) _print "${GREEN}Continuing...${NC}";; + * ) _print "${RED}Invalid option. Exiting script.${NC}" && exit 1;; + esac +} + +# Call the confirmation function +confirm_details + +# Function to replace tokens in each file +replace_tokens() { + local file="$1" + if [[ $(basename $1) != "apply" ]]; then + if [[ "$OS" == "Darwin" ]]; then + # macOS + LC_ALL=C LANG=C sed -i '' -e "s/%USER%/$USERNAME/g" "$file" + LC_ALL=C LANG=C sed -i '' -e "s/%EMAIL%/$GIT_EMAIL/g" "$file" + LC_ALL=C LANG=C sed -i '' -e "s/%NAME%/$GIT_NAME/g" "$file" + LC_ALL=C LANG=C sed -i '' -e "s/%GITHUB_USER%/$GITHUB_USER/g" "$file" + LC_ALL=C LANG=C sed -i '' -e "s/%GITHUB_SECRETS_REPO%/$GITHUB_SECRETS_REPO/g" "$file" + else + # Linux or other + sed -i -e "s/%USER%/$USERNAME/g" "$file" + sed -i -e "s/%EMAIL%/$GIT_EMAIL/g" "$file" + sed -i -e "s/%NAME%/$GIT_NAME/g" "$file" + sed -i -e "s/%INTERFACE%/$PRIMARY_IFACE/g" "$file" + sed -i -e "s/%DISK%/$BOOT_DISK/g" "$file" + sed -i -e "s/%HOST%/$HOST_NAME/g" "$file" + sed -i -e "s/%GITHUB_USER%/$GITHUB_USER/g" "$file" + sed -i -e "s/%GITHUB_SECRETS_REPO%/$GITHUB_SECRETS_REPO/g" "$file" + fi + fi +} + +# Insert secrets repo into flake +insert_secrets_input +insert_secrets_output + +# Traverse directories and call replace_tokens on each Nix file +export -f replace_tokens +find . -type f -exec bash -c 'replace_tokens "$0"' {} \; + +echo "$USERNAME" > /tmp/username.txt +_print "${GREEN}User $USERNAME information applied.${NC}" diff --git a/apps/aarch64-darwin/build b/apps/aarch64-darwin/build new file mode 100755 index 00000000..0c4ca115 --- /dev/null +++ b/apps/aarch64-darwin/build @@ -0,0 +1,19 @@ +#!/bin/sh -e + +GREEN='\033[1;32m' +YELLOW='\033[1;33m' +RED='\033[1;31m' +NC='\033[0m' + +SYSTEM_TYPE="aarch64-darwin" +FLAKE_SYSTEM="darwinConfigurations.${SYSTEM_TYPE}.system" + +export NIXPKGS_ALLOW_UNFREE=1 + +echo "${YELLOW}Starting build...${NC}" +nix --extra-experimental-features 'nix-command flakes' build .#$FLAKE_SYSTEM $@ + +echo "${YELLOW}Cleaning up...${NC}" +unlink ./result + +echo "${GREEN}Switch to new generation complete!${NC}" diff --git a/apps/aarch64-darwin/build-switch b/apps/aarch64-darwin/build-switch new file mode 100755 index 00000000..a83f85a2 --- /dev/null +++ b/apps/aarch64-darwin/build-switch @@ -0,0 +1,22 @@ +#!/bin/sh -e + +GREEN='\033[1;32m' +YELLOW='\033[1;33m' +RED='\033[1;31m' +NC='\033[0m' + +SYSTEM_TYPE="aarch64-darwin" +FLAKE_SYSTEM="darwinConfigurations.${SYSTEM_TYPE}.system" + +export NIXPKGS_ALLOW_UNFREE=1 + +echo "${YELLOW}Starting build...${NC}" +nix --extra-experimental-features 'nix-command flakes' build .#$FLAKE_SYSTEM $@ + +echo "${YELLOW}Switching to new generation...${NC}" +./result/sw/bin/darwin-rebuild switch --flake .#${SYSTEM_TYPE} $@ + +echo "${YELLOW}Cleaning up...${NC}" +unlink ./result + +echo "${GREEN}Switch to new generation complete!${NC}" diff --git a/apps/aarch64-darwin/check-keys b/apps/aarch64-darwin/check-keys new file mode 100755 index 00000000..4bd9dd81 --- /dev/null +++ b/apps/aarch64-darwin/check-keys @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +set -e + +RED='\033[0;31m' +GREEN='\033[0;32m' +NC='\033[0m' + +username=${USER} +export SSH_DIR=/Users/${username}/.ssh + +lint_keys() { + if [[ -f "${SSH_DIR}/id_ed25519" && -f "${SSH_DIR}/id_ed25519.pub" && -f "${SSH_DIR}/id_ed25519_agenix" && -f "${SSH_DIR}/id_ed25519_agenix.pub" ]]; then + echo -e "${GREEN}All SSH keys are present.${NC}" + else + echo -e "${RED}Some SSH keys are missing.${NC}" + if [[ ! -f "${SSH_DIR}/id_ed25519" ]]; then + echo -e "${RED}Missing: id_ed25519${NC}" + fi + if [[ ! -f "${SSH_DIR}/id_ed25519.pub" ]]; then + echo -e "${RED}Missing: id_ed25519.pub${NC}" + fi + if [[ ! -f "${SSH_DIR}/id_ed25519_agenix" ]]; then + echo -e "${RED}Missing: id_ed25519_agenix${NC}" + fi + if [[ ! -f "${SSH_DIR}/id_ed25519_agenix.pub" ]]; then + echo -e "${RED}Missing: id_ed25519_agenix.pub${NC}" + fi + echo -e "${GREEN}Run the createKeys command to generate the missing keys.${NC}" + exit 1 + fi +} + +lint_keys diff --git a/apps/aarch64-darwin/copy-keys b/apps/aarch64-darwin/copy-keys new file mode 100755 index 00000000..904cc15d --- /dev/null +++ b/apps/aarch64-darwin/copy-keys @@ -0,0 +1,68 @@ +#!/usr/bin/env bash +set -e + +RED='\033[0;31m' +GREEN='\033[0;32m' +NC='\033[0m' + +username=${USER} +export SSH_DIR=/Users/${username}/.ssh + +handle_no_usb() { + echo -e ${RED}No USB drive found or mounted.${NC}" + echo -e ${GREEN}If you have not yet set up your keys, run the script to generate new SSH keys.${NC}" + exit 1 +} + +mount_usb() { + MOUNT_PATH="" + for dev in $(diskutil list | grep -o 'disk[0-9]'); do + MOUNT_PATH="$(diskutil info /dev/${dev} | grep \"Mount Point\" | awk -F: '{print $2}' | xargs)" + if [ -n "${MOUNT_PATH}" ]; then + echo -e "${GREEN}USB drive found at ${MOUNT_PATH}.${NC}" + break + fi + done + + if [ -z "${MOUNT_PATH}" ]; then + echo -e "${RED}No USB drive found.${NC}" + fi +} + +copy_keys() { + if [ -n "${MOUNT_PATH}" ]; then + cp "${MOUNT_PATH}/id_ed25519_agenix.pub" ${SSH_DIR} + cp "${MOUNT_PATH}/id_ed25519_agenix" ${SSH_DIR} + chmod 600 ${SSH_DIR}/id_ed25519_{agenix,agenix.pub} + else + echo -e "${RED}No USB drive found. Aborting.${NC}" + exit 1 + fi +} + +setup_ssh_directory() { + mkdir -p ${SSH_DIR} +} + +set_keys() { + cp ${MOUNT_PATH}/id_ed25519_github.pub ${SSH_DIR}/id_ed25519.pub + cp ${MOUNT_PATH}/id_ed25519_github ${SSH_DIR}/id_ed25519 + chmod 600 ${SSH_DIR}/id_ed25519 + chmod 644 ${SSH_DIR}/id_ed25519.pub +} + +change_ownership() { + chown ${username}:staff ${SSH_DIR}/id_ed25519{,.pub} + chown ${username}:staff ${SSH_DIR}/id_ed25519_{agenix,agenix.pub} +} + +setup_ssh_directory +mount_usb + +if [ -z "${MOUNT_PATH}" ]; then + handle_no_usb +else + copy_keys + set_keys + change_ownership +fi diff --git a/apps/aarch64-darwin/create-keys b/apps/aarch64-darwin/create-keys new file mode 100755 index 00000000..9fdfe433 --- /dev/null +++ b/apps/aarch64-darwin/create-keys @@ -0,0 +1,46 @@ +#!/usr/bin/env bash +set -e + +RED='\033[0;31m' +GREEN='\033[0;32m' +NC='\033[0m' + +username=${USER} +export SSH_DIR=/Users/${username}/.ssh + +setup_ssh_directory() { + mkdir -p ${SSH_DIR} +} + +prompt_for_key_generation() { + local key_name=$1 + if [[ -f "${SSH_DIR}/${key_name}" ]]; then + echo -e "${RED}Existing SSH key found for ${key_name}.${NC}" + cat "${SSH_DIR}/${key_name}.pub" + read -p "Do you want to replace it? (y/n) " -n 1 -r + echo + if [[ $REPLY =~ ^[Yy]$ ]]; then + return 0 # Indicate key should be replaced + else + return 1 # Indicate key should be kept + fi + fi + return 0 # Indicate no key exists, so it should be created +} + +generate_key() { + local key_name=$1 + if prompt_for_key_generation "$key_name"; then + ssh-keygen -t ed25519 -f "${SSH_DIR}/${key_name}" -N "" + chown ${username}:staff "${SSH_DIR}/${key_name}"{,.pub} + else + echo -e "${GREEN}Kept existing ${key_name}.${NC}" + fi +} + +setup_ssh_directory +generate_key "id_ed25519" +generate_key "id_ed25519_agenix" + +echo -e "${GREEN}SSH key setup complete.${NC}" +echo -e "${GREEN}Remember to add the necessary keys to Github or other services as required.${NC}" diff --git a/apps/aarch64-darwin/rollback b/apps/aarch64-darwin/rollback new file mode 100755 index 00000000..c41b8d58 --- /dev/null +++ b/apps/aarch64-darwin/rollback @@ -0,0 +1,24 @@ +#!/bin/sh -e + +GREEN='\033[1;32m' +YELLOW='\033[1;33m' +RED='\033[1;31m' +NC='\033[0m' + +FLAKE="Dustins-MBP" + +echo "${YELLOW}Available generations:${NC}" +/run/current-system/sw/bin/darwin-rebuild --list-generations + +echo "${YELLOW}Enter the generation number for rollback:${NC}" +read GEN_NUM + +if [ -z "$GEN_NUM" ]; then + echo "${RED}No generation number entered. Aborting rollback.${NC}" + exit 1 +fi + +echo "${YELLOW}Rolling back to generation $GEN_NUM...${NC}" +/run/current-system/sw/bin/darwin-rebuild switch --flake .#$FLAKE --switch-generation $GEN_NUM + +echo "${GREEN}Rollback to generation $GEN_NUM complete!${NC}" diff --git a/apps/aarch64-linux b/apps/aarch64-linux new file mode 100644 index 00000000..1877bdc1 --- /dev/null +++ b/apps/aarch64-linux @@ -0,0 +1 @@ +x86_64-linux diff --git a/apps/x86_64-linux/apply b/apps/x86_64-linux/apply new file mode 100755 index 00000000..0a6ce005 --- /dev/null +++ b/apps/x86_64-linux/apply @@ -0,0 +1,142 @@ +#!/usr/bin/env bash + +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +# Determine the operating system +export OS=$(uname) + +# Primary network interface +if [[ "$OS" != "Darwin" ]]; then + export PRIMARY_IFACE=$(ip -o -4 route show to default | awk '{print $5}') + echo -e "${GREEN}Found primary network interface $PRIMARY_IFACE${NC}" +fi + +# Custom print function +_print() { + if [[ "$OS" == "Darwin" ]]; then + echo -e "$1" + else + echo "$1" + fi +} + +# Custom prompt function +_prompt() { + local message="$1" + local variable="$2" + + _print "$message" + read -r $variable +} + +# Fetch username from the system +export USERNAME=$(whoami) + +# If the username is 'nixos' or 'root', ask the user for their username +if [[ "$USERNAME" == "nixos" ]] || [[ "$USERNAME" == "root" ]]; then + _prompt "${YELLOW}You're running as $USERNAME. Please enter your desired username: ${NC}" USERNAME +fi + +# Check if git is available +if command -v git >/dev/null 2>&1; then + # Fetch email and name from git config + export GIT_EMAIL=$(git config --get user.email) + export GIT_NAME=$(git config --get user.name) +else + _print "${RED}Git is not available on this system.${NC}" +fi + +# If git email is not found or git is not available, ask the user +if [[ -z "$GIT_EMAIL" ]]; then + _prompt "${YELLOW}Please enter your email: ${NC}" GIT_EMAIL +fi + +# If git name is not found or git is not available, ask the user +if [[ -z "$GIT_NAME" ]]; then + _prompt "${YELLOW}Please enter your name: ${NC}" GIT_NAME +fi + +select_boot_disk() { + local disks + local _boot_disk + + _print "${YELLOW}Available disks:${NC}" + disks=$(lsblk -nd --output NAME,SIZE | grep -v loop) + echo "$disks" + + # Warning message for data deletion + _print "${RED}WARNING: All data on the chosen disk will be erased during the installation!${NC}" + _prompt "${YELLOW}Please choose your boot disk (e.g., nvme0n1, sda): ${NC}" _boot_disk + + # Confirmation for disk selection to prevent accidental data loss + _print "${YELLOW}You have selected $_boot_disk as the boot disk. This will delete everything on this disk. Are you sure? (Y/N): ${NC}" + read -r confirmation + if [[ "$confirmation" =~ ^[Yy]$ ]]; then + export BOOT_DISK=$_boot_disk + else + _print "${RED}Disk selection cancelled by the user. Please run the script again to select the correct disk.${NC}" + exit 1 + fi +} + +# Set hostname and find primary disk if this is NixOS +if [[ "$OS" != "Darwin" ]]; then + _prompt "${YELLOW}Please enter a hostname for the system: ${NC}" HOST_NAME + export HOST_NAME + select_boot_disk +fi + +# Confirmation step +confirm_details() { + _print "${GREEN}Username: $USERNAME" + _print "Email: $GIT_EMAIL" + _print "Name: $GIT_NAME${NC}" + + if([[ "$OS" != "Darwin" ]]); then + _print "${GREEN}Primary interface: $PRIMARY_IFACE" + _print "Boot disk: $BOOT_DISK" + _print "Hostname: $HOST_NAME${NC}" + fi + + _prompt "${YELLOW}Is this correct? (Y/N): ${NC}" choice + + case "$choice" in + [Nn] ) _print "${RED}Exiting script.${NC}" && exit 1;; + [Yy] ) _print "${GREEN}Continuing...${NC}";; + * ) _print "${RED}Invalid option. Exiting script.${NC}" && exit 1;; + esac +} + +# Call the confirmation function +confirm_details + +# Function to replace tokens in each file +replace_tokens() { + local file="$1" + if [[ $(basename $1) != "apply" ]]; then + if [[ "$OS" == "Darwin" ]]; then + # macOS + LC_ALL=C LANG=C sed -i '' -e "s/%USER%/$USERNAME/g" "$file" + LC_ALL=C LANG=C sed -i '' -e "s/%EMAIL%/$GIT_EMAIL/g" "$file" + LC_ALL=C LANG=C sed -i '' -e "s/%NAME%/$GIT_NAME/g" "$file" + else + # Linux or other + sed -i -e "s/%USER%/$USERNAME/g" "$file" + sed -i -e "s/%EMAIL%/$GIT_EMAIL/g" "$file" + sed -i -e "s/%NAME%/$GIT_NAME/g" "$file" + sed -i -e "s/%INTERFACE%/$PRIMARY_IFACE/g" "$file" + sed -i -e "s/%DISK%/$BOOT_DISK/g" "$file" + sed -i -e "s/%HOST%/$HOST_NAME/g" "$file" + fi + fi +} + +# Traverse directories and call replace_tokens on each Nix file +export -f replace_tokens +find . -type f -exec bash -c 'replace_tokens "$0"' {} \; + +echo "$USERNAME" > /tmp/username.txt +_print "${GREEN}User $USERNAME information applied.${NC}" diff --git a/apps/x86_64-linux/build-switch b/apps/x86_64-linux/build-switch new file mode 100755 index 00000000..5e1a68fa --- /dev/null +++ b/apps/x86_64-linux/build-switch @@ -0,0 +1,28 @@ +#!/bin/sh -e + +RED='\033[1;31m' +GREEN='\033[1;32m' +YELLOW='\033[1;33m' +NC='\033[0m' + +SYSTEM=$(uname -m) + +case "$SYSTEM" in + x86_64) + FLAKE_TARGET="x86_64-linux" + ;; + aarch64) + FLAKE_TARGET="aarch64-linux" + ;; + *) + echo -e "${RED}Unsupported architecture: $SYSTEM${NC}" + exit 1 + ;; +esac + +echo -e "${YELLOW}Starting...${NC}" + +# We pass SSH from user to root so root can download secrets from our private Github +sudo SSH_AUTH_SOCK=$SSH_AUTH_SOCK /run/current-system/sw/bin/nixos-rebuild switch --flake .#$FLAKE_TARGET $@ + +echo -e "${GREEN}Switch to new generation complete!${NC}" diff --git a/apps/x86_64-linux/check-keys b/apps/x86_64-linux/check-keys new file mode 100755 index 00000000..ae922b10 --- /dev/null +++ b/apps/x86_64-linux/check-keys @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +set -e + +RED='\033[0;31m' +GREEN='\033[0;32m' +NC='\033[0m' + +# We're assuming this is being run as root in the NixOS installer +export SSH_DIR=/root/.ssh + +check_keys() { + if [[ -f "${SSH_DIR}/id_ed25519" && -f "${SSH_DIR}/id_ed25519.pub" && -f "${SSH_DIR}/id_ed25519_agenix" && -f "${SSH_DIR}/id_ed25519_agenix.pub" ]]; then + echo -e "${GREEN}All SSH keys are present.${NC}" + else + echo -e "${RED}Some SSH keys are missing.${NC}" + if [[ ! -f "${SSH_DIR}/id_ed25519" ]]; then + echo -e "${RED}Missing: id_ed25519${NC}" + fi + if [[ ! -f "${SSH_DIR}/id_ed25519.pub" ]]; then + echo -e "${RED}Missing: id_ed25519.pub${NC}" + fi + if [[ ! -f "${SSH_DIR}/id_ed25519_agenix" ]]; then + echo -e "${RED}Missing: id_ed25519_agenix${NC}" + fi + if [[ ! -f "${SSH_DIR}/id_ed25519_agenix.pub" ]]; then + echo -e "${RED}Missing: id_ed25519_agenix.pub${NC}" + fi + echo -e "${GREEN}Run the createKeys script to generate the missing keys.${NC}" + exit 1 + fi +} + +check_keys diff --git a/apps/x86_64-linux/copy-keys b/apps/x86_64-linux/copy-keys new file mode 100755 index 00000000..660175ec --- /dev/null +++ b/apps/x86_64-linux/copy-keys @@ -0,0 +1,71 @@ +#!/usr/bin/env bash +set -e + +unmount_usb() { + if mountpoint -q /mnt/usb; then + sudo umount /mnt/usb + echo -e "\e[0;32mUSB drive unmounted.\e[0m" + fi +} + +mount_usb() { + if mountpoint -q /mnt/usb; then + echo -e "\e[0;32mUSB drive already mounted.\e[0m" + else + device_found=false + for dev in sda sdb sdc sdd sde sdf sdg sdh sdi sdj sdk sdl; do + if sudo blkid /dev/$dev | grep -iq 'TYPE="vfat"'; then + device_found=true + mkdir -p /mnt/usb + sudo mount /dev/$dev /mnt/usb && { echo -e "\e[0;32mUSB drive mounted successfully on /dev/$dev.\e[0m"; break; } || echo -e "\e[0;31mFailed to mount /dev/$dev.\e[0m" + fi + done + if [ "$device_found" = false ]; then + echo -e "\e[0;31mNo USB devices found.\e[0m" + fi + fi +} + +setup_ssh_directory() { + export SSH_DIR=/root/.ssh + mkdir -p $SSH_DIR +} + +check_file_exists() { + if [[ ! -f $1 ]]; then + echo -e "\e[0;31mError: File $1 does not exist.\e[0m" + exit 1 + fi +} + +copy_keys() { + check_file_exists "/mnt/usb/id_ed25519_agenix.pub" + check_file_exists "/mnt/usb/id_ed25519_agenix" + cp /mnt/usb/id_ed25519_agenix.pub $SSH_DIR + cp /mnt/usb/id_ed25519_agenix $SSH_DIR + chmod 600 $SSH_DIR/id_ed25519_{agenix,agenix.pub} + echo -e "\e[0;32mKeys copied successfully.\e[0m" +} + +set_keys() { + check_file_exists "/mnt/usb/id_ed25519_github.pub" + check_file_exists "/mnt/usb/id_ed25519_github" + cp /mnt/usb/id_ed25519_github.pub $SSH_DIR/id_ed25519.pub + cp /mnt/usb/id_ed25519_github $SSH_DIR/id_ed25519 + chmod 600 $SSH_DIR/id_ed25519 + chmod 644 $SSH_DIR/id_ed25519.pub +} + +change_ownership() { + chown nixos:wheel $SSH_DIR/id_ed25519{,.pub} + chown nixos:wheel $SSH_DIR/id_ed25519_{agenix,agenix.pub} +} + +trap unmount_usb EXIT + +setup_ssh_directory +mount_usb +copy_keys +set_keys +change_ownership +unmount_usb diff --git a/apps/x86_64-linux/create-keys b/apps/x86_64-linux/create-keys new file mode 100755 index 00000000..138ec6e6 --- /dev/null +++ b/apps/x86_64-linux/create-keys @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +set -e + +RED='\033[0;31m' +GREEN='\033[0;32m' +NC='\033[0m' + +# We're assuming this is being run as root in the NixOS installer +export SSH_DIR=/root/.ssh + +setup_ssh_directory() { + mkdir -p ${SSH_DIR} +} + +generate_keys() { + ssh-keygen -t ed25519 -f "${SSH_DIR}/id_ed25519" -N "" + ssh-keygen -t ed25519 -f "${SSH_DIR}/id_ed25519_agenix" -N "" + chmod 600 ${SSH_DIR}/id_ed25519{,_agenix}{,.pub} +} + +setup_ssh_directory +generate_keys + +echo -e "${GREEN}New SSH keys have been generated.${NC}" +echo -e "${GREEN}1) Add the id_ed25519 key to Github.${NC}" +cat "${SSH_DIR}/id_ed25519.pub" +echo -e "${GREEN}2) Create a private nix-secrets repo in Github, even if it's empty.${NC}" diff --git a/apps/x86_64-linux/install b/apps/x86_64-linux/install new file mode 100755 index 00000000..87db3cf5 --- /dev/null +++ b/apps/x86_64-linux/install @@ -0,0 +1,80 @@ +#!/usr/bin/env bash +set -exu + +check_installer() { + if [ -e /etc/NIXOS ]; then + echo -e "\e[1;32mRunning in the NixOS installer environment.\e[0m" + else + echo -e "\e[1;31mNot running in the NixOS installer environment.\e[0m" + exit 1 + fi +} + +cleanup() { + rm -rf nixos-config-main.zip nixos-config-main nixos-config +} + +download_config() { + curl -LJ0 https://github.com/dustinlyons/nixos-config/archive/main.zip -o nixos-config-main.zip + unzip nixos-config-main.zip + mv nixos-config-main/templates/starter nixos-config + cd nixos-config +} + +run_apply() { + ./apps/x86_64-linux/apply + if [ ! -f /tmp/username.txt ]; then + echo -e "\e[1;31mError: /tmp/username.txt does not exist.\e[0m" + exit 1 + fi + export USERNAME=$(cat /tmp/username.txt) +} + +run_disko() { + sudo nix run --extra-experimental-features nix-command --extra-experimental-features flakes \ + github:nix-community/disko -- --mode zap_create_mount ./modules/nixos/disk-config.nix +} + +setup_files() { + sudo mkdir -p /mnt/etc/nixos + sudo cp -r * /mnt/etc/nixos + cd /mnt/etc/nixos +} + +install_nixos() { + ARCH=$(uname -m) + + case "$ARCH" in + x86_64) + FLAKE_TARGET="x86_64-linux" + ;; + aarch64) + FLAKE_TARGET="aarch64-linux" + ;; + *) + echo -e "${RED}Unsupported architecture: $ARCH${CLEAR}" + exit 1 + ;; + esac + + sudo nixos-install --flake .#$FLAKE_TARGET $@ + sudo chmod -R 775 /mnt/etc/nixos +} + +prompt_reboot() { + read -p "Do you want to reboot now? (y/yes) " choice + case "$choice" in + y|Y|yes|YES ) echo -e "\e[1;32mRebooting...\e[0m" && sudo reboot;; + * ) echo -e "\e[1;33mReboot skipped.\e[0m";; + esac +} + +cleanup +check_installer +download_config +run_apply +run_disko +setup_files +install_nixos +cleanup +prompt_reboot diff --git a/apps/x86_64-linux/install-with-secrets b/apps/x86_64-linux/install-with-secrets new file mode 100755 index 00000000..f6cb0a03 --- /dev/null +++ b/apps/x86_64-linux/install-with-secrets @@ -0,0 +1,104 @@ +#!/usr/bin/env bash +set -exu + +check_installer() { + if [ -e /etc/NIXOS ]; then + echo -e "\e[1;32mRunning in the NixOS installer environment.\e[0m" + else + echo -e "\e[1;31mNot running in the NixOS installer environment.\e[0m" + exit 1 + fi +} + +cleanup() { + rm -rf nixos-config-main.zip nixos-config-main nixos-config +} + +download_config() { + curl -LJ0 https://github.com/dustinlyons/nixos-config/archive/main.zip -o nixos-config-main.zip + unzip nixos-config-main.zip + mv nixos-config-main/templates/starterWithSecrets nixos-config + cd nixos-config +} + +run_apply() { + ./apps/x86_64-linux/apply + if [ ! -f /tmp/username.txt ]; then + echo -e "\e[1;31mError: /tmp/username.txt does not exist.\e[0m" + exit 1 + fi + export USERNAME=$(cat /tmp/username.txt) +} + +run_disko() { + sudo nix run --extra-experimental-features nix-command --extra-experimental-features flakes \ + github:nix-community/disko -- --mode zap_create_mount ./modules/nixos/disk-config.nix +} + +setup_files() { + sudo mkdir -p /mnt/etc/nixos + sudo cp -r * /mnt/etc/nixos + cd /mnt/etc/nixos + + mkdir -p /root/.ssh + touch /root/.ssh/known_hosts + ssh-keyscan -t ed25519 github.com >> /root/.ssh/known_hosts +} + +setup_ssh_keys() { + mkdir -p /mnt/home/${USERNAME}/.ssh + chown nixos /mnt/home/${USERNAME}/.ssh + + chown nixos /root/.ssh/id_ed25519_agenix{,.pub} + cp --preserve=all /root/.ssh/id_ed25519_agenix /mnt/home/${USERNAME}/.ssh/id_ed25519 + cp --preserve=all /root/.ssh/id_ed25519_agenix.pub /mnt/home/${USERNAME}/.ssh/id_ed25519.pub + cp --preserve=all /root/.ssh/id_ed25519 /mnt/home/${USERNAME}/.ssh/id_github + cp --preserve=all /root/.ssh/id_ed25519.pub /mnt/home/${USERNAME}/.ssh/id_github.pub + + chmod 600 /mnt/home/${USERNAME}/.ssh/id_ed25519{,.pub} + chmod 600 /mnt/home/${USERNAME}/.ssh/id_github{,.pub} +} + +link_home_dir() { + ln -s /mnt/home/${USERNAME} /home/${USERNAME} # Used to grab initial secrets +} + +install_nixos() { + ARCH=$(uname -m) + + case "$ARCH" in + x86_64) + FLAKE_TARGET="x86_64-linux" + ;; + aarch64) + FLAKE_TARGET="aarch64-linux" + ;; + *) + echo -e "${RED}Unsupported architecture: $ARCH${CLEAR}" + exit 1 + ;; + esac + + sudo nixos-install --flake .#$FLAKE_TARGET $@ + sudo chmod -R 775 /mnt/etc/nixos +} + +prompt_reboot() { + read -p "Do you want to reboot now? (y/yes) " choice + case "$choice" in + y|Y|yes|YES ) echo -e "\e[1;32mRebooting...\e[0m" && sudo reboot;; + * ) echo -e "\e[1;33mReboot skipped.\e[0m";; + esac +} + +cleanup +check_installer +download_config +run_apply +run_disko +setup_files +setup_ssh_keys +link_home_dir +install_nixos +cleanup +prompt_reboot diff --git a/flake.lock b/flake.lock index 4294ddad..206a9a02 100644 --- a/flake.lock +++ b/flake.lock @@ -47,6 +47,23 @@ "url": "ssh://gitea@git.sealight.xyz/aynish/basant" } }, + "brew-src": { + "flake": false, + "locked": { + "lastModified": 1705326576, + "narHash": "sha256-9PvMgHgdbpb5vBO8fHCRufodR731ynzGMF9+68vKWck=", + "owner": "Homebrew", + "repo": "brew", + "rev": "1c612baa096c69f2fcb221c74e6f5b9979efdcee", + "type": "github" + }, + "original": { + "owner": "Homebrew", + "ref": "4.2.4", + "repo": "brew", + "type": "github" + } + }, "darwin": { "inputs": { "nixpkgs": [ @@ -69,6 +86,27 @@ "type": "github" } }, + "darwin_2": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1709771483, + "narHash": "sha256-Hjzu9nCknHLQvhdaRFfCEprH0o15KcaNu1QDr3J88DI=", + "owner": "LnL7", + "repo": "nix-darwin", + "rev": "550340062c16d7ef8c2cc20a3d2b97bcd3c6b6f6", + "type": "github" + }, + "original": { + "owner": "LnL7", + "ref": "master", + "repo": "nix-darwin", + "type": "github" + } + }, "deploy-rs": { "inputs": { "flake-compat": "flake-compat", @@ -267,6 +305,24 @@ "inputs": { "systems": "systems_3" }, + "locked": { + "lastModified": 1687709756, + "narHash": "sha256-Y5wKlQSkgEK2weWdOu4J3riRd+kV/VCgHsqLNTTWQ/0=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "dbabf0ca0c0c4bce6ea5eaf65af5cb694d2082c7", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_5": { + "inputs": { + "systems": "systems_4" + }, "locked": { "lastModified": 1681202837, "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=", @@ -360,6 +416,54 @@ "type": "github" } }, + "homebrew-bundle": { + "flake": false, + "locked": { + "lastModified": 1709834002, + "narHash": "sha256-KNRwMnyo6ZLphIh2bn02KNOtRf2X3NHqUbS7y4Vmn+M=", + "owner": "homebrew", + "repo": "homebrew-bundle", + "rev": "bb1c80baa7fac67bbffe81a2862c75a5dc7ea4a7", + "type": "github" + }, + "original": { + "owner": "homebrew", + "repo": "homebrew-bundle", + "type": "github" + } + }, + "homebrew-cask": { + "flake": false, + "locked": { + "lastModified": 1709955474, + "narHash": "sha256-pE5x579FqCieeeEmrUtNKoBsMG41WSOfGWtXCTI9FP4=", + "owner": "homebrew", + "repo": "homebrew-cask", + "rev": "43b9db57368e350c116398c7da6cb5401cd37ebe", + "type": "github" + }, + "original": { + "owner": "homebrew", + "repo": "homebrew-cask", + "type": "github" + } + }, + "homebrew-core": { + "flake": false, + "locked": { + "lastModified": 1709956143, + "narHash": "sha256-5eyfpnVhxVv3+n53vp4j9DNx7O+mqtQqUn90JKS1PMM=", + "owner": "homebrew", + "repo": "homebrew-core", + "rev": "a38d7e99bc103e9564208f2d155701d70001c8cc", + "type": "github" + }, + "original": { + "owner": "homebrew", + "repo": "homebrew-core", + "type": "github" + } + }, "llamacpp": { "inputs": { "flake-utils": "flake-utils_3", @@ -381,12 +485,51 @@ "type": "github" } }, + "nix-darwin": { + "inputs": { + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1688307440, + "narHash": "sha256-7PTjbN+/+b799YN7Tk2SS5Vh8A0L3gBo8hmB7Y0VXug=", + "owner": "LnL7", + "repo": "nix-darwin", + "rev": "b06bab83bdf285ea0ae3c8e145a081eb95959047", + "type": "github" + }, + "original": { + "owner": "LnL7", + "repo": "nix-darwin", + "type": "github" + } + }, + "nix-homebrew": { + "inputs": { + "brew-src": "brew-src", + "flake-utils": "flake-utils_4", + "nix-darwin": "nix-darwin", + "nixpkgs": "nixpkgs_2" + }, + "locked": { + "lastModified": 1705952034, + "narHash": "sha256-H0nk8Gk8kPw4yi2WwOTsSHgPrzSwyNgWEYHk10IJwfc=", + "owner": "zhaofengli-wip", + "repo": "nix-homebrew", + "rev": "40f5ee46b58e7c5f1927e2c5a583dc3d7e571ed9", + "type": "github" + }, + "original": { + "owner": "zhaofengli-wip", + "repo": "nix-homebrew", + "type": "github" + } + }, "nix-matrix-appservices": { "inputs": { "devshell": "devshell", "flake-compat": "flake-compat_3", "nixlib": "nixlib", - "nixpkgs": "nixpkgs" + "nixpkgs": "nixpkgs_3" }, "locked": { "lastModified": 1683490239, @@ -434,6 +577,35 @@ } }, "nixpkgs": { + "locked": { + "lastModified": 1687274257, + "narHash": "sha256-TutzPriQcZ8FghDhEolnHcYU2oHIG5XWF+/SUBNnAOE=", + "path": "/nix/store/22qgs3skscd9bmrxv9xv4q5d4wwm5ppx-source", + "rev": "2c9ecd1f0400076a4d6b2193ad468ff0a7e7fdc5", + "type": "path" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1688049487, + "narHash": "sha256-100g4iaKC9MalDjUW9iN6Jl/OocTDtXdeAj7pEGIRh4=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "4bc72cae107788bf3f24f30db2e2f685c9298dc9", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_3": { "locked": { "lastModified": 1662099760, "narHash": "sha256-MdZLCTJPeHi/9fg6R9fiunyDwP3XHJqDd51zWWz9px0=", @@ -449,7 +621,7 @@ "type": "github" } }, - "nixpkgs_2": { + "nixpkgs_4": { "locked": { "lastModified": 1704874635, "narHash": "sha256-YWuCrtsty5vVZvu+7BchAxmcYzTMfolSPP5io8+WYCg=", @@ -505,16 +677,21 @@ "inputs": { "agenix": "agenix", "basant": "basant", + "darwin": "darwin_2", "deploy-rs": "deploy-rs", "disko": "disko", "eww": "eww", "grasp": "grasp", "hardware": "hardware", "home-manager": "home-manager_2", + "homebrew-bundle": "homebrew-bundle", + "homebrew-cask": "homebrew-cask", + "homebrew-core": "homebrew-core", "llamacpp": "llamacpp", + "nix-homebrew": "nix-homebrew", "nix-matrix-appservices": "nix-matrix-appservices", "nixos-hardware": "nixos-hardware", - "nixpkgs": "nixpkgs_2", + "nixpkgs": "nixpkgs_4", "nur": "nur", "poonam": "poonam", "rust-overlay": "rust-overlay", @@ -525,7 +702,7 @@ }, "rust-overlay": { "inputs": { - "flake-utils": "flake-utils_4", + "flake-utils": "flake-utils_5", "nixpkgs": [ "nixpkgs" ] @@ -606,6 +783,21 @@ "type": "github" } }, + "systems_4": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, "tidal-src": { "flake": false, "locked": { diff --git a/flake.nix b/flake.nix index caac031d..f33377d0 100644 --- a/flake.nix +++ b/flake.nix @@ -34,6 +34,27 @@ # Matrix nix-matrix-appservices.url = "gitlab:coffeetables/nix-matrix-appservices"; + # OSX + darwin = { + url = "github:LnL7/nix-darwin/master"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + nix-homebrew = { + url = "github:zhaofengli-wip/nix-homebrew"; + }; + homebrew-bundle = { + url = "github:homebrew/homebrew-bundle"; + flake = false; + }; + homebrew-core = { + url = "github:homebrew/homebrew-core"; + flake = false; + }; + homebrew-cask = { + url = "github:homebrew/homebrew-cask"; + flake = false; + }; + # Others nur.url = "github:nix-community/NUR"; rust-overlay = { @@ -76,6 +97,11 @@ , eww , llamacpp , vimwikicli + , darwin + , nix-homebrew + , homebrew-bundle + , homebrew-core + , homebrew-cask , ... }@inputs: let @@ -118,7 +144,8 @@ nix-matrix-appservices.overlay unstableOverlay llamaOverlay - vimwikiOverlay + # TODO Not available publically + # vimwikiOverlay self.overlays.additions self.overlays.modifications ]; @@ -136,14 +163,15 @@ tidalcycles.overlays.default # needed for nvim which comes pre-installed lol ]; }); + + darwinSystems = [ "aarch64-darwin" "x86_64-darwin" ]; in { - # Your custom packages - # Acessible through 'nix build', 'nix shell', etc packages = forAllSystems (system: let pkgs = nixpkgsFor.${system}; in import ./pkgs { pkgs = pkgs; } ); + # Devshell for bootstrapping # Acessible through 'nix develop' or 'nix-shell' (legacy) devShells = forAllSystems (system: @@ -160,6 +188,39 @@ # These are usually stuff you would upstream into home-manager homeManagerModules = import ./modules/home-manager; + darwinConfigurations = { + "Anishs-MacBook-Pro" = darwin.lib.darwinSystem rec { + system = "aarch64-darwin"; + pkgs = nixpkgsFor.${system}; + specialArgs = { inherit inputs self; }; + modules = [ + ./hosts/darwin + # agenix.darwinModule.age + home-manager.darwinModules.home-manager + nix-homebrew.darwinModules.nix-homebrew + { + users.users.anishlakhwara.home = "/Users/anishlakhwara"; + home-manager = { + users.anishlakhwara = import ./home/darwin; + useGlobalPkgs = true; + useUserPackages = true; + }; + nix-homebrew = { + user = "anishlakhwara"; + enable = true; + taps = { + "homebrew/homebrew-core" = homebrew-core; + "homebrew/homebrew-cask" = homebrew-cask; + "homebrew/homebrew-bundle" = homebrew-bundle; + }; + mutableTaps = false; + autoMigrate = true; + }; + } + ]; + }; + }; + # NixOS configuration entrypoint nixosConfigurations = { curve = nixpkgs.lib.nixosSystem rec { diff --git a/home/darwin/default.nix b/home/darwin/default.nix new file mode 100644 index 00000000..b0eda243 --- /dev/null +++ b/home/darwin/default.nix @@ -0,0 +1,26 @@ +{ self, pkgs, ... }: +{ + imports = [ + ../profiles/nvim + ../profiles/cli + ../profiles/direnv + ../profiles/git + ../profiles/task + ../profiles/kitty + # ../profiles/firefox + ]; + + home.username = "anishlakhwara"; + home.homeDirectory = "/Users/anishlakhwara"; + home.stateVersion = "22.05"; + + programs.zsh.initExtra = "PATH=/Users/anishlakhwara/.sg:/opt/homebrew/bin:$PATH"; + + # Managing sketchybar plugins from home-manager + home.file = { + ".config/sketchybar" = { + source = ./sketchybar; + recursive = true; + }; + }; +} diff --git a/home/darwin/sketchybar/items/battery.sh b/home/darwin/sketchybar/items/battery.sh new file mode 100644 index 00000000..0414f3bc --- /dev/null +++ b/home/darwin/sketchybar/items/battery.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +COLOR="$CYAN" + +sketchybar --add item battery right \ + --set battery \ + update_freq=60 \ + icon.color="$COLOR" \ + icon.padding_left=10 \ + label.padding_right=10 \ + label.color="$COLOR" \ + background.height=26 \ + background.corner_radius="$CORNER_RADIUS" \ + background.padding_right=5 \ + background.border_width="$BORDER_WIDTH" \ + background.border_color="$COLOR" \ + background.color="$BAR_COLOR" \ + background.drawing=on \ + script="$PLUGIN_DIR/power.sh" \ + --subscribe battery power_source_change diff --git a/home/darwin/sketchybar/items/calendar.sh b/home/darwin/sketchybar/items/calendar.sh new file mode 100644 index 00000000..064a1919 --- /dev/null +++ b/home/darwin/sketchybar/items/calendar.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +COLOR="$BLUE" + +sketchybar --add item calendar right \ + --set calendar update_freq=15 \ + icon.color="$COLOR" \ + icon.padding_left=10 \ + label.color="$COLOR" \ + label.padding_right=10 \ + background.height=26 \ + background.corner_radius="$CORNER_RADIUS" \ + background.padding_right=5 \ + background.border_width="$BORDER_WIDTH" \ + background.border_color="$COLOR" \ + background.color="$BAR_COLOR" \ + background.drawing=on \ + script="$PLUGIN_DIR/calendar.sh" diff --git a/home/darwin/sketchybar/items/clock.sh b/home/darwin/sketchybar/items/clock.sh new file mode 100644 index 00000000..0dbf7e41 --- /dev/null +++ b/home/darwin/sketchybar/items/clock.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +COLOR="$MAGENTA" + +sketchybar --add item clock right \ + --set clock update_freq=60 \ + icon.padding_left=10 \ + icon.color="$COLOR" \ + icon=" " \ + label.color="$COLOR" \ + label.padding_right=5 \ + label.width=43 \ + align=center \ + background.height=26 \ + background.corner_radius="$CORNER_RADIUS" \ + background.padding_right=2 \ + background.border_width="$BORDER_WIDTH" \ + background.border_color="$COLOR" \ + background.color="$BAR_COLOR" \ + background.drawing=on \ + script="$PLUGIN_DIR/clock.sh" diff --git a/home/darwin/sketchybar/items/cpu.sh b/home/darwin/sketchybar/items/cpu.sh new file mode 100644 index 00000000..b4c6493e --- /dev/null +++ b/home/darwin/sketchybar/items/cpu.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +COLOR="$YELLOW" + +sketchybar --add item cpu right \ + --set cpu \ + update_freq=3 \ + icon.color="$COLOR" \ + icon.padding_left=10 \ + label.color="$COLOR" \ + label.padding_right=10 \ + background.height=26 \ + background.corner_radius="$CORNER_RADIUS" \ + background.padding_right=5 \ + background.border_width="$BORDER_WIDTH" \ + background.border_color="$COLOR" \ + background.color="$BAR_COLOR" \ + background.drawing=on \ + script="$PLUGIN_DIR/cpu.sh" diff --git a/home/darwin/sketchybar/items/front_app.sh b/home/darwin/sketchybar/items/front_app.sh new file mode 100644 index 00000000..ecee1a8c --- /dev/null +++ b/home/darwin/sketchybar/items/front_app.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +COLOR="$WHITE" + +sketchybar \ + --add item front_app left \ + --set front_app script="$PLUGIN_DIR/front_app.sh" \ + icon.drawing=off \ + background.height=26 \ + background.padding_left=0 \ + background.padding_right=10 \ + background.border_width="$BORDER_WIDTH" \ + background.border_color="$COLOR" \ + background.corner_radius="$CORNER_RADIUS" \ + background.color="$BAR_COLOR" \ + label.color="$COLOR" \ + label.padding_left=10 \ + label.padding_right=10 \ + associated_display=active \ + --subscribe front_app front_app_switched diff --git a/home/darwin/sketchybar/items/spaces.sh b/home/darwin/sketchybar/items/spaces.sh new file mode 100644 index 00000000..52743696 --- /dev/null +++ b/home/darwin/sketchybar/items/spaces.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash + +SPACE_ICONS=("1" "2" "3" "4" "5" "6" "7" "8" "9" "10") + +sketchybar --add item spacer.1 left \ + --set spacer.1 background.drawing=off \ + label.drawing=off \ + icon.drawing=off \ + width=10 + +for i in {0..9}; do + sid=$((i + 1)) + sketchybar --add space space.$sid left \ + --set space.$sid associated_space=$sid \ + label.drawing=off \ + icon.padding_left=10 \ + icon.padding_right=10 \ + background.padding_left=-5 \ + background.padding_right=-5 \ + script="$PLUGIN_DIR/space.sh" +done + +sketchybar --add item spacer.2 left \ + --set spacer.2 background.drawing=off \ + label.drawing=off \ + icon.drawing=off \ + width=5 + +sketchybar --add bracket spaces '/space.*/' \ + --set spaces background.border_width="$BORDER_WIDTH" \ + background.border_color="$RED" \ + background.corner_radius="$CORNER_RADIUS" \ + background.color="$BAR_COLOR" \ + background.height=26 \ + background.drawing=on + +sketchybar --add item separator left \ + --set separator icon= \ + icon.font="$FONT:Regular:16.0" \ + background.padding_left=26 \ + background.padding_right=15 \ + label.drawing=off \ + associated_display=active \ + icon.color="$YELLOW" diff --git a/home/darwin/sketchybar/items/spotify.sh b/home/darwin/sketchybar/items/spotify.sh new file mode 100644 index 00000000..b94fe7aa --- /dev/null +++ b/home/darwin/sketchybar/items/spotify.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +COLOR="$ORANGE" + +sketchybar --add item spotify q \ + --set spotify \ + scroll_texts=on \ + icon=󰎆 \ + icon.color="$COLOR" \ + icon.padding_left=10 \ + background.color="$BAR_COLOR" \ + background.height=26 \ + background.corner_radius="$CORNER_RADIUS" \ + background.border_width="$BORDER_WIDTH" \ + background.border_color="$COLOR" \ + background.padding_right=-5 \ + background.drawing=on \ + label.padding_right=10 \ + label.max_chars=20 \ + associated_display=active \ + updates=on \ + script="$PLUGIN_DIR/spotify.sh" \ + --subscribe spotify media_change diff --git a/home/darwin/sketchybar/items/volume.sh b/home/darwin/sketchybar/items/volume.sh new file mode 100644 index 00000000..77f746db --- /dev/null +++ b/home/darwin/sketchybar/items/volume.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +COLOR="$GREEN" + +sketchybar \ + --add item sound right \ + --set sound \ + icon.color="$COLOR" \ + icon.padding_left=10 \ + label.color="$COLOR" \ + label.padding_right=10 \ + background.height=26 \ + background.corner_radius="$CORNER_RADIUS" \ + background.padding_right=5 \ + background.border_width="$BORDER_WIDTH" \ + background.border_color="$COLOR" \ + background.color="$BAR_COLOR" \ + background.drawing=on \ + script="$PLUGIN_DIR/sound.sh" \ + --subscribe sound volume_change diff --git a/home/darwin/sketchybar/plugins/calendar.sh b/home/darwin/sketchybar/plugins/calendar.sh new file mode 100755 index 00000000..9194e224 --- /dev/null +++ b/home/darwin/sketchybar/plugins/calendar.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +sketchybar --set "$NAME" icon="󰸗 " label="$(date '+%a %d. %b')" diff --git a/home/darwin/sketchybar/plugins/clock.sh b/home/darwin/sketchybar/plugins/clock.sh new file mode 100755 index 00000000..f5f6d9f2 --- /dev/null +++ b/home/darwin/sketchybar/plugins/clock.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +LABEL=$(date '+%H:%M') +sketchybar --set "$NAME" icon=" " label="$LABEL" diff --git a/home/darwin/sketchybar/plugins/cpu.sh b/home/darwin/sketchybar/plugins/cpu.sh new file mode 100755 index 00000000..77e7573b --- /dev/null +++ b/home/darwin/sketchybar/plugins/cpu.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +sketchybar --set "$NAME" icon="" label="$(ps -A -o %cpu | awk '{s+=$1} END {s /= 8} END {printf "%.1f%%\n", s}')" diff --git a/home/darwin/sketchybar/plugins/front_app.sh b/home/darwin/sketchybar/plugins/front_app.sh new file mode 100755 index 00000000..8f446a35 --- /dev/null +++ b/home/darwin/sketchybar/plugins/front_app.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +case "$SENDER" in +"front_app_switched") + sketchybar --set "$NAME" label="$INFO" + ;; +esac diff --git a/home/darwin/sketchybar/plugins/power.sh b/home/darwin/sketchybar/plugins/power.sh new file mode 100755 index 00000000..181ae01e --- /dev/null +++ b/home/darwin/sketchybar/plugins/power.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +PERCENTAGE=$(pmset -g batt | grep -Eo "\d+%" | cut -d% -f1) +CHARGING=$(pmset -g batt | grep 'AC Power') + +if [ "$PERCENTAGE" = "" ]; then + exit 0 +fi + +case ${PERCENTAGE} in +9[0-9] | 100) + ICON=" " + ;; +[6-8][0-9]) + ICON=" " + ;; +[3-5][0-9]) + ICON=" " + ;; +[1-2][0-9]) + ICON=" " + ;; +*) ICON=" " ;; +esac + +if [ "$CHARGING" != "" ]; then + ICON="" +fi + +sketchybar --set "$NAME" icon="$ICON" label="${PERCENTAGE}% " diff --git a/home/darwin/sketchybar/plugins/sound.sh b/home/darwin/sketchybar/plugins/sound.sh new file mode 100755 index 00000000..65f9446a --- /dev/null +++ b/home/darwin/sketchybar/plugins/sound.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +VOLUME=$(osascript -e "output volume of (get volume settings)") +MUTED=$(osascript -e "output muted of (get volume settings)") + +if [ "$MUTED" != "false" ]; then + ICON="󰖁 " + VOLUME=0 +else + case ${VOLUME} in + 100) ICON=" " ;; + [5-9]*) ICON=" " ;; + [0-9]*) ICON=" " ;; + *) ICON=" " ;; + esac +fi + +sketchybar -m \ + --set "$NAME" icon=$ICON \ + --set "$NAME" label="$VOLUME%" diff --git a/home/darwin/sketchybar/plugins/space.sh b/home/darwin/sketchybar/plugins/space.sh new file mode 100755 index 00000000..79b4d338 --- /dev/null +++ b/home/darwin/sketchybar/plugins/space.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +source "$HOME/.config/sketchybar/variables.sh" # Loads all defined colors + +SPACE_ICONS=(" " " " "󰺻 " " " " " "6" "7" "8" "9" "10") + +SPACE_CLICK_SCRIPT="yabai -m space --focus $SID 2>/dev/null" + +if [ "$SELECTED" = "true" ]; then + sketchybar --animate tanh 5 --set "$NAME" \ + icon.color="$RED" \ + icon="${SPACE_ICONS[$SID - 1]}" \ + click_script="$SPACE_CLICK_SCRIPT" +else + sketchybar --animate tanh 5 --set "$NAME" \ + icon.color="$COMMENT" \ + icon="${SPACE_ICONS[$SID - 1]}" \ + click_script="$SPACE_CLICK_SCRIPT" +fi diff --git a/home/darwin/sketchybar/plugins/spotify.sh b/home/darwin/sketchybar/plugins/spotify.sh new file mode 100755 index 00000000..d0dbc33e --- /dev/null +++ b/home/darwin/sketchybar/plugins/spotify.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +STATE="$(echo "$INFO" | jq -r '.state')" +APP="$(echo "$INFO" | jq -r '.app')" + +if [ "$STATE" = "playing" ] && [ "$APP" == "Spotify" ]; then + MEDIA="$(echo "$INFO" | jq -r '.title + " - " + .artist')" + sketchybar --set "$NAME" label="$MEDIA" drawing=on +else + sketchybar --set "$NAME" drawing=off +fi diff --git a/home/darwin/sketchybar/variables.sh b/home/darwin/sketchybar/variables.sh new file mode 100644 index 00000000..84ca8c83 --- /dev/null +++ b/home/darwin/sketchybar/variables.sh @@ -0,0 +1,50 @@ +#!/usr/bin/env sh + +# Color Palette +# Tokyonight Night +BLACK=0xff24283b +WHITE=0xffa9b1d6 +MAGENTA=0xffbb9af7 +BLUE=0xff7aa2f7 +CYAN=0xff7dcfff +GREEN=0xff9ece6a +YELLOW=0xffe0af68 +ORANGE=0xffff9e64 +RED=0xfff7768e +BAR_COLOR=0xff1a1b26 +COMMENT=0xff565f89 + +# Tokyonight Day +# BLACK=0xffe9e9ed +# WHITE=0xff3760bf +# MAGENTA=0xff9854f1 +# BLUE=0xff2e7de9 +# CYAN=0xff007197 +# GREEN=0xff587539 +# YELLOW=0xff8c6c3e +# ORANGE=0xffb15c00 +# RED=0xfff52a65 +# BAR_COLOR=0xffe1e2e7 + +TRANSPARENT=0x00000000 + +# General bar colors +ICON_COLOR=$WHITE # Color of all icons +LABEL_COLOR=$WHITE # Color of all labels + +ITEM_DIR="$HOME/.config/sketchybar/items" +PLUGIN_DIR="$HOME/.config/sketchybar/plugins" + +FONT="Iosevka Nerd Font" + +PADDINGS=3 + +POPUP_BORDER_WIDTH=2 +POPUP_CORNER_RADIUS=11 +POPUP_BACKGROUND_COLOR=$BLACK +POPUP_BORDER_COLOR=$COMMENT + +CORNER_RADIUS=15 +BORDER_WIDTH=2 + +SHADOW=on diff --git a/home/gui/default.nix b/home/gui/default.nix index 152b1685..9b846f1e 100644 --- a/home/gui/default.nix +++ b/home/gui/default.nix @@ -8,5 +8,6 @@ ../profiles/cal ../profiles/sync/kitaab ../profiles/ssh + ../profiles/kitty ]; } diff --git a/home/profiles/cli/default.nix b/home/profiles/cli/default.nix index 3eb0bdf8..9d423c98 100644 --- a/home/profiles/cli/default.nix +++ b/home/profiles/cli/default.nix @@ -2,31 +2,37 @@ { home.packages = with pkgs; [ binutils - coreutils + # coreutils dnsutils dasht dosfstools - #git + # git bottom gptfdisk starship - iputils - jq + # TODO Not available on Darwin + # iputils + # usbutils + # cached-nix-shell + # utillinux + # strace + # mtr + # gdb + # fontconfig + # whois + + # jq manix moreutils nix-index - cached-nix-shell nmap ripgrep skim tealdeer - usbutils - utillinux - whois iftop wget curl - exa + eza bat fd ncdu @@ -35,11 +41,9 @@ nix-index silver-searcher tcpdump - mtr file lsof atool - strace zip unzip rsync @@ -48,18 +52,16 @@ glow pass less - gdb xxd taskwarrior gnupg syncthing dijo - #ssb-patchwork - fontconfig + # ssb-patchwork pandoc taskwarrior-tui - python3Packages.howdoi - vimwiki-cli + # TODO marked broken + # python3Packages.howdoi (pkgs.writeScriptBin "jq-repl" '' #!/usr/bin/env bash @@ -202,7 +204,8 @@ enableZshIntegration = true; }; - services.kdeconnect.enable = true; + # Only available on Linux + # services.kdeconnect.enable = true; home.shellAliases = { # quick cd @@ -216,9 +219,9 @@ gen-secret = "< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c\${1:-32};echo;"; # modern cli tools - ls = "exa --icons"; - l = "exa -l --icons"; - la = "exa -la --icons"; + ls = "eza --icons"; + l = "eza -l --icons"; + la = "eza -la --icons"; tree = "ls --tree --icons"; cat = "bat"; unzip = "aunpack"; @@ -272,6 +275,7 @@ srch = "ns nixpkgs"; orch = "ns override"; nrb = "cd /tmp; sudo nixos-rebuild switch --flake '/home/anish/usr/helm#curve'; cd $OLDPWD"; + nrd = "cd /tmp; darwin-rebuild switch --flake /Users/anishlakhwara/usr/helm#Anishs-MacBook-Pro; cd $OLDPWD"; nrt = "cd /tmp; sudo nixos-rebuild test --flake '/home/anish/usr/helm#curve'; cd $OLDPWD"; ned = "cd /home/anish/usr/helm; vim; cd $OLDPWD"; ncd = "cd /home/anish/usr/helm"; diff --git a/home/profiles/desktop/default.nix b/home/profiles/desktop/default.nix index 054289d6..ce80b2d1 100644 --- a/home/profiles/desktop/default.nix +++ b/home/profiles/desktop/default.nix @@ -26,7 +26,6 @@ in gtk-engine-murrine gtk_engines maim - kitty libreoffice inotify-tools offpunk @@ -66,8 +65,6 @@ in recursive = true; }; ".config/dunst/dunstrc".source = ./dunstrc; - ".config/kitty/kitty.conf".source = ./kitty.conf; - ".config/kitty/ayu.conf".source = ./ayu-kitty.conf; ".config/zathura/zathurarc".source = ./zathurarc; ".background-image".source = ./background.jpg; #gtk4 theme diff --git a/home/profiles/desktop/ayu-dark-kitty.conf b/home/profiles/kitty/ayu-dark-kitty.conf similarity index 100% rename from home/profiles/desktop/ayu-dark-kitty.conf rename to home/profiles/kitty/ayu-dark-kitty.conf diff --git a/home/profiles/desktop/ayu-kitty.conf b/home/profiles/kitty/ayu-kitty.conf similarity index 100% rename from home/profiles/desktop/ayu-kitty.conf rename to home/profiles/kitty/ayu-kitty.conf diff --git a/home/profiles/kitty/default.nix b/home/profiles/kitty/default.nix new file mode 100644 index 00000000..2899c3cc --- /dev/null +++ b/home/profiles/kitty/default.nix @@ -0,0 +1,11 @@ +{ pkgs, config, lib, ... }: + +{ + home.packages = with pkgs; [ + kitty + ]; + home.file = { + ".config/kitty/kitty.conf".source = ./kitty.conf; + ".config/kitty/ayu.conf".source = ./ayu-kitty.conf; + }; +} diff --git a/home/profiles/desktop/kitty.conf b/home/profiles/kitty/kitty.conf similarity index 90% rename from home/profiles/desktop/kitty.conf rename to home/profiles/kitty/kitty.conf index 388f4ed2..5c1400ac 100644 --- a/home/profiles/desktop/kitty.conf +++ b/home/profiles/kitty/kitty.conf @@ -8,6 +8,7 @@ open_url_with default mouse_map left click ungrabbed mouse_click_url_or_select confirm_os_window_close 0 enable_audio_bell no +hide_window_decorations titlebar-only -- Allows zen-mode.nvim to increase font size -- allow_remote_control socket-only -- listen_on unix:/tmp/kitty diff --git a/home/profiles/nvim/default.nix b/home/profiles/nvim/default.nix index ed44f780..34544a49 100644 --- a/home/profiles/nvim/default.nix +++ b/home/profiles/nvim/default.nix @@ -624,16 +624,16 @@ in capabilities = require('cmp_nvim_lsp').default_capabilities() - -- fennel-ls is bleeding edge local lspconfig = require('lspconfig') - require("lspconfig.configs")["fennel-ls"] = { - default_config = { - cmd = {"fennel-ls"}, - filetypes = {"fennel"}, - root_dir = function(dir) return lspconfig.util.find_git_ancestor(dir) end, - settings = {} - } - } + -- fennel-ls is bleeding edge + -- require("lspconfig.configs")["fennel-ls"] = { + -- default_config = { + -- cmd = {"fennel-ls"}, + -- filetypes = {"fennel"}, + -- root_dir = function(dir) return lspconfig.util.find_git_ancestor(dir) end, + -- settings = {} + -- } + -- } local servers = { 'clojure_lsp', 'terraform_lsp', 'zls', 'pyright', 'rust_analyzer', 'tsserver', 'lua_ls'} for _, lsp in ipairs(servers) do @@ -653,12 +653,12 @@ in capabilities = capabilities, } -- fennel-ls doesn't support gps - lspconfig['fennel-ls'].setup { - on_attach = function(client, bufnr) - format.on_attach(client) - end, - capabilities = capabilities, - } + -- lspconfig['fennel-ls'].setup { + -- on_attach = function(client, bufnr) + -- format.on_attach(client) + -- end, + -- capabilities = capabilities, + -- } -- deprecated pylsp -- require('lspconfig').pylsp.setup { @@ -781,30 +781,30 @@ in require('leap').set_default_keymaps() -- supercollider - local scnvim = require 'scnvim' - local map = scnvim.map - local map_expr = scnvim.map_expr - scnvim.setup { - keymaps = { - ['e'] = map('editor.send_line', {'i', 'n'}), - ['s'] = map_expr('CmdPeriod.run', {'i', 'n'}), - ['t'] = { - map('editor.send_block', {'i', 'n'}), - map('editor.send_selection', 'x'), - }, - [''] = map('postwin.toggle'), - [''] = map('postwin.toggle', 'i'), - [''] = map('postwin.clear', {'n', 'i'}), - [''] = map('signature.show', {'n', 'i'}), - [''] = map('sclang.hard_stop', {'n', 'x', 'i'}), - ['st'] = map('sclang.start'), - ['sk'] = map('sclang.recompile'), - [''] = map_expr('s.boot'), - [''] = map_expr('s.meter'), - } - } + -- local scnvim = require 'scnvim' + -- local map = scnvim.map + -- local map_expr = scnvim.map_expr + -- scnvim.setup { + -- keymaps = { + -- ['e'] = map('editor.send_line', {'i', 'n'}), + -- ['s'] = map_expr('CmdPeriod.run', {'i', 'n'}), + -- ['t'] = { + -- map('editor.send_block', {'i', 'n'}), + -- map('editor.send_selection', 'x'), + -- }, + -- [''] = map('postwin.toggle'), + -- [''] = map('postwin.toggle', 'i'), + -- [''] = map('postwin.clear', {'n', 'i'}), + -- [''] = map('signature.show', {'n', 'i'}), + -- [''] = map('sclang.hard_stop', {'n', 'x', 'i'}), + -- ['st'] = map('sclang.start'), + -- ['sk'] = map('sclang.recompile'), + -- [''] = map_expr('s.boot'), + -- [''] = map_expr('s.meter'), + -- } + -- } -- You gotta run :SCNvimGenerateAssets for this first - require("luasnip").add_snippets("supercollider", require("scnvim/utils").get_snippets()) + -- require("luasnip").add_snippets("supercollider", require("scnvim/utils").get_snippets()) -- zen mode require('zen-mode').setup{ @@ -863,12 +863,12 @@ in # used to compile tree-sitter grammar python-with-my-packages nodejs - clojure-lsp + # clojure-lsp clojure rnix-lsp terraform-lsp rust-analyzer - clj-kondo + # clj-kondo zls gcc nodePackages_latest.pyright @@ -878,7 +878,7 @@ in nodePackages.typescript nodePackages.typescript-language-server luajitPackages.lua-lsp - fennel-ls + # fennel-ls ]; plugins = with pkgs.vimPlugins // customPlugins; [ @@ -895,7 +895,7 @@ in telescope-nvim plenary-nvim nvim-navic - (nvim-treesitter.withPlugins (p: [ p.nix p.clojure p.python p.fennel p.lua p.html p.css p.regex p.supercollider p.beancount p.markdown p.glsl p.yaml p.toml p.dockerfile p.json ])) + (nvim-treesitter.withPlugins (p: [ p.nix p.clojure p.python p.fennel p.lua p.html p.css p.regex p.beancount p.markdown p.glsl p.yaml p.toml p.dockerfile p.json ])) nvim-treesitter-context my-fterm barbar-nvim @@ -953,10 +953,10 @@ in vim-sexp-mappings-for-regular-people fennel-vim - vim-tidal + # vim-tidal # experimental nvim-luapad - scnvim + # scnvim leap vim-beancount # vimtex diff --git a/home/profiles/task/default.nix b/home/profiles/task/default.nix index 0862f9ec..5813ccae 100644 --- a/home/profiles/task/default.nix +++ b/home/profiles/task/default.nix @@ -8,8 +8,8 @@ # taskwarrior needs write access to this file for centexts # this way, we get a copy of the file, and we make sure it's writable ".taskrc".source = ./taskrc; - ".taskrc".executable = true; - ".taskrc".onChange = "cp ~/.taskrc ~/.taskrc2;rm ~/.taskrc;mv ~/.taskrc2 ~/.taskrc;chmod +w ~/.taskrc"; + # ".taskrc".executable = true; + # ".taskrc".onChange = "cp ~/.taskrc ~/.taskrc2;rm ~/.taskrc;mv ~/.taskrc2 ~/.taskrc;chmod +w ~/.taskrc"; ".task/keys/ca.cert".source = ./ca.cert; ".task/keys/public.cert".source = ./public.cert; diff --git a/hosts/darwin/casks/default.nix b/hosts/darwin/casks/default.nix new file mode 100644 index 00000000..87f18787 --- /dev/null +++ b/hosts/darwin/casks/default.nix @@ -0,0 +1,34 @@ +{ pkgs, ... }: + +{ + homebrew.enable = true; + homebrew.brews = [ + "kind" + "kubectl" + ]; + homebrew.casks = [ + # Development Tools + "homebrew/cask/docker" + # "insomnia" + # "tableplus" + # "ngrok" + "postico" + "wireshark" + + # Communication Tools + # Already installed manually + # "loom" + # "slack" + # "zoom" + # "firefox" + + # Utility Tools + # "syncthing" + + # Productivity Tools + "raycast" + + # AI + # "diffusionbee" + ]; +} diff --git a/hosts/darwin/default.nix b/hosts/darwin/default.nix new file mode 100644 index 00000000..70c0f141 --- /dev/null +++ b/hosts/darwin/default.nix @@ -0,0 +1,125 @@ +{ agenix, config, pkgs, ... }: + +{ + imports = [ + ./sketchybar + ./yabai + ./casks + # ../../modules/darwin/secrets.nix + # ../../modules/darwin/home-manager.nix + # ../../modules/shared + # ../../modules/shared/cachix + # agenix.darwinModules.default + ]; + + environment.systemPackages = [ + pkgs.go + ]; + + # Auto upgrade nix package and the daemon service. + services.nix-daemon.enable = true; + nixpkgs.hostPlatform = "aarch64-darwin"; + programs.zsh.enable = true; + + # Setup user, packages, programs + nix = { + # package = pkgs.nixUnstable; + settings.trusted-users = [ "@admin" "anishlakhwara" ]; + + gc = { + user = "root"; + automatic = true; + interval = { Weekday = 0; Hour = 2; Minute = 0; }; + options = "--delete-older-than 30d"; + }; + + # Turn this on to make command line easier + extraOptions = '' + experimental-features = nix-command flakes + ''; + }; + + # Turn off NIX_PATH warnings now that we're using flakes + system.checks.verifyNixPath = false; + + # Load configuration that is shared across systems + # environment.systemPackages = with pkgs; [ + # + # ] ++ (import ../../modules/shared/packages.nix { inherit pkgs; }); + + # Enable fonts dir + fonts.fontDir.enable = true; + fonts.fonts = with pkgs; [ + fira-code + fira-code-symbols + hermit + #hack + siji + font-awesome + proggyfonts + (nerdfonts.override { fonts = [ "FiraCode" "DroidSansMono" "Iosevka" ]; }) + ]; + + system = { + stateVersion = 4; + + keyboard = { + enableKeyMapping = true; + }; + + defaults = { + LaunchServices = { + LSQuarantine = false; + }; + + NSGlobalDomain = { + AppleShowAllExtensions = true; + ApplePressAndHoldEnabled = false; + + # 120, 90, 60, 30, 12, 6, 2 + KeyRepeat = 2; + + # 120, 94, 68, 35, 25, 15 + InitialKeyRepeat = 15; + + "com.apple.mouse.tapBehavior" = 1; + "com.apple.sound.beep.volume" = 0.0; + "com.apple.sound.beep.feedback" = 0; + }; + + loginwindow = { + # disable guest account + GuestEnabled = false; + # show name instead of username + SHOWFULLNAME = false; + }; + + dock = { + autohide = true; + autohide-delay = 0.0; + autohide-time-modifier = 1.0; + static-only = false; + showhidden = false; + show-recents = false; + launchanim = true; + mouse-over-hilite-stack = true; + orientation = "bottom"; + tilesize = 48; + }; + + finder = { + _FXShowPosixPathInTitle = false; + }; + + trackpad = { + Clicking = false; + TrackpadThreeFingerDrag = true; + }; + }; + + # keyboard = { + # enableKeyMapping = true; + # remapCapsLockToControl = true; + # }; + }; +} diff --git a/hosts/darwin/sketchybar/default.nix b/hosts/darwin/sketchybar/default.nix new file mode 100644 index 00000000..8fe56678 --- /dev/null +++ b/hosts/darwin/sketchybar/default.nix @@ -0,0 +1,10 @@ +{ pkgs, ... }: + +{ + services.sketchybar = { + enable = true; + config = (builtins.readFile ./sketchybarrc); + extraPackages = [ pkgs.jq ]; + }; + +} diff --git a/hosts/darwin/sketchybar/sketchybarrc b/hosts/darwin/sketchybar/sketchybarrc new file mode 100755 index 00000000..cecc054d --- /dev/null +++ b/hosts/darwin/sketchybar/sketchybarrc @@ -0,0 +1,58 @@ +#!/usr/bin/env bash + +source "$HOME/.config/sketchybar/variables.sh" # Loads all defined colors + +# General bar and defaults +# parts I didn't want + # y_offset=5 \ + # margin=5 \ + +sketchybar --bar height=35 \ + color="$BAR_COLOR" \ + shadow="$SHADOW" \ + position=top \ + sticky=on \ + padding_right=0 \ + padding_left=3 \ + corner_radius="$CORNER_RADIUS" \ + blur_radius=20 \ + notch_width=200 \ + --default updates=when_shown \ + icon.font="$FONT:Bold:13.5" \ + icon.color="$ICON_COLOR" \ + icon.padding_left="$PADDINGS" \ + icon.padding_right="$PADDINGS" \ + label.font="$FONT:Bold:13.0" \ + label.color="$LABEL_COLOR" \ + label.padding_left="$PADDINGS" \ + label.padding_right="$PADDINGS" \ + background.padding_right="$PADDINGS" \ + background.padding_left="$PADDINGS" \ + popup.background.border_width=1 \ + popup.background.corner_radius=11 \ + popup.background.border_color="$POPUP_BORDER_COLOR" \ + popup.background.color="$POPUP_BACKGROUND_COLOR" \ + popup.background.shadow.drawing="$SHADOW" + +# Left +# source "$ITEM_DIR/apple.sh" +source "$ITEM_DIR/spaces.sh" + +# Center (of notch) +# source "$ITEM_DIR/spotify.sh" +source "$ITEM_DIR/front_app.sh" + +# Right +source "$ITEM_DIR/clock.sh" +source "$ITEM_DIR/calendar.sh" +source "$ITEM_DIR/battery.sh" +source "$ITEM_DIR/volume.sh" +source "$ITEM_DIR/cpu.sh" + +#################### Finalizing Setup #################### + +# sketchybar --hotload true + +sketchybar --update + +echo "sketchybar configuration loaded.." diff --git a/hosts/darwin/yabai/default.nix b/hosts/darwin/yabai/default.nix new file mode 100644 index 00000000..5a9769ef --- /dev/null +++ b/hosts/darwin/yabai/default.nix @@ -0,0 +1,102 @@ +{pkgs, ... }: + +{ + services.yabai = { + enable = true; + config = { + mouse_follows_focus = "off"; + focus_follows_mouse = "off"; + window_placement = "second_child"; + window_topmost = "off"; + window_opacity = "off"; + window_opacity_duration = 0.0; + window_shadow = "on"; + window_border = "off"; + window_border_placement = "inset"; + window_border_width = 4; + window_border_radius = -1.0; + active_window_border_topmost = "off"; + active_window_border_color = "0xff775759"; + normal_window_border_color = "0xff505050"; + insert_window_border_color = "0xffd75f5f"; + active_window_opacity = 1.0; + normal_window_opacity = 0.9; + split_ratio = 0.73; + auto_balance = "on"; + mouse_modifier = "fn"; + mouse_action1 = "move"; + mouse_action2 = "resize"; + layout = "bsp"; + top_padding = 5; + bottom_padding = 5; + left_padding = 5; + right_padding = 5; + window_gap = 5; + }; + extraConfig = '' + # Do not manage windows with certain titles eg. Copying files or moving to bin + yabai -m rule --add title="(Copy|Bin|About This Mac|Info)" manage=off + # Do not manage some apps which are not resizable + yabai -m rule --add app="^(Calculator|System Preferences|[sS]tats|[Jj]et[Bb]rains [Tt]ool[Bb]ox|kftray)$" manage=off + ''; + }; + + system.activationScripts.yabai = { + enable = true; + text = '' + yabai --install-service && yabai --start-service + ''; + }; + + services.skhd = { + enable = true; + skhdConfig = '' +# Open iTerm2 +cmd - enter : kitty --single-instance -d ~ + +################## +# Window Motions # +################## +# Rotate +lalt - r : yabai -m space --rotate 90 +# Mirror verticaly +lalt - x : yabai -m space --mirror y-axis +# Mirror horizontaly +lalt - y : yabai -m space --mirror x-axis +# yes, i know i swapped x and y, but I mainly use y-axis and y is further... +# Fullscreen +cmd - f : yabai -m window --toggle zoom-fullscreen +# Swap +lalt - q : yabai -m window --swap west +lalt - s : yabai -m window --swap south +lalt - z : yabai -m window --swap north +lalt - d : yabai -m window --swap east +# Warp +shift + lalt - q : yabai -m window --warp west +shift + lalt - s : yabai -m window --warp south +shift + lalt - z : yabai -m window --warp north +shift + lalt - d : yabai -m window --warp east + +######### +# Focus # +######### +# Clockwise +# alt - tab : yabai -m window --focus "$(yabai -m query --windows --space | jq -re "[sort_by(.id, .frame) | .[] | select(.role == \"AXWindow\" and .subrole == \"AXStandardWindow\") | .id] | nth(index($(yabai -m query --windows --window | jq -re ".id")) - 1)")" +# Counter-clockwise +# shift - tab : yabai -m window --focus "$(yabai -m query --windows --space | jq -re "[sort_by(.id, .frame) | reverse | .[] | select(.role == \"AXWindow\" and .subrole == \"AXStandardWindow\") | .id] | nth(index($(yabai -m query --windows --window | jq -re ".id")) - 1)")" + +########## +# Spaces # +########## +ctrl - left : yabai -m space --focus prev +ctrl - right : yabai -m space --focus next +ctrl + shift - right : yabai -m window --space next; yabai -m space --focus next +ctrl + shift - left : yabai -m window --space prev; yabai -m space --focus prev +cmd - 1 : yabai -m window --space 1; yabai -m space --focus 1 +cmd - 2 : yabai -m window --space 2; yabai -m space --focus 2 +cmd - 3 : yabai -m window --space 3; yabai -m space --focus 3 +cmd - 4 : yabai -m window --space 4; yabai -m space --focus 4 +cmd - 5 : yabai -m window --space 5; yabai -m space --focus 5 + ''; + }; +} diff --git a/modules/darwin/README.md b/modules/darwin/README.md new file mode 100644 index 00000000..ccff20ff --- /dev/null +++ b/modules/darwin/README.md @@ -0,0 +1,12 @@ + +## Layout +``` +. +├── dock # MacOS dock configuration +├── casks.nix # List of homebrew casks +├── default.nix # Defines module, system-level config +├── files.nix # Non-Nix, static configuration files (now immutable!) +├── home-manager.nix # Defines user programs +├── packages.nix # List of packages to install for MacOS +├── secrets.nix # Age-encrypted secrets with agenix +``` diff --git a/modules/darwin/casks.nix b/modules/darwin/casks.nix new file mode 100644 index 00000000..f39cae26 --- /dev/null +++ b/modules/darwin/casks.nix @@ -0,0 +1,26 @@ +_: + +[ + # Development Tools + "homebrew/cask/docker" + # "insomnia" + # "tableplus" + # "ngrok" + "postico" + "wireshark" + + # Communication Tools + "loom" + # Already installed manually + # "slack" + # "zoom" + + # Utility Tools + "syncthing" + + # Productivity Tools + "raycast" + + # AI + # "diffusionbee" +] diff --git a/modules/darwin/dock/default.nix b/modules/darwin/dock/default.nix new file mode 100644 index 00000000..19af49f9 --- /dev/null +++ b/modules/darwin/dock/default.nix @@ -0,0 +1,67 @@ +{ config, pkgs, lib, ... }: +with lib; +let + cfg = config.local.dock; + inherit (pkgs) stdenv dockutil; +in +{ + options = { + local.dock.enable = mkOption { + description = "Enable dock"; + default = stdenv.isDarwin; + example = false; + }; + + local.dock.entries = mkOption + { + description = "Entries on the Dock"; + type = with types; listOf (submodule { + options = { + path = lib.mkOption { type = str; }; + section = lib.mkOption { + type = str; + default = "apps"; + }; + options = lib.mkOption { + type = str; + default = ""; + }; + }; + }); + readOnly = true; + }; + }; + + config = + mkIf cfg.enable + ( + let + normalize = path: if hasSuffix ".app" path then path + "/" else path; + entryURI = path: "file://" + (builtins.replaceStrings + [" " "!" "\"" "#" "$" "%" "&" "'" "(" ")"] + ["%20" "%21" "%22" "%23" "%24" "%25" "%26" "%27" "%28" "%29"] + (normalize path) + ); + wantURIs = concatMapStrings + (entry: "${entryURI entry.path}\n") + cfg.entries; + createEntries = concatMapStrings + (entry: "${dockutil}/bin/dockutil --no-restart --add '${entry.path}' --section ${entry.section} ${entry.options}\n") + cfg.entries; + in + { + system.activationScripts.postUserActivation.text = '' + echo >&2 "Setting up the Dock..." + haveURIs="$(${dockutil}/bin/dockutil --list | ${pkgs.coreutils}/bin/cut -f2)" + if ! diff -wu <(echo -n "$haveURIs") <(echo -n '${wantURIs}') >&2 ; then + echo >&2 "Resetting Dock." + ${dockutil}/bin/dockutil --no-restart --remove all + ${createEntries} + killall Dock + else + echo >&2 "Dock setup complete." + fi + ''; + } + ); +} diff --git a/modules/darwin/files.nix b/modules/darwin/files.nix new file mode 100644 index 00000000..530f1098 --- /dev/null +++ b/modules/darwin/files.nix @@ -0,0 +1,54 @@ +{ user, config, pkgs, ... }: + +let + xdg_configHome = "${config.users.users.${user}.home}/.config"; + xdg_dataHome = "${config.users.users.${user}.home}/.local/share"; + xdg_stateHome = "${config.users.users.${user}.home}/.local/state"; in +{ + + # Raycast script so that "Run Emacs" is available and uses Emacs daemon + "${xdg_dataHome}/bin/emacsclient" = { + executable = true; + text = '' + #!/bin/zsh + # + # Required parameters: + # @raycast.schemaVersion 1 + # @raycast.title Run Emacs + # @raycast.mode silent + # + # Optional parameters: + # @raycast.packageName Emacs + # @raycast.icon ${xdg_dataHome}/img/icons/Emacs.icns + # @raycast.iconDark ${xdg_dataHome}/img/icons/Emacs.icns + + if [[ $1 = "-t" ]]; then + # Terminal mode + ${pkgs.emacs}/bin/emacsclient -t $@ + else + # GUI mode + ${pkgs.emacs}/bin/emacsclient -c -n $@ + fi + ''; + }; + + # Script to import Drafts into Emacs org-roam + "${xdg_dataHome}/bin/import-drafts" = { + executable = true; + text = '' + #!/bin/sh + + for f in ${xdg_stateHome}/drafts/* + do + if [[ ! "$f" =~ "done" ]]; then + echo "Importing $f" + filename="$(head -c 10 $f)" + output="${xdg_dataHome}/org-roam/daily/$filename.org" + echo '\n' >> "$output" + tail -n +3 $f >> "$output" + mv $f done + fi + done + ''; + }; +} diff --git a/modules/darwin/home-manager.nix b/modules/darwin/home-manager.nix new file mode 100644 index 00000000..9f856079 --- /dev/null +++ b/modules/darwin/home-manager.nix @@ -0,0 +1,85 @@ +{ config, pkgs, lib, home-manager, ... }: + +let + user = "anishlakhwara"; + # Define the content of your file as a derivation + myEmacsLauncher = pkgs.writeScript "emacs-launcher.command" '' + #!/bin/sh + emacsclient -c -n & + ''; + sharedFiles = import ../shared/files.nix { inherit config pkgs; }; + additionalFiles = import ./files.nix { inherit user config pkgs; }; +in +{ + imports = [ + ./dock + ]; + + # It me + users.users.${user} = { + name = "${user}"; + home = "/Users/${user}"; + isHidden = false; + shell = pkgs.zsh; + }; + + # Enable home-manager + home-manager = { + useGlobalPkgs = true; + users.${user} = { pkgs, config, lib, ... }:{ + home = { + enableNixpkgsReleaseCheck = false; + packages = pkgs.callPackage ./packages.nix {}; + file = lib.mkMerge [ + sharedFiles + additionalFiles + { "emacs-launcher.command".source = myEmacsLauncher; } + ]; + + stateVersion = "23.11"; + }; + + programs = {} // import ../shared/home-manager.nix { inherit config pkgs lib; }; + + # Marked broken Oct 20, 2022 check later to remove this + # https://github.com/nix-community/home-manager/issues/3344 + manual.manpages.enable = false; + }; + }; + + # Fully declarative dock using the latest from Nix Store + local = { + dock.enable = true; + dock.entries = [ + { path = "/Applications/Slack.app/"; } + { path = "/System/Applications/Messages.app/"; } + { path = "/System/Applications/Facetime.app/"; } + { path = "/Applications/Telegram.app/"; } + { path = "${pkgs.alacritty}/Applications/Alacritty.app/"; } + { path = "/System/Applications/Music.app/"; } + { path = "/System/Applications/News.app/"; } + { path = "/System/Applications/Photos.app/"; } + { path = "/System/Applications/Photo Booth.app/"; } + { path = "/System/Applications/TV.app/"; } + { path = "${pkgs.jetbrains.phpstorm}/Applications/PhpStorm.app/"; } + { path = "/Applications/TablePlus.app/"; } + { path = "/Applications/Asana.app/"; } + { path = "/Applications/Drafts.app/"; } + { path = "/System/Applications/Home.app/"; } + { + path = toString myEmacsLauncher; + section = "others"; + } + { + path = "${config.users.users.${user}.home}/.local/share/"; + section = "others"; + options = "--sort name --view grid --display folder"; + } + { + path = "${config.users.users.${user}.home}/.local/share/downloads"; + section = "others"; + options = "--sort name --view grid --display stack"; + } + ]; + }; +} diff --git a/modules/darwin/packages.nix b/modules/darwin/packages.nix new file mode 100644 index 00000000..7eaa1d81 --- /dev/null +++ b/modules/darwin/packages.nix @@ -0,0 +1,7 @@ +{ pkgs }: + +with pkgs; +let shared-packages = import ../shared/packages.nix { inherit pkgs; }; in +shared-packages ++ [ + dockutil +] diff --git a/modules/darwin/secrets.nix b/modules/darwin/secrets.nix new file mode 100644 index 00000000..bed9479e --- /dev/null +++ b/modules/darwin/secrets.nix @@ -0,0 +1,47 @@ +{ config, pkgs, agenix, secrets, ... }: + +let user = "dustin"; in +{ + age = { + identityPaths = [ + "/Users/${user}/.ssh/id_ed25519" + ]; + + secrets = { + "syncthing-cert" = { + symlink = true; + path = "/Users/${user}/Library/Application Support/Syncthing/cert.pem"; + file = "${secrets}/darwin-syncthing-cert.age"; + mode = "644"; + owner = "${user}"; + group = "staff"; + }; + + "syncthing-key" = { + symlink = true; + path = "/Users/${user}/Library/Application Support/Syncthing/key.pem"; + file = "${secrets}/darwin-syncthing-key.age"; + mode = "600"; + owner = "${user}"; + group = "staff"; + }; + + "github-ssh-key" = { + symlink = true; + path = "/Users/${user}/.ssh/id_github"; + file = "${secrets}/github-ssh-key.age"; + mode = "600"; + owner = "${user}"; + group = "staff"; + }; + + "github-signing-key" = { + symlink = false; + path = "/Users/${user}/.ssh/pgp_github.key"; + file = "${secrets}/github-signing-key.age"; + mode = "600"; + owner = "${user}"; + }; + }; + }; +}