Skip to content

Commit ce40442

Browse files
authored
Merge pull request #320 from IBM-Cloud/dev
Promote dev to master
2 parents fd5c5ed + 1a93e7b commit ce40442

File tree

8 files changed

+376
-21
lines changed

8 files changed

+376
-21
lines changed

.secrets.baseline

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"files": "^.secrets.baseline$|go.sum",
44
"lines": null
55
},
6-
"generated_at": "2022-02-28T20:29:11Z",
6+
"generated_at": "2022-05-16T18:04:42Z",
77
"plugins_used": [
88
{
99
"name": "AWSKeyDetector"
@@ -191,15 +191,15 @@
191191
"hashed_secret": "90919f1360ad1f9525de7a64061c105d061df1c8",
192192
"is_secret": false,
193193
"is_verified": false,
194-
"line_number": 377,
194+
"line_number": 378,
195195
"type": "JSON Web Token",
196196
"verified_result": null
197197
},
198198
{
199199
"hashed_secret": "40e89785a3d6a88c5ef431f64ec054b1d39e186e",
200200
"is_secret": false,
201201
"is_verified": false,
202-
"line_number": 393,
202+
"line_number": 394,
203203
"type": "JSON Web Token",
204204
"verified_result": null
205205
}
@@ -353,7 +353,7 @@
353353
}
354354
]
355355
},
356-
"version": "0.13.1+ibm.45.dss",
356+
"version": "0.13.1+ibm.48.dss",
357357
"word_list": {
358358
"file": null,
359359
"hash": null

bluemix/version.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package bluemix
33
import "fmt"
44

55
// Version is the SDK version
6-
var Version = VersionType{Major: 0, Minor: 9, Build: 0}
6+
var Version = VersionType{Major: 0, Minor: 10, Build: 0}
77

88
// VersionType describe version info
99
type VersionType struct {

go.mod

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,20 @@ require (
1010
github.com/nicksnyder/go-i18n v1.3.0
1111
github.com/onsi/ginkgo v1.3.1
1212
github.com/onsi/gomega v1.1.0
13-
github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365
13+
github.com/spf13/cobra v1.0.0
14+
github.com/spf13/pflag v1.0.3
15+
github.com/stretchr/testify v1.2.2
1416
golang.org/x/crypto v0.0.0-20211202192323-5770296d904e
1517
gopkg.in/cheggaaa/pb.v1 v1.0.15
1618
gopkg.in/yaml.v2 v2.4.0
1719
)
1820

1921
require (
20-
github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2 // indirect
21-
github.com/golang/protobuf v0.0.0-20170331031902-2bba0603135d // indirect
22+
github.com/davecgh/go-spew v1.1.1 // indirect
23+
github.com/golang/protobuf v1.3.1 // indirect
24+
github.com/inconshreveable/mousetrap v1.0.0 // indirect
2225
github.com/mattn/go-isatty v0.0.5-0.20180830101745-3fb116b82035 // indirect
23-
github.com/pmezard/go-difflib v0.0.0-20151207182434-e8554b8641db // indirect
24-
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
26+
github.com/pmezard/go-difflib v1.0.0 // indirect
2527
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 // indirect
2628
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 // indirect
2729
)

go.sum

Lines changed: 133 additions & 11 deletions
Large diffs are not rendered by default.

plugin/plugin.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import (
88

99
"github.com/IBM-Cloud/ibm-cloud-cli-sdk/bluemix/endpoints"
1010
"github.com/IBM-Cloud/ibm-cloud-cli-sdk/bluemix/models"
11+
"github.com/spf13/cobra"
12+
"github.com/spf13/pflag"
1113
)
1214

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

107+
// ConvertCobraFlagsToPluginFlags will convert flags defined by Cobra framework to Plugin Flags
108+
// Method is used when defining the Flags in command metadata. @see Plugin#GetMetadata() for use case
109+
func ConvertCobraFlagsToPluginFlags(cmd *cobra.Command) []Flag {
110+
var flags []Flag
111+
cmd.Flags().VisitAll(func(f *pflag.Flag) {
112+
var name string
113+
if f.Shorthand != "" {
114+
name = f.Shorthand + "," + f.Name
115+
} else {
116+
name = f.Name
117+
}
118+
hasValue := true
119+
if f.Value.Type() == "bool" {
120+
hasValue = false
121+
}
122+
flags = append(flags, Flag{
123+
Name: name,
124+
Description: f.Usage,
125+
HasValue: hasValue,
126+
Hidden: f.Hidden,
127+
})
128+
})
129+
130+
return flags
131+
132+
}
133+
105134
// Flag describes a command option
106135
type Flag struct {
107136
Name string // name of the option

plugin/plugin_shim_test.go

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
package plugin
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"os"
7+
"testing"
8+
9+
"github.com/IBM-Cloud/ibm-cloud-cli-sdk/testhelpers"
10+
"github.com/spf13/cobra"
11+
"github.com/stretchr/testify/assert"
12+
)
13+
14+
type cobraTestPlugin struct {
15+
cmd *cobra.Command
16+
metadata string
17+
}
18+
19+
type urfaveTestPlugin struct {
20+
metadata string
21+
}
22+
23+
func marshalMetadata(meta PluginMetadata) string {
24+
json, err := json.Marshal(meta)
25+
if err != nil {
26+
panic(fmt.Errorf("could not marshal metadata: %v", err.Error()))
27+
}
28+
29+
return string(json)
30+
}
31+
32+
var pluginMetadata = PluginMetadata{
33+
Name: "test",
34+
Commands: []Command{
35+
{
36+
Name: "list",
37+
Description: "List your apps, containers and services in the target space.",
38+
Usage: "ibmcloud list",
39+
},
40+
},
41+
}
42+
43+
func (p *cobraTestPlugin) GetMetadata() PluginMetadata {
44+
p.cmd = testhelpers.GenerateCobraCommand()
45+
pluginMetadata.Commands[0].Flags = ConvertCobraFlagsToPluginFlags(p.cmd)
46+
p.metadata = marshalMetadata(fillMetadata(pluginMetadata))
47+
48+
return pluginMetadata
49+
}
50+
51+
func (p *urfaveTestPlugin) GetMetadata() PluginMetadata {
52+
pluginMetadata.Commands[0].Flags = []Flag{
53+
{
54+
Name: "output",
55+
Description: "Specify output format, only 'JSON' is supported.",
56+
Hidden: false,
57+
HasValue: true,
58+
},
59+
}
60+
p.metadata = marshalMetadata(fillMetadata(pluginMetadata))
61+
62+
return pluginMetadata
63+
}
64+
65+
func (p *cobraTestPlugin) Run(context PluginContext, args []string) {}
66+
func (p *urfaveTestPlugin) Run(context PluginContext, args []string) {}
67+
68+
func TestStartWithArgsWithCobraCommand(t *testing.T) {
69+
orgStdout := os.Stdout
70+
stdoutMock := testhelpers.CreateMockStdout()
71+
stdoutFile := stdoutMock.File
72+
73+
// cleanup mock
74+
defer func() {
75+
os.Stdout = orgStdout
76+
os.RemoveAll(stdoutFile.Name())
77+
stdoutFile.Close()
78+
}()
79+
80+
// mock stdout with empty file
81+
os.Stdout = stdoutFile
82+
83+
cmd := []string{"SendMetadata"}
84+
pl := &cobraTestPlugin{}
85+
86+
StartWithArgs(pl, cmd)
87+
88+
stdoutMockOut := stdoutMock.Read()
89+
90+
assert.Equal(t, pl.metadata, string(stdoutMockOut))
91+
}
92+
93+
func TestStartWithArgsWithUrfaveCommand(t *testing.T) {
94+
orgStdout := os.Stdout
95+
stdoutMock := testhelpers.CreateMockStdout()
96+
stdoutFile := stdoutMock.File
97+
98+
// cleanup mock
99+
defer func() {
100+
os.Stdout = orgStdout
101+
os.RemoveAll(stdoutFile.Name())
102+
stdoutFile.Close()
103+
}()
104+
105+
// mock stdout with empty file
106+
os.Stdout = stdoutFile
107+
108+
cmd := []string{"SendMetadata"}
109+
pl := &urfaveTestPlugin{}
110+
111+
StartWithArgs(pl, cmd)
112+
113+
stdoutMockOut := stdoutMock.Read()
114+
115+
assert.Equal(t, pl.metadata, string(stdoutMockOut))
116+
117+
}

plugin/plugin_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package plugin
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/IBM-Cloud/ibm-cloud-cli-sdk/testhelpers"
8+
"github.com/stretchr/testify/assert"
9+
)
10+
11+
func TestConvertCobraFlagsToPluginFlags(t *testing.T) {
12+
assert := assert.New(t)
13+
cmd := testhelpers.GenerateCobraCommand()
14+
outputFlag := cmd.Flag("output")
15+
quietFlag := cmd.Flag("quiet")
16+
deprecateFlag := cmd.Flag("outputJSON")
17+
18+
flags := ConvertCobraFlagsToPluginFlags(cmd)
19+
20+
assert.Equal(3, len(flags))
21+
22+
// NOTE: flags are sorted in lexicographical order
23+
assert.Equal(outputFlag.Usage, flags[0].Description)
24+
assert.True(flags[0].HasValue)
25+
assert.Equal(outputFlag.Hidden, flags[0].Hidden)
26+
assert.Equal(outputFlag.Name, flags[0].Name)
27+
28+
assert.Equal(deprecateFlag.Usage, flags[1].Description)
29+
assert.False(flags[1].HasValue)
30+
assert.Equal(deprecateFlag.Hidden, flags[1].Hidden)
31+
assert.Equal(deprecateFlag.Name, flags[1].Name)
32+
33+
assert.Equal(quietFlag.Usage, flags[2].Description)
34+
assert.False(flags[2].HasValue)
35+
assert.Equal(quietFlag.Hidden, flags[2].Hidden)
36+
assert.Equal(fmt.Sprintf("%s,%s", quietFlag.Shorthand, quietFlag.Name), flags[2].Name)
37+
}

testhelpers/command.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package testhelpers
2+
3+
import (
4+
"fmt"
5+
"io/ioutil"
6+
"os"
7+
8+
"github.com/spf13/cobra"
9+
)
10+
11+
// GenerateCobraCommand will create a cobra command with basic flags used for testing
12+
func GenerateCobraCommand() *cobra.Command {
13+
cmd := &cobra.Command{
14+
Use: "example",
15+
}
16+
17+
cmd.Flags().StringP("output", "", "", "Specify output format, only 'JSON' is supported.")
18+
cmd.Flags().BoolP("quiet", "q", false, "Suppress verbose output")
19+
cmd.Flags().BoolP("outputJSON", "", false, "Output data into JSON format")
20+
21+
// NOTE: Added #nosec tag since flag is not attached to a real command
22+
cmd.Flags().MarkDeprecated("outputJSON", "outputJSON deprecated use --output instead") // #nosec
23+
return cmd
24+
}
25+
26+
type mockStdoutFile struct {
27+
File *os.File
28+
}
29+
30+
// CreateMockStdout will create a temp file used for mocking stdout for testing
31+
func CreateMockStdout() *mockStdoutFile {
32+
f, err := os.CreateTemp("", "cli_sdk_mock_stdout")
33+
if err != nil {
34+
panic(fmt.Errorf("failed to create tmp file for mocking stdout: %v", err.Error()))
35+
}
36+
return &mockStdoutFile{
37+
File: f,
38+
}
39+
}
40+
41+
// Read will open the temp mock stdout file and return contents as a string
42+
func (m *mockStdoutFile) Read() string {
43+
out, err := ioutil.ReadFile(m.File.Name())
44+
if err != nil {
45+
panic(fmt.Errorf("failed to read stdout file: %v", err.Error()))
46+
}
47+
return string(out)
48+
}

0 commit comments

Comments
 (0)