git clone https://github.com/everett7623/vps_scripts.git
cd vps_scriptsNo build step — everything is Bash. All tests accept REPO_ROOT_OVERRIDE (and LAUNCHER_OVERRIDE where relevant).
- Inspect the target script and any shared helpers it sources.
- Check whether the change belongs in the modular path (
vps.sh,lib/,scripts/,tests/) or only in the legacy launcher (vps_scripts.sh— legacy-only, no new features). - Make the smallest change that improves reliability or safety without hiding errors.
- Run syntax validation and relevant repo tests.
- Update docs if behavior or workflow changed.
Run all commands from the repo root.
bash -n vps.sh
bash -n vps_scripts.sh
bash -n lib/common_functions.sh
bash -n scripts/system_tools/install_deps.shLAUNCHER_OVERRIDE="$PWD/vps.sh" REPO_ROOT_OVERRIDE="$PWD" bash tests/validate_launcher_paths.sh
REPO_ROOT_OVERRIDE="$PWD" bash tests/validate_system_tools_launcher.sh
REPO_ROOT_OVERRIDE="$PWD" bash tests/validate_service_install_launcher.sh
REPO_ROOT_OVERRIDE="$PWD" bash tests/validate_active_category_coverage.shREPO_ROOT_OVERRIDE="$PWD" bash tests/validate_core_assets.sh
REPO_ROOT_OVERRIDE="$PWD" bash tests/validate_script_headers.sh
REPO_ROOT_OVERRIDE="$PWD" bash tests/validate_line_endings_policy.sh
REPO_ROOT_OVERRIDE="$PWD" bash tests/validate_update_scripts_legacy.sh
REPO_ROOT_OVERRIDE="$PWD" bash tests/validate_update_log_handoff.shREPO_ROOT_OVERRIDE="$PWD" bash tests/validate_system_tools.sh
REPO_ROOT_OVERRIDE="$PWD" bash tests/validate_common_helpers.shREPO_ROOT_OVERRIDE="$PWD" bash tests/validate_docker_installer_safety.sh
REPO_ROOT_OVERRIDE="$PWD" bash tests/validate_python_installer_safety.sh
REPO_ROOT_OVERRIDE="$PWD" bash tests/validate_kubernetes_installer_safety.sh
REPO_ROOT_OVERRIDE="$PWD" bash tests/validate_go_installer_safety.sh
REPO_ROOT_OVERRIDE="$PWD" bash tests/validate_java_installer_safety.sh
REPO_ROOT_OVERRIDE="$PWD" bash tests/validate_nginx_installer_safety.sh
REPO_ROOT_OVERRIDE="$PWD" bash tests/validate_mysql_installer_safety.sh
REPO_ROOT_OVERRIDE="$PWD" bash tests/validate_postgresql_installer_safety.sh
REPO_ROOT_OVERRIDE="$PWD" bash tests/validate_redis_installer_safety.shREPO_ROOT_OVERRIDE="$PWD" bash tests/validate_input_contract.sh
REPO_ROOT_OVERRIDE="$PWD" bash tests/validate_remote_module_runtime.sh
REPO_ROOT_OVERRIDE="$PWD" bash tests/validate_execution_safety.shREPO_ROOT_OVERRIDE="$PWD" bash tests/validate_ui_framework.sh
REPO_ROOT_OVERRIDE="$PWD" bash tests/validate_ui_layout.sh
REPO_ROOT_OVERRIDE="$PWD" bash tests/validate_chinese_ui.sh
REPO_ROOT_OVERRIDE="$PWD" bash tests/validate_loader_performance.sh
REPO_ROOT_OVERRIDE="$PWD" bash tests/validate_menu_eof.sh
REPO_ROOT_OVERRIDE="$PWD" bash tests/validate_command_install.sh
REPO_ROOT_OVERRIDE="$PWD" bash tests/validate_legacy_launcher_policy.shshellcheck vps.sh vps_scripts.sh
shellcheck lib/common_functions.shbash run_all_tests.sh- Create
scripts/<category>/<name>.shwith#!/bin/bashheader,set -euo pipefail, and the defensive library-sourcing pattern - Add menu entry in
vps.shusingrun_repo_script "scripts/<category>/<name>.sh" - Add safety test in
tests/validate_<name>_installer_safety.sh(for service_install) - Update
tests/validate_service_install_launcher.shor category-specific launcher test - Run full test suite
- Add
print_menu_itemandcaseentry in the relevant menu function - Use
run_remote_script_urlfor single-URL scripts,run_remote_commandfor multi-step commands - Update the prompt range (e.g.,
[0-5]→[0-6]) - Run
tests/validate_launcher_paths.shand category-specific tests
SCRIPT_PATH=$(readlink -f "$0")
SCRIPT_DIR=$(dirname "$SCRIPT_PATH")
PROJECT_ROOT=$(dirname "$(dirname "$SCRIPT_DIR")")
LIB_FILE="$PROJECT_ROOT/lib/common_functions.sh"
CONFIG_FILE="$PROJECT_ROOT/config/vps_scripts.conf"
if [ -f "$LIB_FILE" ]; then
source "$LIB_FILE"
[ -f "$CONFIG_FILE" ] && source "$CONFIG_FILE"
else
# Inline fallback: define minimal print_* and check_root functions
fiAlways use mktemp or mktemp -d with the XXXXXX suffix pattern. Never use predictable /tmp paths.
local work_dir
work_dir=$(mktemp -d "/tmp/mybuild.XXXXXX") || { print_error "..."; exit 1; }
# ... do work ...
rm -rf -- "${work_dir}"
# Or use trap for automatic cleanup:
trap 'rm -rf -- "${work_dir}"' EXITWith set -euo pipefail:
- Use
|| trueon commands expected to fail (e.g.,systemctl stop ufw || true) - Use
if ! cmd; then ... fiwhen you need the error message before exit - Use
|| { print_error "..."; exit 1; }for fatal errors - Guard
command substitutionpipelines with|| truewhenset -ecould preempt your empty-check:result=$(some_pipeline | grep ... | tail -1) || true if [[ -z "$result" ]]; then ... fi
- First-party launcher safety
- Idempotent installers (safe to run twice)
- Reduced hidden side effects
- Clear rollback and cleanup behavior
- Consistent logging and status messages
- Cross-platform line endings (LF, enforced by
.gitattributes)
- One responsibility per script
- Shared helpers in
lib/common_functions.sh export -fall library functions for sub-shell availability- New menu entries must point to existing files or valid URLs
scripts/update_scripts/was removed — do not restore it; migrate needed logic into a focused module- Avoid
evalunless no safer alternative exists - Prefer arrays over command strings for package-manager commands
- Validate user input before using in commands, paths, or service names
- Quote variables unless unquoted expansion is genuinely required
- Terminal scripts cannot control the user's font size. Use bold/bright hierarchy, whitespace, and concise labels to improve readability instead.
- Respect
VPS_UI_WIDTHfor deterministic previews and tests; otherwise detect the terminal width and cap wide layouts at 88 columns. - Use
text_display_width()plus explicit padding for mixed Chinese/ASCII columns. Do not useprintf %-Nsdirectly for CJK menu alignment. - Switch long menu details to a second indented line below 64 columns.
- Avoid clearing the screen when stdout is not a TTY or
TERMis unset/dumb.
See RELEASE_CHECKLIST.md and VERSIONING.md. Key steps:
- Update
CHANGELOG.mdUnreleased section - Update
version.jsonversion and release_date - Review
TASKS.mdandPROGRESS.mdfor milestone completion - Run full test suite (
bash run_all_tests.sh) - Test remote launcher command from a clean environment