Automate MacOS Setup: Bootstrapping Script Guide

by Alex Johnson 49 views

Setting up a new MacOS installation can be a tedious process, especially when you have a specific set of configurations and applications you want to install. This comprehensive guide provides a solution by creating a bash script structure for bootstrapping a new MacOS installation with your preferred configurations. This approach involves a main script that orchestrates the process and individual module scripts for installing and configuring specific applications. This modular design enhances organization, maintainability, and reusability.

Understanding the Need for a Bootstrapping Script

Manually installing and configuring applications on a new MacOS system can be time-consuming and prone to errors. A bootstrapping script automates this process, ensuring consistency and saving valuable time. By creating a well-structured script, you can easily replicate your preferred setup across multiple machines or after system resets. The primary goal is to streamline the setup process, making it efficient and reliable.

The benefits of using a bootstrapping script are numerous:

  • Time-saving: Automate repetitive tasks, reducing setup time significantly.
  • Consistency: Ensure the same configuration across multiple machines.
  • Reduced Errors: Minimize manual errors during installation and configuration.
  • Maintainability: Easily update and modify configurations in a modular fashion.
  • Reusability: Use the script for future installations or system resets.

Designing the Bash Script Structure

The structure of the bootstrapping script is crucial for its effectiveness. It consists of a main script that acts as the central control point and individual module scripts for each application or configuration. Each module has its own directory, allowing for associated configuration files to be stored alongside the script. This organization promotes clarity and ease of maintenance.

The main script (bootstrap.sh) will:

  1. Set up necessary environment variables.
  2. Check for required dependencies (e.g., Homebrew).
  3. Execute module scripts in a predefined order.
  4. Handle errors and logging.
  5. Provide a user-friendly interface with progress updates.

Each module script (e.g., modules/homebrew/install.sh) will:

  1. Install the specific application or configure the system.
  2. Copy configuration files to the appropriate locations.
  3. Perform any necessary post-installation tasks.
  4. Log the installation status.

This modular approach allows for easy addition, removal, or modification of individual components without affecting the entire setup process.

Core Components and Their Installation

For starters, our bootstrapping script will handle the installation and configuration of several key applications. These include XCode, Homebrew, Antidote, Starship, Ghostty, fastfetch, Karabiner Elements, Obsidian, Keka, and Rectangle. Each of these components enhances the MacOS experience by providing essential tools and utilities.

1. Installing XCode

XCode is a prerequisite for Homebrew and many other developer tools on MacOS. While it can be installed manually from the App Store, automating this step ensures a consistent installation process. The installation of XCode is crucial as it provides the necessary compilers and build tools required for many command-line utilities and applications. The bootstrapping script will check if XCode is already installed and, if not, initiate the installation process. This step is vital for ensuring that all subsequent installations, especially Homebrew, proceed smoothly.

The module script for XCode (modules/xcode/install.sh) will:

  • Check if XCode Command Line Tools are installed.
  • If not, prompt the user to install them using xcode-select --install.
  • Verify the installation by checking the XCode version.
#!/bin/bash

echo "[XCode]: Checking for XCode Command Line Tools..."
if ! xcode-select -p &> /dev/null; then
 echo "[XCode]: XCode Command Line Tools not found. Installing..."
 xcode-select --install
 echo "[XCode]: Please click 'Install' and accept the license agreement when prompted."
 sleep 60 # Give the user time to install
else
 echo "[XCode]: XCode Command Line Tools are already installed."
fi

if xcodebuild -version &> /dev/null; then
 echo "[XCode]: XCode is installed."
else
 echo "[XCode]: XCode installation failed."
 exit 1
fi

2. Installing Homebrew

Homebrew is a package manager for MacOS, simplifying the installation of various software packages. It is a cornerstone of MacOS development and administration. The bootstrapping script will install Homebrew using the official installation script and ensure it is correctly configured in the system’s PATH. This step is essential as Homebrew will be used to install most of the other applications and utilities.

The module script for Homebrew (modules/homebrew/install.sh) will:

  • Download and execute the Homebrew installation script.
  • Add Homebrew to the system’s PATH.
  • Update Homebrew to ensure it is up to date.
#!/bin/bash

echo "[Homebrew]: Installing Homebrew..."
if ! command -v brew &> /dev/null; then
 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
 echo 'eval "$($(brew --prefix)/bin/brew shellenv)"' >> ~/.zprofile
 eval "$($(brew --prefix)/bin/brew shellenv)"
else
 echo "[Homebrew]: Homebrew is already installed."
fi

echo "[Homebrew]: Updating Homebrew..."
brew update

3. Installing and Configuring Antidote

Antidote is a Zsh plugin manager that helps manage and load Zsh plugins efficiently. It streamlines the process of using and updating plugins, making your Zsh environment more powerful and customizable. The bootstrapping script will install Antidote via Homebrew and create a blank .zsh_plugins.txt file, automating its copying to the home folder and loading it in Antidote. This ensures that your Zsh environment is set up correctly with your preferred plugins.

