Skip to content

Commit

Permalink
Merge pull request #2 from kumaya/patch
Browse files Browse the repository at this point in the history
create atlas_patch go utility
  • Loading branch information
kumaya authored Dec 10, 2021
2 parents e7099ae + 35cd6de commit d813277
Show file tree
Hide file tree
Showing 13 changed files with 2,557 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@

# Dependency directories (remove the comment below to include it)
vendor/

**/*.emitted.swagger.json
**/*.emitted.private.swagger.json
16 changes: 16 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
PROJECT_ROOT ?= $(PWD)
GO_PACKAGES ?= $(shell go list ./... | grep -v vendor)
GO_TEST_FLAGS ?= -v -cover

.PHONY: fmt
fmt:
@go fmt $(GO_PACKAGES)

.PHONY: test
test: fmt
@go test $(GO_TEST_FLAGS) $(GO_PACKAGES)

.PHONY: vendor
vendor:
@go mod tidy
@go mod vendor
9 changes: 9 additions & 0 deletions cmd/server/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package main

import "github.com/spf13/pflag"

var (
swaggerFiles = pflag.StringSlice("files", []string{}, "input swagger file location")
withPrivate = pflag.Bool("with_private", false, "if unset, generate swagger schema without operations 0 as 'private' work only if atlas_patch set")
withCustomAnnotations = pflag.Bool("with_custom_annotations", false, "if set, you became available to use custom annotations")
)
58 changes: 58 additions & 0 deletions cmd/server/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package main

import (
"fmt"
"io/ioutil"
"os"
"strings"

"github.com/golang/glog"
"github.com/infobloxopen/atlas-openapiv2-patch/internal/descriptor"
genopenapi "github.com/infobloxopen/atlas-openapiv2-patch/pkg/svc"
"github.com/spf13/pflag"
)

func run(reg *descriptor.Registry, swaggerFiles []string) error {
for _, file := range swaggerFiles {
fileName := file
var f []byte
var err error
f, err = ioutil.ReadFile(file)
if err != nil {
return err
}
resp := genopenapi.AtlasSwagger(f, reg.IsWithPrivateOperations(), reg.IsWithCustomAnnotations())

if reg.IsWithPrivateOperations() {
err = os.Remove(file)
if err != nil {
return err
}
fileName = strings.Replace(file, ".swagger.json", ".private.swagger.json", -1)
}
err = ioutil.WriteFile(fileName, []byte(resp), os.FileMode(0644))
if err != nil {
return fmt.Errorf("unable to generate swagger definition")
}
glog.V(1).Infof("New OpenAPI file will emit")
}
return nil
}

func main() {
pflag.Parse()
reg := descriptor.NewRegistry()

reg.SetPrivateOperations(*withPrivate)
reg.SetCustomAnnotations(*withCustomAnnotations)
glog.V(1).Info("Processing code generator request")

if len(*swaggerFiles) == 0 {
glog.Fatal("invalid swagger input files provided")
}
err := run(reg, *swaggerFiles)
if err != nil {
glog.Fatal(err)
}
return
}
164 changes: 164 additions & 0 deletions cmd/server/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
package main

import (
"bytes"
"fmt"
"io"
"io/ioutil"
"os"
"testing"

"github.com/infobloxopen/atlas-openapiv2-patch/internal/descriptor"
)

const (
succeed = "\u2713"
failed = "\u2717"
red = "\033[31m"
green = "\033[32m"
yellow = "\033[33m"
reset = "\033[0m"
sampleSwaggerFile = "../../internal/testdata/atlaspatch.swagger.json"
)

func deepCompare(file1, file2 string) (bool, error) {
const chunkSize = 64000

f1, err := os.Open(file1)
if err != nil {
return false, fmt.Errorf("cannot open %q file, error: %v", file1, err)
}
defer f1.Close()

f2, err := os.Open(file2)
if err != nil {
return false, fmt.Errorf("cannot open %q file, error: %v", file2, err)
}
defer f2.Close()

for {
b1 := make([]byte, chunkSize)
_, err1 := f1.Read(b1)

b2 := make([]byte, chunkSize)
_, err2 := f2.Read(b2)

if err1 != nil || err2 != nil {
if err1 == io.EOF && err2 == io.EOF {
return true, nil
} else if err1 == io.EOF || err2 == io.EOF {
return false, nil
} else {
return false, fmt.Errorf("unexpected (not EOF) error "+
"when reading files (1, 2): %v, %v", err1, err2)
}
}

if !bytes.Equal(b1, b2) {
return false, nil
}
}
}

func createFiles(fileNames []string) error {
for _, file := range fileNames {
var f []byte
f, err := ioutil.ReadFile(sampleSwaggerFile)
if err != nil {
return err
}
err = ioutil.WriteFile(file, f, os.FileMode(0666))
return err
}
return nil
}

