Skip to content

Commit

Permalink
Mac: WIP initial working version
Browse files Browse the repository at this point in the history
  • Loading branch information
fortes committed Feb 12, 2024
1 parent c03415b commit 519cfb2
Show file tree
Hide file tree
Showing 9 changed files with 233 additions and 28 deletions.
13 changes: 13 additions & 0 deletions .github/workflows/mac-os.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
name: MacOS
on: [push]

jobs:
build:
runs-on: macos-14

steps:
- uses: actions/checkout@v4

- name: Setup machine
run: bash ./scripts/setup_mac

13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ Graphical sections are Linux-only, and use:
* foot
* Firefox

On MacOS, use:

* Alacritty
* Rectangle

## Letting me own your machine

```sh
Expand Down Expand Up @@ -204,7 +209,13 @@ The Bullseye to Bookworm upgrade requires a few manual steps that I'm too lazy t
### Mac
- Not fully functional, see `mac-setup` branch for current status
Still a work in progress, but kinda works
- [ ] May want to install command line tools manually in order to get `git`: `xcode-select --install`
- [ ] Set `terminal.app` profile, send option as meta key
- [ ] `terminal.app` sucks with colors, so once installs happen, switch to Alacritty and pin it in the dock
- [ ] Music scripts depend on `playerctl`, which requires `dbus` which does not exist on Mac. Will need to switch to scripting `cmus` directly perhaps?
- [ ] Figure out how to get [M1 CI running](https://github.blog/changelog/2024-01-30-github-actions-introducing-the-new-m1-macos-runner-available-to-open-source/) to check builds
## Known Issues
Expand Down
43 changes: 43 additions & 0 deletions scripts/brew-packages
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
1password-cli
alacritty
bash
bash-completion@2
bat
oven-sh/bun/bun
chafa
cmus
deno
docker
duf
# Conflicts due to protobuf
# MisterTea/et/et
eza
fd
firefox
fnm
fzf
git
git-crypt
git-extras
git-lfs
helix
htop
hugo
jq
keychain
mpv
ncdu
neovim
pipx
rclone
rectangle
ripgrep
sad
shellcheck
speedtest-cli
stow
tmux
visual-studio-code
wget
yt-dlp
zoxide
11 changes: 9 additions & 2 deletions scripts/create_local_profile
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,19 @@ IFS=$'\n\t'

main() {
local is_crostini=$([[ -f /etc/apt/sources.list.d/cros.list ]] && printf 1)
local is_mac=$([[ ${OSTYPE:-} == 'darwin'* ]] && printf 1)
local is_docker=$([[ -f /.dockerenv ]] && printf 1)
local is_wsl=$([[ -d /run/WSL ]] && printf 1)
# Default to headless in Crostini / Docker / WSL, even though GUI might be
# possible, can always be overridden
local is_headless=$([[ -n "${is_crostini}${is_docker}${is_wsl}" || \
local is_headless=$([[ -n "${is_crostini}${is_docker}${is_mac}${is_wsl}" || \
-z "${WAYLAND_DISPLAY:-}" ]] && printf 1)

cat <<PROFILE_TEMPLATE
# Generated $(date +%F)
export IS_CROSTINI="${is_crostini:-}"
export IS_DOCKER="${is_docker:-}"
export IS_MAC="${is_mac:-}"
export IS_WSL="${is_wsl:-}"
export IS_HEADLESS="${is_headless:-}"
Expand All @@ -38,4 +40,9 @@ export IS_HEADLESS="${is_headless:-}"
PROFILE_TEMPLATE
}

main "${@}"
if [[ "${BASH_VERSINFO:-0}" -ge 4 ]]; then
main "${@}"
else
# Ancient Mac Bash version does not support `@`
main
fi
117 changes: 117 additions & 0 deletions scripts/setup_mac
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#!/usr/bin/env bash
# Work in progress setup for the Mac
#
# TODO:
# - Use `/bin/sh` instead of bash, since will eventually go away
# - Or maybe `dash`?
# - Move over to zsh
#
# Usage: setup_mac

set -euo pipefail
IFS=$'\n\t'

declare -r brew_prefix="/opt/homebrew"
declare dotfiles_root
dotfiles_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"

setup_shell() {
local homebrew_bash_path="${brew_prefix}/bin/bash"

# TODO: Should really just move to zsh since Mac will probably ditch bash
if [[ -x "${homebrew_bash_path}" ]] && [[ "${SHELL:-}" != "${homebrew_bash_path}" ]]; then
if ! grep -q "${homebrew_bash_path}" /etc/shells; then
echo "Adding ${homebrew_bash_path} to shell list (requires sudo)"
echo "${homebrew_bash_path}" | sudo tee -a /etc/shells > /dev/null
fi

# Only change shell if running interactively, otherwise fails in CI which
# can't do the required auth
if [[ -t 1 ]] ; then
echo "Changing shell to bash ($homebrew_bash_path)"
chsh -s "${homebrew_bash_path}"
fi
fi
}

install_command_line_tools() {
if ! xcode-select -p > /dev/null 2>&1; then
echo "Installing command line tools"
xcode-select --install
fi
}

install_homebrew() {
if [[ ! -x "${brew_prefix}/bin/brew" ]]; then
echo "Installing Homebrew"
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
fi

if [[ ! -f "$HOME/.profile.brew" ]]; then
echo "Exporting brew shellenv"
"${brew_prefix}/bin/brew" shellenv > "$HOME/.profile.brew"
fi

# Ensure `brew` in path for rest of script
# shellcheck source=/dev/null
. "$HOME/.profile.brew"
}

install_homebrew_packages() {
echo "Installing homebrew packages"
# Use full path just in case `brew` not in path during initial setup
grep -v "^#" "${dotfiles_root}/scripts/brew-packages" | \
xargs "${brew_prefix}/bin/brew" install --quiet
}

main() {
if ! uname -s | grep -q Darwin; then
>&2 echo "Only works on Mac!"
exit 1
fi

# Make sure to load `command_exists` helper
# shellcheck source=../stowed-files/bash/.profile
. "${dotfiles_root}/stowed-files/bash/.profile"

local local_profile_path="$HOME/.profile.local"

if [[ ! -f "$local_profile_path" ]]; then
echo "Generating $local_profile_path"
"${dotfiles_root}/scripts/create_local_profile" > "$local_profile_path"
fi

# shellcheck source=/dev/null
. "$local_profile_path"

install_command_line_tools
install_homebrew
install_homebrew_packages

# Remove default files before stowing, otherwise stow fails
"${dotfiles_root}/scripts/remove_default_dotfiles"
"${dotfiles_root}/scripts/stow"

setup_shell

"${dotfiles_root}/scripts/lock_local_files"

# Non-brew package managers
"${dotfiles_root}/scripts/install_node_packages"
"${dotfiles_root}/scripts/install_python_packages"

"${dotfiles_root}/scripts/generate_completions"

# TODO: Neovim plugin install?

echo "Setup complete!"
}

if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
if [[ "${BASH_VERSINFO:-0}" -ge 4 ]]; then
main "${@}"
else
# Ancient Mac Bash version does not support `@`
main
fi
fi
9 changes: 9 additions & 0 deletions stowed-files/alacritty/.config/alacritty/alacritty.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[env]
# tmux uses `$SHELL` which isn't set by `chsh` on MacOS
SHELL = "/opt/homebrew/bin/bash"
[shell]
# Only used on MacOS, so this path is OK
program = "/opt/homebrew/bin/bash"
args = ["--login"]
[window]
option_as_alt = "OnlyLeft"
41 changes: 22 additions & 19 deletions stowed-files/bash/.bashrc
Original file line number Diff line number Diff line change
Expand Up @@ -42,40 +42,40 @@ if [[ -z "${COLORTERM:-}" ]] && [[ "$TERM" =~ "256color" ]]; then
fi

# Bash Options {{{
# cd without typing cd
shopt -qs autocd
# cd without typing cd (unsupported in Mac version)
shopt -qs autocd 2> /dev/null || true
# Auto-correct directory typos
shopt -qs cdspell
# Check hash before executing
shopt -qs checkhash
# Check for stopped jobs before exiting
shopt -qs checkjobs
# Check for stopped jobs before exiting (unsupported in Mac version)
shopt -qs checkjobs 2> /dev/null || true
# Check window size after each command, and update $LINES and $COLUMNS
shopt -s checkwinsize
shopt -qs checkwinsize
# Save all lines of multiline commands
shopt -s cmdhist
# Expand directory names when doing file completion
shopt -qs direxpand
# Fix typos for directories in completion
shopt -qs dirspell
shopt -qs cmdhist
# Expand directory names when doing file completion (unsupported in Mac version)
shopt -qs direxpand 2> /dev/null || true
# Fix typos for directories in completion (unsupported in Mac version)
shopt -qs dirspell 2> /dev/null || true
# Include filenames that begin with '.' in filename expansion
shopt -qs dotglob
# Extended pattern matching
shopt -qs extglob
# Allow escape sequencing within ${parameter} expansions
shopt -qs extquote
# Support ** for expansion
shopt -qs globstar
# Support ** for expansion (unsupported in Mac version)
shopt -qs globstar 2> /dev/null || true
# Append to history list. Allow editing of history substitution in readline
shopt -qs histappend histreedit histverify
# Do hostname completion on words that contain @
shopt -qs hostcomplete
# Don't search path for completions when on an empty line
shopt -s no_empty_cmd_completion
shopt -qs no_empty_cmd_completion
# Case insensitive glob matching and case statements
shopt -s nocaseglob nocasematch
shopt -qs nocaseglob nocasematch
# Expand aliases in order to find completions
shopt -s progcomp_alias
shopt -qs progcomp_alias
# }}}

# shellcheck disable=SC2034
Expand Down Expand Up @@ -127,7 +127,7 @@ PS1="$BASE_PROMPT ""\${HAS_JOBS:+$JOB_COUNT}"
git_prompt_location="/etc/bash_completion.d/git-prompt"
if [ ! -r "${git_prompt_location}" ]; then
# Homebrew
git_prompt_location="/usr/local/etc/bash_completion.d/git-prompt.sh"
git_prompt_location="/opt/homebrew/etc/bash_completion.d/git-prompt.sh"
fi

if [ -r "${git_prompt_location}" ]; then
Expand Down Expand Up @@ -215,7 +215,7 @@ export MOZ_ENABLE_WAYLAND=1
# FZF keybindings (Debian)
source_if_exists "/usr/share/doc/fzf/examples/key-bindings.bash"
# FZF keybindings (Homebrew)
source_if_exists "/usr/local/opt/fzf/shell/key-bindings.bash"
source_if_exists "/opt/homebrew/opt/fzf/shell/key-bindings.bash"

if command_exists fnm; then
eval "$(fnm env)"
Expand All @@ -226,8 +226,11 @@ export ET_NO_TELEMETRY=1

# Load system bash completion
source_if_exists "/etc/bash_completion"
# Load homebrew bash completion
source_if_exists "/usr/local/etc/bash_completion"
# Load Homebrew bash completion, see https://docs.brew.sh/Shell-Completion
source_if_exists "/opt/homebrew/etc/profile.d/bash_completion.sh"
source_if_exists "/opt/homebrew/etc/bash_completion.d"
source_if_exists "/opt/homebrew/share/bash-completion/bash_completion"

# Load local bash completion
source_if_exists "$HOME/.local/completion.d"

Expand Down
11 changes: 5 additions & 6 deletions stowed-files/bash/.local/bin/fd_with_git
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
#!/usr/bin/env sh

FD_COMMAND="fd"
if ! command -v "${FD_COMMAND}" > /dev/null; then
fd_command="fd"
if ! command -v "${fd_command}" > /dev/null; then
# Debian uses `fdfind`
FD_COMMAND="fdfind"
fd_command="fdfind"
fi
export FD_COMMAND

if [ "$#" -eq 0 ]; then
# Default to matching all files
Expand All @@ -14,7 +13,7 @@ fi

if git rev-parse --is-inside-work-tree > /dev/null 2>&1; then
git_root=$(git rev-parse --show-cdup)
"${FD_COMMAND}" --type file --follow --hidden --relative-path "$@" "${git_root:-.}"
"${fd_command}" --type file --follow --hidden --relative-path "$@" "${git_root:-.}"
else
"${FD_COMMAND}" --type file --follow --relative-path "$@"
"${fd_command}" --type file --follow --relative-path "$@"
fi
3 changes: 3 additions & 0 deletions stowed-files/bash/.profile
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ if [[ -n ${VISUAL:-} ]]; then
export EDITOR VISUAL
fi

# Homebrew paths, etc
source_if_exists "$HOME/.profile.brew"

# Locally-installed packages belong in path
add_to_path "$HOME/.local/bin"

Expand Down

0 comments on commit 519cfb2

Please sign in to comment.