Skip to content

Commit 9ae7712

Browse files
committed
add multi-command chaining with __ separator
- support running multiple commands in sequence (e.g., cli lint __ build __ test) - stop execution on first failure and propagate exit code - add tests for multi-command execution, argument passing, and failure handling
1 parent c5e9a46 commit 9ae7712

2 files changed

Lines changed: 90 additions & 0 deletions

File tree

cli.sh

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,42 @@
11
# SPDX-License-Identifier: MIT
22
# Licensed under the MIT License. See LICENSE file in the project root.
33

4+
# Separator for chaining multiple commands (e.g., cli lint __ build __ test)
5+
CLI_COMMAND_SEPARATOR="__"
6+
47
function cli {
8+
# Check for multi-command separator
9+
local has_separator=false
10+
for arg in "$@"; do
11+
if [ "$arg" = "$CLI_COMMAND_SEPARATOR" ]; then
12+
has_separator=true
13+
break
14+
fi
15+
done
16+
17+
if [ "$has_separator" = true ]; then
18+
local cmd_args=()
19+
for arg in "$@"; do
20+
if [ "$arg" = "$CLI_COMMAND_SEPARATOR" ]; then
21+
if [ ${#cmd_args[@]} -gt 0 ]; then
22+
_cli_single "${cmd_args[@]}" || return $?
23+
cmd_args=()
24+
fi
25+
else
26+
cmd_args+=("$arg")
27+
fi
28+
done
29+
# Execute final command group
30+
if [ ${#cmd_args[@]} -gt 0 ]; then
31+
_cli_single "${cmd_args[@]}" || return $?
32+
fi
33+
return 0
34+
fi
35+
36+
_cli_single "$@"
37+
}
38+
39+
function _cli_single {
540
local cmd="$1"
641

742
# Collect scripts, Deno tasks, NPM tasks and Makefile tasks

tests/cli.bats

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,3 +185,58 @@ EOF
185185
[ "$status" -eq 0 ]
186186
[[ "$output" == *"scripts wins"* ]]
187187
}
188+
189+
# =============================================================================
190+
# Multi-command execution tests
191+
# =============================================================================
192+
193+
@test "executes multiple commands separated by __" {
194+
mkdir -p "$BATS_TEST_DIRNAME/tmp/multi-cmd/scripts"
195+
echo '#!/bin/bash
196+
echo "lint: $*"' > "$BATS_TEST_DIRNAME/tmp/multi-cmd/scripts/lint.sh"
197+
echo '#!/bin/bash
198+
echo "build: $*"' > "$BATS_TEST_DIRNAME/tmp/multi-cmd/scripts/build.sh"
199+
chmod +x "$BATS_TEST_DIRNAME/tmp/multi-cmd/scripts"/*.sh
200+
201+
cd "$BATS_TEST_DIRNAME/tmp/multi-cmd"
202+
run cli lint __ build
203+
[ "$status" -eq 0 ]
204+
[[ "$output" == *"lint:"* ]]
205+
[[ "$output" == *"build:"* ]]
206+
}
207+
208+
@test "multi-command passes arguments to each command" {
209+
mkdir -p "$BATS_TEST_DIRNAME/tmp/multi-args/scripts"
210+
echo '#!/bin/bash
211+
echo "lint: $*"' > "$BATS_TEST_DIRNAME/tmp/multi-args/scripts/lint.sh"
212+
echo '#!/bin/bash
213+
echo "build: $*"' > "$BATS_TEST_DIRNAME/tmp/multi-args/scripts/build.sh"
214+
echo '#!/bin/bash
215+
echo "test: $*"' > "$BATS_TEST_DIRNAME/tmp/multi-args/scripts/test.sh"
216+
chmod +x "$BATS_TEST_DIRNAME/tmp/multi-args/scripts"/*.sh
217+
218+
cd "$BATS_TEST_DIRNAME/tmp/multi-args"
219+
run cli lint --fix __ build -o dist __ test --watch
220+
[ "$status" -eq 0 ]
221+
[[ "$output" == *"lint: --fix"* ]]
222+
[[ "$output" == *"build: -o dist"* ]]
223+
[[ "$output" == *"test: --watch"* ]]
224+
}
225+
226+
@test "multi-command stops on first failure" {
227+
mkdir -p "$BATS_TEST_DIRNAME/tmp/multi-fail/scripts"
228+
echo '#!/bin/bash
229+
echo "first ok"' > "$BATS_TEST_DIRNAME/tmp/multi-fail/scripts/first.sh"
230+
echo '#!/bin/bash
231+
echo "second fails" && exit 1' > "$BATS_TEST_DIRNAME/tmp/multi-fail/scripts/second.sh"
232+
echo '#!/bin/bash
233+
echo "third should not run"' > "$BATS_TEST_DIRNAME/tmp/multi-fail/scripts/third.sh"
234+
chmod +x "$BATS_TEST_DIRNAME/tmp/multi-fail/scripts"/*.sh
235+
236+
cd "$BATS_TEST_DIRNAME/tmp/multi-fail"
237+
run cli first __ second __ third
238+
[ "$status" -eq 1 ]
239+
[[ "$output" == *"first ok"* ]]
240+
[[ "$output" == *"second fails"* ]]
241+
[[ "$output" != *"third should not run"* ]]
242+
}

0 commit comments

Comments
 (0)