#!/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 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 int main(){std::cout<<"hello from cpp"</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 ==="