diff --git a/.github/workflows/cloc.yml b/.github/workflows/cloc.yml index d6ff20d..4592bb4 100644 --- a/.github/workflows/cloc.yml +++ b/.github/workflows/cloc.yml @@ -24,7 +24,7 @@ jobs: - name: Count Lines Of Code id: loc run: | - curl -sLO https://github.com/vearutop/sccdiff/releases/download/v1.0.1/linux_amd64.tar.gz && tar xf linux_amd64.tar.gz + curl -sLO https://github.com/vearutop/sccdiff/releases/download/v1.0.2/linux_amd64.tar.gz && tar xf linux_amd64.tar.gz && echo "b17e76bede22af0206b4918d3b3c4e7357f2a21b57f8de9e7c9dc0eb56b676c0 sccdiff" | shasum -c OUTPUT=$(cd pr && ../sccdiff -basedir ../base) echo "${OUTPUT}" OUTPUT="${OUTPUT//$'\n'/%0A}" diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index b4f7600..48207f9 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -27,7 +27,7 @@ jobs: uses: golangci/golangci-lint-action@v3.1.0 with: # Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version. - version: v1.45.2 + version: v1.46.2 # Optional: working directory, useful for monorepos # working-directory: somedir diff --git a/.github/workflows/gorelease.yml b/.github/workflows/gorelease.yml index 429d5ed..0a5a701 100644 --- a/.github/workflows/gorelease.yml +++ b/.github/workflows/gorelease.yml @@ -35,12 +35,12 @@ jobs: with: path: | ~/go/bin/gorelease - key: ${{ runner.os }}-gorelease + key: ${{ runner.os }}-gorelease-fork - name: Gorelease id: gorelease run: | - test -e ~/go/bin/gorelease || go install golang.org/x/exp/cmd/gorelease@latest - OUTPUT=$(gorelease || exit 0) + test -e ~/go/bin/gorelease || (rm -rf /tmp/gorelease && mkdir -p /tmp/gorelease && cd /tmp/gorelease && go mod init foo && go mod edit -replace golang.org/x/exp=github.com/vearutop/golang-exp@gorelease-generic && go get golang.org/x/exp/cmd/gorelease && go install golang.org/x/exp/cmd/gorelease) + OUTPUT=$(gorelease 2>&1 || exit 0) echo "${OUTPUT}" OUTPUT="${OUTPUT//$'\n'/%0A}" echo "::set-output name=report::$OUTPUT" diff --git a/.github/workflows/test-unit.yml b/.github/workflows/test-unit.yml index a1d30c9..2494dc4 100644 --- a/.github/workflows/test-unit.yml +++ b/.github/workflows/test-unit.yml @@ -16,11 +16,12 @@ env: GO111MODULE: "on" RUN_BASE_COVERAGE: "on" # Runs test for PR base in case base test coverage is missing. COV_GO_VERSION: 1.18.x # Version of Go to collect coverage + TARGET_DELTA_COV: 90 # Target coverage of changed lines, in percents jobs: test: strategy: matrix: - go-version: [ 1.16.x, 1.17.x, 1.18.x, tip ] + go-version: [ 1.16.x, 1.17.x, 1.18.x ] runs-on: ubuntu-latest steps: - name: Install Go stable @@ -28,6 +29,7 @@ jobs: uses: actions/setup-go@v3 with: go-version: ${{ matrix.go-version }} + - name: Install Go tip if: matrix.go-version == 'tip' run: | @@ -37,8 +39,10 @@ jobs: tar -C ~/sdk/gotip -xzf gotip.tar.gz ~/sdk/gotip/bin/go version echo "PATH=$HOME/go/bin:$HOME/sdk/gotip/bin/:$PATH" >> $GITHUB_ENV + - name: Checkout code uses: actions/checkout@v2 + - name: Go cache uses: actions/cache@v2 with: @@ -51,6 +55,7 @@ jobs: key: ${{ runner.os }}-go-cache-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ runner.os }}-go-cache + - name: Restore base test coverage id: base-coverage if: matrix.go-version == env.COV_GO_VERSION @@ -59,36 +64,51 @@ jobs: path: | unit-base.txt # Use base sha for PR or new commit hash for master/main push in test result key. - key: ${{ runner.os }}-unit-test-coverage-${{ (github.event.pull_request.base.sha != github.event.after) && github.event.pull_request.base.sha || github.event.after }} + key: ${{ runner.os }}-unit-test-base-coverage-${{ (github.event.pull_request.base.sha != github.event.after) && github.event.pull_request.base.sha || github.event.after }} + - name: Checkout base code if: matrix.go-version == env.COV_GO_VERSION && env.RUN_BASE_COVERAGE == 'on' && steps.base-coverage.outputs.cache-hit != 'true' && github.event.pull_request.base.sha != '' uses: actions/checkout@v2 with: ref: ${{ github.event.pull_request.base.sha }} path: __base + - name: Run test for base code if: matrix.go-version == env.COV_GO_VERSION && env.RUN_BASE_COVERAGE == 'on' && steps.base-coverage.outputs.cache-hit != 'true' && github.event.pull_request.base.sha != '' run: | cd __base - make | grep test-unit && (make test-unit && go tool cover -func=./unit.coverprofile | sed -e 's/.go:[0-9]*:\t/.go\t/g' | sed -e 's/\t\t*/\t/g' > ../unit-base.txt) || echo "No test-unit in base" + make | grep test-unit && (make test-unit && go tool cover -func=./unit.coverprofile > ../unit-base.txt) || echo "No test-unit in base" + - name: Test id: test run: | make test-unit - go tool cover -func=./unit.coverprofile | sed -e 's/.go:[0-9]*:\t/.go\t/g' | sed -e 's/\t\t*/\t/g' > unit.txt - OUTPUT=$(test -e unit-base.txt && (diff unit-base.txt unit.txt || exit 0) || cat unit.txt) - echo "${OUTPUT}" - OUTPUT="${OUTPUT//$'\n'/%0A}" + go tool cover -func=./unit.coverprofile > unit.txt TOTAL=$(grep 'total:' unit.txt) echo "${TOTAL}" - echo "::set-output name=diff::$OUTPUT" echo "::set-output name=total::$TOTAL" - - name: Store base coverage - if: ${{ github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main' }} - run: cp unit.txt unit-base.txt + + - name: Annotate missing test coverage + id: annotate + if: matrix.go-version == env.COV_GO_VERSION && github.event.pull_request.base.sha != '' + run: | + git fetch origin master ${{ github.event.pull_request.base.sha }} + curl -sLO https://github.com/vearutop/gocovdiff/releases/download/v1.3.3/linux_amd64.tar.gz && tar xf linux_amd64.tar.gz && echo "5408045c76208635f1aedf895f79e9e809dc3c42c961e3b20db8119174cffcf5 gocovdiff" | shasum -c + REP=$(./gocovdiff -cov unit.coverprofile -gha-annotations gha-unit.txt -delta-cov-file delta-cov-unit.txt -target-delta-cov ${TARGET_DELTA_COV}) + echo "${REP}" + REP="${REP//$'\n'/%0A}" + cat gha-unit.txt + test -e unit-base.txt && cat unit-base.txt + DIFF=$(test -e unit-base.txt && ./gocovdiff -func-cov unit.txt -func-base-cov unit-base.txt || echo "Missing base coverage file") + DIFF="${DIFF//$'\n'/%0A}" + TOTAL=$(cat delta-cov-unit.txt) + echo "::set-output name=rep::$REP" + echo "::set-output name=diff::$DIFF" + echo "::set-output name=total::$TOTAL" + - name: Comment Test Coverage continue-on-error: true - if: matrix.go-version == env.COV_GO_VERSION + if: matrix.go-version == env.COV_GO_VERSION && github.event.pull_request.base.sha != '' uses: marocchino/sticky-pull-request-comment@v2 with: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -96,13 +116,23 @@ jobs: message: | ### Unit Test Coverage ${{ steps.test.outputs.total }} + ${{ steps.annotate.outputs.total }} +
Coverage of changed lines + + ${{ steps.annotate.outputs.rep }} + +
+
Coverage diff with base branch - ```diff - ${{ steps.test.outputs.diff }} - ``` + ${{ steps.annotate.outputs.diff }} +
+ - name: Store base coverage + if: ${{ github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main' }} + run: cp unit.txt unit-base.txt + - name: Upload code coverage if: matrix.go-version == env.COV_GO_VERSION uses: codecov/codecov-action@v1 diff --git a/.golangci.yml b/.golangci.yml index 97710e1..9fa56cf 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -37,6 +37,8 @@ linters: - tagliatelle - errname - ireturn + - exhaustruct + - nonamedreturns issues: exclude-use-default: false diff --git a/Makefile b/Makefile index 77a5ec3..c181688 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -#GOLANGCI_LINT_VERSION := "v1.45.2" # Optional configuration to pinpoint golangci-lint version. +#GOLANGCI_LINT_VERSION := "v1.46.2" # Optional configuration to pinpoint golangci-lint version. # The head of Makefile determines location of dev-go to include standard targets. GO ?= go diff --git a/field.go b/field.go index dd7355c..d3e36fa 100644 --- a/field.go +++ b/field.go @@ -13,10 +13,18 @@ type DeferredString func() interface{} // String implements fmt.Stringer. func (d DeferredString) String() string { + if d == nil { + panic("ctxd: DeferredString is nil") + } + return fmt.Sprintf("%+v", d()) } // MarshalJSON implements json.Marshaler. func (d DeferredJSON) MarshalJSON() ([]byte, error) { + if d == nil { + panic("ctxd: DeferredJSON is nil") + } + return json.Marshal(d()) } diff --git a/field_test.go b/field_test.go index 6008f28..faa082b 100644 --- a/field_test.go +++ b/field_test.go @@ -15,4 +15,9 @@ func TestDeferredJSON_MarshalJSON(t *testing.T) { v, err := ctxd.DeferredJSON(func() interface{} { return []int{1, 2, 3} }).MarshalJSON() assert.NoError(t, err) assert.Equal(t, "[1,2,3]", string(v)) + + assert.Panics(t, func() { + _, err := ctxd.DeferredJSON(nil).MarshalJSON() + assert.NoError(t, err) // Unreachable. + }) } diff --git a/go.mod b/go.mod index 1d8e1a7..45fdbe3 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/bool64/ctxd go 1.17 require ( - github.com/bool64/dev v0.2.5 + github.com/bool64/dev v0.2.15 github.com/stretchr/testify v1.7.1 github.com/swaggest/usecase v1.1.2 ) diff --git a/go.sum b/go.sum index 7a4a08c..4b72749 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,6 @@ -github.com/bool64/dev v0.2.5 h1:H0bylghwcjDBBhEwSFTjArEO9Dr8cCaB54QSOF7esOA= github.com/bool64/dev v0.2.5/go.mod h1:cTHiTDNc8EewrQPy3p1obNilpMpdmlUesDkFTF2zRWU= +github.com/bool64/dev v0.2.15 h1:6fC2Z4hxl1CMRbGdwkK0WciHQOqtlIm1UJ/Hyx/Ly8w= +github.com/bool64/dev v0.2.15/go.mod h1:/csLrm+4oDSsKJRIVS0mrywAonLnYKFG8RvGT7Jh9b8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=