Skip to content

Commit dafe633

Browse files
committed
[#2086] Added support for --interactive flag when running ahoy update-vortex.
1 parent 408003d commit dafe633

File tree

5 files changed

+219
-2
lines changed

5 files changed

+219
-2
lines changed

.vortex/.ahoy.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ commands:
4646
ahoy lint-scripts
4747
ahoy lint-dockerfiles
4848
ahoy lint-docs
49+
ahoy lint-markdown
4950
5051
lint-installer:
5152
cmd: composer --working-dir installer lint

.vortex/CLAUDE.md

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -807,6 +807,151 @@ UPDATE_FIXTURES=1 ./vendor/bin/phpunit --filter 'testInstall.*"scenario_name"'
807807
- **PHPUnit workflow tests**: Slower (integration level, ~minutes)
808808
- **Installer tests**: Slowest (full installation simulation, ~minutes)
809809
810+
## Shell Script Development Patterns
811+
812+
### Script Structure Best Practices
813+
814+
Vortex shell scripts follow a consistent structure for maintainability and clarity:
815+
816+
**Standard Script Structure**:
817+
818+
1. **Shebang and header comments** - Script purpose and requirements
819+
2. **Environment loading** - Load `.env` and `.env.local` files
820+
3. **Shell options** - Set `set -eu` and optional debug mode
821+
4. **Variable declarations** - All variables with defaults in one section
822+
5. **Helper functions** - Output formatters and utility functions
823+
6. **Pre-flight checks** - Verify required commands are available
824+
7. **Argument parsing** - Parse command-line arguments (modifies variables)
825+
8. **Main execution** - Core script logic
826+
827+
**Example Structure**:
828+
829+
```bash
830+
#!/usr/bin/env bash
831+
##
832+
# Script purpose.
833+
#
834+
# shellcheck disable=SC1090,SC1091
835+
836+
# Environment loading.
837+
t=$(mktemp) && export -p >"${t}" && set -a && . ./.env && if [ -f ./.env.local ]; then . ./.env.local; fi && set +a && . "${t}" && rm "${t}" && unset t
838+
839+
set -eu
840+
[ "${VORTEX_DEBUG-}" = "1" ] && set -x
841+
842+
# Variable declarations with defaults.
843+
VARIABLE_ONE="${VARIABLE_ONE:-default_value}"
844+
VARIABLE_TWO="${VARIABLE_TWO:-0}"
845+
846+
# ------------------------------------------------------------------------------
847+
848+
# Helper functions.
849+
info() { printf "[INFO] %s\n" "${1}"; }
850+
fail() { printf "[FAIL] %s\n" "${1}"; }
851+
852+
# Pre-flight checks.
853+
for cmd in required_cmd1 required_cmd2; do command -v "${cmd}" >/dev/null || {
854+
fail "Command ${cmd} is not available"
855+
exit 1
856+
}; done
857+
858+
# Parse arguments.
859+
for arg in "$@"; do
860+
if [ "${arg}" = "--flag" ]; then
861+
VARIABLE_TWO=1
862+
else
863+
VARIABLE_ONE="${arg}"
864+
fi
865+
done
866+
867+
# ------------------------------------------------------------------------------
868+
869+
# Main execution.
870+
# ... script logic here ...
871+
```
872+
873+
**Key Principles**:
874+
875+
- **Keep variable section clean**: Declare all variables with defaults together, don't mix with argument parsing
876+
- **Separate concerns**: Variable declarations → Pre-flight checks → Argument parsing → Execution
877+
- **Consistent ordering**: Maintain the same section order across all scripts
878+
- **Clear boundaries**: Use separator lines (`# ----...`) between major sections
879+
880+
### Script Development Workflow
881+
882+
When creating or modifying shell scripts, follow this workflow to ensure code quality and documentation consistency:
883+
884+
1. **Create/Modify Script**: Make changes to the script in `scripts/vortex/` or `scripts/custom/`
885+
2. **Lint Scripts**: Run `ahoy lint-scripts` from the `.vortex/` directory to check shell script quality
886+
3. **Update Documentation**: Run `ahoy update-docs` from the `.vortex/` directory to regenerate documentation from script variables
887+
4. **Lint Documentation**: Run `ahoy lint-docs` from the `.vortex/` directory to ensure documentation formatting is correct
888+
5. **Lint Markdown Files**: Run `ahoy lint-markdown` from the `.vortex/` directory to check all markdown files for formatting issues
889+
890+
**Example Workflow**:
891+
892+
```bash
893+
# After modifying a script, navigate to .vortex directory
894+
cd .vortex
895+
896+
# Run the quality checks
897+
ahoy lint-scripts # Lint all shell scripts
898+
ahoy update-docs # Update documentation from script variables
899+
ahoy lint-docs # Lint documentation files
900+
ahoy lint-markdown # Lint markdown files (or use ahoy lint-markdown-fix to auto-fix)
901+
```
902+
903+
**Important Notes**:
904+
905+
- **Commands must be run from `.vortex/` directory**: All commands (`lint-scripts`, `update-docs`, `lint-docs`, `lint-markdown`) must be executed from the `.vortex/` directory
906+
- **Scripts must be linted** before committing to ensure they follow shell script best practices
907+
- **Documentation must be updated** whenever script variables or structure changes
908+
- **Documentation must be linted** to maintain consistent formatting across all docs
909+
- **Markdown auto-fix available**: Use `ahoy lint-markdown-fix` to automatically fix markdown formatting issues
910+
911+
### BATS Testing with Interactive Scripts
912+
913+
**Critical Understanding**: BATS tests mock shell commands - they don't actually execute them.
914+
915+
When testing scripts that would normally require user interaction (e.g., running with `--no-interaction` flag omitted):
916+
917+
**How Mocking Works**:
918+
919+
```bash
920+
# In BATS test:
921+
create_global_command_wrapper "php"
922+
923+
# Later in test:
924+
"@php installer.php --uri=https://example.com # 0"
925+
```
926+
927+
This creates a mock that:
928+
929+
- Intercepts calls to `php` command
930+
- Returns immediately with exit code 0
931+
- Never actually executes the PHP script
932+
- **Does not hang waiting for user input**
933+
934+
**Implication**: Scripts with interactive modes can be safely tested without hanging, because the test mocks prevent actual execution.
935+
936+
### Simplicity Over Complexity
937+
938+
**Lesson**: When implementing new features, start with the simplest solution that works.
939+
940+
**Example from `update-vortex.sh`**:
941+
942+
- ✅ **Simple**: Two conditional branches with explicit commands
943+
- ❌ **Complex**: Array building, argument iteration, dynamic construction
944+
945+
**Why Simpler is Better**:
946+
947+
- Easier to read and understand
948+
- More predictable behavior
949+
- Better test alignment (argument order is explicit)
950+
- Fewer edge cases to handle
951+
- Faster debugging when issues occur
952+
953+
**When to Use Complexity**: Only when you need to handle many permutations or truly dynamic argument sets. For simple binary choices (interactive vs non-interactive), conditional execution is clearer.
954+
810955
## Installer Development Patterns
811956
812957
### Code Refactoring and Performance Optimization

.vortex/docs/content/workflows/variables.mdx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1182,6 +1182,14 @@ Default value: `UNDEFINED`
11821182

11831183
Defined or used in: `.env`
11841184

1185+
### `VORTEX_INSTALLER_INTERACTIVE`
1186+
1187+
Run installer in interactive mode.
1188+
1189+
Default value: `0`
1190+
1191+
Defined or used in: `scripts/vortex/update-vortex.sh`
1192+
11851193
### `VORTEX_INSTALLER_PATH`
11861194

11871195
The path to the installer script.<br/>If set, this will override the VORTEX_INSTALLER_URL.

.vortex/tests/bats/unit/update-vortex.bats

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,3 +203,51 @@ load ../_helper.bash
203203

204204
popd >/dev/null || exit 1
205205
}
206+
207+
@test "Script runs in interactive mode when --interactive flag is provided" {
208+
pushd "${LOCAL_REPO_DIR}" >/dev/null || exit 1
209+
210+
create_global_command_wrapper "curl"
211+
create_global_command_wrapper "php"
212+
213+
export VORTEX_INSTALLER_URL_CACHE_BUST="1234567890"
214+
215+
declare -a STEPS=(
216+
"@curl -fsSL https://www.vortextemplate.com/install?1234567890 -o installer.php # 0"
217+
"@php installer.php --uri=https://github.com/drevops/vortex.git@stable # 0"
218+
"Using installer script from URL: https://www.vortextemplate.com/install"
219+
"Downloading installer to installer.php"
220+
)
221+
222+
mocks="$(run_steps "setup")"
223+
run "${ROOT_DIR}/scripts/vortex/update-vortex.sh" --interactive
224+
run_steps "assert" "${mocks[@]}"
225+
226+
assert_success
227+
228+
popd >/dev/null || exit 1
229+
}
230+
231+
@test "Script runs in interactive mode with custom template repository" {
232+
pushd "${LOCAL_REPO_DIR}" >/dev/null || exit 1
233+
234+
create_global_command_wrapper "curl"
235+
create_global_command_wrapper "php"
236+
237+
export VORTEX_INSTALLER_URL_CACHE_BUST="1234567890"
238+
239+
declare -a STEPS=(
240+
"@curl -fsSL https://www.vortextemplate.com/install?1234567890 -o installer.php # 0"
241+
"@php installer.php --uri=https://github.com/custom/repo.git@main # 0"
242+
"Using installer script from URL: https://www.vortextemplate.com/install"
243+
"Downloading installer to installer.php"
244+
)
245+
246+
mocks="$(run_steps "setup")"
247+
run "${ROOT_DIR}/scripts/vortex/update-vortex.sh" --interactive https://github.com/custom/repo.git@main
248+
run_steps "assert" "${mocks[@]}"
249+
250+
assert_success
251+
252+
popd >/dev/null || exit 1
253+
}

scripts/vortex/update-vortex.sh

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ set -eu
2626
# /local/path/to/vortex.git@stable # Will auto-discover the latest stable tag from local repo.
2727
# /local/path/to/[email protected] # Will use specific release from local repo.
2828
# /local/path/to/vortex.git@abcd123 # Will use specific commit from local repo.
29-
VORTEX_INSTALLER_TEMPLATE_REPO="${VORTEX_INSTALLER_TEMPLATE_REPO:-${1:-https://github.com/drevops/vortex.git@stable}}"
29+
VORTEX_INSTALLER_TEMPLATE_REPO="${VORTEX_INSTALLER_TEMPLATE_REPO:-https://github.com/drevops/vortex.git@stable}"
3030

3131
# The URL of the installer script.
3232
VORTEX_INSTALLER_URL="${VORTEX_INSTALLER_URL:-https://www.vortextemplate.com/install}"
@@ -38,6 +38,9 @@ VORTEX_INSTALLER_URL_CACHE_BUST="${VORTEX_INSTALLER_URL_CACHE_BUST:-"$(date +%s)
3838
# If set, this will override the VORTEX_INSTALLER_URL.
3939
VORTEX_INSTALLER_PATH="${VORTEX_INSTALLER_PATH:-}"
4040

41+
# Run installer in interactive mode.
42+
VORTEX_INSTALLER_INTERACTIVE="${VORTEX_INSTALLER_INTERACTIVE:-0}"
43+
4144
# ------------------------------------------------------------------------------
4245

