Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CLOUDP-236398: Adding merge command skeleton #6

Merged
merged 6 commits into from Mar 8, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 5 additions & 1 deletion tools/cli/go.mod
Expand Up @@ -3,12 +3,15 @@ module mongodb/openapi/tools/cli
go 1.22.1

require (
github.com/getkin/kin-openapi v0.120.0
github.com/spf13/cobra v1.8.0
github.com/stretchr/testify v1.8.4
github.com/tufin/oasdiff v1.9.5
)

require (
github.com/getkin/kin-openapi v0.120.0 // indirect
cloud.google.com/go v0.110.10 // indirect
github.com/davecgh/go-spew v1.1.1 // 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
Expand All @@ -17,6 +20,7 @@ require (
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/pmezard/go-difflib v1.0.0 // 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
Expand Down
8 changes: 8 additions & 0 deletions tools/cli/go.sum
@@ -1,3 +1,7 @@
cloud.google.com/go v0.110.10 h1:LXy9GEO+timppncPIAZoOj3l58LIU9k+kn48AN7IO3Y=
cloud.google.com/go v0.110.10/go.mod h1:v1OoFqYxiBkUrruItNM3eT4lLByNjxmJSV/xDKJNnic=
github.com/TwiN/go-color v1.4.1 h1:mqG0P/KBgHKVqmtL5ye7K0/Gr4l6hTksPgTgMk3mUzc=
github.com/TwiN/go-color v1.4.1/go.mod h1:WcPf/jtiW95WBIsEeY1Lc/b8aaWoiqQpu5cf8WFxu+s=
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=
Expand All @@ -9,6 +13,8 @@ github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogB
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/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
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=
Expand Down Expand Up @@ -42,6 +48,8 @@ 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=
golang.org/x/exp v0.0.0-20231108232855-2478ac86f678 h1:mchzmB1XO2pMaKFRqk/+MV3mgGG96aqaPXaMifQU47w=
golang.org/x/exp v0.0.0-20231108232855-2478ac86f678/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE=
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=
Expand Down
24 changes: 24 additions & 0 deletions tools/cli/internal/cli/flag/flag.go
@@ -0,0 +1,24 @@
// 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 flag

const (
Base = "base"
BaseShort = "b"
External = "external"
ExternalShort = "e"
Output = "output"
OutputShort = "o"
)
44 changes: 38 additions & 6 deletions tools/cli/internal/cli/merge/merge.go
Expand Up @@ -15,31 +15,60 @@
package merge

import (
"fmt"
"log"
"mongodb/openapi/tools/cli/internal/cli/flag"
"mongodb/openapi/tools/cli/internal/cli/usage"
"os"

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

const (
DefaultOutputFileName = "FOAS.json"
)

type Opts struct {
Base *load.SpecInfo
basePath string
outputPath string
externalPaths []string
}

func (o *Opts) Run(_ []string) error {
// To add in follow up PR: CLOUDP-225849
return nil
return o.saveFile([]byte("test"))
}

func (o *Opts) PreRunE(_ []string) error {
// To Add in follow up PR: CLOUDP-225849
if o.basePath == "" {
return fmt.Errorf("no base OAS detected. Please, use the flag %s to include the base OAS", flag.Base)
}

if o.externalPaths == nil {
return fmt.Errorf("no external OAS detected. Please, use the flag %s to include at least one OAS", flag.External)
}

return nil
}

func (o *Opts) saveFile(data []byte) error {
if err := os.WriteFile(o.outputPath, data, 0o600); err != nil {
return err
}

log.Printf("\nMerged spec was saved in '%s'.\n\n", o.outputPath)
return nil
}

// Builder builds the merge command with the following signature:
// merge -b base-oas -e external-oas-1 -e external-oas-2
func Builder() *cobra.Command {
opts := &Opts{}

cmd := &cobra.Command{
Use: "merge [base-spec] [spec-1] [spec-2] [spec-3] ... [spec-n]",
Use: "merge -b [base-spec] -e [spec-1] -e [spec-2]",
andreaangiolillo marked this conversation as resolved.
Show resolved Hide resolved
Short: "Merge Open API specifications into a base spec.",
Args: cobra.MinimumNArgs(2),
Args: cobra.NoArgs,
PreRunE: func(_ *cobra.Command, args []string) error {
return opts.PreRunE(args)
},
Expand All @@ -48,5 +77,8 @@ func Builder() *cobra.Command {
},
}

cmd.Flags().StringVarP(&opts.basePath, flag.Base, flag.BaseShort, "", usage.Base)
cmd.Flags().StringArrayVarP(&opts.externalPaths, flag.External, flag.ExternalShort, nil, usage.External)
cmd.Flags().StringVarP(&opts.outputPath, flag.Output, flag.OutputShort, DefaultOutputFileName, usage.Output)
return cmd
}
30 changes: 30 additions & 0 deletions tools/cli/internal/cli/merge/merge_test.go
@@ -0,0 +1,30 @@
// 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 (
"mongodb/openapi/tools/cli/internal/cli/flag"
"mongodb/openapi/tools/cli/internal/cli/validator"
"testing"
)

func TestCreateBuilder(t *testing.T) {
validator.ValidateSubCommandsAndFlags(
t,
Builder(),
0,
[]string{flag.Base, flag.External, flag.Output},
)
}
21 changes: 21 additions & 0 deletions tools/cli/internal/cli/usage/usage.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 usage

const (
Base = "Base OAS. The command will merge other OASes into it."
External = "OASes that will be merged into the base OAS."
Output = "File name where the command will store the output."
)
41 changes: 41 additions & 0 deletions tools/cli/internal/cli/validator/command.go
@@ -0,0 +1,41 @@
// 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 validator

import (
"testing"

"github.com/spf13/cobra"
"github.com/stretchr/testify/assert"
)

// ValidateSubCommandsAndFlags validates a cobra.Command, verifying the number of sub commands
// and the flags that are being defined for it.
func ValidateSubCommandsAndFlags(t *testing.T, subject *cobra.Command, nSubCommands int, flags []string) {
t.Helper()
a := assert.New(t)
if len(subject.Commands()) != nSubCommands {
t.Errorf("Sub command count mismatch. Expected %d, got %d. "+
"Check the CmdValidator for your command.\n", nSubCommands, len(subject.Commands()))
}
if len(flags) == 0 {
a.False(subject.HasAvailableFlags(), "expected command to not have flags but it does")
return
}
a.True(subject.HasAvailableFlags(), "expected command to have flag but has none")
for _, f := range flags {
a.NotNilf(subject.Flags().Lookup(f), "command has no flag: %s", f)
}
}