The module script for Antidote (modules/antidote/install.sh) will:

  • Install Antidote using Homebrew.
  • Create a blank .zsh_plugins.txt file.
  • Copy the file to the home directory.
  • Load the plugins in Antidote by adding the necessary lines to the .zshrc file.
#!/bin/bash

echo "[Antidote]: Installing Antidote..."
brew install antidote

echo "[Antidote]: Creating .zsh_plugins.txt..."
touch .zsh_plugins.txt

echo "[Antidote]: Copying .zsh_plugins.txt to home directory..."
cp .zsh_plugins.txt $HOME/.zsh_plugins.txt

echo "[Antidote]: Configuring Antidote in .zshrc..."
if grep -q "antidote init" ~/.zshrc; then
 echo "[Antidote]: Antidote already configured in .zshrc."
else
 echo "\n# Antidote configuration\nsource $(brew --prefix)/share/antidote/antidote.zsh\nantidote init" >> ~/.zshrc
fi

echo "[Antidote]: Antidote installed and configured."

4. Installing and Configuring Starship

Starship is a cross-shell prompt that is highly customizable and provides a consistent look and feel across different terminals. It enhances the terminal experience by providing useful information and a visually appealing prompt. The bootstrapping script will install Starship via Homebrew and create a blank starship.toml file, automating its copying to ~/.config/starship.toml. This ensures that Starship is correctly installed and configured with your custom settings.

The module script for Starship (modules/starship/install.sh) will:

  • Install Starship using Homebrew.
  • Create a blank starship.toml file.
  • Copy the file to ~/.config/starship.toml.
  • Add the necessary lines to the .zshrc file to initialize Starship.
#!/bin/bash

echo "[Starship]: Installing Starship..."
brew install starship

echo "[Starship]: Creating starship.toml..."
mkdir -p ~/.config
touch ~/.config/starship.toml

echo "[Starship]: Configuring Starship in .zshrc..."
if grep -q "starship init zsh" ~/.zshrc; then
 echo "[Starship]: Starship already configured in .zshrc."
else
 echo "\n# Starship configuration\neval \"$(starship init zsh)\"" >> ~/.zshrc
fi

echo "[Starship]: Starship installed and configured."

5. Installing and Configuring Ghostty

Ghostty is a modern, cross-platform terminal emulator focused on performance and user experience. It provides a sleek interface and advanced features for terminal users. The bootstrapping script will install Ghostty via Homebrew and create a blank config file, automating its copying to $HOME/Library/Application Support/com.mitchellh.ghostty/config. This ensures that Ghostty is installed and ready to be configured to your preferences.

The module script for Ghostty (modules/ghostty/install.sh) will:

  • Install Ghostty using Homebrew.
  • Create the necessary directory for Ghostty configuration.
  • Create a blank config file.
  • Copy the file to $HOME/Library/Application Support/com.mitchellh.ghostty/config.
#!/bin/bash

echo "[Ghostty]: Installing Ghostty..."
brew install ghostty

echo "[Ghostty]: Creating Ghostty config directory..."
mkdir -p "$HOME/Library/Application Support/com.mitchellh.ghostty"

echo "[Ghostty]: Creating Ghostty config file..."
touch "$HOME/Library/Application Support/com.mitchellh.ghostty/config"

echo "[Ghostty]: Ghostty installed and configured."

6. Installing fastfetch

fastfetch is a system information tool that displays details about your operating system, hardware, and software in a visually appealing format. It is a lightweight and fast alternative to other system information tools. The bootstrapping script will install fastfetch via Homebrew, making it easy to access system information from the terminal.

The module script for fastfetch (modules/fastfetch/install.sh) will:

  • Install fastfetch using Homebrew.
#!/bin/bash

echo "[fastfetch]: Installing fastfetch..."
brew install fastfetch

echo "[fastfetch]: fastfetch installed."

7. Installing Karabiner Elements

Karabiner Elements is a powerful keyboard customization tool for MacOS. It allows you to remap keys, create complex keyboard shortcuts, and customize keyboard behavior. The bootstrapping script will install Karabiner Elements via Homebrew, providing you with the ability to tailor your keyboard to your specific needs.

The module script for Karabiner Elements (modules/karabiner-elements/install.sh) will:

  • Install Karabiner Elements using Homebrew.
#!/bin/bash

echo "[Karabiner Elements]: Installing Karabiner Elements..."
brew install karabiner-elements

echo "[Karabiner Elements]: Karabiner Elements installed."

8. Installing Obsidian

Obsidian is a powerful note-taking and knowledge management application that uses Markdown files. It allows you to create a network of interconnected notes, making it an excellent tool for personal knowledge management. The bootstrapping script will install Obsidian via Homebrew, ensuring you have a reliable and efficient way to manage your notes and knowledge.

The module script for Obsidian (modules/obsidian/install.sh) will:

  • Install Obsidian using Homebrew.
#!/bin/bash

echo "[Obsidian]: Installing Obsidian..."
brew install obsidian

echo "[Obsidian]: Obsidian installed."

9. Installing Keka