4346
# @formatter:off
@@ -54,6 +57,14 @@ for cmd in php curl; do command -v "${cmd}" >/dev/null || {
5457
exit 1
5558
}; done
5659

60+
for arg in "$@"; do
61+
if [ "${arg}" = "--interactive" ]; then
62+
VORTEX_INSTALLER_INTERACTIVE=1
63+
else
64+
VORTEX_INSTALLER_TEMPLATE_REPO="${arg}"
65+
fi
66+
done
67+
5768
if [ -n "${VORTEX_INSTALLER_PATH}" ]; then
5869
note "Using installer script from local path: ${VORTEX_INSTALLER_PATH}"
5970
if [ ! -f "${VORTEX_INSTALLER_PATH}" ]; then
@@ -70,4 +81,8 @@ else
7081
fi
7182
fi
7283

73-
php "${VORTEX_INSTALLER_PATH}" --no-interaction --uri="${VORTEX_INSTALLER_TEMPLATE_REPO}"
84+
if [ "${VORTEX_INSTALLER_INTERACTIVE}" = "0" ]; then
85+
php "${VORTEX_INSTALLER_PATH}" --no-interaction --uri="${VORTEX_INSTALLER_TEMPLATE_REPO}"
86+
else
87+
php "${VORTEX_INSTALLER_PATH}" --uri="${VORTEX_INSTALLER_TEMPLATE_REPO}"
88+
fi

0 commit comments

Comments
 (0)