Skip to content

Commit

Permalink
CLOUDP-225849: Add scaffolding of the openapi cli (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
andreaangiolillo committed Mar 7, 2024
1 parent 706edf3 commit e1e42ca
Show file tree
Hide file tree
Showing 9 changed files with 323 additions and 0 deletions.
15 changes: 15 additions & 0 deletions .gitignore
@@ -0,0 +1,15 @@
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
/tools/*/bin/*
/tools/*/dist/*

# We don't want to commit env variables
*.env

# Tool generated files
*.idea
*.vscode
1 change: 1 addition & 0 deletions tools/.tool-versions
@@ -0,0 +1 @@
golang 1.22.1
51 changes: 51 additions & 0 deletions tools/cli/Makefile
@@ -0,0 +1,51 @@
# A Self-Documenting Makefile: http://marmelab.com/blog/2016/02/29/auto-documented-makefile.html

SOURCE_FILES?=./cmd
BINARY_NAME=openapicli
VERSION=v0.0.1
GIT_SHA?=$(shell git rev-parse HEAD)
DESTINATION=./bin/$(BINARY_NAME)

LINKER_GH_SHA_FLAG=-s -w -X github.com/mongodb/openapi/tools/cli/internal/version.GitCommit=${GIT_SHA}
LINKER_FLAGS=${LINKER_GH_SHA_FLAG} -X github.com/mongodb/openapi/tools/cli/internal/version.Version=${VERSION}

DEBUG_FLAGS=all=-N -l

export TERM := linux-m
export GO111MODULE := on

.PHONY: deps
deps: ## Download go module dependencies
@echo "==> Installing go.mod dependencies..."
go mod download
go mod tidy

.PHONY: setup
setup: deps ## Set up dev env

.PHONY: fmt
fmt: ### Format all go files with goimports and gofmt
find . -name "*.go" -exec gofmt -w "{}" \;
find . -name "*.go" -exec goimports -l -w "{}" \;

.PHONY: build
build:
@echo "==> Building openapicli binary"
go build -ldflags "$(LINKER_FLAGS)" -o $(DESTINATION) $(SOURCE_FILES)


.PHONY: build-debug
build-debug:
@echo "==> Building openapicli binary for debugging"
go build -gcflags="$(DEBUG_FLAGS)" -ldflags "$(LINKER_FLAGS)" -o $(DESTINATION) $(SOURCE_FILES)


.PHONY: list
list: ## List all make targets
@${MAKE} -pRrn : -f $(MAKEFILE_LIST) 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | egrep -v -e '^[^[:alnum:]]' -e '^$@$$' | sort


.PHONY: help
.DEFAULT_GOAL := help
help:
@grep -h -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
34 changes: 34 additions & 0 deletions tools/cli/cmd/openapicli.go
@@ -0,0 +1,34 @@
// Copyright 2024 MongoDB Inc
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
"context"
"mongodb/openapi/tools/cli/internal/cli/root/openapi"
"os"
)

// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute(ctx context.Context) {
rootCmd := openapi.Builder()
if err := rootCmd.ExecuteContext(ctx); err != nil {
os.Exit(1)
}
}

func main() {
Execute(context.Background())
}
23 changes: 23 additions & 0 deletions tools/cli/go.mod
@@ -0,0 +1,23 @@
module mongodb/openapi/tools/cli

go 1.22.1

require (
github.com/spf13/cobra v1.8.0
github.com/tufin/oasdiff v1.9.5
)

require (
github.com/getkin/kin-openapi v0.120.0 // indirect
github.com/go-openapi/jsonpointer v0.20.0 // indirect
github.com/go-openapi/swag v0.22.4 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/invopop/yaml v0.2.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
github.com/perimeterx/marshmallow v1.1.5 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/yargevad/filepathx v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
50 changes: 50 additions & 0 deletions tools/cli/go.sum
@@ -0,0 +1,50 @@
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
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/getkin/kin-openapi v0.120.0 h1:MqJcNJFrMDFNc07iwE8iFC5eT2k/NPUFDIpNeiZv8Jg=
github.com/getkin/kin-openapi v0.120.0/go.mod h1:PCWw/lfBrJY4HcdqE3jj+QFkaFK8ABoqo7PvqVhXXqw=
github.com/go-openapi/jsonpointer v0.20.0 h1:ESKJdU9ASRfaPNOPRx12IUyA1vn3R9GiE3KYD14BXdQ=
github.com/go-openapi/jsonpointer v0.20.0/go.mod h1:6PGzBjjIIumbLYysB73Klnms1mwnU4G3YHOECG3CedA=
github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU=
github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM=
github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/invopop/yaml v0.2.0 h1:7zky/qH+O0DwAyoobXUqvVBwgBFRxKoQ/3FjcVpjTMY=
github.com/invopop/yaml v0.2.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q=
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.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
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.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s=
github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw=
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/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
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/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/tufin/oasdiff v1.9.5 h1:xXzfLj8ezA14E6miyPQyNnO+c0qvefJazirMij8WyMQ=
github.com/tufin/oasdiff v1.9.5/go.mod h1:E1XiSLK/vnxZDmkB8pUYsiYUpdMjCKj47tNUmVnSIzA=
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
github.com/yargevad/filepathx v1.0.0 h1:SYcT+N3tYGi+NvazubCNlvgIPbzAk7i7y2dwg3I5FYc=
github.com/yargevad/filepathx v1.0.0/go.mod h1:BprfX/gpYNJHJfc35GjRRpVcwWXS89gGulUIU5tK3tA=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v3 v3.0.0/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=
62 changes: 62 additions & 0 deletions tools/cli/internal/cli/merge/merge.go
@@ -0,0 +1,62 @@
// Copyright 2024 MongoDB Inc
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package merge

import (
"github.com/spf13/cobra"
"github.com/tufin/oasdiff/load"
)

type Opts struct {
Base *load.SpecInfo
outputPath string
}

func (o *Opts) Run(args []string) error {
// To add in follow up PR: CLOUDP-225849
return nil
}

func (o *Opts) removeExternalReferences(paths []string, federated *load.SpecInfo) ([]byte, error) {
// To add in follow up PR: CLOUDP-225849
return nil, nil

}
func (o *Opts) saveFile(data []byte) error {
return nil
}

func (o *Opts) PreRunE(args []string) error {
// To Add in follow up PR: CLOUDP-225849
return nil
}

func Builder() *cobra.Command {
opts := &Opts{}

cmd := &cobra.Command{
Use: "merge [base-spec] [spec-1] [spec-2] [spec-3] ... [spec-n]",
Short: "Merge Open API specifications into a base spec.",
Args: cobra.MinimumNArgs(2),
PreRunE: func(cmd *cobra.Command, args []string) error {
return opts.PreRunE(args)
},
RunE: func(cmd *cobra.Command, args []string) error {
return opts.Run(args)
},
}

return cmd
}
66 changes: 66 additions & 0 deletions tools/cli/internal/cli/root/openapi/builder.go
@@ -0,0 +1,66 @@
// Copyright 2024 MongoDB Inc
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package openapi

import (
"fmt"
"mongodb/openapi/tools/cli/internal/cli/merge"
"mongodb/openapi/tools/cli/internal/version"
"runtime"

"github.com/spf13/cobra"
)

const (
ToolName = "openapicli"
verTemplate = `openapicli version: %s
git version: %s
Go version: %s
os: %s
arch: %s
compiler: %s
`
)

// Builder conditionally adds children commands as needed.
// This is important in particular for Atlas as it dynamically sets flags for cluster creation and
// this can be slow to timeout on environments with limited internet access (Ops Manager).
func Builder() *cobra.Command {
rootCmd := &cobra.Command{
Version: version.Version,
Use: ToolName,
Short: "CLI tool to validate and merge your Open API Specifications",
Example: ` # Display the help menu for the merge command:
openapicli merge --help
`,
SilenceUsage: true,
}

rootCmd.SetVersionTemplate(formattedVersion())
rootCmd.AddCommand(
merge.Builder(),
)
return rootCmd
}

func formattedVersion() string {
return fmt.Sprintf(verTemplate,
version.Version,
version.GitCommit,
runtime.Version(),
runtime.GOOS,
runtime.GOARCH,
runtime.Compiler)
}
21 changes: 21 additions & 0 deletions tools/cli/internal/version/version.go
@@ -0,0 +1,21 @@
// Copyright 2024 MongoDB Inc
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package version

// These variables are set at compilation time in the Makefile
var (
Version = "next" // Version for CLI.
GitCommit = "next" // GitCommit git sha of the build.
)

0 comments on commit e1e42ca

Please sign in to comment.