Skip to content

Instantly share code, notes, and snippets.

@qu8n
Last active February 28, 2025 23:01
Show Gist options
  • Save qu8n/48dd4b4374a45b5df4d1754519e43abe to your computer and use it in GitHub Desktop.
Save qu8n/48dd4b4374a45b5df4d1754519e43abe to your computer and use it in GitHub Desktop.
s
#!/bin/zsh
# ==============================================================================
# Install the prerequisites
# ==============================================================================
# Install Homebrew
if ! command -v brew &> /dev/null; then
echo "Installing Homebrew. You might be prompted the password..."
NONINTERACTIVE=1 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
if [ ! -f ~/.zprofile ]; then
echo "Creating ~/.zprofile file..."
touch ~/.zprofile
fi
if ! grep -q "brew shellenv" ~/.zprofile; then
echo "Adding Homebrew to PATH in ~/.zprofile..."
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile
fi
# Source the profile to make brew available in current session
source ~/.zprofile
else
echo "Homebrew already installed, skipping installation."
fi
# Install Git (Xcode installed an older version of Git, we want the latest)
echo "Updating Git to latest version..."
brew install git
# Install Oh My Zsh
# (The `--unattended` flag prevents the reloading of the shell after installation,
# which would prevent the rest of the script from running)
if [ ! -d "$HOME/.oh-my-zsh" ]; then
echo "Installing Oh My Zsh..."
# (The `--unattended` flag prevents the reloading of the shell after installation,
# which would prevent the rest of the script from running)
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended
else
echo "Oh My Zsh already installed, skipping installation."
fi
# Install Powerlevel10k theme
if [ ! -d "${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes/powerlevel10k" ]; then
echo "Installing Powerlevel10k theme..."
git clone --depth=1 https://github.com/romkatv/powerlevel10k.git "${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes/powerlevel10k"
else
echo "Powerlevel10k theme already installed, skipping installation."
fi
# ==============================================================================
# Set up the local dotfiles repo
# ==============================================================================
# Clone the remote dotfiles repo into a bare Git repo of the new machine's $HOME
# (What's a bare repo? https://craftquest.io/articles/what-is-a-bare-git-repository)
if [ ! -d "$HOME/.cfg" ]; then
echo "Cloning dotfiles repository..."
git clone --bare https://github.com/qu8n/dotfiles.git $HOME/.cfg
else
echo "Dotfiles repository already exists, skipping clone."
fi
# Define the `config` function instead of an alias so it works within the script
config() {
/usr/bin/git --git-dir=$HOME/.cfg/ --work-tree=$HOME "$@"
}
# Checkout the actual content from the bare repository to the $HOME directory
# If the command above fails because there are existing files that would be
# overwritten, back them up to a temporary directory and try the checkout again.
config checkout
if [ $? = 0 ]; then
echo "Checked out config.";
else
echo "Backing up pre-existing dot files.";
mkdir -p .config-backup
config checkout 2>&1 | egrep "\s+\." | awk {'print $1'} | xargs -I{} mv {} .config-backup/{}
config checkout
fi;
# Disable the bare repo from showing untracked files
config config --local status.showUntrackedFiles no
# Symlink selected config files to the directories where their respective
# programs expect them
mkdir -p ~/.config
create_symlink() {
local source="$1"
local target="$2"
if [ -L "$target" ]; then
echo "Removing existing symlink: $target"
rm "$target"
elif [ -e "$target" ]; then
echo "Backing up existing file/directory: $target"
mv "$target" "$target.backup.$(date +%Y%m%d%H%M%S)"
fi
echo "Creating symlink: $source -> $target"
ln -s "$source" "$target"
}
create_symlink ~/nvim ~/.config/nvim
create_symlink ~/karabiner ~/.config/karabiner
# ==============================================================================
# Install Homebrew formulaes and casks
# ==============================================================================
# Install Rosetta 2 if on Apple Silicon
# (Some packages were built for Intel Mac, so we need Rosetta to run them on M1)
if [[ $(uname -m) == 'arm64' ]]; then
echo "Apple Silicon detected, installing Rosetta 2..."
# Check if Rosetta is already installed
if ! /usr/bin/pgrep -q oahd; then
softwareupdate --install-rosetta --agree-to-license
else
echo "Rosetta 2 already installed, skipping installation."
fi
else
echo "Intel Mac detected, skipping Rosetta 2 installation."
fi
# Install Homebrew formulaes and casks
if [ -f ~/homebrew/Brewfile ]; then
echo "Installing Homebrew packages from Brewfile..."
brew bundle --file ~/homebrew/Brewfile
else
echo "Error: ~/homebrew/Brewfile not found!"
exit 1
fi
# I've purchased the license keys for older versions of some apps. `brew install`
# downloads the binary for the latest version, which isn't covered by my license.
# Next, we need to revert to the archived versions of these apps.
#
# How to find the archived version of a cask:
# 1. Go to the main Homebrew page of the cask (e.g. https://formulae.brew.sh/cask/cleanshot)
# 2. Click on "Cask code on Github"
# 3. Click on "History"
# 4. Click on the commit name of the desired version
# 5. Click on the ellipsis (...)
# 6. Click on "View file" > "Raw"
# 7. Copy the URL, then `curl` it into ~/homebrew/archived-versions
install_archived_app() {
local app_name="$1"
local rb_file="$2"
echo "Managing $app_name installation..."
# Check if the app is installed
if brew list "$app_name" &>/dev/null; then
echo "Uninstalling latest version of $app_name..."
brew uninstall --zap "$app_name"
fi
# Check if the archived version file exists
if [ -f "$rb_file" ]; then
echo "Installing archived version of $app_name..."
brew install --HEAD -s "$rb_file"
else
echo "Error: Archived version file not found: $rb_file"
return 1
fi
}
# Install archived versions of apps
install_archived_app "cleanshot" ~/homebrew/archived-versions/cleanshot.rb
install_archived_app "tableplus" ~/homebrew/archived-versions/tableplus.rb
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment