Skip to content

Commit 52bd2de

Browse files
committed
feat(config): add shorthand syntax for schedule, run, build, and log
Support both string and object forms for cleaner simple configs: - schedule: "*/5 * * * *" instead of schedule: { cron: "..." } - run: "./app" instead of run: { sh: "..." } - build: "cargo build" instead of build: { sh: "..." } - log: "output.log" instead of log: { file: "..." } Full object form still available when additional options needed.
1 parent 6da5513 commit 52bd2de

File tree

3 files changed

+286
-76
lines changed

3 files changed

+286
-76
lines changed

CLAUDE.md

Lines changed: 70 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -29,32 +29,48 @@ src/
2929

3030
```rust
3131
// config.rs - Raw config structs (deserialized from YAML)
32-
struct BuildConfigRaw {
33-
sh: String, // Build command (runs in build/ dir)
34-
timeout: Option<String>,
35-
env_file: Option<String>,
36-
env: Option<HashMap<String, String>>,
37-
working_dir: Option<String>,
32+
// All support shorthand (string) or full (object) form via #[serde(untagged)]
33+
34+
enum ScheduleConfigRaw {
35+
Simple(String), // "*/5 * * * *"
36+
Full { cron: String, timezone: Option<String> },
3837
}
3938

40-
struct RunConfigRaw {
41-
sh: String, // Run command (runs in run/ dir)
42-
timeout: String, // Default: "1h"
43-
concurrency: Concurrency,
44-
retry: Option<RetryConfigRaw>,
45-
working_dir: Option<String>,
46-
env_file: Option<String>,
47-
env: Option<HashMap<String, String>>,
39+
enum BuildConfigRaw {
40+
Simple(String), // "cargo build"
41+
Full {
42+
sh: String,
43+
timeout: Option<String>,
44+
env_file: Option<String>,
45+
env: Option<HashMap<String, String>>,
46+
working_dir: Option<String>,
47+
},
48+
}
49+
50+
enum RunConfigRaw {
51+
Simple(String), // "./app"
52+
Full {
53+
sh: String,
54+
timeout: String, // Default: "1h"
55+
concurrency: Concurrency,
56+
retry: Option<RetryConfigRaw>,
57+
working_dir: Option<String>,
58+
env_file: Option<String>,
59+
env: Option<HashMap<String, String>>,
60+
},
4861
}
4962

50-
struct LogConfigRaw {
51-
file: Option<String>, // Path to log file (relative to run dir)
52-
max_size: String, // Default: "10M"
63+
enum LogConfigRaw {
64+
Simple(String), // "output.log"
65+
Full {
66+
file: Option<String>,
67+
max_size: String, // Default: "10M"
68+
},
5369
}
5470

5571
struct JobConfig {
5672
name: Option<String>,
57-
schedule: ScheduleConfig,
73+
schedule: ScheduleConfigRaw,
5874
build: Option<BuildConfigRaw>,
5975
run: RunConfigRaw,
6076
log: Option<LogConfigRaw>,
@@ -110,12 +126,32 @@ struct RunnerConfig {
110126
env_file: Option<String>, // Path to .env file (relative to repo root)
111127
env: Option<HashMap<String, String>>, // Inline env vars
112128
}
113-
114-
struct ScheduleConfig { cron: String, timezone: Option<String> }
115129
```
116130

117131
## Config Format
118132

133+
### Minimal (shorthand syntax)
134+
135+
```yaml
136+
jobs:
137+
hello:
138+
schedule: "*/5 * * * *" # Shorthand for { cron: "..." }
139+
run: echo hello # Shorthand for { sh: "..." }
140+
```
141+
142+
### With build step
143+
144+
```yaml
145+
jobs:
146+
my-app:
147+
schedule: "0 * * * *"
148+
build: cargo build # Shorthand for { sh: "..." }
149+
run: ./target/debug/app
150+
log: output.log # Shorthand for { file: "..." }
151+
```
152+
153+
### Full syntax (all options)
154+
119155
```yaml
120156
runner: # Optional: global settings
121157
timezone: Asia/Tokyo # Optional: IANA name, "inherit" (system), or omit for UTC
@@ -130,14 +166,14 @@ runner: # Optional: global settings
130166
jobs:
131167
<job-id>: # Key = ID (used for directories)
132168
name: "Display Name" # Optional (defaults to job-id)
133-
schedule:
169+
schedule: # String or object
134170
cron: "*/5 * * * *"
135171
timezone: Asia/Tokyo # Optional: job-level timezone override
136-
build: # Optional: build configuration
172+
build: # Optional: string or object
137173
sh: cargo build # Build command (runs in build/ directory)
138174
timeout: 30m # Optional: timeout for build (defaults to run.timeout)
139175
working_dir: ./subdir # Optional: working directory (relative to build dir)
140-
run: # Run configuration
176+
run: # String or object
141177
sh: ./target/debug/app # Run command (runs in run/ directory)
142178
timeout: 10s # Optional (default: 1h)
143179
concurrency: skip # Optional: parallel|wait|skip|replace (default: skip)
@@ -147,7 +183,7 @@ jobs:
147183
delay: 1s # Initial delay (default: 1s), exponential backoff
148184
jitter: 500ms # Optional: random variation 0-500ms added to retry delay
149185
# If omitted, auto-inferred as 25% of delay (e.g., 250ms for 1s delay)
150-
log: # Optional: logging configuration
186+
log: # Optional: string or object
151187
file: output.log # File path for stdout/stderr
152188
max_size: 10M # Max size before rotation (default: 10M)
153189
working_dir: ./subdir # Optional: working directory for build & run (can be overridden)
@@ -226,13 +262,19 @@ mise exec -- cargo test # Run tests
226262

227263
## Logging
228264

229-
When `log.file` is set, command stdout/stderr is appended to the specified file. If not set, output is discarded.
265+
When `log` is set, command stdout/stderr is appended to the specified file. If not set, output is discarded.
230266

231267
```yaml
232268
jobs:
233269
backup:
234-
run:
235-
sh: ./scripts/backup.sh
270+
schedule: "0 2 * * *"
271+
run: ./scripts/backup.sh
272+
log: backup.log # Shorthand: written to <job_dir>/backup.log
273+
274+
# Or with rotation settings:
275+
backup-full:
276+
schedule: "0 2 * * *"
277+
run: ./scripts/backup.sh
236278
log:
237279
file: backup.log # Written to <job_dir>/backup.log
238280
max_size: 50M # Rotate when file exceeds 50MB
@@ -280,8 +322,7 @@ runner:
280322
281323
jobs:
282324
my-job:
283-
schedule:
284-
cron: "* * * * *"
325+
schedule: "* * * * *"
285326
build:
286327
sh: cargo build
287328
env_file: .env.build # Build-specific

