repos
/ taproot main

taproot

mirror

The dotfiles and containers I use to set up a machine for development, one container to write code in and another that runs a local coding model on the desktop's GPU.

alpine-linuxcaddydevelopment-environmentdockerdotfileshomelabinfrastructureneovimserver-configurationtmux

2.5 KB · 66 lines · Bash Raw History
 1#!/bin/sh
 2#
 3# webdev-exec.sh
 4#
 5# Run a build tool inside the webdev container against this same source tree.
 6#
 7# aiagent has no toolchain of its own, so the docker exec lives here instead,
 8# symlinked to `go`, `gofmt` and `bun` on PATH. The agent types `go build ./...`
 9# and never has to know another container was involved.
10#
11# Both containers mount bythewood-code and both run as UID 1001, so the file
12# webdev writes is the file aiagent reads. Only the mount point differs, and
13# translating it is what this script is for.
14#
15# Invoked by its own name it takes the command as the first argument:
16#     webdev-exec make check
17#
18
19set -eu
20
21CONTAINER=bythewood-webdev
22AI_ROOT=/home/ai/code
23DEV_ROOT=/home/dev/code
24
25# Called through one of the symlinks, argv[0] is the tool. Matching the symlink
26# names rather than this script's own name means renaming the script cannot
27# quietly turn every invocation into a wrong one.
28cmd=$(basename "$0")
29case "$cmd" in
30    go|gofmt|bun) ;;
31    *)
32        if [ $# -eq 0 ]; then
33            echo "usage: webdev-exec <command> [args...]" >&2
34            exit 2
35        fi
36        cmd=$1
37        shift ;;
38esac
39
40# Checked here rather than by letting `docker exec` fail, so a missing container
41# is never reported as a compile error. The agent acts on these messages.
42state=$(sudo docker inspect -f '{{.State.Running}}' "$CONTAINER" 2>/dev/null || echo missing)
43if [ "$state" != "true" ]; then
44    echo "webdev-exec: cannot run '$cmd': the $CONTAINER container is not running." >&2
45    echo "webdev-exec: this container has no toolchain of its own; it borrows webdev's." >&2
46    echo "webdev-exec: ask the human to start it (\`make up\` from a taproot" >&2
47    echo "webdev-exec: clone, or \`docker start $CONTAINER\`), or carry on with" >&2
48    echo "webdev-exec: work that does not need to build. Do not claim the code builds." >&2
49    exit 127
50fi
51
52# The shared volume is the only path both containers can see. Anywhere else and
53# webdev would quietly build the wrong tree, or nothing at all.
54dir=$(pwd)
55case "$dir" in
56    "$AI_ROOT"|"$AI_ROOT"/*) dir="$DEV_ROOT${dir#$AI_ROOT}" ;;
57    *)
58        echo "webdev-exec: cannot run '$cmd' from $dir." >&2
59        echo "webdev-exec: only $AI_ROOT and below is shared with webdev. cd there first." >&2
60        exit 127 ;;
61esac
62
63# No --tty, so tools emit plain text instead of progress bars and cursor
64# escapes. The exec inherits the image's ENV, so Go and bun are on PATH there.
65exec sudo docker exec --workdir "$dir" --user dev "$CONTAINER" "$cmd" "$@"