2 Commits
Author SHA1 Message Date
Fabian Ising 874a823d1e [AC] Migrate from brew 2026-09-01 08:29:15 +02:00
Fabian Ising cc90b515c6 [MAC] Add DNS reset 2026-08-28 10:58:53 +02:00
6 changed files with 288 additions and 7 deletions
+3 -3
View File
@@ -8,7 +8,7 @@ This is a personal dotfiles repository targeting macOS (Apple Silicon + Intel) a
Setup is platform-specific and runs from the repo root: Setup is platform-specific and runs from the repo root:
- **macOS:** `./setup_mac.sh` — brews dependencies, creates a `neovim` virtualenv, then calls `./clone_and_link_mac.sh`. Uses GNU coreutils' `gln` (not `ln`), so coreutils must be installed first. - **macOS:** `./setup_mac.sh` — brews dependencies, installs the latest verified upstream Alacritty release, creates a `neovim` virtualenv, then calls `./clone_and_link_mac.sh`. Uses GNU coreutils' `gln` (not `ln`), so coreutils must be installed first.
- **Arch:** `./setup_arch.sh` — pacman deps, then `./clone_and_link.sh` + `./copy_fonts_arch.sh`. - **Arch:** `./setup_arch.sh` — pacman deps, then `./clone_and_link.sh` + `./copy_fonts_arch.sh`.
- `clone_and_link*.sh` create the symlinks (`~/.zsh`, `~/.zshrc`, `~/.tmux`, `~/.tmux.conf`, `~/.config/nvim`, `~/.config/alacritty`, virtualenvwrapper hooks). `link_config.sh` is a simpler standalone variant. - `clone_and_link*.sh` create the symlinks (`~/.zsh`, `~/.zshrc`, `~/.tmux`, `~/.tmux.conf`, `~/.config/nvim`, `~/.config/alacritty`, virtualenvwrapper hooks). `link_config.sh` is a simpler standalone variant.
- `general_setup.sh` switches the login shell to zsh and triggers plugin installs. - `general_setup.sh` switches the login shell to zsh and triggers plugin installs.
@@ -33,5 +33,5 @@ Practical rule: **edit the `.example` source, not the generated symlink target.*
## Maintenance ## Maintenance
- `./update_mac.sh` — macOS update runner. Default (no args) runs `--brew-update --cleanup --diagnostics --update-others`; other flags: `--system-update`, `--permission-fix` (strips Caskroom/App quarantine xattrs). Run `./update_mac.sh --help` for the list. `--update-others` also runs `claude --update` and `Codex --update`. - `./update_mac.sh` — macOS update runner. Default (no args) runs `--brew-update --cleanup --diagnostics --update-others`; other flags: `--system-update`, `--permission-fix` (strips Caskroom/App quarantine xattrs). Run `./update_mac.sh --help` for the list. `--update-others` also updates Alacritty from its verified upstream release, then runs `claude --update` and `Codex --update`.
- `brew_autoupdate`sets up scheduled brew auto-updates. - `brew_autoupdate`runs scheduled brew and Alacritty auto-updates.
+1
View File
@@ -6,5 +6,6 @@ export HOMEBREW_LOGS='/Users/ising/Library/Logs/Homebrew'
export SUDO_ASKPASS='/Users/ising/Library/Application Support/com.github.domt4.homebrew-autoupdate/brew_autoupdate_sudo_gui' export SUDO_ASKPASS='/Users/ising/Library/Application Support/com.github.domt4.homebrew-autoupdate/brew_autoupdate_sudo_gui'
defaults export com.apple.dock "/tmp/dock-layout.plist" defaults export com.apple.dock "/tmp/dock-layout.plist"
/bin/date && /opt/homebrew/bin/brew update && /opt/homebrew/bin/brew upgrade --formula -v && /opt/homebrew/bin/brew upgrade --cask -v && /opt/homebrew/bin/brew cleanup && /usr/bin/open -g /opt/homebrew/Library/Taps/homebrew/homebrew-autoupdate/notifier/brew-autoupdate.app /bin/date && /opt/homebrew/bin/brew update && /opt/homebrew/bin/brew upgrade --formula -v && /opt/homebrew/bin/brew upgrade --cask -v && /opt/homebrew/bin/brew cleanup && /usr/bin/open -g /opt/homebrew/Library/Taps/homebrew/homebrew-autoupdate/notifier/brew-autoupdate.app
/Users/ising/dotfiles/install_alacritty_mac.sh
defaults import com.apple.dock "/tmp/dock-layout.plist" defaults import com.apple.dock "/tmp/dock-layout.plist"
killall dock killall dock
+265
View File
@@ -0,0 +1,265 @@
#!/bin/bash
set -euo pipefail
readonly RELEASE_API="https://api.github.com/repos/alacritty/alacritty/releases/latest"
readonly APPLICATIONS_DIR="/Applications"
readonly APP_NAME="Alacritty.app"
temp_dir=""
mount_point=""
cleanup() {
if [[ -n "$mount_point" && -d "$mount_point" ]]; then
hdiutil detach "$mount_point" >/dev/null 2>&1 || true
fi
if [[ -n "$temp_dir" && -d "$temp_dir" ]]; then
rm -rf "$temp_dir"
fi
}
trap cleanup EXIT INT TERM
die() {
echo "Alacritty update failed: $*" >&2
exit 1
}
require_command() {
command -v "$1" >/dev/null 2>&1 || die "required command not found: $1"
}
app_version() {
/usr/libexec/PlistBuddy -c "Print :CFBundleShortVersionString" \
"$1/Contents/Info.plist" 2>/dev/null || true
}
version_is_newer() {
local left="${1%%-*}"
local right="${2%%-*}"
local left_major left_minor left_patch
local right_major right_minor right_patch
IFS=. read -r left_major left_minor left_patch <<< "$left"
IFS=. read -r right_major right_minor right_patch <<< "$right"
[[ "$left_major" =~ ^[0-9]+$ && "$left_minor" =~ ^[0-9]+$ && "$left_patch" =~ ^[0-9]+$ ]] || return 1
[[ "$right_major" =~ ^[0-9]+$ && "$right_minor" =~ ^[0-9]+$ && "$right_patch" =~ ^[0-9]+$ ]] || return 1
(( 10#$left_major > 10#$right_major )) && return 0
(( 10#$left_major < 10#$right_major )) && return 1
(( 10#$left_minor > 10#$right_minor )) && return 0
(( 10#$left_minor < 10#$right_minor )) && return 1
(( 10#$left_patch > 10#$right_patch ))
}
run_for_applications() {
if [[ -w "$APPLICATIONS_DIR" ]]; then
"$@"
else
sudo "$@"
fi
}
safe_link() {
local source="$1"
local destination="$2"
if [[ -e "$destination" && ! -L "$destination" ]]; then
die "will not replace non-symlink: $destination"
fi
ln -sfn "$source" "$destination"
}
assert_linkable() {
local destination="$1"
if [[ -e "$destination" && ! -L "$destination" ]]; then
die "will not replace non-symlink: $destination"
fi
}
validate_shell_artifacts() {
local app="$1"
local brew_prefix="$2"
local resources="$app/Contents/Resources"
local source manpage section
for source in \
"$app/Contents/MacOS/alacritty" \
"$resources/completions/alacritty.bash" \
"$resources/completions/alacritty.fish" \
"$resources/completions/_alacritty" \
"$resources/61/alacritty" \
"$resources/61/alacritty-direct"; do
[[ -f "$source" ]] || die "required artifact is missing: ${source#"$app/"}"
done
assert_linkable "$brew_prefix/bin/alacritty"
assert_linkable "$brew_prefix/etc/bash_completion.d/alacritty"
assert_linkable "$brew_prefix/share/fish/vendor_completions.d/alacritty.fish"
assert_linkable "$brew_prefix/share/zsh/site-functions/_alacritty"
assert_linkable "$HOME/.terminfo/61/alacritty"
assert_linkable "$HOME/.terminfo/61/alacritty-direct"
for section in 1 5 7; do
for manpage in "$resources"/*."$section".gz; do
[[ -e "$manpage" ]] || continue
assert_linkable "$brew_prefix/share/man/man$section/${manpage##*/}"
done
done
}
install_shell_artifacts() {
local app="$APPLICATIONS_DIR/$APP_NAME"
local resources="$app/Contents/Resources"
local brew_prefix="$1"
local manpage section
mkdir -p \
"$brew_prefix/bin" \
"$brew_prefix/etc/bash_completion.d" \
"$brew_prefix/share/fish/vendor_completions.d" \
"$brew_prefix/share/zsh/site-functions" \
"$brew_prefix/share/man/man1" \
"$brew_prefix/share/man/man5" \
"$brew_prefix/share/man/man7" \
"$HOME/.terminfo/61"
safe_link "$app/Contents/MacOS/alacritty" "$brew_prefix/bin/alacritty"
safe_link "$resources/completions/alacritty.bash" "$brew_prefix/etc/bash_completion.d/alacritty"
safe_link "$resources/completions/alacritty.fish" "$brew_prefix/share/fish/vendor_completions.d/alacritty.fish"
safe_link "$resources/completions/_alacritty" "$brew_prefix/share/zsh/site-functions/_alacritty"
safe_link "$resources/61/alacritty" "$HOME/.terminfo/61/alacritty"
safe_link "$resources/61/alacritty-direct" "$HOME/.terminfo/61/alacritty-direct"
for section in 1 5 7; do
for manpage in "$resources"/*."$section".gz; do
[[ -e "$manpage" ]] || continue
safe_link "$manpage" "$brew_prefix/share/man/man$section/${manpage##*/}"
done
done
}
restore_previous_app() {
local destination="$1"
local backup="$2"
run_for_applications rm -rf "$destination"
if [[ -d "$backup" ]]; then
run_for_applications /usr/bin/ditto "$backup" "$destination"
fi
}
main() {
local destination="$APPLICATIONS_DIR/$APP_NAME"
local release_json latest_tag latest_version asset_name asset_url asset_digest
local expected_sha actual_sha dmg staged_app staged_version installed_version
local previous_app brew_prefix brew_managed=false
[[ "$(uname -s)" == "Darwin" ]] || die "this installer only supports macOS"
require_command brew
require_command curl
require_command jq
require_command hdiutil
require_command codesign
brew_prefix="$(brew --prefix)"
if brew list --cask alacritty >/dev/null 2>&1; then
brew_managed=true
fi
temp_dir="$(mktemp -d "${TMPDIR:-/tmp}/alacritty-update.XXXXXX")"
release_json="$temp_dir/release.json"
curl --fail --location --silent --show-error --retry 3 \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"$RELEASE_API" -o "$release_json"
latest_tag="$(jq -er '.tag_name' "$release_json")"
latest_version="${latest_tag#v}"
asset_name="Alacritty-${latest_tag}.dmg"
asset_url="$(jq -er --arg asset "$asset_name" \
'.assets[] | select(.name == $asset) | .browser_download_url' "$release_json")"
asset_digest="$(jq -er --arg asset "$asset_name" \
'.assets[] | select(.name == $asset) | .digest' "$release_json")"
[[ "$asset_digest" == sha256:* ]] || die "GitHub did not provide a SHA-256 digest for $asset_name"
expected_sha="$(printf '%s' "${asset_digest#sha256:}" | tr '[:upper:]' '[:lower:]')"
[[ "$expected_sha" =~ ^[[:xdigit:]]{64}$ ]] || die "invalid SHA-256 digest for $asset_name"
installed_version=""
if [[ -d "$destination" ]]; then
installed_version="$(app_version "$destination")"
fi
if [[ "$installed_version" == "$latest_version" && "$brew_managed" == false ]]; then
validate_shell_artifacts "$destination" "$brew_prefix"
install_shell_artifacts "$brew_prefix"
echo "Alacritty $installed_version is already up to date."
return
fi
if [[ -n "$installed_version" ]] && version_is_newer "$installed_version" "$latest_version"; then
echo "Installed Alacritty $installed_version is newer than stable $latest_version; leaving it unchanged."
return
fi
echo "Installing Alacritty $latest_version from the upstream release."
dmg="$temp_dir/$asset_name"
curl --fail --location --silent --show-error --retry 3 "$asset_url" -o "$dmg"
actual_sha="$(shasum -a 256 "$dmg" | awk '{print $1}')"
[[ "$actual_sha" == "$expected_sha" ]] || die "SHA-256 mismatch for $asset_name"
mount_point="$temp_dir/mount"
mkdir -p "$mount_point"
hdiutil attach "$dmg" -nobrowse -readonly -mountpoint "$mount_point" >/dev/null
[[ -d "$mount_point/$APP_NAME" ]] || die "$APP_NAME is missing from $asset_name"
staged_app="$temp_dir/$APP_NAME"
/usr/bin/ditto "$mount_point/$APP_NAME" "$staged_app"
hdiutil detach "$mount_point" >/dev/null
mount_point=""
staged_version="$(app_version "$staged_app")"
[[ "$staged_version" == "$latest_version" ]] || die "release metadata says $latest_version, app says $staged_version"
codesign --verify --deep --strict "$staged_app" || die "the staged app has an invalid ad-hoc signature"
xattr -dr com.apple.quarantine "$staged_app" 2>/dev/null || true
validate_shell_artifacts "$staged_app" "$brew_prefix"
previous_app="$temp_dir/previous/$APP_NAME"
if [[ -d "$destination" ]]; then
mkdir -p "${previous_app%/*}"
/usr/bin/ditto "$destination" "$previous_app"
fi
if [[ "$brew_managed" == true ]]; then
echo "Migrating Alacritty away from the disabled Homebrew cask."
if ! brew uninstall --cask alacritty; then
restore_previous_app "$destination" "$previous_app"
install_shell_artifacts "$brew_prefix" || true
die "Homebrew could not uninstall its Alacritty cask"
fi
fi
if ! run_for_applications rm -rf "$destination" || \
! run_for_applications /usr/bin/ditto "$staged_app" "$destination"; then
restore_previous_app "$destination" "$previous_app"
die "could not install $destination"
fi
if ! codesign --verify --deep --strict "$destination" || \
[[ "$(app_version "$destination")" != "$latest_version" ]]; then
restore_previous_app "$destination" "$previous_app"
die "installed app validation failed; restored the previous app"
fi
install_shell_artifacts "$brew_prefix"
echo "Alacritty $latest_version installed successfully."
}
if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
main "$@"
fi
+6 -4
View File
@@ -6,14 +6,16 @@
# Distributed under terms of the MIT license. # Distributed under terms of the MIT license.
# #
brew install neovim tmux alacritty coreutils cmake golang npm virtualenvwrapper brew install neovim tmux coreutils cmake golang jq npm virtualenvwrapper
source /opt/homebrew/bin/virtualenvwrapper.sh ./install_alacritty_mac.sh
BREW_PREFIX="$(brew --prefix)"
source "$BREW_PREFIX/bin/virtualenvwrapper.sh"
mkvirtualenv neovim mkvirtualenv neovim
pip3 install pynvim pip3 install pynvim
npm install -g neovim npm install -g neovim
echo For alacritty to work seemlessly with tmux, we will have to add '/usr/local/bin'\ echo For alacritty to work seamlessly with tmux, we will add the Homebrew bin directory\
to the path. This will require your root password. to the path. This will require your root password.
sudo launchctl config user path /usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin sudo launchctl config user path /usr/bin:/bin:/usr/sbin:/sbin:"$BREW_PREFIX/bin":/usr/local/bin
cp $PWD/nvim/scheme.vim.template $PWD/nvim/scheme.vim cp $PWD/nvim/scheme.vim.template $PWD/nvim/scheme.vim
cp $PWD/.config/alacritty/schemes.yml.template $PWD/.config/alacritty/schemes.yml cp $PWD/.config/alacritty/schemes.yml.template $PWD/.config/alacritty/schemes.yml
./clone_and_link_mac.sh ./clone_and_link_mac.sh
+11
View File
@@ -1,5 +1,13 @@
#!/bin/bash #!/bin/bash
SCRIPT_SOURCE="${BASH_SOURCE[0]}"
while [[ -L "$SCRIPT_SOURCE" ]]; do
SCRIPT_DIR="$(cd -P "$(dirname "$SCRIPT_SOURCE")" >/dev/null 2>&1 && pwd)"
SCRIPT_SOURCE="$(readlink "$SCRIPT_SOURCE")"
[[ "$SCRIPT_SOURCE" != /* ]] && SCRIPT_SOURCE="$SCRIPT_DIR/$SCRIPT_SOURCE"
done
SCRIPT_DIR="$(cd -P "$(dirname "$SCRIPT_SOURCE")" >/dev/null 2>&1 && pwd)"
ARCH=`uname -m` ARCH=`uname -m`
if [[ $ARCH == "arm64" ]]; then if [[ $ARCH == "arm64" ]]; then
PREFIX="/opt/homebrew/" PREFIX="/opt/homebrew/"
@@ -55,6 +63,9 @@ function update_others {
echo "Update other stuff" echo "Update other stuff"
echo "----------" echo "----------"
echo "-- ALACRITTY"
"$SCRIPT_DIR/install_alacritty_mac.sh" || echo "Alacritty update failed." >&2
if [ -x "$(command -v claude)" ]; then if [ -x "$(command -v claude)" ]; then
echo "-- CLAUDE" echo "-- CLAUDE"
claude --update claude --update
+2
View File
@@ -40,3 +40,5 @@ alias python="python3"
# Tahoe 26 WindowServer bug: windows stay interactive but can't be moved by # Tahoe 26 WindowServer bug: windows stay interactive but can't be moved by
# mouse or API until the window-management daemon is restarted (no logout). # mouse or API until the window-management daemon is restarted (no logout).
alias unstick-windows="killall WindowManager" alias unstick-windows="killall WindowManager"
alias resetdns="sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder"