|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +## Project Overview |
| 4 | + |
| 5 | +rollcron is a Rust CLI tool that functions as a self-updating cron scheduler, similar to GitHub Actions but for local/remote git repositories. |
| 6 | + |
| 7 | +## Directory Structure |
| 8 | + |
| 9 | +``` |
| 10 | +src/ |
| 11 | +├── main.rs # Entry point, CLI parsing, orchestration |
| 12 | +├── config.rs # YAML config parsing, Job struct |
| 13 | +├── git.rs # Git operations (clone, pull, archive) |
| 14 | +└── scheduler.rs # Cron scheduling, job execution |
| 15 | +``` |
| 16 | + |
| 17 | +## Key Types |
| 18 | + |
| 19 | +```rust |
| 20 | +// config.rs |
| 21 | +struct Job { |
| 22 | + id: String, // Key from YAML (used for directories) |
| 23 | + name: String, // Display name (defaults to id) |
| 24 | + schedule: cron::Schedule, |
| 25 | + command: String, |
| 26 | + timeout: Duration, |
| 27 | +} |
| 28 | + |
| 29 | +// Parsed from rollcron.yaml |
| 30 | +struct Config { jobs: HashMap<String, JobConfig> } |
| 31 | +struct JobConfig { name: Option<String>, schedule: ScheduleConfig, run, timeout } |
| 32 | +struct ScheduleConfig { cron: String } |
| 33 | +``` |
| 34 | + |
| 35 | +## Config Format |
| 36 | + |
| 37 | +```yaml |
| 38 | +jobs: |
| 39 | + <job-id>: # Key = ID (used for directories) |
| 40 | + name: "Display Name" # Optional (defaults to job-id) |
| 41 | + schedule: |
| 42 | + cron: "*/5 * * * *" |
| 43 | + run: echo hello |
| 44 | + timeout: 10s # Optional (default: 10s) |
| 45 | +``` |
| 46 | +
|
| 47 | +## Runtime Directory Layout |
| 48 | +
|
| 49 | +``` |
| 50 | +~/.cache/rollcron/ |
| 51 | +├── <repo>-<hash>/ # SoT: git repository |
| 52 | +└── <repo>-<hash>@<job-id>/ # Per-job snapshot (no .git) |
| 53 | +``` |
| 54 | + |
| 55 | +**Important**: Directory names use `job.id` (the YAML key), not `job.name`. |
| 56 | + |
| 57 | +## Assumptions |
| 58 | + |
| 59 | +1. **Git available**: `git` command must be in PATH |
| 60 | +2. **Tar available**: `tar` command for archive extraction |
| 61 | +3. **Shell available**: Jobs run via `sh -c "<command>"` |
| 62 | +4. **Remote auth**: SSH keys or credentials pre-configured for remote repos |
| 63 | +5. **Cron format**: Standard 5-field cron (internally converted to 6-field for `cron` crate) |
| 64 | + |
| 65 | +## Key Flows |
| 66 | + |
| 67 | +### Startup |
| 68 | +1. Parse CLI args (repo, interval) |
| 69 | +2. Clone if remote URL, otherwise use local path |
| 70 | +3. Load config from `rollcron.yaml` |
| 71 | +4. Sync job directories via `git archive` (using job ID) |
| 72 | +5. Start pull task + scheduler |
| 73 | + |
| 74 | +### Pull Cycle (async task) |
| 75 | +1. `git pull --ff-only` |
| 76 | +2. Parse config |
| 77 | +3. Sync all job dirs (by job ID) |
| 78 | +4. Send new jobs to scheduler via watch channel |
| 79 | + |
| 80 | +### Job Execution |
| 81 | +1. Scheduler polls every 1 second |
| 82 | +2. Check each job's cron schedule |
| 83 | +3. If due: spawn task in job's directory (by ID) with timeout |
| 84 | +4. Log using display name |
| 85 | + |
| 86 | +## Constraints |
| 87 | + |
| 88 | +- `cargo build` must pass |
| 89 | +- `cargo test` must pass |
| 90 | + |
| 91 | +## Testing |
| 92 | + |
| 93 | +```bash |
| 94 | +cargo test # Run all tests |
| 95 | +cargo run -- --help # Check CLI |
| 96 | +cargo run -- . -i 10 # Test with local repo |
| 97 | +``` |
| 98 | + |
| 99 | +## Common Modifications |
| 100 | + |
| 101 | +### Add new config field |
| 102 | +1. Update `JobConfig` in `config.rs` |
| 103 | +2. Update `Job` struct if runtime field |
| 104 | +3. Add to `parse_config()` conversion |
| 105 | +4. Add test case |
| 106 | + |
| 107 | +### Change sync mechanism |
| 108 | +- Edit `sync_to_job_dir()` in `git.rs` |
| 109 | +- Currently: `git archive HEAD | tar -x` |
| 110 | + |
| 111 | +### Add CLI flag |
| 112 | +1. Add field to `Args` struct in `main.rs` |
| 113 | +2. Use `#[arg(...)]` attribute for clap |
0 commit comments