diff --git a/.claude-test.sh b/.claude-test.sh new file mode 100755 index 0000000..de1ae73 --- /dev/null +++ b/.claude-test.sh @@ -0,0 +1,28 @@ +#!/bin/sh +set -x +echo "== rustc =="; rustc --version +echo "== cargo =="; cargo --version +echo "== rustfmt =="; rustfmt --version +echo "== clippy =="; cargo clippy --version +echo "== just =="; just --version +echo "== sccache =="; sccache --version +echo "== cargo-nextest =="; cargo nextest --version +echo "== cargo-audit =="; cargo audit --version +echo "== cargo-binstall =="; cargo binstall --version +echo "== targets installed =="; rustup target list --installed +echo "== nightly + miri =="; rustup run nightly rustc --version; cargo +nightly miri --version +echo "== cross compile aarch64-musl hello world ==" +mkdir -p /tmp/hello && cd /tmp/hello +cat > Cargo.toml <<'EOF' +[package] +name = "hello" +version = "0.1.0" +edition = "2021" +EOF +mkdir -p src +echo 'fn main() { println!("hello cross"); }' > src/main.rs +cargo build --release --target aarch64-unknown-linux-musl +file target/aarch64-unknown-linux-musl/release/hello +echo "== rust-workflow help ==" +rust-workflow --help 2>&1 | head -20 || echo "rust-workflow not found or errored" +echo "== ALL DONE ==" diff --git a/Dockerfile b/Dockerfile index 0e1f0ed..c8353bd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -82,15 +82,19 @@ ENV CARGO_INSTALL_ROOT=/rust-tools # Install all Rust tools for the target arch — prebuilt binaries ONLY, no source fallback. # Tools without prebuilts for the target arch are silently skipped (exit 0). # This cuts arm64 build time from hours to minutes. +# One `cargo binstall` invocation PER tool — cargo-binstall resolves its whole +# argument list before installing anything, so batching tools in one invocation +# means a single tool with no prebuilt (--disable-strategies compile forbids the +# cargo-install fallback) aborts the entire batch and silently installs nothing, +# even for tools that resolved fine. Isolating each tool's `|| true` is required +# for "skip what's missing, keep what's available" to actually work. RUN --mount=type=cache,id=cargo-registry-native,sharing=shared,target=/usr/local/cargo/registry \ --mount=type=cache,id=cargo-git-native,sharing=locked,target=/usr/local/cargo/git \ set -o pipefail; \ RUST_TARGET="$(cat /tmp/rust-target)"; \ # Disable telemetry prompt — required for non-interactive builds mkdir -p /usr/local/cargo && echo 'disable-telemetry = true' > /usr/local/cargo/binstall.toml; \ - BINSTALL="cargo binstall -y --disable-strategies compile --target ${RUST_TARGET}"; \ - # Core tools — most have prebuilts for both amd64 and arm64 - $BINSTALL \ + for tool in \ cargo-binstall \ cargo-edit \ cargo-watch \ @@ -120,9 +124,7 @@ RUN --mount=type=cache,id=cargo-registry-native,sharing=shared,target=/usr/local cargo-sort \ cargo-hack \ dprint \ - grcov || true; \ - # Secondary tools — may or may not have prebuilts - $BINSTALL \ + grcov \ cargo-llvm-cov \ cargo-tarpaulin \ wasm-pack \ @@ -151,7 +153,10 @@ RUN --mount=type=cache,id=cargo-registry-native,sharing=shared,target=/usr/local flamegraph \ probe-rs \ sqlx-cli \ - sea-orm-cli || true + sea-orm-cli; \ + do \ + cargo binstall -y --disable-strategies compile --target "${RUST_TARGET}" "${tool}" || true; \ + done FROM ${PULL_URL}:${DISTRO_VERSION} AS build ARG TZ diff --git a/rootfs/usr/local/bin/entrypoint.sh b/rootfs/usr/local/bin/entrypoint.sh index 95762bc..175ac04 100755 --- a/rootfs/usr/local/bin/entrypoint.sh +++ b/rootfs/usr/local/bin/entrypoint.sh @@ -480,7 +480,11 @@ SKIP_SERVICE_START="no" [ "$2" = "init" ] && SKIP_SERVICE_START="yes" && CONTAINER_INIT="yes" # - - - - - - - - - - - - - - - - - - - - - - - - - # Start all services if no pidfile and not skipping -if [ "$START_SERVICES" = "yes" ] || [ -z "$1" ]; then +# Start all services only when no command was given at all — an explicit +# command (exec, shell, tail, or an arbitrary program) must reach the case +# statement below instead of being swallowed into daemon/monitor mode, even +# on a first run where START_SERVICES is force-set to "yes" +if [ -z "$1" ]; then if [ "$SKIP_SERVICE_START" = "no" ]; then [ "$1" = "start" ] && shift 1 [ "$1" = "all" ] && shift 1 @@ -622,11 +626,25 @@ procs) exit $? ;; # Launch shell -*/bin/sh | */bin/bash | bash | sh | shell) - shift 1 +# Launch shell — do not shift here: "sh -c 'cmd'" / "bash -c 'cmd'" needs the +# interpreter name kept as argv[0] for __exec_command's `exec "$@"` to work; +# shifting it away turned "sh -c 'cmd'" into `exec -c cmd` (command not found) +*/bin/sh | */bin/bash | bash | sh) __exec_command "$@" exit $? ;; +# "shell" is a keyword, not a real interpreter — it must be shifted away, and +# any remaining args need "sh" prepended so __exec_command's `exec "$@"` gets +# a real interpreter instead of trying to exec "-c" as a program +shell) + shift 1 + if [ $# -eq 0 ]; then + __exec_command + else + __exec_command sh "$@" + fi + exit $? + ;; # execute commands exec) shift 1