Skip to content

Commit

Permalink
Merge pull request #320 from IBM-Cloud/dev
Browse files Browse the repository at this point in the history
Promote dev to master
  • Loading branch information
Aerex authored May 20, 2022
2 parents fd5c5ed + 1a93e7b commit ce40442
Show file tree
Hide file tree
Showing 8 changed files with 376 additions and 21 deletions.
8 changes: 4 additions & 4 deletions .secrets.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"files": "^.secrets.baseline$|go.sum",
"lines": null
},
"generated_at": "2022-02-28T20:29:11Z",
"generated_at": "2022-05-16T18:04:42Z",
"plugins_used": [
{
"name": "AWSKeyDetector"
Expand Down Expand Up @@ -191,15 +191,15 @@
"hashed_secret": "90919f1360ad1f9525de7a64061c105d061df1c8",
"is_secret": false,
"is_verified": false,
"line_number": 377,
"line_number": 378,
"type": "JSON Web Token",
"verified_result": null
},
{
"hashed_secret": "40e89785a3d6a88c5ef431f64ec054b1d39e186e",
"is_secret": false,
"is_verified": false,
"line_number": 393,
"line_number": 394,
"type": "JSON Web Token",
"verified_result": null
}
Expand Down Expand Up @@ -353,7 +353,7 @@
}
]
},
"version": "0.13.1+ibm.45.dss",
"version": "0.13.1+ibm.48.dss",
"word_list": {
"file": null,
"hash": null
Expand Down
2 changes: 1 addition & 1 deletion bluemix/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package bluemix
import "fmt"

// Version is the SDK version
var Version = VersionType{Major: 0, Minor: 9, Build: 0}
var Version = VersionType{Major: 0, Minor: 10, Build: 0}

// VersionType describe version info
type VersionType struct {
Expand Down
12 changes: 7 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,20 @@ require (
github.com/nicksnyder/go-i18n v1.3.0
github.com/onsi/ginkgo v1.3.1
github.com/onsi/gomega v1.1.0
github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365
github.com/spf13/cobra v1.0.0
github.com/spf13/pflag v1.0.3
github.com/stretchr/testify v1.2.2
golang.org/x/crypto v0.0.0-20211202192323-5770296d904e
gopkg.in/cheggaaa/pb.v1 v1.0.15
gopkg.in/yaml.v2 v2.4.0
)

require (
github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2 // indirect
github.com/golang/protobuf v0.0.0-20170331031902-2bba0603135d // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/golang/protobuf v1.3.1 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/mattn/go-isatty v0.0.5-0.20180830101745-3fb116b82035 // indirect
github.com/pmezard/go-difflib v0.0.0-20151207182434-e8554b8641db // indirect
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 // indirect
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 // indirect
)
144 changes: 133 additions & 11 deletions go.sum

Large diffs are not rendered by default.

29 changes: 29 additions & 0 deletions plugin/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (

"github.com/IBM-Cloud/ibm-cloud-cli-sdk/bluemix/endpoints"
"github.com/IBM-Cloud/ibm-cloud-cli-sdk/bluemix/models"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)

// PluginMetadata describes metadata of a plugin.
Expand Down Expand Up @@ -102,6 +104,33 @@ func (c Command) NameAndAliases() []string {
return append([]string{c.Name}, as...)
}

// ConvertCobraFlagsToPluginFlags will convert flags defined by Cobra framework to Plugin Flags
// Method is used when defining the Flags in command metadata. @see Plugin#GetMetadata() for use case
func ConvertCobraFlagsToPluginFlags(cmd *cobra.Command) []Flag {
var flags []Flag
cmd.Flags().VisitAll(func(f *pflag.Flag) {
var name string
if f.Shorthand != "" {
name = f.Shorthand + "," + f.Name
} else {
name = f.Name
}
hasValue := true
if f.Value.Type() == "bool" {
hasValue = false
}
flags = append(flags, Flag{
Name: name,
Description: f.Usage,
HasValue: hasValue,
Hidden: f.Hidden,
})
})

return flags

}

// Flag describes a command option
type Flag struct {
Name string // name of the option
Expand Down
117 changes: 117 additions & 0 deletions plugin/plugin_shim_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package plugin

import (
"encoding/json"
"fmt"
"os"
"testing"

"github.com/IBM-Cloud/ibm-cloud-cli-sdk/testhelpers"
"github.com/spf13/cobra"
"github.com/stretchr/testify/assert"
)

type cobraTestPlugin struct {
cmd *cobra.Command
metadata string
}

type urfaveTestPlugin struct {
metadata string
}

func marshalMetadata(meta PluginMetadata) string {
json, err := json.Marshal(meta)
if err != nil {
panic(fmt.Errorf("could not marshal metadata: %v", err.Error()))
}

return string(json)
}

var pluginMetadata = PluginMetadata{
Name: "test",
Commands: []Command{
{
Name: "list",
Description: "List your apps, containers and services in the target space.",
Usage: "ibmcloud list",
},
},
}

func (p *cobraTestPlugin) GetMetadata() PluginMetadata {
p.cmd = testhelpers.GenerateCobraCommand()
pluginMetadata.Commands[0].Flags = ConvertCobraFlagsToPluginFlags(p.cmd)
p.metadata = marshalMetadata(fillMetadata(pluginMetadata))

return pluginMetadata
}

func (p *urfaveTestPlugin) GetMetadata() PluginMetadata {
pluginMetadata.Commands[0].Flags = []Flag{
{
Name: "output",
Description: "Specify output format, only 'JSON' is supported.",
Hidden: false,
HasValue: true,
},
}
p.metadata = marshalMetadata(fillMetadata(pluginMetadata))

return pluginMetadata
}

func (p *cobraTestPlugin) Run(context PluginContext, args []string) {}
func (p *urfaveTestPlugin) Run(context PluginContext, args []string) {}

func TestStartWithArgsWithCobraCommand(t *testing.T) {
orgStdout := os.Stdout
stdoutMock := testhelpers.CreateMockStdout()
stdoutFile := stdoutMock.File

// cleanup mock
defer func() {
os.Stdout = orgStdout
os.RemoveAll(stdoutFile.Name())
stdoutFile.Close()
}()

// mock stdout with empty file
os.Stdout = stdoutFile

cmd := []string{"SendMetadata"}
pl := &cobraTestPlugin{}

StartWithArgs(pl, cmd)

stdoutMockOut := stdoutMock.Read()

assert.Equal(t, pl.metadata, string(stdoutMockOut))
}

func TestStartWithArgsWithUrfaveCommand(t *testing.T) {
orgStdout := os.Stdout
stdoutMock := testhelpers.CreateMockStdout()
stdoutFile := stdoutMock.File

// cleanup mock
defer func() {
os.Stdout = orgStdout
os.RemoveAll(stdoutFile.Name())
stdoutFile.Close()
}()

// mock stdout with empty file
os.Stdout = stdoutFile

cmd := []string{"SendMetadata"}
pl := &urfaveTestPlugin{}

StartWithArgs(pl, cmd)

stdoutMockOut := stdoutMock.Read()

assert.Equal(t, pl.metadata, string(stdoutMockOut))

}
37 changes: 37 additions & 0 deletions plugin/plugin_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package plugin

import (
"fmt"
"testing"

"github.com/IBM-Cloud/ibm-cloud-cli-sdk/testhelpers"
"github.com/stretchr/testify/assert"
)

func TestConvertCobraFlagsToPluginFlags(t *testing.T) {
assert := assert.New(t)
cmd := testhelpers.GenerateCobraCommand()
outputFlag := cmd.Flag("output")
quietFlag := cmd.Flag("quiet")
deprecateFlag := cmd.Flag("outputJSON")

flags := ConvertCobraFlagsToPluginFlags(cmd)

assert.Equal(3, len(flags))

// NOTE: flags are sorted in lexicographical order
assert.Equal(outputFlag.Usage, flags[0].Description)
assert.True(flags[0].HasValue)
assert.Equal(outputFlag.Hidden, flags[0].Hidden)
assert.Equal(outputFlag.Name, flags[0].Name)

assert.Equal(deprecateFlag.Usage, flags[1].Description)
assert.False(flags[1].HasValue)
assert.Equal(deprecateFlag.Hidden, flags[1].Hidden)
assert.Equal(deprecateFlag.Name, flags[1].Name)

assert.Equal(quietFlag.Usage, flags[2].Description)
assert.False(flags[2].HasValue)
assert.Equal(quietFlag.Hidden, flags[2].Hidden)
assert.Equal(fmt.Sprintf("%s,%s", quietFlag.Shorthand, quietFlag.Name), flags[2].Name)
}
48 changes: 48 additions & 0 deletions testhelpers/command.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package testhelpers

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

"github.com/spf13/cobra"
)

// GenerateCobraCommand will create a cobra command with basic flags used for testing
func GenerateCobraCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "example",
}

cmd.Flags().StringP("output", "", "", "Specify output format, only 'JSON' is supported.")
cmd.Flags().BoolP("quiet", "q", false, "Suppress verbose output")
cmd.Flags().BoolP("outputJSON", "", false, "Output data into JSON format")

// NOTE: Added #nosec tag since flag is not attached to a real command
cmd.Flags().MarkDeprecated("outputJSON", "outputJSON deprecated use --output instead") // #nosec
return cmd
}

type mockStdoutFile struct {
File *os.File
}

// CreateMockStdout will create a temp file used for mocking stdout for testing
func CreateMockStdout() *mockStdoutFile {
f, err := os.CreateTemp("", "cli_sdk_mock_stdout")
if err != nil {
panic(fmt.Errorf("failed to create tmp file for mocking stdout: %v", err.Error()))
}
return &mockStdoutFile{
File: f,
}
}

// Read will open the temp mock stdout file and return contents as a string
func (m *mockStdoutFile) Read() string {
out, err := ioutil.ReadFile(m.File.Name())
if err != nil {
panic(fmt.Errorf("failed to read stdout file: %v", err.Error()))
}
return string(out)
}

0 comments on commit ce40442

Please sign in to comment.