func deleteFiles(fileNames []string) error {
for _, file := range fileNames {
err := os.Remove(file)
if err != nil {
return err
}
}
return nil
}

func Test_run(t *testing.T) {
type args struct {
withPrivate bool
withCustomAnnotations bool
files []string
}
tests := []struct {
name string
args args
wantErr bool
wantFile string
generatedFiles []string
}{
{
name: "without custom flags",
wantErr: false,
args: args{
withPrivate: false,
withCustomAnnotations: false,
files: []string{"../../internal/testdata/atlaspatch.emitted.swagger.json"},
},
wantFile: "../../internal/testdata/atlaspatch.wanted.swagger.json",
generatedFiles: []string{"../../internal/testdata/atlaspatch.emitted.swagger.json"},
},
{
name: "with custom annotation flag",
wantErr: false,
args: args{
withPrivate: false,
withCustomAnnotations: true,
files: []string{"../../internal/testdata/atlaspatch.emitted.swagger.json"},
},
wantFile: "../../internal/testdata/atlaspatch.wanted.swagger.json",
generatedFiles: []string{"../../internal/testdata/atlaspatch.emitted.swagger.json"},
},
{
name: "with private flags",
wantErr: false,
args: args{
withPrivate: true,
withCustomAnnotations: false,
files: []string{"../../internal/testdata/atlaspatch.emitted.swagger.json"},
},
wantFile: "../../internal/testdata/atlaspatch.wanted.private.swagger.json",
generatedFiles: []string{"../../internal/testdata/atlaspatch.emitted.private.swagger.json"},
},
}
reg := descriptor.NewRegistry()
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
reg.SetPrivateOperations(tt.args.withPrivate)
reg.SetCustomAnnotations(tt.args.withCustomAnnotations)
err := createFiles(tt.args.files)
defer deleteFiles(tt.generatedFiles)
defer deleteFiles(tt.args.files)
if err != nil {
t.Fatal(err)
}
err = run(reg, tt.args.files)
if err != nil {
t.Errorf("unable to apply atlas patch, %v", err)
return
}

isEqual, err := deepCompare(tt.generatedFiles[0], tt.wantFile)
if err != nil {
t.Errorf("Emitted vs wanted files content comparison error: %v", err)
return
}

if !isEqual {
t.Errorf("\t%s Emitted swagger JSON file is not equal to wanted one, compare with: "+
"\n"+yellow+" \n\ndiff %s %s\n\n "+reset, failed, tt.args.files, tt.wantFile)
return
}
t.Logf("\t%s %s test is passed", succeed, tt.name)
})
}
}
9 changes: 9 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module github.com/infobloxopen/atlas-openapiv2-patch

go 1.16

require (
github.com/go-openapi/spec v0.20.4
github.com/golang/glog v1.0.0
github.com/spf13/pflag v1.0.5
)
60 changes: 60 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
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=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs=
github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns=
github.com/go-openapi/spec v0.20.4 h1:O8hJrt0UMnhHcluhIdUgCLRWyM2x7QkBXRvOs7m+O1M=
github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM=
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ=
github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA=
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
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/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
golang.org/x/net v0.0.0-20210421230115-4e50805a0758 h1:aEpZnXcAmXkd6AvLb2OPt+EN1Zu/8Ne3pCqPjja5PXY=
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/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-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
47 changes: 47 additions & 0 deletions internal/descriptor/registry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package descriptor

import "fmt"

type Registry struct {
// privateOperations if true, respect private annotations and generate separate openapi files for private ops
privateOperations bool

// customAnnotations if true, allow custom annotations in the openapi spec
customAnnotations bool
}

func NewRegistry() *Registry {
return &Registry{
privateOperations: false,
customAnnotations: false,
}
}

// IsWithPrivateOperations whether private operations are enabled
func (r *Registry) IsWithPrivateOperations() bool {
return r.privateOperations
}

// SetPrivateOperations if true, respect private operation annotation
func (r *Registry) SetPrivateOperations(private bool) {
r.privateOperations = private
}

// IsWithCustomAnnotations whether custom annotations are used
func (r *Registry) IsWithCustomAnnotations() bool {
return r.customAnnotations
}

// SetCustomAnnotations if true, use atlas custom annotations
func (r *Registry) SetCustomAnnotations(custom bool) {
r.customAnnotations = custom
}

func (r *Registry) String() string {
return `
privateOperations ` + fmt.Sprintf("%t", r.privateOperations) + `
customAnnotations ` + fmt.Sprintf("%t", r.customAnnotations) + `
`
}
Loading

0 comments on commit d813277

Please sign in to comment.