README.md

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,8 @@ cargo install --path .
1515
```yaml
1616
jobs:
1717
hello:
18-
schedule:
19-
cron: "*/5 * * * *"
20-
run:
21-
sh: echo "Hello from rollcron!"
18+
schedule: "*/5 * * * *"
19+
run: echo "Hello from rollcron!"
2220
```
2321
2422
3. Run:
@@ -42,8 +40,7 @@ rollcron https://github.com/user/repo --pull-interval 300
4240
jobs:
4341
backup:
4442
name: "Daily Backup"
45-
schedule:
46-
cron: "0 2 * * *"
43+
schedule: "0 2 * * *"
4744
run:
4845
sh: ./scripts/backup.sh
4946
timeout: 5m
@@ -57,23 +54,17 @@ jobs:
5754
```yaml
5855
jobs:
5956
my-app:
60-
schedule:
61-
cron: "0 * * * *"
62-
build:
63-
sh: cargo build --release
64-
timeout: 30m
65-
run:
66-
sh: ./target/release/app
67-
timeout: 10s
57+
schedule: "0 * * * *"
58+
build: cargo build --release
59+
run: ./target/release/app
6860
```
6961
7062
### Docker
7163
7264
```yaml
7365
jobs:
7466
docker-job:
75-
schedule:
76-
cron: "*/10 * * * *"
67+
schedule: "*/10 * * * *"
7768
run:
7869
sh: docker run --rm -v $(pwd):/app -w /app node:20 npm test
7970
timeout: 5m
@@ -90,8 +81,7 @@ runner:
9081

9182
jobs:
9283
deploy:
93-
schedule:
94-
cron: "0 0 * * *"
84+
schedule: "0 0 * * *"
9585
run:
9686
sh: ./deploy.sh
9787
timeout: 10m
@@ -116,6 +106,7 @@ jobs:
116106
name: "Build & Run App"
117107
schedule:
118108
cron: "0 * * * *"
109+
timezone: Asia/Tokyo
119110
build:
120111
sh: cargo build --release
121112
timeout: 30m
@@ -175,16 +166,33 @@ Options:
175166
| Field | Type | Default | Description |
176167
|-------|------|---------|-------------|
177168
| `name` | string, optional | job-id | Display name |
178-
| `schedule.cron` | string | **required** | Cron expression (5 fields: min hour day month weekday) |
179-
| `schedule.timezone` | string, optional | runner's | Job-specific timezone override |
169+
| `schedule` | string or object | **required** | Cron expression or `{ cron, timezone? }` |
170+
| `build` | string or object, optional | - | Build command or full config |
171+
| `run` | string or object | **required** | Run command or full config |
172+
| `log` | string or object, optional | - | Log file path or full config |
180173
| `enabled` | bool, optional | `true` | Enable/disable job |
181174
| `working_dir` | string, optional | - | Working directory for build and run (can be overridden) |
182175
| `env_file` | string, optional | - | Shared .env file for build and run |
183176
| `env` | map, optional | - | Shared environment variables for build and run |
184177
| `webhook` | list, optional | - | Job-specific webhooks (extends runner webhooks) |
185178

179+
#### `jobs.<job-id>.schedule`
180+
181+
Shorthand: `schedule: "*/5 * * * *"`
182+
183+
Full form:
184+
185+
| Field | Type | Default | Description |
186+
|-------|------|---------|-------------|
187+
| `cron` | string | **required** | Cron expression (5 fields: min hour day month weekday) |
188+
| `timezone` | string, optional | runner's | Job-specific timezone override |
189+
186190
#### `jobs.<job-id>.build` (optional)
187191

192+
Shorthand: `build: "cargo build --release"`
193+
194+
Full form:
195+
188196
| Field | Type | Default | Description |
189197
|-------|------|---------|-------------|
190198
| `sh` | string | **required** | Build command (runs in `build/` directory) |
@@ -195,6 +203,10 @@ Options:
195203

196204
#### `jobs.<job-id>.run`
197205

206+
Shorthand: `run: "./app"`
207+
208+
Full form:
209+
198210
| Field | Type | Default | Description |
199211
|-------|------|---------|-------------|
200212
| `sh` | string | **required** | Run command (runs in `run/` directory) |
@@ -214,6 +226,10 @@ Options:
214226

215227
#### `jobs.<job-id>.log` (optional)
216228

229+
Shorthand: `log: "output.log"`
230+
231+
Full form:
232+
217233
| Field | Type | Default | Description |
218234
|-------|------|---------|-------------|
219235
| `file` | string, optional | - | Log file path (relative to job dir) |

0 commit comments

Comments
 (0)