Skip to content

alberti42/macOS-config-manager

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

macos-config-manager

A small, dependency-free Python CLI to snapshot and restore macOS preferences managed via the defaults system.

The idea is simple:

  • Maintain a curated list of preferences you care about in macOS-config-template.json.
  • Run --store to capture the current machine values into a config JSON.
  • Run --restore later to apply that snapshot back (including deleting keys that were absent at capture time).

This is meant for:

  • setting up a new Mac the same way every time
  • keeping multiple machines consistent
  • experimenting with changes and being able to revert

What It Does (and What It Does Not)

Does:

  • Reads and writes macOS preferences via defaults.
  • Supports user-scoped and currentHost-scoped domains.
  • Captures types using defaults export (plists) and stores the values as JSON.
  • On restore, if a key was missing when captured, it is deleted (true revert-to-absent).

Does not:

  • Change settings that are not controlled by defaults.
  • Run privileged operations (sudo), modify system files, or run destructive cleanup commands.

Repository Files

  • macos-config-manager.py - CLI entry point
  • macOS-config-template.json - the maintained template (what to track)
  • macOS-my-config.json - suggested local snapshot name (ignored by git)
  • completions/ - optional static shell completion scripts

Requirements

  • macOS
  • Python 3

No third-party Python packages are required.

Quick Start

  1. Make the script executable
chmod +x macos-config-manager.py
  1. Create a snapshot (store current values)
./macos-config-manager.py --store --template macOS-config-template.json --output macOS-my-config.json --force

At this point you can treat macOS-my-config.json as:

  • a backup of your current state
  • a desired-state file you can edit and re-apply
  1. Preview a restore (prints commands only)
./macos-config-manager.py --restore --input macOS-my-config.json --dry-run
  1. Restore for real
./macos-config-manager.py --restore --input macOS-my-config.json
  1. Restore and restart common affected apps/services
./macos-config-manager.py --restore --input macOS-my-config.json --restart-apps

How It Works

Template (macOS-config-template.json)

The template defines what to track. Each entry is identified by:

  • domain - the preference domain, e.g. com.apple.finder or NSGlobalDomain
  • name - the preference key, e.g. ShowStatusBar
  • scope - user or currentHost
  • type - bool, int, float, string, array, dict (or infer)
  • comment - human-readable description of what the setting controls

Example:

{
  "domain": "com.apple.menuextra.battery",
  "name": "ShowPercent",
  "scope": "user",
  "type": "string",
  "comment": "Battery menu extra: show battery percentage"
}

Stored Config (macOS-my-config.json or any --output)

When you run --store, each template entry becomes a stored entry with:

  • present - whether the key existed at capture time
  • value - the captured value (or null if absent)

On --restore:

  • present: true writes the stored value back.
  • present: false deletes the key.

This is intentional: it lets you accurately revert to "the setting did not exist" rather than guessing a default.

Types

--store uses defaults export and parses the plist, so it can preserve types.

  • bool, int, float, string round-trip cleanly.
  • array and dict are supported, with the practical limitation that restore only supports scalar array items and scalar dict values (bool/int/float/string).

Shell Completion

Static completion scripts are provided in completions/.

Zsh (project-local):

Add to ~/.zshrc:

fpath=(/path/to/this/repo/completions $fpath)
autoload -U compinit && compinit

Bash:

Add to ~/.bashrc (or ~/.bash_profile on macOS bash setups):

source /path/to/this/repo/completions/macos-config-manager.bash

Note: completion triggers for the command name (e.g. macos-config-manager.py on PATH). If you run it as ./macos-config-manager.py, completion may not trigger unless you add an alias.

Safety Notes

  • defaults changes are real system changes; prefer --dry-run first.
  • Some preferences may take effect only after restarting the relevant app.
  • --restart-apps is best-effort; it uses killall and ignores missing/legacy process names.
  • Always review and curate macOS-config-template.json before using it broadly.

Customizing What You Track

Edit macOS-config-template.json directly.

To add a new key, add a new object to options:

{
  "domain": "com.apple.finder",
  "name": "ShowPathbar",
  "scope": "user",
  "type": "bool",
  "comment": "Finder: show path bar"
}

Then re-run --store to capture the current value.

Credits

The initial list of macOS preferences was inspired by:

This repository refactors that idea into a template-driven snapshot/restore tool.

License

This project is licensed under the MIT License.

About

A CLI utilty to manage macOS configurations (export and import)

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors