Convert crontab expressions to macOS launchd plist format.
- Full crontab syntax support (wildcards, ranges, lists, steps)
- Special strings (@reboot, @daily, @weekly, @monthly, @yearly, @annually)
- Environment variable support
- Generates valid launchd plist XML files
- Comprehensive validation with macOS plutil
# Run directly
nix run github:randomn4me/crontab-to-launchd -- "0 2 * * * /usr/bin/backup.sh" com.example.backup
# Install to profile
nix profile install github:randomn4me/crontab-to-launchdpip install -r requirements.txt
python -m crontab_to_launchd.main "0 2 * * * /usr/bin/backup.sh" com.example.backup# Basic usage
crontab-to-launchd "0 2 * * * /usr/bin/backup.sh" com.example.backup
# Save to file
crontab-to-launchd "0 2 * * * /usr/bin/backup.sh" com.example.backup -o backup.plist
# Validate only
crontab-to-launchd "0 2 * * * /usr/bin/backup.sh" com.example.backup -v
# Special strings
crontab-to-launchd "@daily /usr/bin/daily.sh" com.example.dailyfrom crontab_to_launchd.parser import CrontabParser
from crontab_to_launchd.generator import LaunchdGenerator
# Parse crontab
parser = CrontabParser()
entry = parser.parse("0 2 * * * /usr/bin/backup.sh")
# Generate plist
generator = LaunchdGenerator()
xml = generator.generate(entry, "com.example.backup")
print(xml)parser.py: Parses crontab expressions intoCrontabEntrydataclassgenerator.py: ConvertsCrontabEntryto launchd plist XMLmain.py: CLI interface
parser.py (foundation)
↓
generator.py (depends on parser.CrontabEntry)
↓
main.py (CLI, uses both)
# Run all tests
nix run .#test
# Or with pytest
pytest tests/ -v- 83 total tests covering:
- Crontab parser validation
- Launchd XML generation
- Field boundary validation
- Complex pattern combinations
- plutil validation (18 tests)
- Real-world examples (28 patterns)
All generated plist files are validated with macOS plutil -lint to ensure compatibility with launchd.
nix developProvides Python 3, pytest, black, flake8, and all dependencies.
src/crontab_to_launchd/
├── __init__.py
├── parser.py # Crontab parsing
├── generator.py # Launchd XML generation
└── main.py # CLI entry point
tests/
├── test_crontab_parser.py
├── test_launchd_generator.py
├── test_field_validation.py
├── test_comprehensive_patterns.py
└── test_plutil_validation.py
crontab-to-launchd "*/5 * * * * /path/to/script.sh" com.example.every5mincrontab-to-launchd "0 2 * * * /path/to/backup.sh" com.example.backupcrontab-to-launchd "0 9 * * 1-5 /path/to/weekday.sh" com.example.weekdaycrontab-to-launchd "0 9,12,15,18 * * * /path/to/check.sh" com.example.checkMIT