Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ Shell-Bun is designed for both interactive development and automated CI/CD pipel

# Enable debug mode (creates debug.log file)
./shell-bun.sh --debug

# Override the container command for this run
./shell-bun.sh --container "podman exec -it my-builder" my-config.txt
```

#### Non-Interactive Mode (CI/CD)
Expand Down Expand Up @@ -149,7 +152,7 @@ working_dir=~/projects/my-app
```

- `log_dir` (optional): Sets a global directory where log files are stored. Individual apps can override it.
- `container` (optional): When set, every command is executed inside the specified container command. Shell-Bun automatically appends `bash -lc "<your command>"` to the container invocation so complex workflows can stay isolated.
- `container` (optional): When set, every command is executed inside the specified container command. Shell-Bun automatically appends `bash -lc "<your command>"` to the container invocation so complex workflows can stay isolated. You can override the configured value per run with the `--container` CLI flag.

## Testing

Expand Down
49 changes: 45 additions & 4 deletions shell-bun.sh
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ DEBUG_MODE=0
CI_MODE=0
CI_APP=""
CI_ACTIONS=""
CLI_CONTAINER_OVERRIDE=0
CLI_CONTAINER_COMMAND=""

# Parse command line arguments
while [[ $# -gt 0 ]]; do
Expand All @@ -73,6 +75,20 @@ while [[ $# -gt 0 ]]; do
fi
fi
;;
--container)
if [[ $# -lt 2 ]]; then
echo "Error: --container requires a command argument (use --container <cmd> or --container=<cmd>)"
exit 1
fi
CLI_CONTAINER_OVERRIDE=1
CLI_CONTAINER_COMMAND="$2"
shift 2
;;
--container=*)
CLI_CONTAINER_OVERRIDE=1
CLI_CONTAINER_COMMAND="${1#--container=}"
shift
;;
--help|-h)
echo "Shell-Bun v$VERSION - Interactive build environment script"
echo "Copyright (c) 2025, Fredrik Reveny"
Expand All @@ -84,6 +100,7 @@ while [[ $# -gt 0 ]]; do
echo " $0 # Use default config (shell-bun.cfg)"
echo " $0 my-config.txt # Use custom config file"
echo " $0 --debug # Enable debug logging"
echo " $0 --container \"podman exec ...\" # Override container command"
echo ""
echo "Non-interactive mode (CI/CD) with fuzzy pattern matching:"
echo " $0 --ci APP_PATTERN ACTION_PATTERN # Run actions matching patterns"
Expand Down Expand Up @@ -152,7 +169,8 @@ declare -A APP_LOG_DIR=() # Key: "app", Value: "log directory path"
declare -a SELECTED_ITEMS=()
declare -a EXECUTION_RESULTS=() # Track execution results for log viewing
GLOBAL_LOG_DIR="" # Global log directory from config
CONTAINER_COMMAND="" # Global container command from config
CONFIG_CONTAINER_COMMAND="" # Container command defined in config (if any)
CONTAINER_COMMAND="" # Effective container command after CLI overrides

# Function to print colored output
print_color() {
Expand Down Expand Up @@ -236,6 +254,7 @@ parse_config() {
fi

local current_app=""
CONFIG_CONTAINER_COMMAND=""

while IFS= read -r line || [[ -n "$line" ]]; do
# Skip empty lines and comments
Expand All @@ -262,7 +281,7 @@ parse_config() {
GLOBAL_LOG_DIR="$value"
elif [[ -z "$current_app" && "$key" == "container" ]]; then
# Global container command (outside any app section)
CONTAINER_COMMAND="$value"
CONFIG_CONTAINER_COMMAND="$value"
elif [[ -n "$current_app" && "$key" == "working_dir" ]]; then
# Special handling for working_dir
APP_WORKING_DIR["$current_app"]="$value"
Expand All @@ -284,6 +303,12 @@ parse_config() {
fi
done < "$CONFIG_FILE"

if [[ $CLI_CONTAINER_OVERRIDE -eq 1 ]]; then
CONTAINER_COMMAND="$CLI_CONTAINER_COMMAND"
else
CONTAINER_COMMAND="$CONFIG_CONTAINER_COMMAND"
fi

if [[ ${#APPS[@]} -eq 0 ]]; then
print_color "$RED" "Error: No applications found in configuration file!"
exit 1
Expand Down Expand Up @@ -335,7 +360,13 @@ show_app_details() {

# Show container configuration
if [[ -n "$CONTAINER_COMMAND" ]]; then
echo "Container: $CONTAINER_COMMAND"
if [[ $CLI_CONTAINER_OVERRIDE -eq 1 ]]; then
echo "Container: $CONTAINER_COMMAND (overridden via --container)"
else
echo "Container: $CONTAINER_COMMAND"
fi
elif [[ $CLI_CONTAINER_OVERRIDE -eq 1 ]]; then
echo "Container: (overridden via --container to run on host)"
else
echo "Container: (none - runs on host)"
fi
Expand Down Expand Up @@ -1723,7 +1754,17 @@ main() {
parse_config

if [[ -n "$CONTAINER_COMMAND" ]]; then
print_color "$PURPLE" "Container mode enabled using: $CONTAINER_COMMAND"
if [[ $CLI_CONTAINER_OVERRIDE -eq 1 ]]; then
print_color "$PURPLE" "Container mode enabled using CLI override: $CONTAINER_COMMAND"
else
print_color "$PURPLE" "Container mode enabled using: $CONTAINER_COMMAND"
fi
elif [[ $CLI_CONTAINER_OVERRIDE -eq 1 ]]; then
if [[ -n "$CONFIG_CONTAINER_COMMAND" ]]; then
print_color "$YELLOW" "Container command overridden via --container (original: $CONFIG_CONTAINER_COMMAND)"
else
print_color "$YELLOW" "Container command overridden via --container"
fi
fi

# Handle CI mode (non-interactive)
Expand Down
1 change: 1 addition & 0 deletions tests/test_command_line.bats
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ setup() {
[[ "$output" =~ "Usage:" ]]
[[ "$output" =~ "Interactive mode" ]]
[[ "$output" =~ "Non-interactive mode" ]]
[[ "$output" =~ "--container" ]]
}

@test "Help flag: -h" {
Expand Down
49 changes: 49 additions & 0 deletions tests/test_container_override_flag.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#!/usr/bin/env bats

setup() {
export TEST_DIR="$BATS_TEST_DIRNAME"
export SCRIPT_DIR="$(cd "$TEST_DIR/.." && pwd)"
export TEST_CONFIG="$TEST_DIR/fixtures/container_override.cfg"
}

@test "--container overrides container command from config" {
cat > "$TEST_CONFIG" <<'CONFIG'
# Test config to ensure --container CLI flag can override the configured container
container=env CONTAINER_SOURCE=config

[TestApp]
build=echo "container source: ${CONTAINER_SOURCE:-none}"
CONFIG

run "$SCRIPT_DIR/shell-bun.sh" --container "env CONTAINER_SOURCE=cli" --ci TestApp build "$TEST_CONFIG"

echo "Exit code: $status"
echo "Output: $output"

[ "$status" -eq 0 ]
[[ "$output" == *"container source: cli"* ]]
}

@test "--container accepts an empty override to run on the host" {
cat > "$TEST_CONFIG" <<'CONFIG'
# Config uses a failing container command that should be bypassed by an empty override
container=/bin/false

[TestApp]
build=echo host-run
CONFIG

run "$SCRIPT_DIR/shell-bun.sh" --container "" --ci TestApp build "$TEST_CONFIG"

echo "Exit code: $status"
echo "Output: $output"

[ "$status" -eq 0 ]
[[ "$output" == *"host-run"* ]]
}

teardown() {
if [ -f "$TEST_CONFIG" ]; then
rm "$TEST_CONFIG"
fi
}