From 407c733e8ec1ad31c4969d3a0e11fc107c20dc6c Mon Sep 17 00:00:00 2001 From: Viacheslav Poturaev Date: Wed, 13 Jul 2022 17:38:31 +0200 Subject: [PATCH] Remove deprecated swgen, update CI (#14) --- .github/workflows/cloc.yml | 2 +- .github/workflows/golangci-lint.yml | 5 +- .github/workflows/gorelease.yml | 6 +- .github/workflows/test-unit.yml | 69 +++- .golangci.yml | 2 + Makefile | 2 +- amqp/doc.go | 2 - amqp/info.go | 67 --- amqp/info_test.go | 19 - go.mod | 21 +- go.sum | 43 +- reflector/asyncapi-2.0.0/reflect.go | 7 +- reflector/asyncapi-2.1.0/reflect.go | 7 +- reflector/asyncapi-2.1.0/sample.yaml | 18 +- spec-2.0.0/entities.go | 3 +- spec-2.1.0/entities.go | 6 +- spec/entities.go | 3 +- swgen/asyncapi-2.0.0/doc.go | 4 - swgen/asyncapi-2.0.0/example_test.go | 165 -------- swgen/asyncapi-2.0.0/gen.go | 187 --------- swgen/asyncapi-2.0.0/gen_test.go | 79 ---- swgen/asyncapi-2.0.0/sample.md | 414 ------------------- swgen/asyncapi-2.0.0/sample.yaml | 79 ---- swgen/asyncapi/doc.go | 4 - swgen/asyncapi/example_test.go | 163 -------- swgen/asyncapi/gen.go | 182 --------- swgen/asyncapi/gen_test.go | 79 ---- swgen/asyncapi/sample.md | 581 --------------------------- swgen/asyncapi/sample.yaml | 81 ---- 29 files changed, 108 insertions(+), 2192 deletions(-) delete mode 100644 amqp/doc.go delete mode 100644 amqp/info.go delete mode 100644 amqp/info_test.go delete mode 100644 swgen/asyncapi-2.0.0/doc.go delete mode 100644 swgen/asyncapi-2.0.0/example_test.go delete mode 100644 swgen/asyncapi-2.0.0/gen.go delete mode 100644 swgen/asyncapi-2.0.0/gen_test.go delete mode 100644 swgen/asyncapi-2.0.0/sample.md delete mode 100644 swgen/asyncapi-2.0.0/sample.yaml delete mode 100644 swgen/asyncapi/doc.go delete mode 100644 swgen/asyncapi/example_test.go delete mode 100644 swgen/asyncapi/gen.go delete mode 100644 swgen/asyncapi/gen_test.go delete mode 100644 swgen/asyncapi/sample.md delete mode 100644 swgen/asyncapi/sample.yaml 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 a0f4185..48207f9 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -19,12 +19,15 @@ jobs: name: golangci-lint runs-on: ubuntu-latest steps: + - uses: actions/setup-go@v3 + with: + go-version: 1.18.x - uses: actions/checkout@v2 - name: golangci-lint 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.0 + 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 80fa588..f1c678a 100644 --- a/.github/workflows/gorelease.yml +++ b/.github/workflows/gorelease.yml @@ -16,7 +16,7 @@ jobs: steps: - name: Install Go stable if: env.GO_VERSION != 'tip' - uses: actions/setup-go@v2 + uses: actions/setup-go@v3 with: go-version: ${{ env.GO_VERSION }} - name: Install Go tip @@ -35,12 +35,12 @@ jobs: with: path: | ~/go/bin/gorelease - key: ${{ runner.os }}-gorelease + key: ${{ runner.os }}-gorelease-generic - name: Gorelease id: gorelease run: | test -e ~/go/bin/gorelease || go install golang.org/x/exp/cmd/gorelease@latest - OUTPUT=$(gorelease || exit 0) + 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 97ff2c0..cb01973 100644 --- a/.github/workflows/test-unit.yml +++ b/.github/workflows/test-unit.yml @@ -16,6 +16,7 @@ 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: @@ -25,9 +26,10 @@ jobs: steps: - name: Install Go stable if: matrix.go-version != 'tip' - uses: actions/setup-go@v2 + 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,44 +55,55 @@ 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 + if: matrix.go-version == env.COV_GO_VERSION && github.event.pull_request.base.sha != '' uses: actions/cache@v2 with: 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 }} - - 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" + git fetch origin master ${{ github.event.pull_request.base.sha }} + HEAD=$(git rev-parse HEAD) + git reset --hard ${{ github.event.pull_request.base.sha }} + (make test-unit && go tool cover -func=./unit.coverprofile > unit-base.txt) || echo "No test-unit in base" + git reset --hard $HEAD + - 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.4/linux_amd64.tar.gz && tar xf linux_amd64.tar.gz && shasum -a 256 gocovdiff && echo "b351c67526eefeb0671c82e9271ae984875865eed19e911f40f78348cb98347c 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 + 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 +111,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 d919df1..1cdb4eb 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -41,6 +41,8 @@ linters: - tagliatelle - errname - ireturn + - exhaustruct + - nonamedreturns issues: exclude-use-default: false diff --git a/Makefile b/Makefile index f2d37bb..34ee608 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -#GOLANGCI_LINT_VERSION := "v1.45.0" # 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/amqp/doc.go b/amqp/doc.go deleted file mode 100644 index 46d11e4..0000000 --- a/amqp/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package amqp provides a helper to add AMQP information to AsyncAPI 1.2.0 schema. -package amqp diff --git a/amqp/info.go b/amqp/info.go deleted file mode 100644 index 4c7a53e..0000000 --- a/amqp/info.go +++ /dev/null @@ -1,67 +0,0 @@ -// Package amqp implements helper to extend AsyncAPI spec -package amqp - -import ( - "strings" - - "github.com/swaggest/go-asyncapi/swgen/asyncapi" // nolint:staticcheck // Deprecated. -) - -const ( - // Exchange defines spec key. - Exchange = "x-amqp-exchange" - // Exchanges defines spec key. - Exchanges = "x-amqp-exchanges" - // VHost defines spec key. - VHost = "x-amqp-vhost" - // Queue defines spec key. - Queue = "x-amqp-queue" -) - -// Info keeps amqp topic information. -type Info struct { - VHost string `json:"vhost,omitempty"` - Exchange string `json:"exchange,omitempty"` - Exchanges []string `json:"exchanges,omitempty"` - Queue string `json:"queue,omitempty"` -} - -// MessageWithInfo injects amqp info into topic info. -func MessageWithInfo(msg *asyncapi.Message, amqpInfo Info) *asyncapi.Message { - if msg == nil { - msg = &asyncapi.Message{} - } - - if msg.MapOfAnythingValues == nil { - msg.MapOfAnythingValues = map[string]interface{}{} - } - - if amqpInfo.VHost != "" { - msg.MapOfAnythingValues[VHost] = amqpInfo.VHost - msg.Description += "\n\nAMQP VHost: " + amqpInfo.VHost + "." - } - - if len(amqpInfo.Exchanges) > 0 { - if amqpInfo.Exchange != "" { - amqpInfo.Exchanges = append(amqpInfo.Exchanges, amqpInfo.Exchange) - amqpInfo.Exchange = "" - } - - msg.MapOfAnythingValues[Exchanges] = amqpInfo.Exchanges - msg.Description += "\n\nAMQP Exchanges: " + strings.Join(amqpInfo.Exchanges, ", ") + "." - } - - if amqpInfo.Exchange != "" { - msg.MapOfAnythingValues[Exchange] = amqpInfo.Exchange - msg.Description += "\n\nAMQP Exchange: " + amqpInfo.Exchange + "." - } - - if amqpInfo.Queue != "" { - msg.MapOfAnythingValues[Queue] = amqpInfo.Queue - msg.Description += "\n\nAMQP Queue: " + amqpInfo.Queue + "." - } - - msg.Description = strings.TrimLeft(msg.Description, "\n") - - return msg -} diff --git a/amqp/info_test.go b/amqp/info_test.go deleted file mode 100644 index 8a55770..0000000 --- a/amqp/info_test.go +++ /dev/null @@ -1,19 +0,0 @@ -package amqp_test - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "github.com/swaggest/go-asyncapi/amqp" -) - -func TestMessageWithInfo(t *testing.T) { - m := amqp.MessageWithInfo(nil, amqp.Info{ - Exchanges: []string{"some-exchange", "another-exchange"}, - VHost: "some-vhost", - }) - - assert.Equal(t, "AMQP VHost: some-vhost.\n\nAMQP Exchanges: some-exchange, another-exchange.", m.Description) - assert.Equal(t, []string{"some-exchange", "another-exchange"}, m.MapOfAnythingValues[amqp.Exchanges]) - assert.Equal(t, "some-vhost", m.MapOfAnythingValues[amqp.VHost]) -} diff --git a/go.mod b/go.mod index 39f39cb..466ca54 100644 --- a/go.mod +++ b/go.mod @@ -3,24 +3,25 @@ module github.com/swaggest/go-asyncapi go 1.17 require ( - github.com/bool64/dev v0.2.8 - github.com/pkg/errors v0.9.1 - github.com/stretchr/testify v1.7.1 - github.com/swaggest/assertjson v1.6.8 - github.com/swaggest/jsonschema-go v0.3.25 - github.com/swaggest/swgen v0.6.28 + github.com/bool64/dev v0.2.17 + github.com/stretchr/testify v1.8.0 + github.com/swaggest/assertjson v1.7.0 + github.com/swaggest/jsonschema-go v0.3.35 gopkg.in/yaml.v2 v2.4.0 ) require ( - github.com/bool64/shared v0.1.4 // indirect + github.com/bool64/shared v0.1.5 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/iancoleman/orderedmap v0.2.0 // indirect + github.com/mattn/go-isatty v0.0.12 // indirect + github.com/nxadm/tail v1.4.8 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/sergi/go-diff v1.2.0 // indirect - github.com/swaggest/openapi-go v0.2.10 // indirect - github.com/swaggest/refl v1.0.1 // indirect + github.com/swaggest/refl v1.1.0 // indirect github.com/yudai/gojsondiff v1.0.0 // indirect github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect - gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect + golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb // indirect + golang.org/x/sys v0.0.0-20210112080510-489259a85091 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 535a3ab..4c80b87 100644 --- a/go.sum +++ b/go.sum @@ -1,15 +1,14 @@ -github.com/bool64/dev v0.1.17/go.mod h1:cTHiTDNc8EewrQPy3p1obNilpMpdmlUesDkFTF2zRWU= github.com/bool64/dev v0.1.25/go.mod h1:cTHiTDNc8EewrQPy3p1obNilpMpdmlUesDkFTF2zRWU= -github.com/bool64/dev v0.1.27/go.mod h1:cTHiTDNc8EewrQPy3p1obNilpMpdmlUesDkFTF2zRWU= -github.com/bool64/dev v0.1.33/go.mod h1:cTHiTDNc8EewrQPy3p1obNilpMpdmlUesDkFTF2zRWU= github.com/bool64/dev v0.1.41/go.mod h1:cTHiTDNc8EewrQPy3p1obNilpMpdmlUesDkFTF2zRWU= -github.com/bool64/dev v0.1.42/go.mod h1:cTHiTDNc8EewrQPy3p1obNilpMpdmlUesDkFTF2zRWU= github.com/bool64/dev v0.2.5/go.mod h1:cTHiTDNc8EewrQPy3p1obNilpMpdmlUesDkFTF2zRWU= -github.com/bool64/dev v0.2.8 h1:6T1hugHixocOGxLF2bus0knc7EOrXTQ7yTTFZ3F4q/U= -github.com/bool64/dev v0.2.8/go.mod h1:/csLrm+4oDSsKJRIVS0mrywAonLnYKFG8RvGT7Jh9b8= +github.com/bool64/dev v0.2.10/go.mod h1:/csLrm+4oDSsKJRIVS0mrywAonLnYKFG8RvGT7Jh9b8= +github.com/bool64/dev v0.2.16/go.mod h1:/csLrm+4oDSsKJRIVS0mrywAonLnYKFG8RvGT7Jh9b8= +github.com/bool64/dev v0.2.17 h1:jE+T92oazAIV8fvMDJrKjsF1bzfr5XezZ8bM5GS1Cl0= +github.com/bool64/dev v0.2.17/go.mod h1:iJbh1y/HkunEPhgebWRNcs8wfGq7sjvJ6W5iabL8ACg= github.com/bool64/shared v0.1.3/go.mod h1:RF1p1Oi29ofgOvinBpetbF5mceOUP3kpMkvLbWOmtm0= -github.com/bool64/shared v0.1.4 h1:zwtb1dl2QzDa9TJOq2jzDTdb5IPf9XlxTGKN8cySWT0= github.com/bool64/shared v0.1.4/go.mod h1:ryGjsnQFh6BnEXClfVlEJrzjwzat7CmA8PNS5E+jPp0= +github.com/bool64/shared v0.1.5 h1:fp3eUhBsrSjNCQPcSdQqZxxh9bBwrYiZ+zOKFkM0/2E= +github.com/bool64/shared v0.1.5/go.mod h1:081yz68YC9jeFB3+Bbmno2RFWvGKv1lPKkMP6MHJlPs= 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= @@ -51,32 +50,25 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.11.0 h1:+CqWgvj0OZycCaqclBD1pxKHAU+tOkHmQIWvDHq2aug= github.com/onsi/gomega v1.11.0/go.mod h1:azGKhqFUon9Vuj0YmTfLSmx0FUwqXYSTl5re8lQLTUg= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/swaggest/assertjson v1.6.4/go.mod h1:HAXV18oavcbNHwN6wvfzYVrLuAoi3/mJ6sN0ZgNMX9U= -github.com/swaggest/assertjson v1.6.8 h1:1O/9UI5M+2OJI7BeEWKGj0wTvpRXZt5FkOJ4nRkY4rA= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/swaggest/assertjson v1.6.8/go.mod h1:Euf0upn9Vlaf1/llYHTs+Kx5K3vVbpMbsZhth7zlN7M= -github.com/swaggest/jsonschema-go v0.3.19/go.mod h1:NQCceV7I4/UuAy0IwCaDzgyN9ODl9F1s6/egrE2pC3U= -github.com/swaggest/jsonschema-go v0.3.25 h1:HH3iaQ9OAgNC1IZiyOys0qXGIdYAzxT2fMSQRzkN3Ys= -github.com/swaggest/jsonschema-go v0.3.25/go.mod h1:e5wN7j5yYCO8zZ5YL1ekKfcaphBNcr2YbaoceDNWatI= -github.com/swaggest/openapi-go v0.2.10 h1:/4dDhAQdfXIhhsmksH8H4KM++fD7IRH9OEWmoIxW5/s= -github.com/swaggest/openapi-go v0.2.10/go.mod h1:WiDt058r76xA60rTQQtKFXV61X32ANHtNakhvuchE/Y= -github.com/swaggest/refl v0.1.7/go.mod h1:acYd5x8NNxivp+ZHdRZKJYz66n/qjo3Q9Sa/jAivljQ= -github.com/swaggest/refl v1.0.0/go.mod h1:acYd5x8NNxivp+ZHdRZKJYz66n/qjo3Q9Sa/jAivljQ= -github.com/swaggest/refl v1.0.1 h1:YQHb7Ic6EMpdUpxQmTWmf/O4IWN6iIErxJNWA7LwyyM= -github.com/swaggest/refl v1.0.1/go.mod h1:dnx+n9YaI0o+FH+OR2tJZWLABBVIPs9qc4VY9UdrhLE= -github.com/swaggest/swgen v0.6.28 h1:FNGiIX/327gK1HVPx/4m0KFvY1Yu9T1Dptu52uFgw98= -github.com/swaggest/swgen v0.6.28/go.mod h1:EDTM45lbwTSJsNbUooKHgXXU84wyAvtnMjM4055EJaI= +github.com/swaggest/assertjson v1.7.0 h1:SKw5Rn0LQs6UvmGrIdaKQbMR1R3ncXm5KNon+QJ7jtw= +github.com/swaggest/assertjson v1.7.0/go.mod h1:vxMJMehbSVJd+dDWFCKv3QRZKNTpy/ktZKTz9LOEDng= +github.com/swaggest/jsonschema-go v0.3.35 h1:LW5DC0WgR5YdQXyTRc5e8gLdKT0wkACg4aVJyaseU+4= +github.com/swaggest/jsonschema-go v0.3.35/go.mod h1:JAF1nm+uIaMOXktuQepmkiRcgQ5yJk4Ccwx9HVt2cXw= +github.com/swaggest/refl v1.0.2/go.mod h1:DoiPoBJPYHU6Z9fIA6zXQ9uI6VRL6M8BFX5YFT+ym9g= +github.com/swaggest/refl v1.1.0 h1:a+9a75Kv6ciMozPjVbOfcVTEQe81t2R3emvaD9oGQGc= +github.com/swaggest/refl v1.1.0/go.mod h1:g3Qa6ki0A/L2yxiuUpT+cuBURuRaltF5SDQpg1kMZSY= github.com/yosuke-furukawa/json5 v0.1.2-0.20201207051438-cf7bb3f354ff/go.mod h1:sw49aWDqNdRJ6DYUtIQiaA3xyj2IL9tjeNYmX2ixwcU= github.com/yudai/gojsondiff v1.0.0 h1:27cbfqXLVEJ1o8I6v3y9lg8Ydm53EKqHXAOMxEGlCOA= github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= @@ -139,5 +131,6 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/reflector/asyncapi-2.0.0/reflect.go b/reflector/asyncapi-2.0.0/reflect.go index 4ca515b..3b6765e 100644 --- a/reflector/asyncapi-2.0.0/reflect.go +++ b/reflector/asyncapi-2.0.0/reflect.go @@ -3,9 +3,10 @@ package asyncapi import ( "encoding/json" + "errors" + "fmt" "strings" - "github.com/pkg/errors" "github.com/swaggest/go-asyncapi/spec-2.0.0" "github.com/swaggest/jsonschema-go" ) @@ -67,14 +68,14 @@ func (r *Reflector) AddChannel(info ChannelInfo) error { if info.Publish != nil { channelItem.Publish, err = r.makeOperation(&channelItem, info.Publish) if err != nil { - return errors.Wrapf(err, "failed process publish operation for channel %s", info.Name) + return fmt.Errorf("failed process publish operation for channel %s: %w", info.Name, err) } } if info.Subscribe != nil { channelItem.Subscribe, err = r.makeOperation(&channelItem, info.Subscribe) if err != nil { - return errors.Wrapf(err, "failed process subscribe operation for channel %s", info.Name) + return fmt.Errorf("failed process subscribe operation for channel %s: %w", info.Name, err) } } diff --git a/reflector/asyncapi-2.1.0/reflect.go b/reflector/asyncapi-2.1.0/reflect.go index 1a9ba59..bcdb233 100644 --- a/reflector/asyncapi-2.1.0/reflect.go +++ b/reflector/asyncapi-2.1.0/reflect.go @@ -3,9 +3,10 @@ package asyncapi import ( "encoding/json" + "errors" + "fmt" "strings" - "github.com/pkg/errors" "github.com/swaggest/go-asyncapi/spec-2.1.0" "github.com/swaggest/jsonschema-go" ) @@ -67,14 +68,14 @@ func (r *Reflector) AddChannel(info ChannelInfo) error { if info.Publish != nil { channelItem.Publish, err = r.makeOperation(&channelItem, info.Publish) if err != nil { - return errors.Wrapf(err, "failed process publish operation for channel %s", info.Name) + return fmt.Errorf("failed process publish operation for channel %s: %w", info.Name, err) } } if info.Subscribe != nil { channelItem.Subscribe, err = r.makeOperation(&channelItem, info.Subscribe) if err != nil { - return errors.Wrapf(err, "failed process subscribe operation for channel %s", info.Name) + return fmt.Errorf("failed process subscribe operation for channel %s: %w", info.Name, err) } } diff --git a/reflector/asyncapi-2.1.0/sample.yaml b/reflector/asyncapi-2.1.0/sample.yaml index 20b7921..ce098ad 100644 --- a/reflector/asyncapi-2.1.0/sample.yaml +++ b/reflector/asyncapi-2.1.0/sample.yaml @@ -11,10 +11,10 @@ servers: variables: country: enum: - - RU - - US - - DE - - FR + - RU + - US + - DE + - FR default: US description: Country code. channels: @@ -55,8 +55,8 @@ components: items: $ref: '#/components/schemas/Asyncapi210TestSubItem' type: - - array - - "null" + - array + - "null" type: object Asyncapi210TestSubItem: properties: @@ -68,8 +68,8 @@ components: items: type: integer type: - - array - - "null" + - array + - "null" uniqueItems: true type: object messages: @@ -80,7 +80,7 @@ components: description: Tracing header type: string required: - - X-Trace-ID + - X-Trace-ID type: object payload: $ref: '#/components/schemas/Asyncapi210TestMyAnotherMessage' diff --git a/spec-2.0.0/entities.go b/spec-2.0.0/entities.go index ebc52f3..8bff668 100644 --- a/spec-2.0.0/entities.go +++ b/spec-2.0.0/entities.go @@ -5638,8 +5638,7 @@ func (n NonBearerHTTPSecurityScheme) MarshalJSON() ([]byte, error) { } // NonBearerHTTPSecuritySchemeNot structure is generated from "#/definitions/NonBearerHTTPSecurityScheme->not". -type NonBearerHTTPSecuritySchemeNot struct { -} +type NonBearerHTTPSecuritySchemeNot struct{} // UnmarshalJSON decodes JSON. func (n *NonBearerHTTPSecuritySchemeNot) UnmarshalJSON(data []byte) error { diff --git a/spec-2.1.0/entities.go b/spec-2.1.0/entities.go index 51c66ea..dbed4e8 100644 --- a/spec-2.1.0/entities.go +++ b/spec-2.1.0/entities.go @@ -3092,8 +3092,7 @@ func (m MessageEntity) MarshalJSON() ([]byte, error) { } // MessageOneOf1OneOf1HeadersAllOf1 structure is generated from "#/definitions/message/oneOf/1/oneOf/1->headers/allOf/1". -type MessageOneOf1OneOf1HeadersAllOf1 struct { -} +type MessageOneOf1OneOf1HeadersAllOf1 struct{} // UnmarshalJSON decodes JSON. func (m *MessageOneOf1OneOf1HeadersAllOf1) UnmarshalJSON(data []byte) error { @@ -5981,8 +5980,7 @@ func (n NonBearerHTTPSecurityScheme) MarshalJSON() ([]byte, error) { } // NonBearerHTTPSecuritySchemeNot structure is generated from "#/definitions/NonBearerHTTPSecurityScheme->not". -type NonBearerHTTPSecuritySchemeNot struct { -} +type NonBearerHTTPSecuritySchemeNot struct{} // UnmarshalJSON decodes JSON. func (n *NonBearerHTTPSecuritySchemeNot) UnmarshalJSON(data []byte) error { diff --git a/spec/entities.go b/spec/entities.go index ea80b95..b2c2e82 100644 --- a/spec/entities.go +++ b/spec/entities.go @@ -650,8 +650,7 @@ func (i StreamFramingOneOf0) MarshalJSON() ([]byte, error) { } // StreamFramingOneOf1 structure is generated from "#/definitions/stream->framing/oneOf/1". -type StreamFramingOneOf1 struct { -} +type StreamFramingOneOf1 struct{} type marshalStreamFramingOneOf1 StreamFramingOneOf1 diff --git a/swgen/asyncapi-2.0.0/doc.go b/swgen/asyncapi-2.0.0/doc.go deleted file mode 100644 index e0fa26b..0000000 --- a/swgen/asyncapi-2.0.0/doc.go +++ /dev/null @@ -1,4 +0,0 @@ -// Package asyncapi implements reflection-based AsyncAPI 2.0.0 schema generator. -// -// Deprecated: use github.com/swaggest/go-asyncapi/reflector/asyncapi-2.0.0. -package asyncapi diff --git a/swgen/asyncapi-2.0.0/example_test.go b/swgen/asyncapi-2.0.0/example_test.go deleted file mode 100644 index 4b32e6f..0000000 --- a/swgen/asyncapi-2.0.0/example_test.go +++ /dev/null @@ -1,165 +0,0 @@ -package asyncapi_test - -import ( - "fmt" - "io/ioutil" - "time" - - "github.com/swaggest/go-asyncapi/spec-2.0.0" - "github.com/swaggest/go-asyncapi/swgen/asyncapi-2.0.0" // nolint:staticcheck // Deprecated. -) - -func ExampleGenerator_AddChannel() { - type SubItem struct { - Key string `json:"key" description:"Item key"` - Values []int64 `json:"values" uniqueItems:"true" description:"List of item values"` - } - - type MyMessage struct { - Name string `path:"name" description:"Name"` - CreatedAt time.Time `json:"createdAt" description:"Creation time"` - Items []SubItem `json:"items" description:"List of items"` - } - - type MyAnotherMessage struct { - TraceID string `header:"X-Trace-ID" description:"Tracing header" required:"true"` - Item SubItem `json:"item" description:"Some item"` - } - - g := asyncapi.Generator{ - Data: spec.AsyncAPI{ - Servers: map[string]spec.Server{ - "production": { - URL: "api.lovely.com:{port}", - Protocol: "amqp", - }, - }, - Info: spec.Info{ - Version: "1.2.3", // required - Title: "My Lovely Messaging API", - }, - }, - } - must := func(err error) { - if err != nil { - panic(err.Error()) - } - } - must(g.AddChannel(asyncapi.ChannelInfo{ - Name: "one.{name}.two", - BaseChannelItem: &spec.ChannelItem{ - Bindings: &spec.ChannelBindingsObject{ - Amqp: &spec.AMQP091ChannelBindingObject{ - Is: spec.AMQP091ChannelBindingObjectIsRoutingKey, - Exchange: &spec.Exchange{ - Name: "some-exchange", - }, - }, - }, - }, - Publish: &asyncapi.Message{ - MessageEntity: spec.MessageEntity{ - Description: "This is a sample schema.", - Summary: "Sample publisher", - }, - MessageSample: new(MyMessage), - }, - })) - - must(g.AddChannel(asyncapi.ChannelInfo{ - Name: "another.one", - Subscribe: &asyncapi.Message{ - MessageEntity: spec.MessageEntity{ - Description: "This is another sample schema.", - Summary: "Sample consumer", - }, - MessageSample: new(MyAnotherMessage), - }, - })) - - yaml, err := g.Data.MarshalYAML() - must(err) - - fmt.Println(string(yaml)) - must(ioutil.WriteFile("sample.yaml", yaml, 0o600)) - // output: - // asyncapi: 2.0.0 - // info: - // title: My Lovely Messaging API - // version: 1.2.3 - // servers: - // production: - // url: api.lovely.com:{port} - // protocol: amqp - // channels: - // another.one: - // subscribe: - // message: - // $ref: '#/components/messages/MyAnotherMessage' - // one.{name}.two: - // parameters: - // name: - // description: Name - // schema: - // description: Name - // type: string - // publish: - // message: - // $ref: '#/components/messages/MyMessage' - // bindings: - // amqp: - // is: routingKey - // exchange: - // name: some-exchange - // components: - // schemas: - // MyAnotherMessage: - // properties: - // item: - // $ref: '#/components/schemas/SubItem' - // type: object - // MyMessage: - // properties: - // createdAt: - // description: Creation time - // format: date-time - // type: string - // items: - // description: List of items - // items: - // $ref: '#/components/schemas/SubItem' - // type: array - // type: object - // SubItem: - // properties: - // key: - // description: Item key - // type: string - // values: - // description: List of item values - // items: - // format: int64 - // type: integer - // type: array - // uniqueItems: true - // type: object - // messages: - // MyAnotherMessage: - // headers: - // properties: - // X-Trace-ID: - // description: Tracing header - // type: string - // required: - // - X-Trace-ID - // type: object - // payload: - // $ref: '#/components/schemas/MyAnotherMessage' - // summary: Sample consumer - // description: This is another sample schema. - // MyMessage: - // payload: - // $ref: '#/components/schemas/MyMessage' - // summary: Sample publisher - // description: This is a sample schema. -} diff --git a/swgen/asyncapi-2.0.0/gen.go b/swgen/asyncapi-2.0.0/gen.go deleted file mode 100644 index 2083e74..0000000 --- a/swgen/asyncapi-2.0.0/gen.go +++ /dev/null @@ -1,187 +0,0 @@ -package asyncapi - -import ( - "net/http" - "strings" - - "github.com/pkg/errors" - "github.com/swaggest/go-asyncapi/spec-2.0.0" - "github.com/swaggest/swgen" -) - -// Generator generates AsyncAPI definitions from provided message samples. -type Generator struct { - Swg *swgen.Generator - Data spec.AsyncAPI - - channelInfos map[string]ChannelInfo -} - -// Message is a structure that keeps general info and message sample (optional). -type Message struct { - // pkg.Message holds general message info. - spec.MessageEntity - - // MessageSample holds a sample of message to be converted to JSON Schema, e.g. `new(MyMessage)`. - MessageSample interface{} -} - -// ChannelInfo keeps user-defined information about channel. -type ChannelInfo struct { - Name string // event.{streetlightId}.lighting.measured - Publish *Message - Subscribe *Message - BaseChannelItem *spec.ChannelItem // Optional, if set is used as a base to fill with Message data -} - -// AddChannel adds user-defined channel to AsyncAPI definition. -func (g *Generator) AddChannel(info ChannelInfo) error { - if info.Name == "" { - return errors.New("name is required") - } - - var ( - channelItem = spec.ChannelItem{} - err error - ) - - if info.BaseChannelItem != nil { - channelItem = *info.BaseChannelItem - } - - if g.Swg == nil { - g.Swg = swgen.NewGenerator() - } - - if g.Data.Components == nil { - g.Data.Components = &spec.Components{} - } - - if g.Data.Components.Schemas == nil { - g.Data.Components.Schemas = make(map[string]map[string]interface{}) - } - - if g.Data.Components.Messages == nil { - g.Data.Components.Messages = make(map[string]spec.Message) - } - - if info.Publish != nil { - channelItem.Publish, err = g.makeOperation("publish", info, &channelItem, info.Publish) - if err != nil { - return errors.Wrapf(err, "failed process publish operation for channel %s", info.Name) - } - } - - if info.Subscribe != nil { - channelItem.Subscribe, err = g.makeOperation("subscribe", info, &channelItem, info.Subscribe) - if err != nil { - return errors.Wrapf(err, "failed process subscribe operation for channel %s", info.Name) - } - } - - if g.Data.Channels == nil { - g.Data.Channels = make(map[string]spec.ChannelItem) - } - - g.Data.Channels[info.Name] = channelItem - - return nil -} - -func (g *Generator) makeOperation(intent string, info ChannelInfo, channelItem *spec.ChannelItem, m *Message) (*spec.Operation, error) { - if m.MessageSample == nil { - return &spec.Operation{ - Message: &spec.Message{ - Entity: &m.MessageEntity, - }, - }, nil - } - - if g.channelInfos == nil { - g.channelInfos = make(map[string]ChannelInfo) - } - - path := "/" + intent + "/" + info.Name - g.channelInfos[path] = info - - fakeInfo := swgen.PathItemInfo{ - Path: path, - Method: http.MethodPost, - Request: m.MessageSample, - Response: m.MessageSample, - } - obj := g.Swg.SetPathItem(fakeInfo) - - cfg := swgen.JSONSchemaConfig{ - DefinitionsPrefix: "#/components/schemas/", - StripDefinitions: true, - CollectDefinitions: g.Data.Components.Schemas, - } - - groups, err := g.Swg.GetJSONSchemaRequestGroups(obj, cfg) - if err != nil { - return nil, errors.Wrap(err, "failed to make schema") - } - - msg := m.MessageEntity - if headerSchema, ok := groups[`header`]; ok { - msg.Headers, err = headerSchema.ToMap() - if err != nil { - return nil, err - } - - delete(msg.Headers, "$schema") - } - - body, err := g.Swg.GetJSONSchemaRequestBody(obj, cfg) - if err != nil { - return nil, errors.Wrap(err, "failed to make body schema") - } - - msg.Payload = body - - for _, param := range obj.Parameters { - if param.In == `path` { - schema, err := g.Swg.ParamJSONSchema(param, cfg) - if err != nil { - return nil, errors.Wrapf(err, "failed to process param schema for %s", param.Name) - } - - if channelItem.Parameters == nil { - channelItem.Parameters = map[string]spec.Parameter{} - } - - channelItem.Parameters[param.Name] = spec.Parameter{ - Description: param.Description, - Schema: schema, - } - } - } - - if ref, ok := msg.Payload["$ref"].(string); ok && ref != "" { - messageName := strings.TrimPrefix(ref, "#/components/schemas/") - g.Data.Components.Messages[messageName] = spec.Message{ - Entity: &msg, - } - - return &spec.Operation{ - Message: &spec.Message{ - Reference: &spec.Reference{Ref: "#/components/messages/" + messageName}, - }, - }, nil - } - - return &spec.Operation{ - Message: &spec.Message{ - Entity: &msg, - }, - }, nil -} - -// WalkJSONSchemas iterates thorough message payload schemas. -func (g *Generator) WalkJSONSchemas(w func(isPublishing bool, info ChannelInfo, schema map[string]interface{})) error { - return g.Swg.WalkJSONSchemaResponses(func(path, _ string, _ int, schema map[string]interface{}) { - intent := strings.Split(path, "/")[1] - w(intent == "publish", g.channelInfos[path], schema) - }) -} diff --git a/swgen/asyncapi-2.0.0/gen_test.go b/swgen/asyncapi-2.0.0/gen_test.go deleted file mode 100644 index de249f6..0000000 --- a/swgen/asyncapi-2.0.0/gen_test.go +++ /dev/null @@ -1,79 +0,0 @@ -package asyncapi_test - -import ( - "encoding/json" - "testing" - "time" - - "github.com/stretchr/testify/assert" - "github.com/swaggest/go-asyncapi/spec-2.0.0" - "github.com/swaggest/go-asyncapi/swgen/asyncapi-2.0.0" // nolint:staticcheck // Deprecated. -) - -func TestGenerator_WalkJSONSchemas(t *testing.T) { - type SubItem struct { - Key string `json:"key" description:"Item key"` - Values []int64 `json:"values" uniqueItems:"true" description:"List of item values"` - } - - type MyMessage struct { - Name string `path:"name" description:"Name"` - CreatedAt time.Time `json:"createdAt" description:"Creation time"` - Items []SubItem `json:"items" description:"List of items"` - } - - type MyAnotherMessage struct { - TraceID string `header:"X-Trace-ID" description:"Tracing header" required:"true"` - Item SubItem `json:"item" description:"Some item"` - } - - g := asyncapi.Generator{ - Data: spec.AsyncAPI{ - Servers: map[string]spec.Server{ - "production": { - URL: "api.lovely.com:{port}", - Protocol: "amqp", - ProtocolVersion: "AMQP 0.9.1", - }, - }, - Info: spec.Info{ - Version: "1.2.3", // required - Title: "My Lovely Messaging API", - }, - }, - } - assert.NoError(t, g.AddChannel(asyncapi.ChannelInfo{ - Name: "one.{name}.two", - Publish: &asyncapi.Message{ - MessageEntity: spec.MessageEntity{ - Description: "This is a sample schema", - Summary: "Sample publisher", - }, - MessageSample: new(MyMessage), - }, - })) - - assert.NoError(t, g.AddChannel(asyncapi.ChannelInfo{ - Name: "another.one", - Subscribe: &asyncapi.Message{ - MessageEntity: spec.MessageEntity{ - Description: "This is another sample schema", - Summary: "Sample consumer", - }, - MessageSample: new(MyAnotherMessage), - }, - })) - - assert.NoError(t, g.WalkJSONSchemas(func(isPublishing bool, info asyncapi.ChannelInfo, schema map[string]interface{}) { - js, err := json.Marshal(schema) - assert.NoError(t, err) - switch info.Name { - case "one.{name}.two": - assert.Equal(t, `{"$schema":"http://json-schema.org/draft-04/schema#","definitions":{"SubItem":{"properties":{"key":{"description":"Item key","type":"string"},"values":{"description":"List of item values","items":{"format":"int64","type":"integer"},"type":"array","uniqueItems":true}},"type":"object"}},"properties":{"createdAt":{"description":"Creation time","format":"date-time","type":"string"},"items":{"description":"List of items","items":{"$ref":"#/definitions/SubItem"},"type":"array"}},"type":"object"}`, string(js)) - case "another.one": - assert.Equal(t, `{"$schema":"http://json-schema.org/draft-04/schema#","definitions":{"SubItem":{"properties":{"key":{"description":"Item key","type":"string"},"values":{"description":"List of item values","items":{"format":"int64","type":"integer"},"type":"array","uniqueItems":true}},"type":"object"}},"properties":{"item":{"$ref":"#/definitions/SubItem"}},"type":"object"}`, string(js)) - default: - t.Fatal("should not get here") - } - })) -} diff --git a/swgen/asyncapi-2.0.0/sample.md b/swgen/asyncapi-2.0.0/sample.md deleted file mode 100644 index a929a72..0000000 --- a/swgen/asyncapi-2.0.0/sample.md +++ /dev/null @@ -1,414 +0,0 @@ -# My Lovely Messaging API 1.2.3 documentation - - - - - -## Table of Contents - - - -* [Servers](#servers) - - -* [Channels](#channels) - - - - - - -## Servers - - - - - - - - - - - - - - - - - - - -
URLProtocolDescription
api.lovely.com:{port}amqp
-
- URL Variables - - - - - - - - - - - -
NameDefault valuePossible valuesDescription
-
-
- - - - - - -## Channels - - - - - - - - - -#### Channel Parameters - - - - - - - -### `subscribe` another.one - -#### Message - - - -Sample consumer - - - -This is another sample schema. - - - -##### Headers - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionAccepted values
X-Trace-ID string

Tracing header

-
Any
- - - -###### Example of headers _(generated)_ - -```json -{ - "X-Trace-ID": "string" -} -``` - - - - -##### Payload - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionAccepted values
item objectAny
item.key string

Item key

-
Any
item.values array(integer)

List of item values

-
Any
- - - -###### Example of payload _(generated)_ - -```json -{ - "item": { - "key": "string", - "values": [ - 0 - ] - } -} -``` - - - - - - - - - - - - - - -#### Channel Parameters - - - -##### name - - -Name - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionAccepted values
name string

Name

-
Any
- - - - - -### `publish` one.{name}.two - -#### Message - - - -Sample publisher - - - -This is a sample schema. - - - - - -##### Payload - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionAccepted values
createdAt string

Creation time

-
Any
items array(object)

List of items

-
Any
items.key string

Item key

-
Any
items.values array(integer)

List of item values

-
Any
- - - -###### Example of payload _(generated)_ - -```json -{ - "createdAt": "2019-10-22T12:15:29Z", - "items": [ - { - "key": "string", - "values": [ - 0 - ] - } - ] -} -``` - - - - - - - - - - diff --git a/swgen/asyncapi-2.0.0/sample.yaml b/swgen/asyncapi-2.0.0/sample.yaml deleted file mode 100644 index 45204fe..0000000 --- a/swgen/asyncapi-2.0.0/sample.yaml +++ /dev/null @@ -1,79 +0,0 @@ -asyncapi: 2.0.0 -info: - title: My Lovely Messaging API - version: 1.2.3 -servers: - production: - url: api.lovely.com:{port} - protocol: amqp -channels: - another.one: - subscribe: - message: - $ref: '#/components/messages/MyAnotherMessage' - one.{name}.two: - parameters: - name: - description: Name - schema: - description: Name - type: string - publish: - message: - $ref: '#/components/messages/MyMessage' - bindings: - amqp: - is: routingKey - exchange: - name: some-exchange -components: - schemas: - MyAnotherMessage: - properties: - item: - $ref: '#/components/schemas/SubItem' - type: object - MyMessage: - properties: - createdAt: - description: Creation time - format: date-time - type: string - items: - description: List of items - items: - $ref: '#/components/schemas/SubItem' - type: array - type: object - SubItem: - properties: - key: - description: Item key - type: string - values: - description: List of item values - items: - format: int64 - type: integer - type: array - uniqueItems: true - type: object - messages: - MyAnotherMessage: - headers: - properties: - X-Trace-ID: - description: Tracing header - type: string - required: - - X-Trace-ID - type: object - payload: - $ref: '#/components/schemas/MyAnotherMessage' - summary: Sample consumer - description: This is another sample schema. - MyMessage: - payload: - $ref: '#/components/schemas/MyMessage' - summary: Sample publisher - description: This is a sample schema. diff --git a/swgen/asyncapi/doc.go b/swgen/asyncapi/doc.go deleted file mode 100644 index f2453da..0000000 --- a/swgen/asyncapi/doc.go +++ /dev/null @@ -1,4 +0,0 @@ -// Package asyncapi implements reflection-based AsyncAPI 1.2.0 schema generator. -// -// Deprecated: upgrade to AsyncAPI 2.0.0 and use github.com/swaggest/go-asyncapi/reflector/asyncapi-2.0.0. -package asyncapi diff --git a/swgen/asyncapi/example_test.go b/swgen/asyncapi/example_test.go deleted file mode 100644 index 6938ee7..0000000 --- a/swgen/asyncapi/example_test.go +++ /dev/null @@ -1,163 +0,0 @@ -package asyncapi_test - -import ( - "fmt" - "io/ioutil" - "time" - - "github.com/swaggest/go-asyncapi/amqp" - "github.com/swaggest/go-asyncapi/spec" // nolint:staticcheck // Deprecated. - "github.com/swaggest/go-asyncapi/swgen/asyncapi" // nolint:staticcheck // Deprecated. -) - -func ExampleGenerator_AddTopic() { - type SubItem struct { - Key string `json:"key" description:"Item key"` - Values []int64 `json:"values" uniqueItems:"true" description:"List of item values"` - } - - type MyMessage struct { - Name string `path:"name" description:"Name"` - CreatedAt time.Time `json:"createdAt" description:"Creation time"` - Items []SubItem `json:"items" description:"List of items"` - } - - type MyAnotherMessage struct { - TraceID string `header:"X-Trace-ID" description:"Tracing header" required:"true"` - Item SubItem `json:"item" description:"Some item"` - } - - g := asyncapi.Generator{ - Data: spec.AsyncAPI{ - Asyncapi: spec.Asyncapi120, - Servers: []spec.Server{ - { - URL: "api.lovely.com:{port}", - Scheme: spec.ServerSchemeAmqp, - }, - }, - Info: &spec.Info{ - Version: "1.2.3", // required - Title: "My Lovely Messaging API", - }, - }, - } - must := func(err error) { - if err != nil { - panic(err.Error()) - } - } - must(g.AddTopic(asyncapi.TopicInfo{ - Topic: "one.{name}.two", - Publish: amqp.MessageWithInfo(&asyncapi.Message{ - Message: spec.Message{ - Description: "This is a sample schema.", - Summary: "Sample publisher", - }, - MessageSample: new(MyMessage), - }, amqp.Info{ - Exchange: "some-exchange", - VHost: "some-vhost", - Queue: "some-queue", - }), - })) - - must(g.AddTopic(asyncapi.TopicInfo{ - Topic: "another.one", - Subscribe: &asyncapi.Message{ - Message: spec.Message{ - Description: "This is another sample schema.", - Summary: "Sample consumer", - }, - MessageSample: new(MyAnotherMessage), - }, - })) - - yaml, err := g.Data.MarshalYAML() - must(err) - - fmt.Println(string(yaml)) - must(ioutil.WriteFile("sample.yaml", yaml, 0o600)) - // output: - // asyncapi: 1.2.0 - // info: - // title: My Lovely Messaging API - // version: 1.2.3 - // servers: - // - scheme: amqp - // url: api.lovely.com:{port} - // topics: - // another.one: - // subscribe: - // $ref: '#/components/messages/MyAnotherMessage' - // one.{name}.two: - // parameters: - // - description: Name - // name: name - // schema: - // description: Name - // type: string - // publish: - // $ref: '#/components/messages/MyMessage' - // components: - // messages: - // MyAnotherMessage: - // description: This is another sample schema. - // headers: - // properties: - // X-Trace-ID: - // description: Tracing header - // type: string - // required: - // - X-Trace-ID - // type: object - // payload: - // $ref: '#/components/schemas/MyAnotherMessage' - // summary: Sample consumer - // MyMessage: - // description: |- - // This is a sample schema. - // - // AMQP VHost: some-vhost. - // - // AMQP Exchange: some-exchange. - // - // AMQP Queue: some-queue. - // payload: - // $ref: '#/components/schemas/MyMessage' - // summary: Sample publisher - // x-amqp-exchange: some-exchange - // x-amqp-queue: some-queue - // x-amqp-vhost: some-vhost - // schemas: - // MyAnotherMessage: - // properties: - // item: - // $ref: '#/components/schemas/SubItem' - // type: object - // MyMessage: - // properties: - // createdAt: - // description: Creation time - // format: date-time - // type: string - // items: - // description: List of items - // items: - // $ref: '#/components/schemas/SubItem' - // type: array - // type: object - // SubItem: - // properties: - // key: - // description: Item key - // type: string - // values: - // description: List of item values - // items: - // format: int64 - // type: integer - // type: array - // uniqueItems: true - // type: object -} diff --git a/swgen/asyncapi/gen.go b/swgen/asyncapi/gen.go deleted file mode 100644 index 388a2ac..0000000 --- a/swgen/asyncapi/gen.go +++ /dev/null @@ -1,182 +0,0 @@ -package asyncapi - -import ( - "net/http" - "strings" - - "github.com/pkg/errors" - "github.com/swaggest/go-asyncapi/spec" // nolint:staticcheck // Deprecated. - "github.com/swaggest/swgen" -) - -// Generator generates AsyncAPI definitions from provided message samples. -type Generator struct { - Swg *swgen.Generator - Data spec.AsyncAPI - - pathItems map[string]TopicInfo -} - -// Message is a structure that keeps general info and message sample (optional). -type Message struct { - // Message holds general message info. - spec.Message - - // MessageSample holds a sample of message to be converted to JSON Schema, e.g. `new(MyMessage)`. - MessageSample interface{} -} - -// TopicInfo keeps user-defined information about topic. -type TopicInfo struct { - Topic string // event.{streetlightId}.lighting.measured - Publish *Message - Subscribe *Message - BaseTopicItem *spec.TopicItem // Optional, if set is used as a base to fill with Message data. -} - -// AddTopic adds user-defined topic to AsyncAPI definition. -func (g *Generator) AddTopic(info TopicInfo) error { - if info.Topic == "" { - return errors.New("topic is required") - } - - var ( - topicItem = spec.TopicItem{} - err error - ) - - if info.BaseTopicItem != nil { - topicItem = *info.BaseTopicItem - } - - if g.Swg == nil { - g.Swg = swgen.NewGenerator() - } - - if g.Data.Components == nil { - g.Data.Components = &spec.Components{} - } - - if g.Data.Components.Schemas == nil { - g.Data.Components.Schemas = make(map[string]map[string]interface{}) - } - - if g.Data.Components.Messages == nil { - g.Data.Components.Messages = make(map[string]spec.Message) - } - - if info.Publish != nil { - topicItem.Publish, err = g.makeOperation("publish", info, &topicItem, info.Publish) - if err != nil { - return errors.Wrapf(err, "failed process publish operation for topic %s", info.Topic) - } - } - - if info.Subscribe != nil { - topicItem.Subscribe, err = g.makeOperation("subscribe", info, &topicItem, info.Subscribe) - if err != nil { - return errors.Wrapf(err, "failed process subscribe operation for topic %s", info.Topic) - } - } - - if g.Data.Topics == nil { - g.Data.Topics = &spec.Topics{} - } - - if g.Data.Topics.MapOfTopicItemValues == nil { - g.Data.Topics.MapOfTopicItemValues = make(map[string]spec.TopicItem) - } - - g.Data.Topics.MapOfTopicItemValues[info.Topic] = topicItem - - return nil -} - -func (g *Generator) makeOperation(intent string, info TopicInfo, topicItem *spec.TopicItem, m *Message) (*spec.Operation, error) { - if m.MessageSample == nil { - return &spec.Operation{ - Message: &m.Message, - }, nil - } - - if g.pathItems == nil { - g.pathItems = make(map[string]TopicInfo) - } - - path := "/" + intent + "/" + info.Topic - g.pathItems[path] = info - - fakeInfo := swgen.PathItemInfo{ - Path: path, - Method: http.MethodPost, - Request: m.MessageSample, - Response: m.MessageSample, - } - obj := g.Swg.SetPathItem(fakeInfo) - - cfg := swgen.JSONSchemaConfig{ - DefinitionsPrefix: "#/components/schemas/", - StripDefinitions: true, - CollectDefinitions: g.Data.Components.Schemas, - } - - groups, err := g.Swg.GetJSONSchemaRequestGroups(obj, cfg) - if err != nil { - return nil, errors.Wrap(err, "failed to make schema") - } - - msg := m.Message - if headerSchema, ok := groups[`header`]; ok { - msg.Headers, err = headerSchema.ToMap() - if err != nil { - return nil, err - } - - delete(msg.Headers, "$schema") - } - - body, err := g.Swg.GetJSONSchemaRequestBody(obj, cfg) - if err != nil { - return nil, errors.Wrap(err, "failed to make body schema") - } - - msg.Payload = body - - for _, param := range obj.Parameters { - if param.In == `path` { - schema, err := g.Swg.ParamJSONSchema(param, cfg) - if err != nil { - return nil, errors.Wrapf(err, "failed to process param schema for %s", param.Name) - } - - topicItem.Parameters = append(topicItem.Parameters, spec.Parameter{ - Name: param.Name, - Description: param.Description, - Schema: schema, - }) - } - } - - if ref, ok := msg.Payload["$ref"].(string); ok && ref != "" { - messageName := strings.TrimPrefix(ref, "#/components/schemas/") - g.Data.Components.Messages[messageName] = msg - - return &spec.Operation{ - Message: &spec.Message{ - Ref: "#/components/messages/" + messageName, - }, - }, nil - } - - return &spec.Operation{ - Message: &msg, - }, nil -} - -// WalkJSONSchemas iterates thorough message payload schemas. -func (g *Generator) WalkJSONSchemas(w func(isPublishing bool, info TopicInfo, schema map[string]interface{})) error { - return g.Swg.WalkJSONSchemaResponses(func(path, _ string, _ int, schema map[string]interface{}) { - intent := strings.Split(path, "/")[1] - w(intent == "publish", g.pathItems[path], schema) - }) -} diff --git a/swgen/asyncapi/gen_test.go b/swgen/asyncapi/gen_test.go deleted file mode 100644 index 79b1689..0000000 --- a/swgen/asyncapi/gen_test.go +++ /dev/null @@ -1,79 +0,0 @@ -package asyncapi_test - -import ( - "encoding/json" - "testing" - "time" - - "github.com/stretchr/testify/assert" - "github.com/swaggest/go-asyncapi/spec" // nolint:staticcheck // Deprecated. - "github.com/swaggest/go-asyncapi/swgen/asyncapi" // nolint:staticcheck // Deprecated. -) - -func TestGenerator_WalkJSONSchemas(t *testing.T) { - type SubItem struct { - Key string `json:"key" description:"Item key"` - Values []int64 `json:"values" uniqueItems:"true" description:"List of item values"` - } - - type MyMessage struct { - Name string `path:"name" description:"Name"` - CreatedAt time.Time `json:"createdAt" description:"Creation time"` - Items []SubItem `json:"items" description:"List of items"` - } - - type MyAnotherMessage struct { - TraceID string `header:"X-Trace-ID" description:"Tracing header" required:"true"` - Item SubItem `json:"item" description:"Some item"` - } - - g := asyncapi.Generator{ - Data: spec.AsyncAPI{ - Asyncapi: spec.Asyncapi120, - Servers: []spec.Server{ - { - URL: "api.lovely.com:{port}", - Scheme: spec.ServerSchemeAmqp, - }, - }, - Info: &spec.Info{ - Version: "1.2.3", // required - Title: "My Lovely Messaging API", - }, - }, - } - assert.NoError(t, g.AddTopic(asyncapi.TopicInfo{ - Topic: "one.{name}.two", - Publish: &asyncapi.Message{ - Message: spec.Message{ - Description: "This is a sample schema", - Summary: "Sample publisher", - }, - MessageSample: new(MyMessage), - }, - })) - - assert.NoError(t, g.AddTopic(asyncapi.TopicInfo{ - Topic: "another.one", - Subscribe: &asyncapi.Message{ - Message: spec.Message{ - Description: "This is another sample schema", - Summary: "Sample consumer", - }, - MessageSample: new(MyAnotherMessage), - }, - })) - - assert.NoError(t, g.WalkJSONSchemas(func(isPublishing bool, info asyncapi.TopicInfo, schema map[string]interface{}) { - js, err := json.Marshal(schema) - assert.NoError(t, err) - switch info.Topic { - case "one.{name}.two": - assert.Equal(t, `{"$schema":"http://json-schema.org/draft-04/schema#","definitions":{"SubItem":{"properties":{"key":{"description":"Item key","type":"string"},"values":{"description":"List of item values","items":{"format":"int64","type":"integer"},"type":"array","uniqueItems":true}},"type":"object"}},"properties":{"createdAt":{"description":"Creation time","format":"date-time","type":"string"},"items":{"description":"List of items","items":{"$ref":"#/definitions/SubItem"},"type":"array"}},"type":"object"}`, string(js)) - case "another.one": - assert.Equal(t, `{"$schema":"http://json-schema.org/draft-04/schema#","definitions":{"SubItem":{"properties":{"key":{"description":"Item key","type":"string"},"values":{"description":"List of item values","items":{"format":"int64","type":"integer"},"type":"array","uniqueItems":true}},"type":"object"}},"properties":{"item":{"$ref":"#/definitions/SubItem"}},"type":"object"}`, string(js)) - default: - t.Fatal("should not get here") - } - })) -} diff --git a/swgen/asyncapi/sample.md b/swgen/asyncapi/sample.md deleted file mode 100644 index 5dc912a..0000000 --- a/swgen/asyncapi/sample.md +++ /dev/null @@ -1,581 +0,0 @@ -# My Lovely Messaging API 1.2.3 documentation - - - - -## Table of Contents - -* [Connection Details](#servers) -* [Topics](#topics) -* [Messages](#messages) -* [Schemas](#schemas) - - - -## Connection details - - - - - - - - - - - - - - - - - - -
URLSchemeDescription
api.lovely.com:{port}amqp
- - -## Topics - - - -### `subscribe` another.one - - -#### Message - -Sample consumer - -This is another sample schema - -##### Headers - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionAccepted values
X-Trace-ID (required) - string -

Tracing header

-
Any
- - -###### Example of headers _(generated)_ - -```json -{ - "X-Trace-ID": "string" -} -``` - -##### Payload - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionAccepted values
item - object - Any
item.key - string -

Item key

-
Any
item.values - array(integer) -

List of item values

-
Any
- - -###### Example of payload _(generated)_ - -```json -{ - "item": { - "key": "string", - "values": [ - 0 - ] - } -} -``` - - - -### `publish` one.{name}.two - -#### Topic Parameters - -##### name - -Name - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionAccepted values
name - string - Any
- - -#### Message - -Sample publisher - -This is a sample schema, AMQP VHost: some-vhost, AMQP Exchange: some-exchange, AMQP RoutingKey: some-key - - -##### Payload - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionAccepted values
createdAt - string -

Creation time

-
Any
items - array(object) -

List of items

-
Any
items.key - string - Any
items.values - array(integer) - Any
- - -###### Example of payload _(generated)_ - -```json -{ - "createdAt": "2019-01-16T13:20:16Z", - "items": [ - { - "key": "string", - "values": [ - 0 - ] - } - ] -} -``` - - - -## Messages - -### MyAnotherMessage -Sample consumer - -This is another sample schema - -#### Headers - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionAccepted values
X-Trace-ID (required) - string -

Tracing header

-
Any
- - -##### Example of headers _(generated)_ - -```json -{ - "X-Trace-ID": "string" -} -``` - -#### Payload - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionAccepted values
item - object - Any
item.key - string -

Item key

-
Any
item.values - array(integer) -

List of item values

-
Any
- - -##### Example of payload _(generated)_ - -```json -{ - "item": { - "key": "string", - "values": [ - 0 - ] - } -} -``` - -### MyMessage -Sample publisher - -This is a sample schema, AMQP VHost: some-vhost, AMQP Exchange: some-exchange, AMQP RoutingKey: some-key - - - -#### Payload - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionAccepted values
createdAt - string -

Creation time

-
Any
items - array(object) -

List of items

-
Any
items.key - string - Any
items.values - array(integer) - Any
- - -##### Example of payload _(generated)_ - -```json -{ - "createdAt": "2019-01-16T13:20:16Z", - "items": [ - { - "key": "string", - "values": [ - 0 - ] - } - ] -} -``` - - -## Schemas - -#### MyAnotherMessage - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionAccepted values
item - object - Any
item.key - string -

Item key

-
Any
item.values - array(integer) -

List of item values

-
Any
- -##### Example _(generated)_ - -```json -{ - "item": { - "key": "string", - "values": [ - 0 - ] - } -} -``` -#### MyMessage - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionAccepted values
createdAt - string -

Creation time

-
Any
items - array(object) -

List of items

-
Any
items.key - string - Any
items.values - array(integer) - Any
- -##### Example _(generated)_ - -```json -{ - "createdAt": "2019-01-16T13:20:16Z", - "items": [ - { - "key": "string", - "values": [ - 0 - ] - } - ] -} -``` -#### SubItem - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionAccepted values
key - string -

Item key

-
Any
values - array(integer) -

List of item values

-
Any
- -##### Example _(generated)_ - -```json -{ - "key": "string", - "values": [ - 0 - ] -} -``` diff --git a/swgen/asyncapi/sample.yaml b/swgen/asyncapi/sample.yaml deleted file mode 100644 index 311fbdf..0000000 --- a/swgen/asyncapi/sample.yaml +++ /dev/null @@ -1,81 +0,0 @@ -asyncapi: 1.2.0 -info: - title: My Lovely Messaging API - version: 1.2.3 -servers: -- scheme: amqp - url: api.lovely.com:{port} -topics: - another.one: - subscribe: - $ref: '#/components/messages/MyAnotherMessage' - one.{name}.two: - parameters: - - description: Name - name: name - schema: - description: Name - type: string - publish: - $ref: '#/components/messages/MyMessage' -components: - messages: - MyAnotherMessage: - description: This is another sample schema. - headers: - properties: - X-Trace-ID: - description: Tracing header - type: string - required: - - X-Trace-ID - type: object - payload: - $ref: '#/components/schemas/MyAnotherMessage' - summary: Sample consumer - MyMessage: - description: |- - This is a sample schema. - - AMQP VHost: some-vhost. - - AMQP Exchange: some-exchange. - - AMQP Queue: some-queue. - payload: - $ref: '#/components/schemas/MyMessage' - summary: Sample publisher - x-amqp-exchange: some-exchange - x-amqp-queue: some-queue - x-amqp-vhost: some-vhost - schemas: - MyAnotherMessage: - properties: - item: - $ref: '#/components/schemas/SubItem' - type: object - MyMessage: - properties: - createdAt: - description: Creation time - format: date-time - type: string - items: - description: List of items - items: - $ref: '#/components/schemas/SubItem' - type: array - type: object - SubItem: - properties: - key: - description: Item key - type: string - values: - description: List of item values - items: - format: int64 - type: integer - type: array - uniqueItems: true - type: object