Thank you for your interest in contributing to mac-ops! This guide will help you get started with development and explain how to contribute effectively.
-
Clone the repo
git clone https://github.com/yourusername/mac-ops.git cd mac-ops -
Run tests to ensure everything works
zsh tests/test-trash.zsh zsh tests/test-safety.zsh zsh tests/test-modules.zsh
-
Try a dry run to see the tool in action
bin/mac-ops run --dry-run
All tests should pass before making changes.
- macOS 13 or later
- zsh (default macOS shell)
- No external dependencies needed
mac-ops uses only macOS built-in tools to ensure:
- No package manager overhead (Homebrew not required for the tool itself)
- Reliability across different macOS configurations
- Fast execution with minimal startup time
- Maximum portability and system safety
mac-ops/
├── bin/
│ └── mac-ops # CLI entry point with strict mode (ERR_EXIT, PIPE_FAIL)
├── lib/
│ ├── core/ # Core functions (module execution, dry-run)
│ ├── modules/ # Cleanup modules (cache, tmp, log, zombie, etc.)
│ └── utils/ # Shared utilities (logging, color, trash, safety)
├── config/
│ └── default.plist # Default configuration for modules
├── launchd/ # Scheduled execution setup
├── tests/ # Test suites
└── README.md, LICENSE # Documentation
- bin/: Entry point handling CLI arguments, module discovery, and execution
- lib/core/: Core execution logic for running modules and managing dry-run mode
- lib/modules/: Individual cleanup modules (each handles one cleanup task)
- lib/utils/: Shared utilities for logging, colors, trash management, process safety
- config/: Default configuration via plist (module settings, exclusions, paths)
- tests/: Comprehensive test suites using custom assertions
All scripts use the following options for safety:
setopt ERR_EXIT PIPE_FAILThis ensures the script exits on any error and catches pipe failures.
- All variables must be declared with
localinside functions - Global variables should be avoided when possible
- Use descriptive names in lowercase with underscores
- Public functions: Prefix with
mac_ops_(e.g.,mac_ops_cleanup_cache) - Private/internal functions: Prefix with
_mac_ops_(e.g.,_mac_ops_parse_args) - Module main function:
mac_ops_<module_name>()(e.g.,mac_ops_cleanup_cache)
All log messages must use the centralized logging utilities:
mac_ops_log_info "message"- Informational messagesmac_ops_log_warn "message"- Warningsmac_ops_log_error "message"- Errorsmac_ops_log_debug "message"- Debug information (if enabled)
- All comments and user-facing messages must be in English
- Comments should explain the "why", not the "what"
- Use clear, concise language
- Use 2-space indentation
- Keep functions focused and reasonably sized
- Use meaningful variable names
- Avoid deep nesting where possible
Creating a new cleanup module is the primary way to extend mac-ops.
Create lib/modules/my-cleanup.zsh with the main function:
#!/bin/zsh
# My cleanup module description
mac_ops_my_cleanup() {
local dry_run="${1:-false}"
mac_ops_log_info "Cleaning up my resources..."
# Your cleanup logic here
if [[ "$dry_run" == "true" ]]; then
mac_ops_log_info "Would clean up X files (dry-run mode)"
else
# Perform actual cleanup
mac_ops_log_info "Cleaned up X files"
fi
}Add a source line in the module loading section:
source "$SCRIPT_DIR/../lib/modules/my-cleanup.zsh"Add your module to the module discovery in bin/mac-ops:
mac_ops["my-cleanup"]="mac_ops_my_cleanup"If your module performs file-based operations that don't block each other, add it to the parallel execution array:
PARALLEL_MODULES+=(mac_ops_my_cleanup)Update config/default.plist with any module-specific settings:
<key>my-cleanup</key>
<dict>
<key>enabled</key>
<true/>
<key>exclude-paths</key>
<array>
<string>/path/to/exclude</string>
</array>
</dict>Add test cases to tests/test-modules.zsh:
test_my_cleanup_basic() {
local temp_dir=$(mktemp -d)
# Setup test data
mac_ops_my_cleanup false
# Verify results
assert_eq "expected" "actual" "Test description"
rm -rf "$temp_dir"
}Update README.md with:
- What the module cleans up
- What it safely skips
- Any important notes or warnings
mac-ops uses a custom lightweight test framework with these assertion functions:
assert_eq "expected" "actual" "message"- Equality checkassert_true "condition" "message"- Boolean assertionassert_exit_code "expected" "command" "message"- Exit code checkassert_file_exists "path" "message"- File existence check
Run all tests:
zsh tests/test-trash.zsh
zsh tests/test-safety.zsh
zsh tests/test-modules.zshRun a specific test file:
zsh tests/test-modules.zsh- Tests use temporary directories created with
mktemp -d - Tests never touch real system directories
- Cleanup is automatic; no manual intervention needed
- All 64 tests pass reliably
- Use temporary directories for all file operations
- Test both success and failure paths
- Verify side effects (files deleted, logs generated)
- Test with dry-run mode enabled
- Add clear descriptive messages to assertions
-
Fork the repository on GitHub
-
Create a feature branch with a descriptive name
git checkout -b feature/add-new-module
-
Write tests first (or alongside your code)
- Add test cases to
tests/test-modules.zsh - Ensure tests pass before submitting
- Add test cases to
-
Ensure all tests pass
zsh tests/test-trash.zsh && zsh tests/test-safety.zsh && zsh tests/test-modules.zsh
-
Make commits with clear messages
- Use present tense ("Add feature" not "Added feature")
- Reference issues if applicable
-
Submit a pull request with:
- Clear title describing what you've done
- Description of the changes and why they're needed
- Reference to any related issues
- Confirmation that all tests pass
We are committed to providing a welcoming and inspiring community for all. Please be:
- Respectful: Treat all community members with respect
- Constructive: Provide helpful feedback and suggestions
- Inclusive: Welcome diverse perspectives and backgrounds
- Professional: Keep discussions focused on the project and its goals
Unacceptable behavior (harassment, discrimination, etc.) will not be tolerated. Report concerns to the maintainers.
Thank you for contributing to mac-ops! Your help makes this tool better for everyone.