(gist title)
This gist assumes the following directory structure:
- foobar-ws/
- bar/
- bar.go
- go.mod
- foo/
- foo.go
- go.mod
- foobar/
- deployments/foobar/
- Dockerfile
- go.mod
- go.sum
- main.go
- Makefile
- deployments/foobar/
- bar/
(gist title)
This gist assumes the following directory structure:
FROM scratch as empty | |
FROM golang:1.20-alpine AS builder | |
ARG WSDISKPATHS | |
ARG MOD1=./ | |
ARG MOD2=./ | |
ARG MOD3=./ | |
ARG MOD4=./ | |
ARG MOD5=./ | |
ARG MOD6=./ | |
ARG MOD7=./ | |
ARG MOD8=./ | |
ARG MOD9=./ | |
WORKDIR /ws | |
# Copy the additionally used modules into the soon-to-be workspace. | |
COPY --from=bctx1 . ${MOD1} | |
COPY --from=bctx2 . ${MOD2} | |
COPY --from=bctx3 . ${MOD3} | |
COPY --from=bctx4 . ${MOD4} | |
COPY --from=bctx5 . ${MOD5} | |
COPY --from=bctx6 . ${MOD6} | |
COPY --from=bctx7 . ${MOD7} | |
COPY --from=bctx8 . ${MOD8} | |
COPY --from=bctx9 . ${MOD9} | |
# Finally copy in the main module containing a main package to be build. | |
WORKDIR /ws/foobar | |
COPY go.mod go.sum ./ | |
RUN go mod download | |
COPY *.go ./ | |
# Establish the Go workspace | |
WORKDIR /ws | |
RUN go work init ${WSDISKPATHS} | |
RUN go build -v -o /foobar ./foobar |
MAINUSE:=./foobar | |
EMPTYCONTEXT:=.emptyctx | |
NUMCONTEXTS:=9 | |
SHELL:=/bin/bash | |
build: | |
@# find out if we are in workspace mode -- and it we are, then the list of | |
@# modules actually used. | |
@mkdir -p $(EMPTYCONTEXT); \ | |
trap 'rm -rf -- "$(EMPTYCONTEXT)"' EXIT; \ | |
contexts=(); \ | |
workspace_details=$$(go work edit --json); \ | |
if [[ $${workspace_details} ]]; then \ | |
goworkdir=$$(dirname $$(go env GOWORK)); \ | |
echo "found workspace" $${goworkdir}; \ | |
diskpaths=$$(echo $${workspace_details} | jq --raw-output '.Use | .[]? | .DiskPath'); \ | |
echo "modules used in workspace:" $${diskpaths}; \ | |
while IFS= read -r module; do \ | |
if [[ "$${module}" == "$(MAINUSE)" ]]; then \ | |
echo " 🏠" $${module}; \ | |
else \ | |
relcontext=$$(realpath --relative-to="." $${goworkdir}/$${module}); \ | |
contexts+=( $${relcontext} ); \ | |
echo " 🧩" $${module} "» 📁" $${relcontext}; \ | |
fi \ | |
done <<< $${diskpaths}; \ | |
else \ | |
diskpaths="$(MAINUSE)"; \ | |
fi; \ | |
buildctxargs=(); \ | |
buildargs=(); \ | |
ctxno=1; \ | |
for ctx in "$${contexts[@]}"; do \ | |
buildctxargs+=( "--build-context=bctx$${ctxno}=$${ctx}" ); \ | |
buildargs+=( "--build-arg=MOD$${ctxno}=./$$(basename ./$${ctx})/" ); \ | |
((ctxno=ctxno+1)); \ | |
done; \ | |
for ((;ctxno<=$(NUMCONTEXTS);ctxno++)); do \ | |
buildctxargs+=( "--build-context=bctx$${ctxno}=$(EMPTYCONTEXT)" ); \ | |
done; \ | |
echo "args:" $${buildctxargs[*]} $${buildargs[*]}; \ | |
echo "build inside:" $${CWD}; \ | |
docker build \ | |
-f ./deployments/foobar/Dockerfile \ | |
$${buildargs[@]} \ | |
$${buildctxargs[@]} \ | |
--build-arg=WSDISKPATHS="$$(echo $${diskpaths})" \ | |
. |