Skip to content

Commit c472cd6

Browse files
committed
feat(run): add dry-run option
1 parent ee796ae commit c472cd6

File tree

4 files changed

+45
-11
lines changed

4 files changed

+45
-11
lines changed

docs/features/command-reference.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ A concise, code-sourced reference for Shiplog commands, flags, and examples. Glo
4141
- Usage:
4242
- Success case: `git shiplog run --service deploy --reason "Smoke test" -- env printf hi`
4343
- Failure case: `git shiplog run --service deploy --status-failure failed -- false`
44-
- Flags: `--service`, `--reason`, `--status-success`, `--status-failure`, `--ticket`, `--region`, `--cluster`, `--namespace`, `--env`.
45-
- Notes: captures stdout/stderr to a temporary log that is attached as a git note (skipped if empty) and merges `{run:{...}}` into the JSON trailer via `SHIPLOG_EXTRA_JSON`. See `docs/reference/json-schema.md` for the structured payload.
44+
- Flags: `--service`, `--reason`, `--status-success`, `--status-failure`, `--ticket`, `--region`, `--cluster`, `--namespace`, `--env`, `--dry-run`.
45+
- Notes: captures stdout/stderr to a temporary log that is attached as a git note (skipped if empty) and merges `{run:{...}}` into the JSON trailer via `SHIPLOG_EXTRA_JSON`. `--dry-run` prints the command that would execute and exits without running it or writing a journal entry. See `docs/reference/json-schema.md` for the structured payload.
4646

4747
- `ls [ENV] [LIMIT]`
4848
- Purpose: list recent entries.

docs/features/run.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
# Run Command
22

33
## Summary
4-
`git shiplog run` wraps a shell command, captures its stdout/stderr, and records the execution as a Shiplog journal entry. The command output is saved as a git note, and the structured trailer gains a `run` payload describing the invocation.
4+
`git shiplog run` wraps a shell command, captures its stdout/stderr, and records the execution as a Shiplog journal entry. The command output is saved as a git note, and the structured trailer gains a `run` payload describing the invocation. Use `--dry-run` to preview what would happen without executing the command or writing an entry.
55

66
## Usage
77
```bash
88
git shiplog run --service deploy --reason "Smoke test" -- env printf hi
9+
git shiplog run --dry-run --service deploy --reason "Smoke test" -- env printf hi
910
```
1011

1112
- `--service` is required in non-interactive mode (and highly recommended in general).
@@ -14,6 +15,7 @@ git shiplog run --service deploy --reason "Smoke test" -- env printf hi
1415

1516
## Behavior
1617
- Captures stdout/stderr to a temporary file. When not in boring mode, output is also streamed to your terminal via `tee`.
18+
- `--dry-run` prints the wrapped command, returns exit code 0, and skips execution, journal writes, and log attachment.
1719
- Sets `SHIPLOG_BORING=1` and `SHIPLOG_ASSUME_YES=1` while calling `git shiplog write` so no prompts fire.
1820
- Populates `SHIPLOG_EXTRA_JSON` with:
1921
```json
@@ -34,6 +36,7 @@ git shiplog run --service deploy --reason "Smoke test" -- env printf hi
3436
- Returns the wrapped command’s exit code so it can be chained in scripts or CI pipelines.
3537

3638
## Options
39+
- `--dry-run` — Print the command that would execute, then exit without running it or writing a journal entry.
3740
- `--env <name>` — Target journal environment (defaults to `SHIPLOG_ENV` or `prod`).
3841
- `--service <name>` — Service/component; required when prompts are disabled.
3942
- `--reason <text>` — Optional free-form description.

lib/commands.sh

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,7 @@ cmd_run() {
394394
local region="${SHIPLOG_REGION:-}"
395395
local cluster="${SHIPLOG_CLUSTER:-}"
396396

397+
local dry_run=0
397398
local -a run_argv=()
398399
while [ $# -gt 0 ]; do
399400
case "$1" in
@@ -433,6 +434,8 @@ cmd_run() {
433434
shift; cluster="${1:-}"; shift; continue ;;
434435
--cluster=*)
435436
cluster="${1#*=}"; shift; continue ;;
437+
--dry-run)
438+
dry_run=1; shift; continue ;;
436439
--)
437440
shift
438441
while [ $# -gt 0 ]; do run_argv+=("$1"); shift; done
@@ -453,6 +456,26 @@ cmd_run() {
453456
die "shiplog: --service (or SHIPLOG_SERVICE) is required for run"
454457
fi
455458

459+
local -a quoted_cmd=()
460+
local arg
461+
for arg in "${run_argv[@]}"; do
462+
quoted_cmd+=("$(printf '%q' "$arg")")
463+
done
464+
local cmd_display
465+
cmd_display="${quoted_cmd[*]}"
466+
467+
if [ "$dry_run" -eq 1 ]; then
468+
local dry_message="shiplog run --dry-run: would execute: $cmd_display"
469+
if shiplog_can_use_bosun; then
470+
local bosun
471+
bosun=$(shiplog_bosun_bin)
472+
"$bosun" style --title "Dry Run" -- "🚫 ${dry_message#shiplog run --dry-run: }"
473+
else
474+
printf '%s\n' "ℹ️ $dry_message"
475+
fi
476+
return 0
477+
fi
478+
456479
local started_at finished_at
457480
local start_epoch end_epoch duration_s
458481
local log_path; log_path=$(mktemp) || die "shiplog: failed to allocate temp log"
@@ -494,14 +517,6 @@ cmd_run() {
494517
log_attached_bool="true"
495518
fi
496519

497-
local -a quoted_cmd=()
498-
local arg
499-
for arg in "${run_argv[@]}"; do
500-
quoted_cmd+=("$(printf '%q' "$arg")")
501-
done
502-
local cmd_display
503-
cmd_display="${quoted_cmd[*]}"
504-
505520
local argv_json
506521
argv_json=$(printf '%s\n' "${run_argv[@]}" | jq -R . | jq -s .)
507522

test/10_run_command.bats

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,19 @@ teardown() {
7575
[ "$status" -eq 0 ]
7676
[ "$output" = "false" ]
7777
}
78+
79+
@test "run dry-run previews without executing" {
80+
rm -f dry-run-file
81+
[ ! -e dry-run-file ]
82+
83+
run git show-ref "${REF_ROOT}/journal/prod"
84+
[ "$status" -ne 0 ]
85+
86+
run bash -lc 'git shiplog run --dry-run --service test --reason "no-op" -- touch dry-run-file'
87+
[ "$status" -eq 0 ]
88+
[[ "$output" == *"would execute: touch dry-run-file"* ]]
89+
[ ! -e dry-run-file ]
90+
91+
run git show-ref "${REF_ROOT}/journal/prod"
92+
[ "$status" -ne 0 ]
93+
}

0 commit comments

Comments
 (0)