Working with Modules

Modules are the building blocks of your set-me-up environment

Available Modules

Pre-built modules to set up your development environment

Core Module

Required

base

Foundation module that installs Homebrew, rcm, and creates dotfile symlinks.

Always provision base first
smu --provision --module base

Application Modules

app_store

Installs Mac App Store applications via Homebrew bundle.

smu --provision --module app_store --no-base

casks

Installs GUI applications via Homebrew casks.

smu --provision --module casks --no-base

Development Environment Modules

php

Sets up PHP development environment with Composer and common extensions.

smu --provision --module php --no-base

ruby

Sets up Ruby development environment with rbenv and Bundler.

smu --provision --module ruby --no-base

node

Sets up Node.js development environment with nvm and latest LTS version.

smu --provision --module node --no-base

python

Sets up Python development environment with pyenv and latest Python version.

smu --provision --module python --no-base

Advanced Usage

Install Multiple Modules

You can provision multiple modules at once by specifying multiple --module flags:

smu --provision --module app_store --module casks --module php --no-base
This is useful for setting up a complete environment in one command

Module Execution Flow

Understanding how modules are executed

before.sh

(if exists)

Pre-installation tasks and environment preparation

1
Optional Script

Runs first if present in module directory

module.sh

Required

Main installation script with core module logic

2
Core Script

The heart of every module - must exist

brewfile

(if exists)

Homebrew bundle installation of packages and apps

3
Package Manager

Processes Homebrew bundle if file exists

after.sh

(if exists)

Post-installation configuration and cleanup

4
Finalization

Runs last if present - final setup tasks

Execution Order

Only module.sh is required. The other scripts (before.sh, brewfile, after.sh) are optional and will only execute if they exist in your module directory.

Creating Custom Modules

Build your own modules for specialized installations

Basic Module

Create a simple module with a main script:

# Create module directory
mkdir -p ~/set-me-up/modules/mymodule

# Create the main script
cat > ~/set-me-up/modules/mymodule/module.sh << 'EOF'
#!/bin/bash
echo "Installing my custom tools..."
brew install tool1 tool2
EOF

chmod +x ~/set-me-up/modules/mymodule/module.sh

# Provision your module
smu --provision --module mymodule --no-base

Module with Brewfile

Add a brewfile for package management:

# Create the brewfile
cat > ~/set-me-up/modules/mymodule/brewfile << 'EOF'
# CLI tools
brew "tool1"
brew "tool2"

# GUI applications
cask "application1"
cask "application2"
EOF

The brewfile will be automatically processed during provisioning

Module with Hooks

Add before and after hooks for custom logic:

# Before hook (runs first)
cat > ~/set-me-up/modules/mymodule/before.sh << 'EOF'
#!/bin/bash
echo "Preparing environment..."
# Pre-installation tasks
EOF

# After hook (runs last)
cat > ~/set-me-up/modules/mymodule/after.sh << 'EOF'
#!/bin/bash
echo "Finalizing setup..."
# Post-installation tasks
EOF

chmod +x ~/set-me-up/modules/mymodule/*.sh

Module Best Practices

Guidelines for creating reliable and maintainable modules

Make Scripts Idempotent

Scripts should be safe to run multiple times without adverse effects. Check existing state before making changes.

Check for Existing Installations

Don't reinstall unnecessarily. Verify if tools are already present before attempting installation.

Provide Clear Feedback

Echo installation progress and outcomes so users understand what's happening in real-time.

Handle Errors Gracefully

Use proper error checking and exit with appropriate status codes. Fail fast when necessary.

Document Dependencies

Clearly note what must be installed first, such as the base module or other prerequisites.

Use Brewfiles

Leverage Homebrew Bundle for streamlined, declarative package management across modules.

Pro Tip

Following these best practices ensures your modules are robust, maintainable, and work seamlessly with the set-me-up ecosystem. Always test your modules on a clean system before sharing them.

Example: Idempotent Module

A well-structured module that can be run safely multiple times

#!/bin/bash

# Check if already installed
if command -v mytool &> /dev/null; then
    echo "mytool is already installed"
    exit 0
fi

echo "Installing mytool..."
brew install mytool

# Verify installation
if command -v mytool &> /dev/null; then
    echo "✓ mytool installed successfully"
else
    echo "✗ mytool installation failed"
    exit 1
fi

Ready to Explore More?

Learn about dotfile management and customization

Managing Dotfiles Customization