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:
2025-10-30 12:28:05 -05:00
parent 073cb91585
commit 08d10b16cf
5 changed files with 275 additions and 21 deletions

View File

@@ -7,6 +7,7 @@ ARG TEA_VERSION=0.11.1
ENV DEBIAN_FRONTEND=noninteractive
# Install base packages with proper caching
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt/lists,sharing=locked \
apt-get update \
@@ -38,6 +39,16 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
libreadline-dev \
wget \
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 \
&& 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
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
RUN mkdir -p /workspace \
&& chown "${USER_ID}:${GROUP_ID}" /workspace

View File

@@ -3,18 +3,37 @@ registries:
- type: standard
ref: v4.431.0
packages:
# GitHub CLI and related tools
- name: cli/cli@v2.82.1
- name: jesseduffield/lazygit@v0.55.1
# Environment and runtime management
- name: direnv/direnv@v2.37.1
- name: dandavison/delta@0.18.2
- name: ajeetdsouza/zoxide@v0.9.8
# Development and build tools
- name: casey/just@1.43.0
- name: mikefarah/yq@v4.48.1
- name: ducaale/xh@v0.25.0
- name: rs/curlie@v1.8.2
# Configuration management
- name: twpayne/chezmoi@v2.66.1
# Shell scripting tools
- name: mvdan/sh@v3.12.0
- name: koalaman/shellcheck@v0.11.0
- name: mvdan/shfmt@v3.12.0
# Container and Docker tools
- name: hadolint/hadolint@v2.14.0
# Python package management
- name: astral-sh/uv@0.9.6
# File watching and automation
- name: watchexec/watchexec@v2.3.2
# Diagram generation
- name: yuzutech/kroki-cli@0.10.0

View File

@@ -53,18 +53,33 @@ PUSH="${PUSH_OVERRIDE:-false}"
echo "Building ${IMAGE_NAME} with UID=${USER_ID} GID=${GROUP_ID} USERNAME=${USERNAME}"
echo "Primary tag: ${TAG}"
# Ensure builder exists
if ! docker buildx inspect "${BUILDER_NAME}" >/dev/null 2>&1; then
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
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
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..."
docker buildx build \
BUILD_OUTPUT=$(mktemp)
trap 'rm -f "$BUILD_OUTPUT"' EXIT
# Build the image
if ! docker buildx build \
--builder "${BUILDER_NAME}" \
--load \
--progress=plain \
@@ -75,27 +90,98 @@ docker buildx build \
--cache-from "type=local,src=${CACHE_DIR}" \
--cache-to "type=local,dest=${CACHE_DIR},mode=max" \
--tag "${IMAGE_NAME}:${TAG}" \
"${SCRIPT_DIR}"
if [[ "${PUSH}" == "true" ]]; then
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
"${SCRIPT_DIR}" 2>&1 | tee "${BUILD_OUTPUT}"; then
echo "Error: Docker build failed. Check output above for details." >&2
exit 1
fi
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
if command -v trivy &> /dev/null; then
echo "Running security scan with Trivy..."
@@ -103,3 +189,5 @@ if command -v trivy &> /dev/null; then
else
echo "Trivy not found. Install Trivy to perform security scanning."
fi
echo "Build process completed successfully with all verifications."

View File

@@ -29,3 +29,17 @@ services:
- ${HOME}/.cache/qwen:/home/toolbox/.cache/qwen:rw
- ${HOME}/.cache/code:/home/toolbox/.cache/code: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

View 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