{"id":32544434,"url":"https://github.com/cdzombak/mac-install","last_synced_at":"2025-10-28T17:59:25.536Z","repository":{"id":304881220,"uuid":"1020368341","full_name":"cdzombak/mac-install","owner":"cdzombak","description":"Idempotent software suite installer for macOS","archived":false,"fork":false,"pushed_at":"2025-09-26T19:37:23.000Z","size":198,"stargazers_count":11,"open_issues_count":1,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-10-23T21:41:33.569Z","etag":null,"topics":["macos"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cdzombak.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-07-15T18:57:19.000Z","updated_at":"2025-09-26T19:37:27.000Z","dependencies_parsed_at":"2025-07-17T00:41:24.325Z","dependency_job_id":"8b56674f-d0f0-47d1-9621-ec00358fef57","html_url":"https://github.com/cdzombak/mac-install","commit_stats":null,"previous_names":["cdzombak/mac-install"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/cdzombak/mac-install","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cdzombak%2Fmac-install","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cdzombak%2Fmac-install/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cdzombak%2Fmac-install/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cdzombak%2Fmac-install/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cdzombak","download_url":"https://codeload.github.com/cdzombak/mac-install/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cdzombak%2Fmac-install/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":281485702,"owners_count":26509764,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-28T02:00:06.022Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["macos"],"created_at":"2025-10-28T17:59:24.648Z","updated_at":"2025-10-28T17:59:25.522Z","avatar_url":"https://github.com/cdzombak.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# `mac-install`\n\nA program for installing and configuring a software suite on macOS. This tool ensures consistent, repeatable, and maintainable setup processes while reducing manual intervention.\n\n## Features\n\n- **Idempotent Operations**: Safe to run multiple times without side effects\n- **Multi-Source Installation**: Supports Homebrew, Mac App Store, Go modules, npm, gem, and custom scripts\n- **Required vs Optional Groups**: Some groups always install, others prompt the user\n- **State Persistence**: Remembers user choices to avoid re-prompting\n- **Automated Configuration**: Applies post-install configurations automatically\n- **Manual Task Tracking**: Generates checklist for required manual steps\n- **Internal Artifact Management**: Automatically installs Homebrew and dependencies when needed\n\n## Installation\n\n### Homebrew\n\n```shell\nbrew install cdzombak/oss/mac-install\n```\n\n### Manual from build artifacts\n\nPre-built binaries for macOS on various architectures are downloadable from each [GitHub Release](https://github.com/cdzombak/mac-install/releases).\n\n## Quick Start\n\n1. **Create a configuration file** (see `install.example.yaml` for a complete example):\n   ```yaml\n   checklist: $HOME/SystemSetup.md\n   install_groups:\n     - group: Essential Tools\n       software:\n         - name: Git\n           artifact: $BREW/bin/git\n           install:\n             - brew: git\n   ```\n\n   💡 **Pro tip**: Use the included YAML schema (`schema.yaml`) for autocompletion and validation in your editor. The project includes VS Code settings for automatic schema detection. See [SCHEMA.md](SCHEMA.md) for detailed setup instructions for various editors.\n\n2. **Run the installer**:\n   ```bash\n   ./mac-install -config install.example.yaml\n   ```\n   \n   To skip all optional sections:\n   ```bash\n   ./mac-install -config install.example.yaml -skip-optional\n   ```\n   \n   To install only a single piece of software:\n   ```bash\n   ./mac-install -config install.example.yaml -only \"Autodesk\"\n   ```\n\n## Configuration Format\n\nThe configuration is defined in YAML format with the following structure. See [`@cdzombak/dotfiles/mac/install.yaml`](https://github.com/cdzombak/dotfiles/blob/master/mac/install.yaml) for a real-world example.\n\n### Root Level\n\n- `checklist`: Path to the checklist file where manual setup steps are written\n- `install_groups`: Array of software groups to install\n\n### Install Groups\n\nEach group contains:\n- `group`: Human-readable group name (e.g., \"Core Tools\", \"Development\")\n- `optional`: Boolean indicating whether to prompt for each software item (optional, defaults to true)\n- `software`: Array of software definitions\n\n### Software Definitions\n\nEach software item must have:\n- `artifact`: Path to the installed artifact (file/app that indicates successful installation)\n\nOptional fields:\n- `name`: Human-readable software name (defaults to artifact display name if not provided)\n- `note`: Optional note displayed to the user when prompting for installation (useful for warnings, size information, etc.)\n- `persist`: Boolean indicating whether to remember user's choice not to install (defaults to false)\n- `install`: Array of installation steps\n- `configure`: Array of configuration steps\n- `checklist`: Array of manual post-installation steps\n\n**Note:** Artifact paths support asterisk (`*`) wildcards for version-agnostic matching. See [Wildcard Support](#wildcard-support) section for details.\n\n### Installation Methods\n\nThe `install` section supports these methods:\n\n- `brew: package-name` - Install via Homebrew\n- `cask: package-name` - Install GUI app via Homebrew Cask\n- `mas: app-id` - Install from Mac App Store. Accepts either an app ID (e.g., `\"1502933106\"`) or an App Store URL (e.g., `\"https://apps.apple.com/us/app/meshman-3d-viewer-pro/id1502933106?mt=12\"`). **NOTE:** The value must be enclosed in quotes.\n- `npm: package-name` - Install global npm package\n- `gem: package-name` - Install Ruby gem\n- `gomod: package-name` - Install Go module via Homebrew\n- `pipx: package-name` - Install Python package via pipx\n- `dl: url` - Download file from URL and save directly to artifact path\n- `run: command` - Execute shell command\n- `script: /path/to/script.sh` - Run shell script\n- `archive: url` + `file: filename` - Download and extract archive (.dmg, .zip, .tar.gz), then copy specified file to /Applications\n- `archive: url` (without `file`) - Download and extract all files from archive to the directory containing the artifact\n\n**Note:** Archive type is automatically detected from the URL (e.g., URLs containing `.dmg`, `.zip`, `.tar.gz`), HTTP Content-Type headers, or from the downloaded file extension. Supported formats include DMG (disk images), ZIP archives, and TAR.GZ compressed archives.\n\n### Configuration Methods\n\nThe `configure` section supports:\n\n- `ignore_errors: true` - Ignore errors in subsequent configuration steps\n- `run: command` - Execute shell command\n- `script: /path/to/script.sh` - Run shell script\n\n### Automatic Application Launch\n\nWhen installing a `.app` application that has `run` or `script` configuration steps, the application will be automatically opened before configuration begins. This ensures apps that need to be running for configuration are launched automatically.\n\n**Conditions for automatic launch:**\n1. Software was just installed (not already present)\n2. Artifact path ends with `.app`\n3. Configuration steps include at least one `run` or `script` command\n\nThe system waits 2 seconds after opening the application before proceeding with configuration to allow the app to start up properly.\n\n**Note:** If the application cannot be opened, a warning is displayed but the installation process continues.\n\n### Variable Expansion\n\nThe following variables are automatically expanded:\n- `$HOME`: User's home directory\n- `$BREW`: Homebrew prefix (typically `/opt/homebrew` or `/usr/local`)\n- `$ENV_VARIABLE_NAME`: Environment variables using the `$ENV_` prefix (e.g., `$ENV_ASDF_PY` expands to the value of the `ASDF_PY` environment variable)\n\n**Note:** If an environment variable referenced with `$ENV_` is not set, the configuration loading will fail with an error message.\n\n### Wildcard Support\n\nArtifact paths support asterisk (`*`) wildcards for version-agnostic matching. This is useful when application names include version numbers that may change over time.\n\n**Examples:**\n- `/Applications/OpenSCAD*.app` matches both `OpenSCAD.app` and `OpenSCAD-2021.01.app`\n- `$HOME/Library/Application Support/MyApp*/config.json` matches version-specific directories\n- `$BREW/bin/tool-*` matches versioned command-line tools\n\nWildcards use Go's `filepath.Glob` pattern matching and will return true if at least one matching file or directory is found.\n\n## Usage\n\n### Command Line Options\n\n- `-config \u003cfile\u003e`: Path to configuration YAML file (default: `./install.yaml`)\n- `-skip-optional`: Skip all optional sections - no installation, configuration, or checklist actions are taken for items in optional groups\n- `-only \u003cname\u003e`: Install only a single piece of software matching this name. Searches both user-chosen names and artifact basenames. If multiple matches are found, lists candidates and exits with error. Cannot be used with `-skip-optional`.\n\n### Examples\n\n#### Required vs Optional Groups\n\n```yaml\n# Required group - installs automatically\n- group: Essential Tools\n  optional: false\n  software:\n    - name: Homebrew\n      artifact: /opt/homebrew/bin/brew\n      # Homebrew is automatically installed as an internal artifact\n\n# Optional group - prompts user\n- group: Optional Development Tools\n  optional: true  # This is the default\n  software:\n    - name: Visual Studio Code\n      artifact: /Applications/Visual Studio Code.app\n      install:\n        - cask: visual-studio-code\n```\n\n#### Basic Software Installation\n\n```yaml\n- name: Visual Studio Code\n  artifact: /Applications/Visual Studio Code.app\n  install:\n    - cask: visual-studio-code\n  configure:\n    - run: code --install-extension ms-vscode.vscode-json\n  checklist:\n    - Sign in to Settings Sync\n    - Configure preferred themes\n```\n\n#### Software with User Notes\n\n```yaml\n- name: Xcode\n  artifact: /Applications/Xcode.app\n  note: This is a large download and may take 30+ minutes\n  install:\n    - mas: \"497799835\"\n  checklist:\n    - Accept Xcode license agreement\n    - Install additional components when prompted\n```\n\n#### Multiple Installation Methods\n\n```yaml\n- name: Node.js\n  artifact: $BREW/bin/node\n  install:\n    - brew: node\n    - npm: npm@latest\n  configure:\n    - run: npm config set init-license \"MIT\"\n```\n\n#### Error Handling in Configuration\n\n```yaml\n- name: Docker Desktop\n  artifact: /Applications/Docker.app\n  install:\n    - cask: docker\n  configure:\n    - ignore_errors: \"true\"\n    - run: docker --version  # May fail if Docker isn't running\n```\n\n#### Manual Installation Only\n\n```yaml\n- name: Custom Software\n  artifact: /Applications/Custom.app\n  # No install steps - will prompt to add manual installation to checklist\n  checklist:\n    - Download from vendor website\n    - Install manually\n```\n\n#### Persist User Choices\n\n```yaml\n# Software that remembers user's choice not to install\n- name: Optional Tool (Remembered)\n  artifact: /Applications/OptionalTool.app\n  persist: true  # Remember choice - won't ask again if user says no\n  install:\n    - cask: optional-tool\n\n# Software that asks every time\n- name: Optional Tool (Always Ask)\n  artifact: /Applications/AlwaysAsk.app\n  persist: false  # Default - will ask on every run\n  install:\n    - cask: always-ask-tool\n```\n\n#### Archive Installation\n\n```yaml\n# Install specific file from a DMG archive\n- name: Custom Application\n  artifact: /Applications/CustomApp.app\n  install:\n    - archive: https://example.com/releases/CustomApp.dmg\n      file: CustomApp.app  # File/directory to copy from the archive\n  checklist:\n    - Launch CustomApp and complete setup\n    - Enter license key if required\n\n# Extract all files from ZIP archive to target directory\n- name: Font Collection\n  artifact: /Library/Fonts/CustomFont.ttf\n  install:\n    - archive: https://fonts.example.com/font-pack.zip\n      # No 'file' parameter - extracts all files to /Library/Fonts/\n  checklist:\n    - Verify fonts appear in Font Book\n    - Test fonts in applications\n\n# TAR.GZ archive with specific binary extraction\n- name: Command Line Tool\n  artifact: /usr/local/bin/tool\n  install:\n    - archive: https://github.com/vendor/tool/releases/download/v1.0/tool.tar.gz\n      file: tool  # Binary file to copy\n```\n\n#### Wildcard Artifact Paths\n\n```yaml\n# Version-agnostic application matching\n- name: OpenSCAD\n  artifact: /Applications/OpenSCAD*.app  # Matches OpenSCAD.app, OpenSCAD-2021.01.app, etc.\n  install:\n    - cask: openscad\n  checklist:\n    - Configure 3D rendering preferences\n    - Import custom libraries\n\n# Versioned configuration files\n- name: Development Config\n  artifact: $HOME/.config/myapp-*/settings.json\n  install:\n    - dl: https://example.com/config/settings.json\n```\n\n## Program Behavior\n\n### Installation Workflow\n\n1. **Internal Artifacts**: Automatically installs Homebrew and dependencies if any software requires them\n2. **Group Processing**: Processes each software group in order\n3. **Artifact Check**: Verifies if the target artifact already exists\n4. **Skip or Install**: \n   - If exists: Reports \"already installed\", checks for missing checklist items, and skips to configuration\n   - If missing: For optional groups, prompts user; for required groups, installs automatically\n5. **Configuration**: Applies post-install configurations if artifact exists\n6. **Checklist Update**: Adds manual steps to checklist for newly installed software or existing software with missing checklist items\n\n### User Interaction\n\n- For optional groups only: prompts \"Install [software]? (y/N)\" in colored cyan text\n- Required groups (optional: false) install automatically without prompting\n- User choices are persisted in `~/.config/dotfiles/software/` as flag files only when `persist: true`\n- When `persist: false` (default), software will be prompted about on every run\n- Subsequent runs respect previous choices and don't re-prompt for persisted software\n- Colored output provides visual feedback (green=success, yellow=warning, red=error, blue=info)\n\n### State Management\n\n- Exclusion flags stored as files named `no-[normalized-software-name]` only when `persist: true`\n- State directory: `~/.config/dotfiles/software/`\n- Filename normalization: lowercase, spaces→hyphens, slashes→hyphens, `.app` suffix removed\n- Software with `persist: false` (default) will not create state files and will be prompted about every run\n\n**Examples of state file names:**\n- \"Visual Studio Code\" → `no-visual-studio-code`\n- \"1Password 7 - Password Manager.app\" → `no-1password-7---password-manager`\n- \"My App/Tool\" → `no-my-app-tool`\n\n### Checklist Generation\n\n- Manual steps written to specified checklist file (typically `~/SystemSetup.md`)\n- Uses Markdown format with checkboxes\n- Headers based on artifact display names\n- Idempotent: won't create duplicate entries\n- Includes Homebrew caveats when applicable\n- **Automatically creates checklist entries for already-installed software** if the header is missing\n\n### Error Handling\n\n- Program exits with failure if any installation or configuration step fails\n- Idempotent design allows safe re-running to resolve errors\n- Configuration steps can be set to ignore errors with `ignore_errors: true`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcdzombak%2Fmac-install","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcdzombak%2Fmac-install","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcdzombak%2Fmac-install/lists"}