From 566803f36174c47799fe2ed742a843dafc992b2f Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Thu, 29 Jul 2021 19:36:07 +0200 Subject: [PATCH] Container based developer flow Signed-off-by: CrazyMax --- .dockerignore | 1 + .gitignore | 1 + docker-bake.hcl | 47 +++++++++++ docs/yamlgen/generate.go | 117 --------------------------- hack/dockerfiles/yamldocs.Dockerfile | 19 ----- hack/generate-yamldocs | 10 --- hack/lint.Dockerfile | 15 ++++ hack/test.Dockerfile | 20 +++++ hack/vendor.Dockerfile | 24 ++++++ 9 files changed, 108 insertions(+), 146 deletions(-) create mode 100644 .dockerignore create mode 100644 .gitignore create mode 100644 docker-bake.hcl delete mode 100644 docs/yamlgen/generate.go delete mode 100644 hack/dockerfiles/yamldocs.Dockerfile delete mode 100755 hack/generate-yamldocs create mode 100644 hack/lint.Dockerfile create mode 100644 hack/test.Dockerfile create mode 100644 hack/vendor.Dockerfile diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..3f2bc47 --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +/coverage.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3f2bc47 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/coverage.txt diff --git a/docker-bake.hcl b/docker-bake.hcl new file mode 100644 index 0000000..35516be --- /dev/null +++ b/docker-bake.hcl @@ -0,0 +1,47 @@ +variable "GO_VERSION" { + default = "1.16" +} + +group "default" { + targets = ["test"] +} + +group "validate" { + targets = ["lint", "vendor-validate"] +} + +target "lint" { + args = { + GO_VERSION = GO_VERSION + } + dockerfile = "./hack/lint.Dockerfile" + target = "lint" + output = ["type=cacheonly"] +} + +target "vendor-validate" { + args = { + GO_VERSION = GO_VERSION + } + dockerfile = "./hack/vendor.Dockerfile" + target = "validate" + output = ["type=cacheonly"] +} + +target "vendor-update" { + args = { + GO_VERSION = GO_VERSION + } + dockerfile = "./hack/vendor.Dockerfile" + target = "update" + output = ["."] +} + +target "test" { + args = { + GO_VERSION = GO_VERSION + } + dockerfile = "./hack/test.Dockerfile" + target = "test-coverage" + output = ["."] +} diff --git a/docs/yamlgen/generate.go b/docs/yamlgen/generate.go deleted file mode 100644 index a6bb6b3..0000000 --- a/docs/yamlgen/generate.go +++ /dev/null @@ -1,117 +0,0 @@ -package main - -import ( - "fmt" - "io/ioutil" - "log" - "os" - "path/filepath" - "strings" - - "github.com/docker/buildx/commands" - "github.com/docker/cli/cli/command" - "github.com/spf13/cobra" - "github.com/spf13/pflag" -) - -const descriptionSourcePath = "docs/reference/" - -func generateCliYaml(opts *options) error { - dockerCLI, err := command.NewDockerCli() - if err != nil { - return err - } - cmd := &cobra.Command{ - Use: "docker [OPTIONS] COMMAND [ARG...]", - Short: "The base command for the Docker CLI.", - } - cmd.AddCommand(commands.NewRootCmd("buildx", true, dockerCLI)) - disableFlagsInUseLine(cmd) - source := filepath.Join(opts.source, descriptionSourcePath) - fmt.Println("Markdown source:", source) - if err := loadLongDescription(cmd, source); err != nil { - return err - } - - if err := os.MkdirAll(opts.target, 0755); err != nil { - return err - } - - cmd.DisableAutoGenTag = true - return GenYamlTree(cmd, opts.target) -} - -func disableFlagsInUseLine(cmd *cobra.Command) { - visitAll(cmd, func(ccmd *cobra.Command) { - // do not add a `[flags]` to the end of the usage line. - ccmd.DisableFlagsInUseLine = true - }) -} - -// visitAll will traverse all commands from the root. -// This is different from the VisitAll of cobra.Command where only parents -// are checked. -func visitAll(root *cobra.Command, fn func(*cobra.Command)) { - for _, cmd := range root.Commands() { - visitAll(cmd, fn) - } - fn(root) -} - -func loadLongDescription(parentCmd *cobra.Command, path string) error { - for _, cmd := range parentCmd.Commands() { - if cmd.HasSubCommands() { - if err := loadLongDescription(cmd, path); err != nil { - return err - } - } - name := cmd.CommandPath() - log.Println("INFO: Generating docs for", name) - if i := strings.Index(name, " "); i >= 0 { - // remove root command / binary name - name = name[i+1:] - } - if name == "" { - continue - } - mdFile := strings.ReplaceAll(name, " ", "_") + ".md" - fullPath := filepath.Join(path, mdFile) - content, err := ioutil.ReadFile(fullPath) - if os.IsNotExist(err) { - log.Printf("WARN: %s does not exist, skipping\n", mdFile) - continue - } - if err != nil { - return err - } - applyDescriptionAndExamples(cmd, string(content)) - } - return nil -} - -type options struct { - source string - target string -} - -func parseArgs() (*options, error) { - opts := &options{} - cwd, _ := os.Getwd() - flags := pflag.NewFlagSet(os.Args[0], pflag.ContinueOnError) - flags.StringVar(&opts.source, "root", cwd, "Path to project root") - flags.StringVar(&opts.target, "target", "/tmp", "Target path for generated yaml files") - err := flags.Parse(os.Args[1:]) - return opts, err -} - -func main() { - opts, err := parseArgs() - if err != nil { - log.Println(err) - } - fmt.Println("Project root: ", opts.source) - fmt.Println("YAML output dir:", opts.target) - if err := generateCliYaml(opts); err != nil { - log.Println("Failed to generate yaml files:", err) - } -} diff --git a/hack/dockerfiles/yamldocs.Dockerfile b/hack/dockerfiles/yamldocs.Dockerfile deleted file mode 100644 index 6c1a4db..0000000 --- a/hack/dockerfiles/yamldocs.Dockerfile +++ /dev/null @@ -1,19 +0,0 @@ -# syntax = docker/dockerfile:1.2 - -FROM golang:1.16-alpine AS yamlgen -WORKDIR /src -RUN --mount=target=. \ - --mount=target=/root/.cache,type=cache \ - go build -mod=vendor -o /out/yamlgen ./docs/yamlgen - -FROM alpine AS gen -RUN apk add --no-cache rsync git -WORKDIR /src -COPY --from=yamlgen /out/yamlgen /usr/bin -RUN --mount=target=/context \ - --mount=target=.,type=tmpfs,readwrite \ - rsync -a /context/. . \ - && yamlgen --target /out/yaml - -FROM scratch AS update -COPY --from=gen /out / diff --git a/hack/generate-yamldocs b/hack/generate-yamldocs deleted file mode 100755 index 2946371..0000000 --- a/hack/generate-yamldocs +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env bash - -. "$(dirname "$0")"/util -set -eu - -buildxCmd build \ - --output "type=local,dest=./bin/docs/" \ - --file "./hack/dockerfiles/yamldocs.Dockerfile" \ - --progress=plain \ - . diff --git a/hack/lint.Dockerfile b/hack/lint.Dockerfile new file mode 100644 index 0000000..5be2b80 --- /dev/null +++ b/hack/lint.Dockerfile @@ -0,0 +1,15 @@ +# syntax=docker/dockerfile:1.3 +ARG GO_VERSION + +FROM golang:${GO_VERSION}-alpine AS base +RUN apk add --no-cache linux-headers +WORKDIR /src + +FROM golangci/golangci-lint:v1.37-alpine AS golangci-lint + +FROM base AS lint +RUN --mount=type=bind,target=. \ + --mount=type=cache,target=/root/.cache/go-build \ + --mount=type=cache,target=/root/.cache/golangci-lint \ + --mount=from=golangci-lint,source=/usr/bin/golangci-lint,target=/usr/bin/golangci-lint \ + golangci-lint run --timeout 10m0s ./... diff --git a/hack/test.Dockerfile b/hack/test.Dockerfile new file mode 100644 index 0000000..9db38b1 --- /dev/null +++ b/hack/test.Dockerfile @@ -0,0 +1,20 @@ +# syntax=docker/dockerfile:1.2 +ARG GO_VERSION + +FROM golang:${GO_VERSION}-alpine AS base +RUN apk add --no-cache gcc linux-headers musl-dev +WORKDIR /src + +FROM base AS gomod +RUN --mount=type=bind,target=.,rw \ + --mount=type=cache,target=/go/pkg/mod \ + go mod tidy && go mod download + +FROM gomod AS test +RUN --mount=type=bind,target=. \ + --mount=type=cache,target=/go/pkg/mod \ + --mount=type=cache,target=/root/.cache/go-build \ + go test -v -coverprofile=/tmp/coverage.txt -covermode=atomic -race ./... + +FROM scratch AS test-coverage +COPY --from=test /tmp/coverage.txt /coverage.txt diff --git a/hack/vendor.Dockerfile b/hack/vendor.Dockerfile new file mode 100644 index 0000000..8e1a7c4 --- /dev/null +++ b/hack/vendor.Dockerfile @@ -0,0 +1,24 @@ +# syntax=docker/dockerfile:1.3 +ARG GO_VERSION + +FROM golang:${GO_VERSION}-alpine AS base +RUN apk add --no-cache git +WORKDIR /src + +FROM base AS vendored +RUN --mount=type=bind,target=.,rw \ + --mount=type=cache,target=/go/pkg/mod \ + go mod tidy && go mod download && \ + mkdir /out && cp go.mod go.sum /out + +FROM scratch AS update +COPY --from=vendored /out / + +FROM vendored AS validate +RUN --mount=type=bind,target=.,rw \ + git add -A && cp -rf /out/* .; \ + if [ -n "$(git status --porcelain -- go.mod go.sum)" ]; then \ + echo >&2 'ERROR: Vendor result differs. Please vendor your package with "docker buildx bake vendor-update"'; \ + git status --porcelain -- go.mod go.sum; \ + exit 1; \ + fi