diff --git a/.conform.yaml b/.conform.yaml index e12f944..52c3a03 100644 --- a/.conform.yaml +++ b/.conform.yaml @@ -1,37 +1,48 @@ # THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. # -# Generated on 2022-10-24T18:13:55Z by kres ef0ba25. +# Generated on 2024-04-30T10:38:23Z by kres ebc009d. ---- policies: -- type: commit - spec: - dco: true - gpg: - required: true - identity: - gitHubOrganization: siderolabs - spellcheck: - locale: US - maximumOfOneCommit: true - header: - length: 89 - imperative: true - case: lower - invalidLastCharacters: . - body: - required: true - conventional: - types: ["chore","docs","perf","refactor","style","test","release"] - scopes: [".*"] -- type: license - spec: - skipPaths: - - .git/ - - testdata/ - includeSuffixes: - - .go - excludeSuffixes: - - .pb.go - - .pb.gw.go - header: "// This Source Code Form is subject to the terms of the Mozilla Public\u000A// License, v. 2.0. If a copy of the MPL was not distributed with this\u000A// file, You can obtain one at http://mozilla.org/MPL/2.0/.\u000A" + - type: commit + spec: + dco: true + gpg: + required: true + identity: + gitHubOrganization: siderolabs + spellcheck: + locale: US + maximumOfOneCommit: true + header: + length: 89 + imperative: true + case: lower + invalidLastCharacters: . + body: + required: true + conventional: + types: + - chore + - docs + - perf + - refactor + - style + - test + - release + scopes: + - .* + - type: license + spec: + root: . + skipPaths: + - .git/ + - testdata/ + includeSuffixes: + - .go + excludeSuffixes: + - .pb.go + - .pb.gw.go + header: | + // This Source Code Form is subject to the terms of the Mozilla Public + // License, v. 2.0. If a copy of the MPL was not distributed with this + // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/.dockerignore b/.dockerignore index ab0818d..0a03289 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,8 +1,8 @@ # THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. # -# Generated on 2022-10-24T18:13:55Z by kres ef0ba25. +# Generated on 2024-04-30T10:38:23Z by kres ebc009d. -** +* !circular.go !circular_test.go !errors.go diff --git a/.drone.yml b/.drone.yml deleted file mode 100644 index 058977b..0000000 --- a/.drone.yml +++ /dev/null @@ -1,254 +0,0 @@ ---- -# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. -# -# Generated on 2022-10-24T18:13:55Z by kres ef0ba25. - -kind: pipeline -type: kubernetes -name: default - -platform: - os: linux - arch: amd64 - -steps: -- name: setup-ci - pull: always - image: autonomy/build-container:latest - commands: - - sleep 5 - - git fetch --tags - - install-ci-key - - docker buildx create --driver docker-container --platform linux/amd64 --name local --use unix:///var/outer-run/docker.sock - - docker buildx inspect --bootstrap - environment: - SSH_KEY: - from_secret: ssh_key - volumes: - - name: outer-docker-socket - path: /var/outer-run - - name: docker-socket - path: /var/run - - name: buildx - path: /root/.docker/buildx - - name: ssh - path: /root/.ssh - -- name: base - pull: always - image: autonomy/build-container:latest - commands: - - make base - volumes: - - name: outer-docker-socket - path: /var/outer-run - - name: docker-socket - path: /var/run - - name: buildx - path: /root/.docker/buildx - - name: ssh - path: /root/.ssh - depends_on: - - setup-ci - -- name: unit-tests - pull: always - image: autonomy/build-container:latest - commands: - - make unit-tests - volumes: - - name: outer-docker-socket - path: /var/outer-run - - name: docker-socket - path: /var/run - - name: buildx - path: /root/.docker/buildx - - name: ssh - path: /root/.ssh - depends_on: - - base - -- name: unit-tests-race - pull: always - image: autonomy/build-container:latest - commands: - - make unit-tests-race - volumes: - - name: outer-docker-socket - path: /var/outer-run - - name: docker-socket - path: /var/run - - name: buildx - path: /root/.docker/buildx - - name: ssh - path: /root/.ssh - depends_on: - - base - -- name: coverage - pull: always - image: autonomy/build-container:latest - commands: - - make coverage - environment: - CODECOV_TOKEN: - from_secret: CODECOV_TOKEN - volumes: - - name: outer-docker-socket - path: /var/outer-run - - name: docker-socket - path: /var/run - - name: buildx - path: /root/.docker/buildx - - name: ssh - path: /root/.ssh - depends_on: - - unit-tests - -- name: lint - pull: always - image: autonomy/build-container:latest - commands: - - make lint - volumes: - - name: outer-docker-socket - path: /var/outer-run - - name: docker-socket - path: /var/run - - name: buildx - path: /root/.docker/buildx - - name: ssh - path: /root/.ssh - depends_on: - - base - -- name: release-notes - pull: always - image: autonomy/build-container:latest - commands: - - make release-notes - volumes: - - name: outer-docker-socket - path: /var/outer-run - - name: docker-socket - path: /var/run - - name: buildx - path: /root/.docker/buildx - - name: ssh - path: /root/.ssh - when: - event: - - tag - depends_on: - - unit-tests - - coverage - - lint - -- name: release - pull: always - image: plugins/github-release - settings: - api_key: - from_secret: github_token - checksum: - - sha256 - - sha512 - draft: true - files: - - _out/* - note: _out/RELEASE_NOTES.md - volumes: - - name: outer-docker-socket - path: /var/outer-run - - name: docker-socket - path: /var/run - - name: buildx - path: /root/.docker/buildx - - name: ssh - path: /root/.ssh - when: - event: - - tag - depends_on: - - release-notes - -services: -- name: docker - image: docker:20.10-dind - entrypoint: - - dockerd - commands: - - --dns=8.8.8.8 - - --dns=8.8.4.4 - - --mtu=1500 - - --log-level=error - privileged: true - volumes: - - name: outer-docker-socket - path: /var/outer-run - - name: docker-socket - path: /var/run - - name: buildx - path: /root/.docker/buildx - - name: ssh - path: /root/.ssh - -volumes: -- name: outer-docker-socket - host: - path: /var/ci-docker -- name: docker-socket - temp: - medium: memory -- name: buildx - temp: - medium: memory -- name: ssh - temp: - medium: memory - -trigger: - branch: - exclude: - - renovate/* - - dependabot/* - ---- -kind: pipeline -type: kubernetes -name: notify - -platform: - os: linux - arch: amd64 - -clone: - disable: true - -steps: -- name: slack - image: plugins/slack - settings: - channel: proj-talos-maintainers - link_names: true - template: "{{#if build.pull }}\n*{{#success build.status}}✓ Success{{else}}✕ Fail{{/success}}*: {{ repo.owner }}/{{ repo.name }} - \n{{else}}\n*{{#success build.status}}✓ Success{{else}}✕ Fail{{/success}}: {{ repo.owner }}/{{ repo.name }} - Build #{{ build.number }}* (type: `{{ build.event }}`)\n{{/if}}\nCommit: \nBranch: \nAuthor: {{ build.author }}\n<{{ build.link }}|Visit build page>" - webhook: - from_secret: slack_webhook - when: - status: - - success - - failure - -trigger: - branch: - exclude: - - renovate/* - - dependabot/* - status: - - success - - failure - -depends_on: -- default - -... diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..fe3ef79 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,81 @@ +# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. +# +# Generated on 2024-04-30T11:03:25Z by kres d15226e. + +name: default +concurrency: + group: ${{ github.head_ref || github.run_id }} + cancel-in-progress: true +"on": + push: + branches: + - main + - release-* + tags: + - v* + pull_request: + branches: + - main + - release-* +jobs: + default: + permissions: + actions: read + contents: write + issues: read + packages: write + pull-requests: read + runs-on: + - self-hosted + - generic + if: (!startsWith(github.head_ref, 'renovate/') && !startsWith(github.head_ref, 'dependabot/')) + services: + buildkitd: + image: moby/buildkit:v0.13.1 + options: --privileged + ports: + - 1234:1234 + volumes: + - /var/lib/buildkit/${{ github.repository }}:/var/lib/buildkit + - /usr/etc/buildkit/buildkitd.toml:/etc/buildkit/buildkitd.toml + steps: + - name: checkout + uses: actions/checkout@v4 + - name: Unshallow + run: | + git fetch --prune --unshallow + - name: Set up Docker Buildx + id: setup-buildx + uses: docker/setup-buildx-action@v3 + with: + driver: remote + endpoint: tcp://127.0.0.1:1234 + timeout-minutes: 10 + - name: base + run: | + make base + - name: unit-tests + run: | + make unit-tests + - name: unit-tests-race + run: | + make unit-tests-race + - name: coverage + uses: codecov/codecov-action@v4 + with: + files: _out/coverage-unit-tests.txt + token: ${{ secrets.CODECOV_TOKEN }} + timeout-minutes: 3 + - name: lint + run: | + make lint + - name: release-notes + if: startsWith(github.ref, 'refs/tags/') + run: | + make release-notes + - name: Release + if: startsWith(github.ref, 'refs/tags/') + uses: crazy-max/ghaction-github-release@v2 + with: + body_path: _out/RELEASE_NOTES.md + draft: "true" diff --git a/.github/workflows/slack-notify.yaml b/.github/workflows/slack-notify.yaml new file mode 100644 index 0000000..52e2725 --- /dev/null +++ b/.github/workflows/slack-notify.yaml @@ -0,0 +1,92 @@ +# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. +# +# Generated on 2024-04-30T10:38:23Z by kres ebc009d. + +name: slack-notify +"on": + workflow_run: + workflows: + - default + types: + - completed +jobs: + slack-notify: + runs-on: + - self-hosted + - generic + if: github.event.workflow_run.conclusion != 'skipped' + steps: + - name: Get PR number + id: get-pr-number + if: github.event.workflow_run.event == 'pull_request' + env: + GH_TOKEN: ${{ github.token }} + run: | + echo pull_request_number=$(gh pr view -R ${{ github.repository }} ${{ github.event.workflow_run.head_repository.owner.login }}:${{ github.event.workflow_run.head_branch }} --json number --jq .number) >> $GITHUB_OUTPUT + - name: Slack Notify + uses: slackapi/slack-github-action@v1 + with: + channel-id: proj-talos-maintainers + payload: | + { + "attachments": [ + { + "color": "${{ github.event.workflow_run.conclusion == 'success' && '#2EB886' || github.event.workflow_run.conclusion == 'failure' && '#A30002' || '#FFCC00' }}", + "fallback": "test", + "blocks": [ + { + "type": "section", + "fields": [ + { + "type": "mrkdwn", + "text": "${{ github.event.workflow_run.event == 'pull_request' && format('*Pull Request:* {0} (`{1}`)\n<{2}/pull/{3}|{4}>', github.repository, github.ref_name, github.event.repository.html_url, steps.get-pr-number.outputs.pull_request_number, github.event.workflow_run.display_title) || format('*Build:* {0} (`{1}`)\n<{2}/commit/{3}|{4}>', github.repository, github.ref_name, github.event.repository.html_url, github.sha, github.event.workflow_run.display_title) }}" + }, + { + "type": "mrkdwn", + "text": "*Status:*\n`${{ github.event.workflow_run.conclusion }}`" + } + ] + }, + { + "type": "section", + "fields": [ + { + "type": "mrkdwn", + "text": "*Author:*\n`${{ github.actor }}`" + }, + { + "type": "mrkdwn", + "text": "*Event:*\n`${{ github.event.workflow_run.event }}`" + } + ] + }, + { + "type": "divider" + }, + { + "type": "actions", + "elements": [ + { + "type": "button", + "text": { + "type": "plain_text", + "text": "Logs" + }, + "url": "${{ github.event.workflow_run.html_url }}" + }, + { + "type": "button", + "text": { + "type": "plain_text", + "text": "Commit" + }, + "url": "${{ github.event.repository.html_url }}/commit/${{ github.sha }}" + } + ] + } + ] + } + ] + } + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} diff --git a/.golangci.yml b/.golangci.yml index a27086e..a2fcc4f 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,21 +1,20 @@ # THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. # -# Generated on 2022-10-24T18:13:55Z by kres ef0ba25. +# Generated on 2024-04-30T10:38:23Z by kres ebc009d. # options for analysis running run: timeout: 10m issues-exit-code: 1 tests: true - build-tags: [] - skip-dirs: [] - skip-dirs-use-default: true - skip-files: [] + build-tags: [ ] modules-download-mode: readonly # output configuration options output: - format: colored-line-number + formats: + - format: colored-line-number + path: stdout print-issued-lines: true print-linter-name: true uniq-by-line: true @@ -32,57 +31,38 @@ linters-settings: check-blank: true exhaustive: default-signifies-exhaustive: false - funlen: - lines: 60 - statements: 40 gci: - local-prefixes: github.com/siderolabs/go-circular + sections: + - standard # Standard section: captures all standard packages. + - default # Default section: contains all imports that could not be matched to another section type. + - prefix(github.com/siderolabs/go-circular/) # Custom section: groups all imports with the specified Prefix. gocognit: min-complexity: 30 - ireturn: - allow: - - anon - - error - - empty - - stdlib - - github.com\/talos-systems\/kres\/internal\/dag.Node nestif: min-complexity: 5 goconst: min-len: 3 min-occurrences: 3 gocritic: - disabled-checks: [] + disabled-checks: [ ] gocyclo: min-complexity: 20 godot: - check-all: false - godox: - keywords: # default keywords are TODO, BUG, and FIXME, these can be overwritten by this setting - - NOTE - - OPTIMIZE # marks code that should be optimized before merging - - HACK # marks hack-arounds that should be removed before merging + scope: declarations gofmt: simplify: true goimports: - local-prefixes: github.com/siderolabs/go-circular - golint: - min-confidence: 0.8 - gomnd: - settings: {} - gomodguard: {} + local-prefixes: github.com/siderolabs/go-circular/ + gomodguard: { } + gomnd: { } govet: - check-shadowing: true enable-all: true - depguard: - list-type: blacklist - include-go-root: false lll: line-length: 200 tab-width: 4 misspell: locale: US - ignore-words: [] + ignore-words: [ ] nakedret: max-func-lines: 30 prealloc: @@ -91,16 +71,15 @@ linters-settings: for-loops: false # Report preallocation suggestions on for loops, false by default nolintlint: allow-unused: false - allow-leading-space: false - allow-no-explanation: [] + allow-no-explanation: [ ] require-explanation: false require-specific: true - rowserrcheck: {} - testpackage: {} + rowserrcheck: { } + testpackage: { } unparam: check-exported: false unused: - check-exported: false + local-variables-are-used: false whitespace: multi-if: false # Enforces newlines (or comments) after every multi-line if statement multi-func: false # Enforces newlines (or comments) after every multi-line function signature @@ -116,44 +95,60 @@ linters-settings: gofumpt: extra-rules: false cyclop: - # the maximal code complexity to report - max-complexity: 20 + # the maximal code complexity to report + max-complexity: 20 + # depguard: + # Main: + # deny: + # - github.com/OpenPeeDeeP/depguard # this is just an example linters: enable-all: true disable-all: false fast: false disable: - - exhaustruct - exhaustivestruct + - exhaustruct - forbidigo - funlen - - gas - gochecknoglobals - gochecknoinits - godox - goerr113 - gomnd - gomoddirectives + - gosec + - inamedparam - ireturn - nestif - nonamedreturns - nosnakecase - paralleltest + - tagalign - tagliatelle - thelper - typecheck - varnamelen - wrapcheck + - depguard # Disabled because starting with golangci-lint 1.53.0 it doesn't allow denylist alone anymore + - testifylint # complains about our assert recorder and has a number of false positives for assert.Greater(t, thing, 1) + - protogetter # complains about us using Value field on typed spec, instead of GetValue which has a different signature + - perfsprint # complains about us using fmt.Sprintf in non-performance critical code, updating just kres took too long # abandoned linters for which golangci shows the warning that the repo is archived by the owner + - deadcode + - golint + - ifshort - interfacer - maligned - - golint - scopelint + - structcheck + - varcheck + # disabled as it seems to be broken - goes into imported libraries and reports issues there + - musttag issues: - exclude: [] - exclude-rules: [] + exclude: [ ] + exclude-rules: [ ] exclude-use-default: false exclude-case-sensitive: false max-issues-per-linter: 10 diff --git a/Dockerfile b/Dockerfile index 8c9c7db..0a9a71d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,8 @@ -# syntax = docker/dockerfile-upstream:1.2.0-labs +# syntax = docker/dockerfile-upstream:1.7.0-labs # THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. # -# Generated on 2022-10-24T18:13:55Z by kres ef0ba25. +# Generated on 2024-04-30T10:38:23Z by kres ebc009d. ARG TOOLCHAIN @@ -10,9 +10,9 @@ ARG TOOLCHAIN FROM scratch AS generate # runs markdownlint -FROM docker.io/node:18.10.0-alpine3.16 AS lint-markdown +FROM docker.io/node:21.7.3-alpine3.19 AS lint-markdown WORKDIR /src -RUN npm i -g markdownlint-cli@0.32.2 +RUN npm i -g markdownlint-cli@0.39.0 RUN npm i sentences-per-line@0.2.1 COPY .markdownlint.json . COPY ./README.md ./README.md @@ -27,27 +27,32 @@ FROM --platform=${BUILDPLATFORM} toolchain AS tools ENV GO111MODULE on ARG CGO_ENABLED ENV CGO_ENABLED ${CGO_ENABLED} +ARG GOTOOLCHAIN +ENV GOTOOLCHAIN ${GOTOOLCHAIN} +ARG GOEXPERIMENT +ENV GOEXPERIMENT ${GOEXPERIMENT} ENV GOPATH /go +ARG DEEPCOPY_VERSION +RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/go/pkg go install github.com/siderolabs/deep-copy@${DEEPCOPY_VERSION} \ + && mv /go/bin/deep-copy /bin/deep-copy ARG GOLANGCILINT_VERSION -RUN go install github.com/golangci/golangci-lint/cmd/golangci-lint@${GOLANGCILINT_VERSION} \ +RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/go/pkg go install github.com/golangci/golangci-lint/cmd/golangci-lint@${GOLANGCILINT_VERSION} \ && mv /go/bin/golangci-lint /bin/golangci-lint -ARG GOFUMPT_VERSION -RUN go install mvdan.cc/gofumpt@${GOFUMPT_VERSION} \ - && mv /go/bin/gofumpt /bin/gofumpt -RUN go install golang.org/x/vuln/cmd/govulncheck@latest \ +RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/go/pkg go install golang.org/x/vuln/cmd/govulncheck@latest \ && mv /go/bin/govulncheck /bin/govulncheck ARG GOIMPORTS_VERSION -RUN go install golang.org/x/tools/cmd/goimports@${GOIMPORTS_VERSION} \ +RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/go/pkg go install golang.org/x/tools/cmd/goimports@${GOIMPORTS_VERSION} \ && mv /go/bin/goimports /bin/goimports -ARG DEEPCOPY_VERSION -RUN go install github.com/siderolabs/deep-copy@${DEEPCOPY_VERSION} \ - && mv /go/bin/deep-copy /bin/deep-copy +ARG GOFUMPT_VERSION +RUN go install mvdan.cc/gofumpt@${GOFUMPT_VERSION} \ + && mv /go/bin/gofumpt /bin/gofumpt # tools and sources FROM tools AS base WORKDIR /src -COPY ./go.mod . -COPY ./go.sum . +COPY go.mod go.mod +COPY go.sum go.sum +RUN cd . RUN --mount=type=cache,target=/go/pkg go mod download RUN --mount=type=cache,target=/go/pkg go mod verify COPY ./circular.go ./circular.go @@ -64,28 +69,33 @@ RUN FILES="$(gofumpt -l .)" && test -z "${FILES}" || (echo -e "Source code is no # runs goimports FROM base AS lint-goimports -RUN FILES="$(goimports -l -local github.com/siderolabs/go-circular .)" && test -z "${FILES}" || (echo -e "Source code is not formatted with 'goimports -w -local github.com/siderolabs/go-circular .':\n${FILES}"; exit 1) +RUN FILES="$(goimports -l -local github.com/siderolabs/go-circular/ .)" && test -z "${FILES}" || (echo -e "Source code is not formatted with 'goimports -w -local github.com/siderolabs/go-circular/ .':\n${FILES}"; exit 1) # runs golangci-lint FROM base AS lint-golangci-lint +WORKDIR /src COPY .golangci.yml . ENV GOGC 50 +RUN golangci-lint config verify --config .golangci.yml RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/root/.cache/golangci-lint --mount=type=cache,target=/go/pkg golangci-lint run --config .golangci.yml # runs govulncheck FROM base AS lint-govulncheck +WORKDIR /src RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/go/pkg govulncheck ./... # runs unit-tests with race detector FROM base AS unit-tests-race +WORKDIR /src ARG TESTPKGS RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/go/pkg --mount=type=cache,target=/tmp CGO_ENABLED=1 go test -v -race -count 1 ${TESTPKGS} # runs unit-tests FROM base AS unit-tests-run +WORKDIR /src ARG TESTPKGS RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/go/pkg --mount=type=cache,target=/tmp go test -v -covermode=atomic -coverprofile=coverage.txt -coverpkg=${TESTPKGS} -count 1 ${TESTPKGS} FROM scratch AS unit-tests -COPY --from=unit-tests-run /src/coverage.txt /coverage.txt +COPY --from=unit-tests-run /src/coverage.txt /coverage-unit-tests.txt diff --git a/Makefile b/Makefile index 831263e..92d699a 100644 --- a/Makefile +++ b/Makefile @@ -1,30 +1,33 @@ # THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. # -# Generated on 2022-10-24T18:13:55Z by kres ef0ba25. +# Generated on 2024-04-30T11:03:09Z by kres d15226e. # common variables SHA := $(shell git describe --match=none --always --abbrev=8 --dirty) -TAG := $(shell git describe --tag --always --dirty) +TAG := $(shell git describe --tag --always --dirty --match v[0-9]\*) +ABBREV_TAG := $(shell git describe --tags >/dev/null 2>/dev/null && git describe --tag --always --match v[0-9]\* --abbrev=0 || echo 'undefined') BRANCH := $(shell git rev-parse --abbrev-ref HEAD) ARTIFACTS := _out +IMAGE_TAG ?= $(TAG) WITH_DEBUG ?= false WITH_RACE ?= false REGISTRY ?= ghcr.io USERNAME ?= siderolabs REGISTRY_AND_USERNAME ?= $(REGISTRY)/$(USERNAME) -GOLANGCILINT_VERSION ?= v1.50.0 -GOFUMPT_VERSION ?= v0.4.0 -GO_VERSION ?= 1.19 -GOIMPORTS_VERSION ?= v0.1.12 -PROTOBUF_GO_VERSION ?= 1.28.1 -GRPC_GO_VERSION ?= 1.2.0 -GRPC_GATEWAY_VERSION ?= 2.11.3 -VTPROTOBUF_VERSION ?= 0.3.0 -DEEPCOPY_VERSION ?= v0.5.5 +PROTOBUF_GO_VERSION ?= 1.33.0 +GRPC_GO_VERSION ?= 1.3.0 +GRPC_GATEWAY_VERSION ?= 2.19.1 +VTPROTOBUF_VERSION ?= 0.6.0 +DEEPCOPY_VERSION ?= v0.5.6 +GOLANGCILINT_VERSION ?= v1.57.2 +GOFUMPT_VERSION ?= v0.6.0 +GO_VERSION ?= 1.22.2 +GOIMPORTS_VERSION ?= v0.20.0 GO_BUILDFLAGS ?= GO_LDFLAGS ?= CGO_ENABLED ?= 0 +GOTOOLCHAIN ?= local TESTPKGS ?= ./... KRES_IMAGE ?= ghcr.io/siderolabs/kres:latest CONFORMANCE_IMAGE ?= ghcr.io/siderolabs/conform:latest @@ -37,28 +40,32 @@ PROGRESS ?= auto PUSH ?= false CI_ARGS ?= COMMON_ARGS = --file=Dockerfile +COMMON_ARGS += --provenance=false COMMON_ARGS += --progress=$(PROGRESS) COMMON_ARGS += --platform=$(PLATFORM) COMMON_ARGS += --push=$(PUSH) COMMON_ARGS += --build-arg=ARTIFACTS="$(ARTIFACTS)" COMMON_ARGS += --build-arg=SHA="$(SHA)" COMMON_ARGS += --build-arg=TAG="$(TAG)" +COMMON_ARGS += --build-arg=ABBREV_TAG="$(ABBREV_TAG)" COMMON_ARGS += --build-arg=USERNAME="$(USERNAME)" COMMON_ARGS += --build-arg=REGISTRY="$(REGISTRY)" COMMON_ARGS += --build-arg=TOOLCHAIN="$(TOOLCHAIN)" COMMON_ARGS += --build-arg=CGO_ENABLED="$(CGO_ENABLED)" COMMON_ARGS += --build-arg=GO_BUILDFLAGS="$(GO_BUILDFLAGS)" COMMON_ARGS += --build-arg=GO_LDFLAGS="$(GO_LDFLAGS)" -COMMON_ARGS += --build-arg=GOLANGCILINT_VERSION="$(GOLANGCILINT_VERSION)" -COMMON_ARGS += --build-arg=GOFUMPT_VERSION="$(GOFUMPT_VERSION)" -COMMON_ARGS += --build-arg=GOIMPORTS_VERSION="$(GOIMPORTS_VERSION)" +COMMON_ARGS += --build-arg=GOTOOLCHAIN="$(GOTOOLCHAIN)" +COMMON_ARGS += --build-arg=GOEXPERIMENT="$(GOEXPERIMENT)" COMMON_ARGS += --build-arg=PROTOBUF_GO_VERSION="$(PROTOBUF_GO_VERSION)" COMMON_ARGS += --build-arg=GRPC_GO_VERSION="$(GRPC_GO_VERSION)" COMMON_ARGS += --build-arg=GRPC_GATEWAY_VERSION="$(GRPC_GATEWAY_VERSION)" COMMON_ARGS += --build-arg=VTPROTOBUF_VERSION="$(VTPROTOBUF_VERSION)" COMMON_ARGS += --build-arg=DEEPCOPY_VERSION="$(DEEPCOPY_VERSION)" +COMMON_ARGS += --build-arg=GOLANGCILINT_VERSION="$(GOLANGCILINT_VERSION)" +COMMON_ARGS += --build-arg=GOIMPORTS_VERSION="$(GOIMPORTS_VERSION)" +COMMON_ARGS += --build-arg=GOFUMPT_VERSION="$(GOFUMPT_VERSION)" COMMON_ARGS += --build-arg=TESTPKGS="$(TESTPKGS)" -TOOLCHAIN ?= docker.io/golang:1.19-alpine +TOOLCHAIN ?= docker.io/golang:1.22-alpine # help menu @@ -81,13 +88,30 @@ To create a builder instance, run: docker buildx create --name local --use +If running builds that needs to be cached aggresively create a builder instance with the following: + + docker buildx create --name local --use --config=config.toml + +config.toml contents: + +[worker.oci] + gc = true + gckeepstorage = 50000 + + [[worker.oci.gcpolicy]] + keepBytes = 10737418240 + keepDuration = 604800 + filters = [ "type==source.local", "type==exec.cachemount", "type==source.git.checkout"] + [[worker.oci.gcpolicy]] + all = true + keepBytes = 53687091200 If you already have a compatible builder instance, you may use that instead. ## Artifacts All artifacts will be output to ./$(ARTIFACTS). Images will be tagged with the -registry "$(REGISTRY)", username "$(USERNAME)", and a dynamic tag (e.g. $(IMAGE):$(TAG)). +registry "$(REGISTRY)", username "$(USERNAME)", and a dynamic tag (e.g. $(IMAGE):$(IMAGE_TAG)). The registry and username can be overridden by exporting REGISTRY, and USERNAME respectively. @@ -102,7 +126,7 @@ endif ifneq (, $(filter $(WITH_DEBUG), t true TRUE y yes 1)) GO_BUILDFLAGS += -tags sidero.debug else -GO_LDFLAGS += -s -w +GO_LDFLAGS += -s endif all: unit-tests lint @@ -126,7 +150,8 @@ lint-gofumpt: ## Runs gofumpt linter. .PHONY: fmt fmt: ## Formats the source code @docker run --rm -it -v $(PWD):/src -w /src golang:$(GO_VERSION) \ - bash -c "export GO111MODULE=on; export GOPROXY=https://proxy.golang.org; \ + bash -c "export GOTOOLCHAIN=local; \ + export GO111MODULE=on; export GOPROXY=https://proxy.golang.org; \ go install mvdan.cc/gofumpt@$(GOFUMPT_VERSION) && \ gofumpt -w ." @@ -148,10 +173,6 @@ unit-tests: ## Performs unit tests unit-tests-race: ## Performs unit tests with race detection enabled. @$(MAKE) target-$@ -.PHONY: coverage -coverage: ## Upload coverage data to codecov.io. - bash -c "bash <(curl -s https://codecov.io/bash) -f $(ARTIFACTS)/coverage.txt -X fix" - .PHONY: lint-markdown lint-markdown: ## Runs markdownlint. @$(MAKE) target-$@ @@ -162,7 +183,7 @@ lint: lint-golangci-lint lint-gofumpt lint-govulncheck lint-goimports lint-markd .PHONY: rekres rekres: @docker pull $(KRES_IMAGE) - @docker run --rm -v $(PWD):/src -w /src -e GITHUB_TOKEN $(KRES_IMAGE) + @docker run --rm --net=host --user $(shell id -u):$(shell id -g) -v $(PWD):/src -w /src -e GITHUB_TOKEN $(KRES_IMAGE) .PHONY: help help: ## This help menu. diff --git a/circular_test.go b/circular_test.go index 427c785..027a09a 100644 --- a/circular_test.go +++ b/circular_test.go @@ -4,6 +4,7 @@ package circular_test +//nolint:gci import ( "bytes" "context" @@ -49,7 +50,7 @@ func (suite *CircularSuite) TestWrites() { suite.Require().Equal(8192, buf.Capacity()) suite.Require().EqualValues(6100, buf.Offset()) - for i := 0; i < 20; i++ { + for i := range 20 { l := 1 << i n, err = buf.Write(make([]byte, l)) @@ -141,7 +142,7 @@ func (suite *CircularSuite) TestStreamingMultipleReaders() { readers := make([]*circular.StreamingReader, n) - for i := 0; i < n; i++ { + for i := range n { readers[i] = buf.GetStreamingReader() } @@ -155,11 +156,9 @@ func (suite *CircularSuite) TestStreamingMultipleReaders() { var wg sync.WaitGroup defer wg.Wait() - for i := 0; i < n; i++ { + for i := range n { wg.Add(1) - i := i - go func() { defer wg.Done() diff --git a/go.mod b/go.mod index 1059746..b3df58a 100644 --- a/go.mod +++ b/go.mod @@ -1,10 +1,10 @@ module github.com/siderolabs/go-circular -go 1.19 +go 1.22 require ( - github.com/stretchr/testify v1.8.1 - golang.org/x/time v0.1.0 + github.com/stretchr/testify v1.9.0 + golang.org/x/time v0.5.0 ) require ( diff --git a/go.sum b/go.sum index 9dfcaa0..7301572 100644 --- a/go.sum +++ b/go.sum @@ -10,8 +10,12 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= golang.org/x/time v0.1.0 h1:xYY+Bajn2a7VBmTM5GikTmnK8ZuX8YgnQCqZpbBNtmA= golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/reader.go b/reader.go index 9531e4b..82dbdbd 100644 --- a/reader.go +++ b/reader.go @@ -25,9 +25,7 @@ type Reader struct { // Read implements io.Reader. func (r *Reader) Read(p []byte) (n int, err error) { if atomic.LoadUint32(&r.closed) > 0 { - err = ErrClosed - - return + return n, ErrClosed } r.buf.mu.Lock() @@ -35,19 +33,15 @@ func (r *Reader) Read(p []byte) (n int, err error) { if r.off < r.buf.off-int64(r.buf.opt.MaxCapacity) { // reader is falling too much behind - err = ErrOutOfSync - - return + return n, ErrOutOfSync } if r.off == r.endOff { - err = io.EOF - - return + return n, io.EOF } if len(p) == 0 { - return + return n, err } n = int(r.endOff - r.off) diff --git a/streaming.go b/streaming.go index de8ff5a..1a293ad 100644 --- a/streaming.go +++ b/streaming.go @@ -26,13 +26,11 @@ type StreamingReader struct { // Read implements io.Reader. func (r *StreamingReader) Read(p []byte) (n int, err error) { if atomic.LoadUint32(&r.closed) > 0 { - err = ErrClosed - - return + return n, ErrClosed } if len(p) == 0 { - return + return n, err } r.buf.mu.Lock() @@ -47,9 +45,7 @@ func (r *StreamingReader) Read(p []byte) (n int, err error) { r.buf.cond.Wait() if atomic.LoadUint32(&r.closed) > 0 { - err = ErrClosed - - return + return n, ErrClosed } }