Keka is a free file archiver for MacOS that supports a wide range of compression formats. It provides a simple and intuitive interface for compressing and decompressing files. The bootstrapping script will install Keka via Homebrew, giving you a convenient tool for managing compressed files.

The module script for Keka (modules/keka/install.sh) will:

  • Install Keka using Homebrew.
#!/bin/bash

echo "[Keka]: Installing Keka..."
brew install keka

echo "[Keka]: Keka installed."

10. Installing Rectangle

Rectangle is a window management application for MacOS that allows you to move and resize windows using keyboard shortcuts. It is a lightweight and efficient tool that enhances productivity by simplifying window management. The bootstrapping script will install Rectangle via Homebrew, providing you with a convenient way to organize your workspace.

The module script for Rectangle (modules/rectangle/install.sh) will:

  • Install Rectangle using Homebrew.
#!/bin/bash

echo "[Rectangle]: Installing Rectangle..."
brew install rectangle

echo "[Rectangle]: Rectangle installed."

The Main Bootstrapping Script (bootstrap.sh)

The main script orchestrates the installation process by calling the individual module scripts. It sets up the environment, checks for dependencies, executes the module scripts, and handles errors. The script is designed to be user-friendly, providing progress updates and logging information.

#!/bin/bash

# Set script to exit immediately if a command exits with a non-zero status
set -e

# Define the modules to install
MODULES=(
 xcode
 homebrew
 antidote
 starship
 ghostty
 fastfetch
 karabiner-elements
 obsidian
 keka
 rectangle
)

# Function to log messages
log() {
 echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1"
}

# Function to execute a module script
execute_module() {
 MODULE_NAME="$1"
 log "[Main]: Executing module: $MODULE_NAME"
 if [ -f "modules/$MODULE_NAME/install.sh" ]; then
 bash "modules/$MODULE_NAME/install.sh" || {
 log "[Main]: Module $MODULE_NAME failed to install."
 exit 1
 }
 else
 log "[Main]: Module $MODULE_NAME install script not found."
 exit 1
 fi
}

# Check for necessary tools
log "[Main]: Checking for necessary tools..."
if ! command -v curl &> /dev/null; then
 log "[Main]: curl is required. Please install it."
 exit 1
fi

# Execute each module script
log "[Main]: Starting module installations..."
for MODULE in "${MODULES[@]}"; do
 execute_module "$MODULE"
done

log "[Main]: All modules installed successfully."

echo "\n[Main]: MacOS bootstrapping complete!"

# Ask the user to restart the terminal
echo "[Main]: Please restart your terminal for the changes to take effect."

exit 0

Step-by-Step Execution Guide

  1. Create the Script Structure:

    • Create a main directory for your bootstrapping script (e.g., macos-bootstrap).
    • Inside this directory, create the bootstrap.sh file and a modules directory.
    • Within the modules directory, create subdirectories for each application (e.g., homebrew, antidote, starship).
    • Place the corresponding install.sh script in each module directory.
  2. Make the Main Script Executable:

    • Open your terminal and navigate to the macos-bootstrap directory.
    • Run the command chmod +x bootstrap.sh to make the script executable.
  3. Run the Bootstrapping Script:

    • Execute the script by running ./bootstrap.sh in the terminal.
    • Follow the on-screen prompts and provide any necessary input (e.g., XCode Command Line Tools installation).
  4. Review the Output:

    • The script will display progress updates for each module installation.
    • If any errors occur, the script will log them and exit.
  5. Restart Your Terminal:

    • After the script completes successfully, restart your terminal for the changes to take effect.

Best Practices for Bootstrapping Scripts

Creating and maintaining bootstrapping scripts involves several best practices that ensure the script remains effective and reliable over time. These practices include modularity, error handling, logging, and security considerations.

  • Modularity: Breaking down the script into modules, as demonstrated in this guide, allows for easier maintenance and updates. Each module should handle a specific task, making it easier to troubleshoot and modify.
  • Error Handling: Implementing robust error handling is crucial. The script should check for errors after each command and log them appropriately. This helps in identifying and resolving issues quickly.
  • Logging: Comprehensive logging provides valuable insights into the script’s execution. Logging should include timestamps, module names, and status messages. This information is essential for debugging and monitoring the script’s performance.
  • Security: Avoid hardcoding sensitive information, such as passwords or API keys, in the script. Use environment variables or secure configuration files to store sensitive data. Regularly review and update the script to address any security vulnerabilities.
  • Idempotency: Ensure that the script can be run multiple times without causing issues. This is particularly important for tasks like creating configuration files or installing software. The script should check if a task has already been performed before attempting to perform it again.

Conclusion

Automating the MacOS setup process with a bootstrapping script is a significant time-saver and ensures consistency across multiple installations. By following the modular approach outlined in this guide, you can create a robust and maintainable script tailored to your specific needs. The script structure, including the main script and module scripts, provides a clear and organized way to manage your MacOS configurations. This comprehensive guide has provided you with the tools and knowledge necessary to create your own bootstrapping script, streamlining your MacOS setup process and enhancing your productivity.

For further reading on shell scripting and automation, check out this Bash Scripting Tutorial.