v0.1 step 1: Dockerfile + per-language toolchain smoke
Monolith image with every toolchain in the spec: - Python 3.12 + uv/ruff/mypy/pytest/pip-audit/semgrep - Node 22 LTS + bun - Go 1.22 + govulncheck/staticcheck - Rust stable + cargo-audit/cargo-deny - Ruby 3.x + bundler-audit - PHP 8.x + composer/phpstan - JDK 17 + 21 + Maven + Gradle - .NET 8 SDK - Swift 5.9.2 - Kotlin 1.9.25 - clang + cmake + valgrind + ASan/UBSan/TSan - bash + shellcheck smoke.sh proves each toolchain compiles + runs a hello-world. compose.yml uses the existing 'sulkta' bridge network. No API yet (steps 2-3); no MCP yet (step 7); no runner yet (step 4). This is the foundation. NOTE: docker build + smoke verification not yet run — sandbox doesn't have docker. Needs `docker compose build && docker compose up` on Lucy or any real Docker host before we trust the Dockerfile. Spec: memory/spec-crafting-table.md
This commit is contained in:
parent
5bd1b1de7e
commit
4e668a79e1
5 changed files with 619 additions and 1 deletions
48
.gitignore
vendored
Normal file
48
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
# Python
|
||||
__pycache__/
|
||||
*.pyc
|
||||
*.pyo
|
||||
.venv/
|
||||
venv/
|
||||
.mypy_cache/
|
||||
.ruff_cache/
|
||||
.pytest_cache/
|
||||
|
||||
# Node / TS
|
||||
node_modules/
|
||||
dist/
|
||||
*.tsbuildinfo
|
||||
|
||||
# Rust
|
||||
target/
|
||||
|
||||
# Go
|
||||
/bin/
|
||||
|
||||
# Java / Kotlin / Gradle / Maven
|
||||
build/
|
||||
out/
|
||||
.gradle/
|
||||
*.class
|
||||
*.jar
|
||||
.mvn/
|
||||
|
||||
# .NET
|
||||
.dotnet/
|
||||
obj/
|
||||
|
||||
# Swift
|
||||
.swiftpm/
|
||||
.build/
|
||||
*.xcodeproj/
|
||||
|
||||
# Misc
|
||||
.cache/
|
||||
.env
|
||||
*.log
|
||||
.DS_Store
|
||||
|
||||
# Editor
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
263
Dockerfile
Normal file
263
Dockerfile
Normal file
|
|
@ -0,0 +1,263 @@
|
|||
# crafting-table v0.1 — polyglot dev/build/audit container
|
||||
#
|
||||
# Step 1 of 10: monolith image with every toolchain in the spec.
|
||||
# Spec: Sulkta-Coop/openclaw-workspace/memory/spec-crafting-table.md
|
||||
#
|
||||
# Toolchain version pins (bump these to upgrade):
|
||||
# NODE_VERSION 22.11.0 (LTS)
|
||||
# GO_VERSION 1.22.10
|
||||
# RUST_CHANNEL stable
|
||||
# BUN_VERSION latest (rolling — pinned at install only)
|
||||
# DOTNET_VERSION 8.0
|
||||
# SWIFT_VERSION 5.9.2
|
||||
# KOTLIN_VERSION 1.9.25
|
||||
# GRADLE_VERSION 8.10
|
||||
# JDK 17 (default) + 21 (alongside, via JAVA_HOME_21)
|
||||
#
|
||||
# Image runs as non-root user `crafter` (uid 1000) with passwordless sudo.
|
||||
# Persistent caches mounted at /caches/{cargo,maven,gradle,npm,pip}.
|
||||
# Workspace at /workspace. Per-job state at /data.
|
||||
|
||||
FROM debian:bookworm-slim
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive \
|
||||
LANG=C.UTF-8 \
|
||||
LC_ALL=C.UTF-8
|
||||
|
||||
# ---------- Toolchain version pins ----------
|
||||
ENV NODE_VERSION=22.11.0 \
|
||||
GO_VERSION=1.22.10 \
|
||||
DOTNET_CHANNEL=8.0 \
|
||||
SWIFT_VERSION=5.9.2 \
|
||||
SWIFT_PLATFORM=ubuntu22.04 \
|
||||
KOTLIN_VERSION=1.9.25 \
|
||||
GRADLE_VERSION=8.10
|
||||
|
||||
# ============================================================
|
||||
# 1. System base — apt packages
|
||||
# ============================================================
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
curl wget git ca-certificates gnupg lsb-release apt-transport-https \
|
||||
build-essential pkg-config make cmake ninja-build \
|
||||
jq ripgrep fd-find \
|
||||
valgrind clang lld llvm \
|
||||
python3 python3-pip python3-venv python3-dev \
|
||||
php-cli php-curl php-mbstring php-xml php-zip composer \
|
||||
ruby ruby-dev ruby-bundler \
|
||||
bash shellcheck bats \
|
||||
openjdk-17-jdk-headless \
|
||||
sudo unzip xz-utils zstd \
|
||||
libcurl4 libxml2 libedit2 libsqlite3-0 libpython3-dev \
|
||||
libncurses6 libtinfo6 libgcc-s1 libstdc++6 \
|
||||
libssl-dev libffi-dev \
|
||||
zlib1g-dev liblzma-dev libbz2-dev \
|
||||
locales tzdata \
|
||||
&& ln -sf /usr/bin/fdfind /usr/local/bin/fd \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# ============================================================
|
||||
# 2. Node 22 LTS via NodeSource
|
||||
# ============================================================
|
||||
RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
|
||||
&& apt-get install -y --no-install-recommends nodejs \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& npm install -g pnpm tsx eslint typescript
|
||||
|
||||
# ============================================================
|
||||
# 3. Go (download from go.dev tarball)
|
||||
# ============================================================
|
||||
RUN ARCH="$(dpkg --print-architecture)" \
|
||||
&& case "$ARCH" in \
|
||||
amd64) GOARCH=amd64 ;; \
|
||||
arm64) GOARCH=arm64 ;; \
|
||||
*) echo "Unsupported arch $ARCH" && exit 1 ;; \
|
||||
esac \
|
||||
&& curl -fsSL "https://go.dev/dl/go${GO_VERSION}.linux-${GOARCH}.tar.gz" -o /tmp/go.tgz \
|
||||
&& tar -C /usr/local -xzf /tmp/go.tgz \
|
||||
&& rm /tmp/go.tgz
|
||||
ENV PATH=/usr/local/go/bin:/root/go/bin:$PATH \
|
||||
GOPATH=/root/go
|
||||
|
||||
# ============================================================
|
||||
# 4. Microsoft .NET 8 SDK (Microsoft apt repo for bookworm/12)
|
||||
# ============================================================
|
||||
RUN curl -fsSL https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor -o /usr/share/keyrings/microsoft.gpg \
|
||||
&& echo "deb [signed-by=/usr/share/keyrings/microsoft.gpg] https://packages.microsoft.com/debian/12/prod bookworm main" > /etc/apt/sources.list.d/microsoft.list \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y --no-install-recommends dotnet-sdk-8.0 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
ENV DOTNET_CLI_TELEMETRY_OPTOUT=1 \
|
||||
DOTNET_NOLOGO=1
|
||||
|
||||
# ============================================================
|
||||
# 5. Swift (Ubuntu 22.04 tarball — works on Debian bookworm
|
||||
# because bookworm ships the right libicu/libstdc++ baseline)
|
||||
# ============================================================
|
||||
RUN ARCH="$(dpkg --print-architecture)" \
|
||||
&& SWIFT_PLAT="${SWIFT_PLATFORM}" \
|
||||
&& case "$ARCH" in \
|
||||
amd64) SWIFT_TARBALL_NAME="swift-${SWIFT_VERSION}-RELEASE-${SWIFT_PLAT}" ;; \
|
||||
arm64) SWIFT_TARBALL_NAME="swift-${SWIFT_VERSION}-RELEASE-${SWIFT_PLAT}-aarch64" ;; \
|
||||
*) echo "Unsupported arch $ARCH for Swift" && exit 1 ;; \
|
||||
esac \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y --no-install-recommends libpython3-dev libxml2-dev \
|
||||
libcurl4-openssl-dev libedit-dev libsqlite3-dev libtinfo-dev libncurses-dev \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& curl -fsSL "https://download.swift.org/swift-${SWIFT_VERSION}-release/${SWIFT_PLAT//./}/swift-${SWIFT_VERSION}-RELEASE/${SWIFT_TARBALL_NAME}.tar.gz" -o /tmp/swift.tgz \
|
||||
&& mkdir -p /opt/swift \
|
||||
&& tar -xzf /tmp/swift.tgz -C /opt/swift --strip-components=1 \
|
||||
&& rm /tmp/swift.tgz
|
||||
ENV PATH=/opt/swift/usr/bin:$PATH
|
||||
|
||||
# ============================================================
|
||||
# 6. Kotlin compiler (direct download from GitHub release)
|
||||
# ============================================================
|
||||
RUN curl -fsSL "https://github.com/JetBrains/kotlin/releases/download/v${KOTLIN_VERSION}/kotlin-compiler-${KOTLIN_VERSION}.zip" -o /tmp/kotlin.zip \
|
||||
&& unzip -q /tmp/kotlin.zip -d /opt \
|
||||
&& mv /opt/kotlinc /opt/kotlin \
|
||||
&& rm /tmp/kotlin.zip
|
||||
ENV PATH=/opt/kotlin/bin:$PATH
|
||||
|
||||
# ============================================================
|
||||
# 7. JDK 21 alongside JDK 17 (Eclipse Temurin via apt)
|
||||
# ============================================================
|
||||
RUN mkdir -p /etc/apt/keyrings \
|
||||
&& curl -fsSL https://packages.adoptium.net/artifactory/api/gpg/key/public | gpg --dearmor -o /etc/apt/keyrings/adoptium.gpg \
|
||||
&& echo "deb [signed-by=/etc/apt/keyrings/adoptium.gpg] https://packages.adoptium.net/artifactory/deb bookworm main" > /etc/apt/sources.list.d/adoptium.list \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y --no-install-recommends temurin-21-jdk \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
ENV JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 \
|
||||
JAVA_HOME_17=/usr/lib/jvm/java-17-openjdk-amd64 \
|
||||
JAVA_HOME_21=/usr/lib/jvm/temurin-21-jdk-amd64
|
||||
RUN update-alternatives --set java ${JAVA_HOME_17}/bin/java || true \
|
||||
&& update-alternatives --set javac ${JAVA_HOME_17}/bin/javac || true
|
||||
|
||||
# ============================================================
|
||||
# 8. Maven (apt) + Gradle (direct download — apt's gradle is ancient)
|
||||
# ============================================================
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends maven \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& curl -fsSL "https://services.gradle.org/distributions/gradle-${GRADLE_VERSION}-bin.zip" -o /tmp/gradle.zip \
|
||||
&& unzip -q /tmp/gradle.zip -d /opt \
|
||||
&& mv /opt/gradle-${GRADLE_VERSION} /opt/gradle \
|
||||
&& rm /tmp/gradle.zip
|
||||
ENV PATH=/opt/gradle/bin:$PATH
|
||||
|
||||
# ============================================================
|
||||
# 9. GitHub CLI (gh)
|
||||
# ============================================================
|
||||
RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \
|
||||
&& chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg \
|
||||
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" > /etc/apt/sources.list.d/github-cli.list \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y --no-install-recommends gh \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# ============================================================
|
||||
# 10. yq (Mike Farah, Go binary)
|
||||
# ============================================================
|
||||
RUN ARCH="$(dpkg --print-architecture)" \
|
||||
&& curl -fsSL "https://github.com/mikefarah/yq/releases/latest/download/yq_linux_${ARCH}" -o /usr/local/bin/yq \
|
||||
&& chmod +x /usr/local/bin/yq
|
||||
|
||||
# ============================================================
|
||||
# 11. shfmt (Go binary)
|
||||
# ============================================================
|
||||
RUN ARCH="$(dpkg --print-architecture)" \
|
||||
&& curl -fsSL "https://github.com/mvdan/sh/releases/latest/download/shfmt_v3.10.0_linux_${ARCH}" -o /usr/local/bin/shfmt \
|
||||
&& chmod +x /usr/local/bin/shfmt
|
||||
|
||||
# ============================================================
|
||||
# 12. Create non-root user `crafter` (uid 1000) with passwordless sudo
|
||||
# and prepare workspace / cache / data dirs
|
||||
# ============================================================
|
||||
RUN useradd -m -u 1000 -s /bin/bash crafter \
|
||||
&& echo "crafter ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/crafter \
|
||||
&& chmod 0440 /etc/sudoers.d/crafter \
|
||||
&& mkdir -p /workspace /caches/cargo /caches/maven /caches/gradle /caches/npm /caches/pip /caches/bun /data \
|
||||
&& chown -R crafter:crafter /workspace /caches /data
|
||||
|
||||
# ============================================================
|
||||
# 13. Switch to crafter for user-scoped installs
|
||||
# ============================================================
|
||||
USER crafter
|
||||
WORKDIR /home/crafter
|
||||
|
||||
# Cache env (point tools at the persisted cache dirs)
|
||||
ENV CARGO_HOME=/caches/cargo \
|
||||
RUSTUP_HOME=/home/crafter/.rustup \
|
||||
GRADLE_USER_HOME=/caches/gradle \
|
||||
MAVEN_OPTS="-Dmaven.repo.local=/caches/maven" \
|
||||
NPM_CONFIG_CACHE=/caches/npm \
|
||||
PIP_CACHE_DIR=/caches/pip \
|
||||
BUN_INSTALL=/home/crafter/.bun \
|
||||
PIPX_HOME=/home/crafter/.local/pipx \
|
||||
PIPX_BIN_DIR=/home/crafter/.local/bin
|
||||
|
||||
ENV PATH=/home/crafter/.local/bin:/caches/cargo/bin:/home/crafter/.bun/bin:$PATH
|
||||
|
||||
# ============================================================
|
||||
# 14. Rust (rustup, stable) + cargo-audit + cargo-deny
|
||||
# ============================================================
|
||||
RUN curl -fsSL https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal --no-modify-path \
|
||||
&& /caches/cargo/bin/rustup component add clippy rustfmt \
|
||||
&& /caches/cargo/bin/cargo install cargo-audit --locked \
|
||||
&& /caches/cargo/bin/cargo install cargo-deny --locked
|
||||
|
||||
# ============================================================
|
||||
# 15. Bun (curl install)
|
||||
# ============================================================
|
||||
RUN curl -fsSL https://bun.sh/install | bash
|
||||
|
||||
# ============================================================
|
||||
# 16. Python user tooling: pipx-managed CLI tools
|
||||
# ============================================================
|
||||
RUN python3 -m pip install --user --break-system-packages --no-cache-dir pipx \
|
||||
&& python3 -m pipx ensurepath \
|
||||
&& pipx install uv \
|
||||
&& pipx install ruff \
|
||||
&& pipx install mypy \
|
||||
&& pipx install pytest \
|
||||
&& pipx install pip-audit \
|
||||
&& pipx install semgrep
|
||||
|
||||
# ============================================================
|
||||
# 17. Go user tooling: govulncheck + staticcheck
|
||||
# ============================================================
|
||||
RUN go install golang.org/x/vuln/cmd/govulncheck@latest \
|
||||
&& go install honnef.co/go/tools/cmd/staticcheck@latest
|
||||
|
||||
# Make GOPATH bin discoverable for the crafter user
|
||||
ENV PATH=/home/crafter/go/bin:$PATH \
|
||||
GOPATH=/home/crafter/go
|
||||
|
||||
# ============================================================
|
||||
# 18. Ruby user tooling: bundler-audit, rubocop
|
||||
# ============================================================
|
||||
RUN gem install --user-install --no-document bundler-audit rubocop || \
|
||||
sudo gem install --no-document bundler-audit rubocop
|
||||
ENV PATH=/home/crafter/.local/share/gem/ruby/3.1.0/bin:$PATH
|
||||
|
||||
# ============================================================
|
||||
# 19. PHP user tooling: phpstan, phpunit (composer global)
|
||||
# ============================================================
|
||||
ENV COMPOSER_HOME=/home/crafter/.composer
|
||||
RUN composer global require --no-interaction phpstan/phpstan phpunit/phpunit
|
||||
ENV PATH=/home/crafter/.composer/vendor/bin:$PATH
|
||||
|
||||
# ============================================================
|
||||
# 20. Smoke script — bake in
|
||||
# ============================================================
|
||||
COPY --chown=crafter:crafter smoke.sh /usr/local/bin/smoke.sh
|
||||
USER root
|
||||
RUN chmod +x /usr/local/bin/smoke.sh
|
||||
USER crafter
|
||||
|
||||
# ============================================================
|
||||
# 21. Final ENV / WORKDIR / CMD
|
||||
# ============================================================
|
||||
WORKDIR /workspace
|
||||
CMD ["/bin/bash"]
|
||||
87
README.md
87
README.md
|
|
@ -1,3 +1,88 @@
|
|||
# crafting-table
|
||||
|
||||
Polyglot dev/build/audit container with autonomous patch loop + email digest. Recipes for every Sulkta repo, structured findings back to clawdforge.
|
||||
Polyglot dev/build/audit container — the build farm for the Sulkta ecosystem.
|
||||
|
||||
## What this is
|
||||
|
||||
A single Docker container with every toolchain we work with, used as a
|
||||
reliable place to compile / test / audit any Sulkta repo regardless of
|
||||
where the caller is — agents, Claude sessions, ad-hoc curl, scheduled cron.
|
||||
|
||||
Eventual surface (v0.1 full): HTTP API + MCP server + project registry +
|
||||
job runner + structured findings + email digest + autonomous patch loop
|
||||
through clawdforge.
|
||||
|
||||
Spec: `Sulkta-Coop/openclaw-workspace/memory/spec-crafting-table.md` (LAN-only).
|
||||
|
||||
## Status — v0.1 step 1 of 10
|
||||
|
||||
- [x] Step 1: Dockerfile + per-language smoke
|
||||
- [ ] Step 2: SQLite ledger + project registry
|
||||
- [ ] Step 3: HTTP API skeleton (FastAPI, port 8810)
|
||||
- [ ] Step 4: Job runner core (asyncio worker pool)
|
||||
- [ ] Step 5: Per-language parsers (Rust / Python / Go / TS first)
|
||||
- [ ] Step 6: Findings extraction + storage
|
||||
- [ ] Step 7: MCP server (stdio JSON-RPC, 8 tools)
|
||||
- [ ] Step 8: Email digest scheduler
|
||||
- [ ] Step 9: Autonomous patch loop (clawdforge integration)
|
||||
- [ ] Step 10: Production recipes — clawdforge, cauldron, tradecraft
|
||||
|
||||
## Toolchains in v0.1
|
||||
|
||||
| Lang | Versions / extras |
|
||||
|----------|--------------------------------------------------------------------|
|
||||
| Python | 3.11 (Debian default) + uv, pipx, pip-audit, ruff, mypy, pytest, semgrep |
|
||||
| Node | 22.11.0 LTS + npm, pnpm, tsx, eslint, typescript |
|
||||
| Bun | latest (rolling) |
|
||||
| Go | 1.22.10 + govulncheck, staticcheck |
|
||||
| Rust | stable (rustup) + clippy, rustfmt, cargo-audit, cargo-deny |
|
||||
| Ruby | 3.1 (Debian default) + bundler, bundler-audit, rubocop |
|
||||
| PHP | 8.2 (Debian default) + composer, phpstan, phpunit |
|
||||
| JDK | 17 (default) + 21 (Temurin, alongside via `JAVA_HOME_21`) |
|
||||
| Maven | 3.x (Debian) |
|
||||
| Gradle | 8.10 |
|
||||
| .NET | 8.0 SDK |
|
||||
| Swift | 5.9.2 (Ubuntu 22.04 tarball — works on Debian bookworm) |
|
||||
| Kotlin | 1.9.25 (compiler) |
|
||||
| C/C++ | clang + lld + cmake + ninja + valgrind |
|
||||
| Bash | bash + shellcheck + bats + shfmt |
|
||||
| Generic | git, jq, yq, ripgrep, fd, gh-cli, curl, wget |
|
||||
|
||||
## Build + smoke
|
||||
|
||||
```bash
|
||||
docker network inspect sulkta >/dev/null 2>&1 || docker network create sulkta
|
||||
docker compose build
|
||||
docker compose up
|
||||
# expect: "=== ALL TOOLCHAINS GREEN ===" then exit 0
|
||||
```
|
||||
|
||||
The smoke compiles + runs a hello-world in every language. If it exits 0,
|
||||
the image is good.
|
||||
|
||||
## Image notes
|
||||
|
||||
- Base: `debian:bookworm-slim`. Swift uses the upstream Ubuntu 22.04 tarball
|
||||
which links against bookworm's libicu/libstdc++ baseline.
|
||||
- Runs as non-root user `crafter` (uid 1000) with passwordless sudo.
|
||||
- Volume mount points: `/workspace`, `/caches/{cargo,maven,gradle,npm,pip,bun}`,
|
||||
`/data`. Compose binds these to named volumes so they survive `compose down`.
|
||||
- Network: external `sulkta` bridge (same one clawdforge + cauldron use).
|
||||
Create with `docker network create sulkta` if missing.
|
||||
- Image size baseline is large (8-15 GB expected). Per spec: that's fine.
|
||||
|
||||
## Layout
|
||||
|
||||
```
|
||||
.
|
||||
├── Dockerfile # monolith image with all toolchains
|
||||
├── compose.yml # build + run-smoke wiring
|
||||
├── smoke.sh # per-language hello-world test, baked in at /usr/local/bin/smoke.sh
|
||||
├── README.md
|
||||
├── LICENSE # MIT
|
||||
└── .gitignore
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
|
|
|||
28
compose.yml
Normal file
28
compose.yml
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
# crafting-table v0.1 — step 1 compose.
|
||||
#
|
||||
# Builds the monolith image and runs the smoke test once.
|
||||
# In step 2+ the `command:` is replaced with the API server entrypoint.
|
||||
name: crafting-table
|
||||
|
||||
services:
|
||||
crafting-table:
|
||||
build: .
|
||||
image: crafting-table:local
|
||||
container_name: crafting-table
|
||||
command: ["/usr/local/bin/smoke.sh"]
|
||||
user: crafter
|
||||
working_dir: /workspace
|
||||
volumes:
|
||||
- workspace:/workspace
|
||||
- caches:/caches
|
||||
- data:/data
|
||||
networks: [sulkta]
|
||||
|
||||
volumes:
|
||||
workspace:
|
||||
caches:
|
||||
data:
|
||||
|
||||
networks:
|
||||
sulkta:
|
||||
external: true
|
||||
194
smoke.sh
Executable file
194
smoke.sh
Executable file
|
|
@ -0,0 +1,194 @@
|
|||
#!/bin/bash
|
||||
# crafting-table v0.1 step 1 — toolchain smoke test.
|
||||
#
|
||||
# Runs INSIDE the built image; prints `--version` and a hello-world for
|
||||
# every advertised toolchain. Exits 0 only if every block succeeds.
|
||||
#
|
||||
# Spec: memory/spec-crafting-table.md (toolchain matrix)
|
||||
|
||||
set -eo pipefail
|
||||
|
||||
echo "=== crafting-table smoke ==="
|
||||
echo "user: $(id)"
|
||||
echo "pwd: $(pwd)"
|
||||
echo
|
||||
|
||||
echo "--- python"
|
||||
python3 --version
|
||||
python3 -c "print('hello from python')"
|
||||
uv --version
|
||||
ruff --version
|
||||
mypy --version
|
||||
pytest --version
|
||||
pip-audit --version
|
||||
semgrep --version
|
||||
echo
|
||||
|
||||
echo "--- node"
|
||||
node --version
|
||||
node -e "console.log('hello from node')"
|
||||
npm --version
|
||||
pnpm --version
|
||||
tsx --version || true
|
||||
echo
|
||||
|
||||
echo "--- bun"
|
||||
bun --version
|
||||
bun -e "console.log('hello from bun')"
|
||||
echo
|
||||
|
||||
echo "--- go"
|
||||
go version
|
||||
mkdir -p /tmp/smoke-go && cd /tmp/smoke-go && go mod init smoke 2>/dev/null || true
|
||||
cat >main.go <<'EOF'
|
||||
package main
|
||||
|
||||
func main() { println("hello from go") }
|
||||
EOF
|
||||
go run main.go
|
||||
cd / && rm -rf /tmp/smoke-go
|
||||
govulncheck -version 2>&1 | head -2 || true
|
||||
staticcheck -version
|
||||
echo
|
||||
|
||||
echo "--- rust"
|
||||
rustc --version
|
||||
cargo --version
|
||||
cargo audit --version
|
||||
cargo deny --version
|
||||
cat >/tmp/smoke.rs <<'EOF'
|
||||
fn main() { println!("hello from rust"); }
|
||||
EOF
|
||||
rustc /tmp/smoke.rs -o /tmp/smoke && /tmp/smoke
|
||||
rm /tmp/smoke /tmp/smoke.rs
|
||||
echo
|
||||
|
||||
echo "--- ruby"
|
||||
ruby --version
|
||||
ruby -e "puts 'hello from ruby'"
|
||||
bundler --version
|
||||
bundle-audit version 2>&1 | head -1 || true
|
||||
rubocop --version
|
||||
echo
|
||||
|
||||
echo "--- php"
|
||||
php --version | head -1
|
||||
php -r "echo 'hello from php', PHP_EOL;"
|
||||
composer --version
|
||||
phpstan --version 2>&1 | head -1
|
||||
phpunit --version | head -1
|
||||
echo
|
||||
|
||||
echo "--- jdk 17 (default)"
|
||||
java -version 2>&1 | head -1
|
||||
javac -version
|
||||
cat >/tmp/Smoke.java <<'EOF'
|
||||
public class Smoke { public static void main(String[] a){ System.out.println("hello from java 17"); } }
|
||||
EOF
|
||||
javac /tmp/Smoke.java -d /tmp && java -cp /tmp Smoke
|
||||
rm /tmp/Smoke.java /tmp/Smoke.class
|
||||
echo
|
||||
|
||||
echo "--- jdk 21 (alongside)"
|
||||
"$JAVA_HOME_21/bin/java" -version 2>&1 | head -1
|
||||
"$JAVA_HOME_21/bin/javac" -version
|
||||
cat >/tmp/Smoke21.java <<'EOF'
|
||||
public class Smoke21 { public static void main(String[] a){ System.out.println("hello from java 21"); } }
|
||||
EOF
|
||||
"$JAVA_HOME_21/bin/javac" /tmp/Smoke21.java -d /tmp && "$JAVA_HOME_21/bin/java" -cp /tmp Smoke21
|
||||
rm /tmp/Smoke21.java /tmp/Smoke21.class
|
||||
echo
|
||||
|
||||
echo "--- maven"
|
||||
mvn -version | head -1
|
||||
echo
|
||||
|
||||
echo "--- gradle"
|
||||
gradle -version 2>&1 | grep -E '^Gradle ' | head -1
|
||||
echo
|
||||
|
||||
echo "--- kotlin"
|
||||
kotlinc -version 2>&1 | head -1
|
||||
cat >/tmp/smoke.kt <<'EOF'
|
||||
fun main() { println("hello from kotlin") }
|
||||
EOF
|
||||
kotlinc /tmp/smoke.kt -include-runtime -d /tmp/smoke.jar 2>/dev/null
|
||||
java -jar /tmp/smoke.jar
|
||||
rm /tmp/smoke.kt /tmp/smoke.jar
|
||||
echo
|
||||
|
||||
echo "--- .net 8"
|
||||
dotnet --version
|
||||
mkdir -p /tmp/smoke-dotnet && cd /tmp/smoke-dotnet
|
||||
dotnet new console -o app -n Smoke --force >/dev/null
|
||||
cd app
|
||||
# Suppress NuGet first-run noise; just run the hello-world.
|
||||
dotnet run --nologo 2>&1 | tail -3
|
||||
cd / && rm -rf /tmp/smoke-dotnet
|
||||
echo
|
||||
|
||||
echo "--- swift"
|
||||
swift --version 2>&1 | head -1
|
||||
cat >/tmp/smoke.swift <<'EOF'
|
||||
print("hello from swift")
|
||||
EOF
|
||||
swift /tmp/smoke.swift
|
||||
rm /tmp/smoke.swift
|
||||
echo
|
||||
|
||||
echo "--- clang/c"
|
||||
clang --version | head -1
|
||||
cat >/tmp/smoke.c <<'EOF'
|
||||
#include <stdio.h>
|
||||
int main(void){puts("hello from c");return 0;}
|
||||
EOF
|
||||
clang /tmp/smoke.c -o /tmp/smoke-c && /tmp/smoke-c
|
||||
rm /tmp/smoke.c /tmp/smoke-c
|
||||
echo
|
||||
|
||||
echo "--- clang++/cpp"
|
||||
clang++ --version | head -1
|
||||
cat >/tmp/smoke.cpp <<'EOF'
|
||||
#include <iostream>
|
||||
int main(){std::cout<<"hello from cpp"<<std::endl;return 0;}
|
||||
EOF
|
||||
clang++ -std=c++17 /tmp/smoke.cpp -o /tmp/smoke-cpp && /tmp/smoke-cpp
|
||||
rm /tmp/smoke.cpp /tmp/smoke-cpp
|
||||
echo
|
||||
|
||||
echo "--- cmake + ninja"
|
||||
cmake --version | head -1
|
||||
ninja --version
|
||||
echo
|
||||
|
||||
echo "--- valgrind"
|
||||
valgrind --version
|
||||
echo
|
||||
|
||||
echo "--- bash + shellcheck + bats + shfmt"
|
||||
bash --version | head -1
|
||||
shellcheck --version | head -2 | tail -1
|
||||
bats --version
|
||||
shfmt --version
|
||||
cat >/tmp/smoke.sh <<'EOF'
|
||||
#!/bin/bash
|
||||
echo "hello from bash"
|
||||
EOF
|
||||
chmod +x /tmp/smoke.sh
|
||||
bash /tmp/smoke.sh
|
||||
shellcheck /tmp/smoke.sh && echo "shellcheck clean"
|
||||
rm /tmp/smoke.sh
|
||||
echo
|
||||
|
||||
echo "--- generic tools"
|
||||
git --version
|
||||
jq --version
|
||||
rg --version | head -1
|
||||
fd --version
|
||||
gh --version | head -1
|
||||
yq --version
|
||||
curl --version | head -1
|
||||
wget --version | head -1
|
||||
echo
|
||||
|
||||
echo "=== ALL TOOLCHAINS GREEN ==="
|
||||
Loading…
Add table
Add a link
Reference in a new issue