diff --git a/.gitignore b/.gitignore index cf31cac..34e8ca3 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ test test.yml .DS_STORE .vscode +.idea diff --git a/go.work b/go.work deleted file mode 100644 index 750df41..0000000 --- a/go.work +++ /dev/null @@ -1,6 +0,0 @@ -go 1.18 - -use ( - ./template/golang-http - ./template/golang-middleware -) diff --git a/template/golang-http/.dockerignore b/template/golang-http/.dockerignore index 32a061f..ba2e1ae 100644 --- a/template/golang-http/.dockerignore +++ b/template/golang-http/.dockerignore @@ -1 +1 @@ -function/vendor/github.com/openfaas/go-function-sdk +function/vendor/github.com/openfaas-incubator/go-function-sdk diff --git a/template/golang-http/Dockerfile b/template/golang-http/Dockerfile index 9aea94c..fb02dc7 100644 --- a/template/golang-http/Dockerfile +++ b/template/golang-http/Dockerfile @@ -6,12 +6,11 @@ ARG BUILDPLATFORM ARG TARGETOS ARG TARGETARCH -RUN apk --no-cache add git +RUN apk --no-cache add git build-base COPY --from=watchdog /fwatchdog /usr/bin/fwatchdog RUN chmod +x /usr/bin/fwatchdog - RUN mkdir -p /go/src/handler WORKDIR /go/src/handler COPY . . @@ -20,8 +19,9 @@ ARG GO111MODULE="on" ARG GOPROXY="" ARG GOFLAGS="" ARG CGO_ENABLED=0 -ENV CGO_ENABLED=${CGO_ENABLED} +# Lift the vendor and go.mod to the main package, cleanup any relative references +RUN sh modules-cleanup.sh # Run a gofmt and exclude all vendored code. RUN test -z "$(gofmt -l $(find . -type f -name '*.go' -not -path "./vendor/*" -not -path "./function/vendor/*"))" || { echo "Run \"gofmt -s -w\" on your Golang code"; exit 1; } @@ -32,7 +32,7 @@ RUN mkdir -p /go/src/handler/function/static RUN GOOS=${TARGETOS} GOARCH=${TARGETARCH} go test ./... -cover WORKDIR /go/src/handler -RUN CGO_ENABLED=${CGO_ENABLED} GOOS=${TARGETOS} GOARCH=${TARGETARCH} \ +RUN GOOS=${TARGETOS} GOARCH=${TARGETARCH} \ go build --ldflags "-s -w" -a -installsuffix cgo -o handler . FROM --platform=${TARGETPLATFORM:-linux/amd64} alpine:3.16.2 as ship diff --git a/template/golang-http/go.mod b/template/golang-http/go.mod index c477c58..9d846a9 100644 --- a/template/golang-http/go.mod +++ b/template/golang-http/go.mod @@ -2,4 +2,8 @@ module handler go 1.18 -require github.com/openfaas/templates-sdk/go-http v0.0.0-20220408082716-5981c545cb03 +replace handler/function => ./function + +require ( + github.com/openfaas/templates-sdk v0.0.0-20200723092016-0ebf61253625 +) diff --git a/template/golang-http/go.sum b/template/golang-http/go.sum index 1725677..80dafb4 100644 --- a/template/golang-http/go.sum +++ b/template/golang-http/go.sum @@ -1,2 +1,2 @@ -github.com/openfaas/templates-sdk/go-http v0.0.0-20220408082716-5981c545cb03 h1:wMIW4ddCuogcuXcFO77BPSMI33s3QTXqLTOHY6mLqFw= -github.com/openfaas/templates-sdk/go-http v0.0.0-20220408082716-5981c545cb03/go.mod h1:2vlqdjIdqUjZphguuCAjoMz6QRPm2O8UT0TaAjd39S8= +github.com/openfaas/templates-sdk v0.0.0-20200723092016-0ebf61253625 h1:6JSt10GDCOw0F67bWnqZ6AYg92pbqCcchTu181aT1w0= +github.com/openfaas/templates-sdk v0.0.0-20200723092016-0ebf61253625/go.mod h1:JWcVHdzlHcR7nLuaDL88Mz68wOqDvOn0CLO6t27OMhk= diff --git a/template/golang-http/go.work b/template/golang-http/go.work deleted file mode 100644 index 8f6f165..0000000 --- a/template/golang-http/go.work +++ /dev/null @@ -1,6 +0,0 @@ -go 1.18 - -use ( - . - ./function -) diff --git a/template/golang-http/modules-cleanup.sh b/template/golang-http/modules-cleanup.sh new file mode 100644 index 0000000..be33886 --- /dev/null +++ b/template/golang-http/modules-cleanup.sh @@ -0,0 +1,157 @@ +#!/usr/bin/env sh + +set -e + +GO111MODULE=$(go env GO111MODULE) + +# move_vendor will copy the function's vendor folder, +# if it exists. +move_vendor() { + if [ ! -d ./function/vendor ]; then + echo "vendor not found" + return + fi + + echo "moving function vendor" + mv -f ./function/vendor . +} + +# cleanup_gomod will move the function's go module +cleanup_gomod() { + + # Nothing to do when modules is explicitly off + # the z prefix protects against any SH wonkiness + # see https://stackoverflow.com/a/18264223 + if [ "z$GO111MODULE" = "zoff" ]; then + echo "modules disabled, skipping go.mod cleanup" + return + fi + + if [ ! -f ./function/go.mod ]; then + echo "module not initialized, skipping go.mod cleanup" + return + fi + + echo "cleaning up go.mod" + + # Copy the user's go.mod + mv -f ./function/go.mod . + mv -f ./function/go.sum . + + # Clean up the go.mod + + # Cleanup any sub-module replacements. + # This requires modifying any replace that points to "./*", + # the user has will use this to reference sub-modules instead + # of sub-packages, which we cleanup below. + echo "cleanup local replace statements" + # 1. Replace references to the local folder with `./function` + sed -i 's/=> \.\//=> \.\/function\//' go.mod + + # Remove any references to the handler/function module. + # It is ok to just remove it because we will replace it later. + # + # Note that these references may or may not exist. We expect the + # go.mod to have a replace statement _if_ developer has subpackages + # in their handler. In this case they will need a this replace statement + # + # replace handler/function => ./ + # + # `go mod` will then add a line that looks like + # + # handler/function v0.0.0-00010101000000-000000000000 + # + # both of these lines need to be replaced, this grep selects everything + # _except_ those offending lines. + grep -v "\shandler/function" go.mod >gomod2 + mv gomod2 go.mod + + # Now update the go.mod + # + # 1. use replace so that imports of handler/function use the local code + # 2. we need to rename the module to handler because our main.go assumes + # this is the package name + go mod edit \ + -replace=handler/function=./function \ + -module handler + + if [ "$DEBUG" -eq 1 ]; then + cat go.mod + echo "" + fi +} + +# cleanup_vendor_modulestxt will cleanup the modules.txt file in the vendor folder +# this file is needed when modules are enabled and it must be in sync with the +# go.mod. To function correctly we need to modify the references to handler/function, +# if they exist. +cleanup_vendor_modulestxt() { + if [ ! -d ./vendor ]; then + echo "no vendor found, skipping modules.txt cleanup" + return + fi + + # Nothing to do when modules is explicitly off + # the z prefix protects against any SH wonkiness + # see https://stackoverflow.com/a/18264223 + if [ "z$GO111MODULE" = "zoff" ]; then + echo "modules disabled, skipping modules.txt cleanup" + return + fi + + echo "cleanup vendor/modules.txt" + + # just in case + touch "./vendor/modules.txt" + + # when vendored, we need to do similar edits to the vendor/modules.txt + # as we did to the go.mod + + # 1. we need to replace any possible copy of the handler code + rm -rf vendor/handler && + + # 2. in modules.txt, we remove existing references to the handler/function + # we reconstruct these in the last step + grep -v "\shandler/function" ./vendor/modules.txt >modulestext + mv modulestext ./vendor/modules.txt + + # 3. Handle any other local replacements. + # any replace that points to `./**` needs to be udpat echo "cleanup local replace statements" + sed -i 's/=> \.\//=> \.\/function\//' ./vendor/modules.txt + + # 4. To make the modules.txt consistent with the new go.mod, + # we add the mising replace to the vendor/modules.txt + echo "## explicit" >>./vendor/modules.txt + echo "# handler/function => ./function" >>./vendor/modules.txt + + if [ "$DEBUG" -eq 1 ]; then + cat ./vendor/modules.txt + echo "" + fi +} + +# has_local_replacement checks if the file contains local go module replacement +has_local_replacement() { + return "$(grep -E -c '=> \./\S+' "$1")" +} + +remove_workspaces() { + if [ -f ./function/go.work ]; then + echo "cleaning function workspace" + rm -f ./function/go.work + return + fi + + echo "no work spaces found" +} + +################ +# main +################ +remove_workspaces + +move_vendor + +cleanup_gomod + +cleanup_vendor_modulestxt diff --git a/template/golang-middleware/Dockerfile b/template/golang-middleware/Dockerfile index ac40b89..8d96a47 100644 --- a/template/golang-middleware/Dockerfile +++ b/template/golang-middleware/Dockerfile @@ -6,12 +6,11 @@ ARG BUILDPLATFORM ARG TARGETOS ARG TARGETARCH -RUN apk --no-cache add git +RUN apk --no-cache add git build-base COPY --from=watchdog /fwatchdog /usr/bin/fwatchdog RUN chmod +x /usr/bin/fwatchdog - RUN mkdir -p /go/src/handler WORKDIR /go/src/handler COPY . . @@ -20,7 +19,6 @@ ARG GO111MODULE="on" ARG GOPROXY="" ARG GOFLAGS="" ARG CGO_ENABLED=0 -ENV CGO_ENABLED=${CGO_ENABLED} # Run a gofmt and exclude all vendored code. RUN test -z "$(gofmt -l $(find . -type f -name '*.go' -not -path "./vendor/*" -not -path "./function/vendor/*"))" || { echo "Run \"gofmt -s -w\" on your Golang code"; exit 1; } @@ -35,7 +33,6 @@ RUN GOOS=${TARGETOS} GOARCH=${TARGETARCH} \ go build --ldflags "-s -w" -a -installsuffix cgo -o handler . FROM --platform=${TARGETPLATFORM:-linux/amd64} alpine:3.16.2 as ship - # Add non root user and certs RUN apk --no-cache add ca-certificates \ && addgroup -S app && adduser -S -g app app