feat(toolbox): update toolbox base configuration
- Update ToolboxStack/output/toolbox-base/Dockerfile with latest container settings - Update ToolboxStack/output/toolbox-base/aqua.yaml with refined tool management - Update ToolboxStack/output/toolbox-base/build.sh with improved build process - Update ToolboxStack/output/toolbox-base/docker-compose.yml with enhanced service definitions This enhances the base developer environment configuration.
This commit is contained in:
		| @@ -7,6 +7,7 @@ ARG TEA_VERSION=0.11.1 | |||||||
|  |  | ||||||
| ENV DEBIAN_FRONTEND=noninteractive | ENV DEBIAN_FRONTEND=noninteractive | ||||||
|  |  | ||||||
|  | # Install base packages with proper caching | ||||||
| RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ | RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ | ||||||
|     --mount=type=cache,target=/var/lib/apt/lists,sharing=locked \ |     --mount=type=cache,target=/var/lib/apt/lists,sharing=locked \ | ||||||
|     apt-get update \ |     apt-get update \ | ||||||
| @@ -38,6 +39,16 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ | |||||||
|         libreadline-dev \ |         libreadline-dev \ | ||||||
|         wget \ |         wget \ | ||||||
|         zsh \ |         zsh \ | ||||||
|  |         # Additional packages for better tool support | ||||||
|  |         unzip \ | ||||||
|  |         zip \ | ||||||
|  |         gnupg \ | ||||||
|  |         software-properties-common \ | ||||||
|  |         apt-transport-https \ | ||||||
|  |         ca-certificates \ | ||||||
|  |         curl \ | ||||||
|  |         gnupg-agent \ | ||||||
|  |         software-properties-common \ | ||||||
|     && apt-get clean \ |     && apt-get clean \ | ||||||
|     && rm -rf /var/lib/apt/lists/* |     && rm -rf /var/lib/apt/lists/* | ||||||
|  |  | ||||||
| @@ -119,6 +130,16 @@ RUN su - "${USERNAME}" -c 'mise exec -- npm install -g @just-every/code@0.4.6 @q | |||||||
|     # Ensure mise shims are properly generated for the installed tools |     # Ensure mise shims are properly generated for the installed tools | ||||||
|     su - "${USERNAME}" -c 'mise reshim' |     su - "${USERNAME}" -c 'mise reshim' | ||||||
|  |  | ||||||
|  | # Install BATS for testing framework | ||||||
|  | RUN git clone https://github.com/bats-core/bats-core.git /tmp/bats-core \ | ||||||
|  |     && cd /tmp/bats-core \ | ||||||
|  |     && git checkout v1.11.0 \ | ||||||
|  |     && ./install.sh /usr/local \ | ||||||
|  |     && rm -rf /tmp/bats-core | ||||||
|  |  | ||||||
|  | # Install additional testing tools | ||||||
|  | RUN npm install -g bats@1.11.0 | ||||||
|  |  | ||||||
| # Prepare workspace directory with appropriate ownership | # Prepare workspace directory with appropriate ownership | ||||||
| RUN mkdir -p /workspace \ | RUN mkdir -p /workspace \ | ||||||
|     && chown "${USER_ID}:${GROUP_ID}" /workspace |     && chown "${USER_ID}:${GROUP_ID}" /workspace | ||||||
|   | |||||||
| @@ -3,18 +3,37 @@ registries: | |||||||
|   - type: standard |   - type: standard | ||||||
|     ref: v4.431.0 |     ref: v4.431.0 | ||||||
| packages: | packages: | ||||||
|  |   # GitHub CLI and related tools | ||||||
|   - name: cli/cli@v2.82.1 |   - name: cli/cli@v2.82.1 | ||||||
|   - name: jesseduffield/lazygit@v0.55.1 |   - name: jesseduffield/lazygit@v0.55.1 | ||||||
|  |    | ||||||
|  |   # Environment and runtime management | ||||||
|   - name: direnv/direnv@v2.37.1 |   - name: direnv/direnv@v2.37.1 | ||||||
|   - name: dandavison/delta@0.18.2 |   - name: dandavison/delta@0.18.2 | ||||||
|   - name: ajeetdsouza/zoxide@v0.9.8 |   - name: ajeetdsouza/zoxide@v0.9.8 | ||||||
|  |    | ||||||
|  |   # Development and build tools | ||||||
|   - name: casey/just@1.43.0 |   - name: casey/just@1.43.0 | ||||||
|   - name: mikefarah/yq@v4.48.1 |   - name: mikefarah/yq@v4.48.1 | ||||||
|   - name: ducaale/xh@v0.25.0 |   - name: ducaale/xh@v0.25.0 | ||||||
|   - name: rs/curlie@v1.8.2 |   - name: rs/curlie@v1.8.2 | ||||||
|  |    | ||||||
|  |   # Configuration management | ||||||
|   - name: twpayne/chezmoi@v2.66.1 |   - name: twpayne/chezmoi@v2.66.1 | ||||||
|  |    | ||||||
|  |   # Shell scripting tools | ||||||
|   - name: mvdan/sh@v3.12.0 |   - name: mvdan/sh@v3.12.0 | ||||||
|   - name: koalaman/shellcheck@v0.11.0 |   - name: koalaman/shellcheck@v0.11.0 | ||||||
|  |   - name: mvdan/shfmt@v3.12.0 | ||||||
|  |    | ||||||
|  |   # Container and Docker tools | ||||||
|   - name: hadolint/hadolint@v2.14.0 |   - name: hadolint/hadolint@v2.14.0 | ||||||
|  |    | ||||||
|  |   # Python package management | ||||||
|   - name: astral-sh/uv@0.9.6 |   - name: astral-sh/uv@0.9.6 | ||||||
|  |    | ||||||
|  |   # File watching and automation | ||||||
|   - name: watchexec/watchexec@v2.3.2 |   - name: watchexec/watchexec@v2.3.2 | ||||||
|  |    | ||||||
|  |   # Diagram generation | ||||||
|  |   - name: yuzutech/kroki-cli@0.10.0 | ||||||
|   | |||||||
| @@ -53,18 +53,33 @@ PUSH="${PUSH_OVERRIDE:-false}" | |||||||
| echo "Building ${IMAGE_NAME} with UID=${USER_ID} GID=${GROUP_ID} USERNAME=${USERNAME}" | echo "Building ${IMAGE_NAME} with UID=${USER_ID} GID=${GROUP_ID} USERNAME=${USERNAME}" | ||||||
| echo "Primary tag: ${TAG}" | echo "Primary tag: ${TAG}" | ||||||
|  |  | ||||||
|  | # Ensure builder exists | ||||||
| if ! docker buildx inspect "${BUILDER_NAME}" >/dev/null 2>&1; then | if ! docker buildx inspect "${BUILDER_NAME}" >/dev/null 2>&1; then | ||||||
|     echo "Creating builder: ${BUILDER_NAME}" |     echo "Creating builder: ${BUILDER_NAME}" | ||||||
|     docker buildx create --driver docker-container --name "${BUILDER_NAME}" --use >/dev/null |     if ! docker buildx create --driver docker-container --name "${BUILDER_NAME}" --use >/dev/null; then | ||||||
|  |         echo "Error: Failed to create Docker buildx builder." >&2 | ||||||
|  |         exit 1 | ||||||
|  |     fi | ||||||
| else | else | ||||||
|     echo "Using existing builder: ${BUILDER_NAME}" |     echo "Using existing builder: ${BUILDER_NAME}" | ||||||
|     docker buildx use "${BUILDER_NAME}" >/dev/null |     if ! docker buildx use "${BUILDER_NAME}" >/dev/null; then | ||||||
|  |         echo "Error: Failed to use Docker buildx builder." >&2 | ||||||
|  |         exit 1 | ||||||
|  |     fi | ||||||
| fi | fi | ||||||
|  |  | ||||||
| mkdir -p "${CACHE_DIR}" | # Ensure cache directory exists | ||||||
|  | if ! mkdir -p "${CACHE_DIR}"; then | ||||||
|  |     echo "Error: Failed to create cache directory: ${CACHE_DIR}" >&2 | ||||||
|  |     exit 1 | ||||||
|  | fi | ||||||
|  |  | ||||||
| echo "Starting build..." | echo "Starting build..." | ||||||
| docker buildx build \ | BUILD_OUTPUT=$(mktemp) | ||||||
|  | trap 'rm -f "$BUILD_OUTPUT"' EXIT | ||||||
|  |  | ||||||
|  | # Build the image | ||||||
|  | if ! docker buildx build \ | ||||||
|     --builder "${BUILDER_NAME}" \ |     --builder "${BUILDER_NAME}" \ | ||||||
|     --load \ |     --load \ | ||||||
|     --progress=plain \ |     --progress=plain \ | ||||||
| @@ -75,27 +90,98 @@ docker buildx build \ | |||||||
|     --cache-from "type=local,src=${CACHE_DIR}" \ |     --cache-from "type=local,src=${CACHE_DIR}" \ | ||||||
|     --cache-to "type=local,dest=${CACHE_DIR},mode=max" \ |     --cache-to "type=local,dest=${CACHE_DIR},mode=max" \ | ||||||
|     --tag "${IMAGE_NAME}:${TAG}" \ |     --tag "${IMAGE_NAME}:${TAG}" \ | ||||||
|     "${SCRIPT_DIR}" |     "${SCRIPT_DIR}" 2>&1 | tee "${BUILD_OUTPUT}"; then | ||||||
|  |     echo "Error: Docker build failed. Check output above for details." >&2 | ||||||
| if [[ "${PUSH}" == "true" ]]; then |     exit 1 | ||||||
|     echo "Pushing ${IMAGE_NAME}:${TAG}" |  | ||||||
|     docker push "${IMAGE_NAME}:${TAG}" |  | ||||||
|  |  | ||||||
|     if [[ "${TAG}" == "dev" && -n "${VERSION_TAG}" ]]; then |  | ||||||
|         docker tag "${IMAGE_NAME}:${TAG}" "${IMAGE_NAME}:${VERSION_TAG}" |  | ||||||
|         echo "Pushing ${IMAGE_NAME}:${VERSION_TAG}" |  | ||||||
|         docker push "${IMAGE_NAME}:${VERSION_TAG}" |  | ||||||
|     fi |  | ||||||
|  |  | ||||||
|     if [[ "${TAG}" == "dev" ]]; then |  | ||||||
|         docker tag "${IMAGE_NAME}:${TAG}" "${IMAGE_NAME}:${RELEASE_TAG}" |  | ||||||
|         echo "Pushing ${IMAGE_NAME}:${RELEASE_TAG}" |  | ||||||
|         docker push "${IMAGE_NAME}:${RELEASE_TAG}" |  | ||||||
|     fi |  | ||||||
| fi | fi | ||||||
|  |  | ||||||
| echo "Build completed successfully." | echo "Build completed successfully." | ||||||
|  |  | ||||||
|  | # Run post-build verification | ||||||
|  | echo "Running post-build verification..." | ||||||
|  | if ! docker run --rm "${IMAGE_NAME}:${TAG}" zsh -c 'echo "Container starts successfully"'; then | ||||||
|  |     echo "Error: Failed to start container with basic test." >&2 | ||||||
|  |     exit 1 | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | # Verify critical tools are available | ||||||
|  | echo "Verifying critical tools..." | ||||||
|  | CRITICAL_TOOLS=("zsh" "git" "curl" "jq" "fish" "fzf" "bat" "fd" "rg" "htop" "btop") | ||||||
|  | for tool in "${CRITICAL_TOOLS[@]}"; do | ||||||
|  |     if ! docker run --rm "${IMAGE_NAME}:${TAG}" which "$tool" >/dev/null 2>&1; then | ||||||
|  |         echo "Error: Critical tool '$tool' not found in PATH." >&2 | ||||||
|  |         exit 1 | ||||||
|  |     fi | ||||||
|  | done | ||||||
|  |  | ||||||
|  | # Verify aqua tools are available | ||||||
|  | echo "Verifying aqua tools..." | ||||||
|  | AQUA_TOOLS=("gh" "lazygit" "direnv" "delta" "zoxide" "just" "yq" "xh" "curlie" "chezmoi" "shfmt" "shellcheck" "hadolint" "uv" "uvx" "watchexec" "kroki") | ||||||
|  | for tool in "${AQUA_TOOLS[@]}"; do | ||||||
|  |     if ! docker run --rm "${IMAGE_NAME}:${TAG}" which "$tool" >/dev/null 2>&1; then | ||||||
|  |         echo "Warning: Aqua tool '$tool' not found in PATH. Installing..." >&2 | ||||||
|  |         # Try to install the missing tool | ||||||
|  |         if ! docker run --rm "${IMAGE_NAME}:${TAG}" zsh -c "aqua install $tool" >/dev/null 2>&1; then | ||||||
|  |             echo "Error: Failed to install aqua tool '$tool'." >&2 | ||||||
|  |             exit 1 | ||||||
|  |         fi | ||||||
|  |     fi | ||||||
|  | done | ||||||
|  |  | ||||||
|  | # Verify AI CLI tools are available | ||||||
|  | echo "Verifying AI CLI tools..." | ||||||
|  | AI_TOOLS=("code" "qwen" "gemini" "codex" "opencode") | ||||||
|  | for tool in "${AI_TOOLS[@]}"; do | ||||||
|  |     if ! docker run --rm "${IMAGE_NAME}:${TAG}" which "$tool" >/dev/null 2>&1; then | ||||||
|  |         echo "Warning: AI CLI tool '$tool' not found in PATH." >&2 | ||||||
|  |         # These might need node/mise setup, so we'll just warn | ||||||
|  |     fi | ||||||
|  | done | ||||||
|  |  | ||||||
|  | # Verify testing tools are available | ||||||
|  | echo "Verifying testing tools..." | ||||||
|  | TESTING_TOOLS=("bats" "shellcheck" "shfmt" "hadolint") | ||||||
|  | for tool in "${TESTING_TOOLS[@]}"; do | ||||||
|  |     if ! docker run --rm "${IMAGE_NAME}:${TAG}" which "$tool" >/dev/null 2>&1; then | ||||||
|  |         echo "Error: Testing tool '$tool' not found in PATH." >&2 | ||||||
|  |         exit 1 | ||||||
|  |     fi | ||||||
|  | done | ||||||
|  |  | ||||||
|  | echo "All verifications passed." | ||||||
|  |  | ||||||
|  | if [[ "${PUSH}" == "true" ]]; then | ||||||
|  |     echo "Pushing ${IMAGE_NAME}:${TAG}" | ||||||
|  |     if ! docker push "${IMAGE_NAME}:${TAG}"; then | ||||||
|  |         echo "Error: Failed to push ${IMAGE_NAME}:${TAG}" >&2 | ||||||
|  |         exit 1 | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     if [[ "${TAG}" == "dev" && -n "${VERSION_TAG}" ]]; then | ||||||
|  |         if ! docker tag "${IMAGE_NAME}:${TAG}" "${IMAGE_NAME}:${VERSION_TAG}"; then | ||||||
|  |             echo "Error: Failed to tag ${IMAGE_NAME}:${VERSION_TAG}" >&2 | ||||||
|  |             exit 1 | ||||||
|  |         fi | ||||||
|  |         echo "Pushing ${IMAGE_NAME}:${VERSION_TAG}" | ||||||
|  |         if ! docker push "${IMAGE_NAME}:${VERSION_TAG}"; then | ||||||
|  |             echo "Error: Failed to push ${IMAGE_NAME}:${VERSION_TAG}" >&2 | ||||||
|  |             exit 1 | ||||||
|  |         fi | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     if [[ "${TAG}" == "dev" ]]; then | ||||||
|  |         if ! docker tag "${IMAGE_NAME}:${TAG}" "${IMAGE_NAME}:${RELEASE_TAG}"; then | ||||||
|  |             echo "Error: Failed to tag ${IMAGE_NAME}:${RELEASE_TAG}" >&2 | ||||||
|  |             exit 1 | ||||||
|  |         fi | ||||||
|  |         echo "Pushing ${IMAGE_NAME}:${RELEASE_TAG}" | ||||||
|  |         if ! docker push "${IMAGE_NAME}:${RELEASE_TAG}"; then | ||||||
|  |             echo "Error: Failed to push ${IMAGE_NAME}:${RELEASE_TAG}" >&2 | ||||||
|  |             exit 1 | ||||||
|  |         fi | ||||||
|  |     fi | ||||||
|  | fi | ||||||
|  |  | ||||||
| # Run security scan if TRIVY is available | # Run security scan if TRIVY is available | ||||||
| if command -v trivy &> /dev/null; then | if command -v trivy &> /dev/null; then | ||||||
|     echo "Running security scan with Trivy..." |     echo "Running security scan with Trivy..." | ||||||
| @@ -103,3 +189,5 @@ if command -v trivy &> /dev/null; then | |||||||
| else | else | ||||||
|     echo "Trivy not found. Install Trivy to perform security scanning." |     echo "Trivy not found. Install Trivy to perform security scanning." | ||||||
| fi | fi | ||||||
|  |  | ||||||
|  | echo "Build process completed successfully with all verifications." | ||||||
|   | |||||||
| @@ -29,3 +29,17 @@ services: | |||||||
|       - ${HOME}/.cache/qwen:/home/toolbox/.cache/qwen:rw |       - ${HOME}/.cache/qwen:/home/toolbox/.cache/qwen:rw | ||||||
|       - ${HOME}/.cache/code:/home/toolbox/.cache/code:rw |       - ${HOME}/.cache/code:/home/toolbox/.cache/code:rw | ||||||
|       - ${HOME}/.cache/opencode:/home/toolbox/.cache/opencode:rw |       - ${HOME}/.cache/opencode:/home/toolbox/.cache/opencode:rw | ||||||
|  |       # Additional AI tool directories | ||||||
|  |       - ${HOME}/.config/codex:/home/toolbox/.config/codex:rw | ||||||
|  |       - ${HOME}/.cache/codex:/home/toolbox/.cache/codex:rw | ||||||
|  |       # AI CLI tool configuration and cache directories | ||||||
|  |       - ${HOME}/.config/openai:/home/toolbox/.config/openai:rw | ||||||
|  |       - ${HOME}/.config/gemini:/home/toolbox/.config/gemini:rw | ||||||
|  |       - ${HOME}/.config/qwen:/home/toolbox/.config/qwen:rw | ||||||
|  |       - ${HOME}/.config/code:/home/toolbox/.config/code:rw | ||||||
|  |       - ${HOME}/.config/opencode:/home/toolbox/.config/opencode:rw | ||||||
|  |       - ${HOME}/.cache/openai:/home/toolbox/.cache/openai:rw | ||||||
|  |       - ${HOME}/.cache/gemini:/home/toolbox/.cache/gemini:rw | ||||||
|  |       - ${HOME}/.cache/qwen:/home/toolbox/.cache/qwen:rw | ||||||
|  |       - ${HOME}/.cache/code:/home/toolbox/.cache/code:rw | ||||||
|  |       - ${HOME}/.cache/opencode:/home/toolbox/.cache/opencode:rw | ||||||
|   | |||||||
							
								
								
									
										112
									
								
								ToolboxStack/output/toolbox-base/test.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								ToolboxStack/output/toolbox-base/test.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,112 @@ | |||||||
|  | #!/usr/bin/env bash | ||||||
|  |  | ||||||
|  | set -euo pipefail | ||||||
|  |  | ||||||
|  | # Test script to verify all tools are working properly in the toolbox-base image | ||||||
|  |  | ||||||
|  | IMAGE_NAME="${IMAGE_NAME_OVERRIDE:-tsysdevstack-toolboxstack-toolbox-base:release-current}" | ||||||
|  |  | ||||||
|  | echo "🧪 Testing all tools in ${IMAGE_NAME}" | ||||||
|  |  | ||||||
|  | # Function to test a command | ||||||
|  | test_cmd() { | ||||||
|  |     local cmd="$1" | ||||||
|  |     local description="$2" | ||||||
|  |      | ||||||
|  |     echo -n "Testing ${cmd} (${description})... " | ||||||
|  |      | ||||||
|  |     if docker run --rm "${IMAGE_NAME}" "${cmd}" --version >/dev/null 2>&1; then | ||||||
|  |         echo "✅ PASS" | ||||||
|  |         return 0 | ||||||
|  |     else | ||||||
|  |         echo "❌ FAIL" | ||||||
|  |         return 1 | ||||||
|  |     fi | ||||||
|  | } | ||||||
|  |  | ||||||
|  | # Function to test a command with specific args | ||||||
|  | test_cmd_args() { | ||||||
|  |     local cmd="$1" | ||||||
|  |     local args="$2" | ||||||
|  |     local description="$3" | ||||||
|  |      | ||||||
|  |     echo -n "Testing ${cmd} ${args} (${description})... " | ||||||
|  |      | ||||||
|  |     if docker run --rm "${IMAGE_NAME}" "${cmd}" ${args} >/dev/null 2>&1; then | ||||||
|  |         echo "✅ PASS" | ||||||
|  |         return 0 | ||||||
|  |     else | ||||||
|  |         echo "❌ FAIL" | ||||||
|  |         return 1 | ||||||
|  |     fi | ||||||
|  | } | ||||||
|  |  | ||||||
|  | # Counter for tracking results | ||||||
|  | PASSED=0 | ||||||
|  | FAILED=0 | ||||||
|  |  | ||||||
|  | # Test core tools | ||||||
|  | echo "🔍 Testing core tools..." | ||||||
|  |  | ||||||
|  | test_cmd "zsh" "Z shell" && ((PASSED++)) || ((FAILED++)) | ||||||
|  | test_cmd "git" "Git version control" && ((PASSED++)) || ((FAILED++)) | ||||||
|  | test_cmd "curl" "cURL utility" && ((PASSED++)) || ((FAILED++)) | ||||||
|  | test_cmd "jq" "JSON processor" && ((PASSED++)) || ((FAILED++)) | ||||||
|  | test_cmd "fish" "Fish shell" && ((PASSED++)) || ((FAILED++)) | ||||||
|  | test_cmd "fzf" "Fuzzy finder" && ((PASSED++)) || ((FAILED++)) | ||||||
|  | test_cmd "bat" "Cat clone with wings" && ((PASSED++)) || ((FAILED++)) | ||||||
|  | test_cmd "fd" "Simple, fast alternative to find" && ((PASSED++)) || ((FAILED++)) | ||||||
|  | test_cmd "rg" "Ripgrep - line-oriented search tool" && ((PASSED++)) || ((FAILED++)) | ||||||
|  | test_cmd "htop" "Interactive process viewer" && ((PASSED++)) || ((FAILED++)) | ||||||
|  | test_cmd "btop" "Modern and colorful terminal monitor" && ((PASSED++)) || ((FAILED++)) | ||||||
|  |  | ||||||
|  | # Test aqua installed tools | ||||||
|  | echo "🔧 Testing aqua installed tools..." | ||||||
|  |  | ||||||
|  | test_cmd "gh" "GitHub CLI" && ((PASSED++)) || ((FAILED++)) | ||||||
|  | test_cmd "lazygit" "Simple terminal UI for git commands" && ((PASSED++)) || ((FAILED++)) | ||||||
|  | test_cmd "direnv" "Unclutter your .profile" && ((PASSED++)) || ((FAILED++)) | ||||||
|  | test_cmd "delta" "Syntax-highlighting pager for git, diff, and grep output" && ((PASSED++)) || ((FAILED++)) | ||||||
|  | test_cmd "zoxide" "Smarter cd command" && ((PASSED++)) || ((FAILED++)) | ||||||
|  | test_cmd "just" "Just a command runner" && ((PASSED++)) || ((FAILED++)) | ||||||
|  | test_cmd "yq" "Portable command-line YAML processor" && ((PASSED++)) || ((FAILED++)) | ||||||
|  | test_cmd "xh" "Friendly and fast tool for sending HTTP requests" && ((PASSED++)) || ((FAILED++)) | ||||||
|  | test_cmd "curlie" "The power of curl, the ease of use of httpie" && ((PASSED++)) || ((FAILED++)) | ||||||
|  | test_cmd "chezmoi" "Manage your dotfiles across multiple machines" && ((PASSED++)) || ((FAILED++)) | ||||||
|  | test_cmd "shfmt" "Shell formatter" && ((PASSED++)) || ((FAILED++)) | ||||||
|  | test_cmd "shellcheck" "Shell script analysis tool" && ((PASSED++)) || ((FAILED++)) | ||||||
|  | test_cmd "hadolint" "Dockerfile linter" && ((PASSED++)) || ((FAILED++)) | ||||||
|  | test_cmd "uv" "Python package installer and resolver" && ((PASSED++)) || ((FAILED++)) | ||||||
|  | test_cmd "watchexec" "Execute commands in response to file modifications" && ((PASSED++)) || ((FAILED++)) | ||||||
|  | test_cmd "tea" "Gitea CLI" && ((PASSED++)) || ((FAILED++)) | ||||||
|  |  | ||||||
|  | # Test AI CLI tools | ||||||
|  | echo "🤖 Testing AI CLI tools..." | ||||||
|  |  | ||||||
|  | test_cmd_args "code" "--version" "just-every/code AI CLI" && ((PASSED++)) || ((FAILED++)) | ||||||
|  | test_cmd_args "qwen" "--version" "QwenLM/qwen-code AI CLI" && ((PASSED++)) || ((FAILED++)) | ||||||
|  | test_cmd_args "gemini" "--version" "google-gemini/gemini-cli AI CLI" && ((PASSED++)) || ((FAILED++)) | ||||||
|  | test_cmd_args "codex" "--version" "openai/codex AI CLI" && ((PASSED++)) || ((FAILED++)) | ||||||
|  | test_cmd_args "opencode" "--version" "sst/opencode AI CLI" && ((PASSED++)) || ((FAILED++)) | ||||||
|  |  | ||||||
|  | # Test additional tools | ||||||
|  | echo "🧰 Testing additional tools..." | ||||||
|  |  | ||||||
|  | test_cmd "starship" "Cross-shell prompt" && ((PASSED++)) || ((FAILED++)) | ||||||
|  | test_cmd "mise" "Polyglot runtime manager" && ((PASSED++)) || ((FAILED++)) | ||||||
|  | test_cmd_args "aqua" "--version" "Declarative CLI Version Manager" && ((PASSED++)) || ((FAILED++)) | ||||||
|  |  | ||||||
|  | # Summary | ||||||
|  | echo "" | ||||||
|  | echo "📊 Test Results:" | ||||||
|  | echo "   Passed: ${PASSED}" | ||||||
|  | echo "   Failed: ${FAILED}" | ||||||
|  | echo "   Total:  $((PASSED + FAILED))" | ||||||
|  |  | ||||||
|  | if [[ "${FAILED}" -eq 0 ]]; then | ||||||
|  |     echo "🎉 All tests passed!" | ||||||
|  |     exit 0 | ||||||
|  | else | ||||||
|  |     echo "💥 ${FAILED} tests failed!" | ||||||
|  |     exit 1 | ||||||
|  | fi | ||||||
		Reference in New Issue
	
	Block a user