Skip to content

Commit 019d4be

Browse files
authored
Add extra information to status command (#1429)
Add into elastic-package status command a new parameter `--info` that allows to show extra information for each version of the package. Currently the supported parameters allow us to show condition about kibana.version, condition about elastic.subscription and the categories set for this package.
1 parent 50d16f8 commit 019d4be

File tree

4 files changed

+172
-60
lines changed

4 files changed

+172
-60
lines changed

cmd/status.go

Lines changed: 117 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,24 @@ If a package name is specified, then information about that package is
3030
returned, otherwise this command checks if the current directory is a
3131
package directory and reports its status.`
3232

33+
const (
34+
kibanaVersionParameter = "kibana.version"
35+
categoriesParamter = "categories"
36+
elasticsearchSubscriptionParameter = "elastic.subscription"
37+
)
38+
39+
var (
40+
bold = color.New(color.Bold)
41+
red = color.New(color.FgRed, color.Bold)
42+
cyan = color.New(color.FgCyan, color.Bold)
43+
44+
availableExtraInfoParameters = []string{
45+
kibanaVersionParameter,
46+
categoriesParamter,
47+
elasticsearchSubscriptionParameter,
48+
}
49+
)
50+
3351
func setupStatusCommand() *cobraext.Command {
3452
cmd := &cobra.Command{
3553
Use: "status [package]",
@@ -40,6 +58,7 @@ func setupStatusCommand() *cobraext.Command {
4058
}
4159
cmd.Flags().BoolP(cobraext.ShowAllFlagName, "a", false, cobraext.ShowAllFlagDescription)
4260
cmd.Flags().String(cobraext.StatusKibanaVersionFlagName, "", cobraext.StatusKibanaVersionFlagDescription)
61+
cmd.Flags().StringSlice(cobraext.StatusExtraInfoFlagName, nil, fmt.Sprintf(cobraext.StatusExtraInfoFlagDescription, strings.Join(availableExtraInfoParameters, ",")))
4362

4463
return cobraext.NewCommand(cmd, cobraext.ContextPackage)
4564
}
@@ -59,6 +78,16 @@ func statusCommandAction(cmd *cobra.Command, args []string) error {
5978
if err != nil {
6079
return cobraext.FlagParsingError(err, cobraext.StatusKibanaVersionFlagName)
6180
}
81+
extraParameters, err := cmd.Flags().GetStringSlice(cobraext.StatusExtraInfoFlagName)
82+
if err != nil {
83+
return cobraext.FlagParsingError(err, cobraext.StatusExtraInfoFlagName)
84+
}
85+
86+
err = validateExtraInfoParameters(extraParameters)
87+
if err != nil {
88+
return fmt.Errorf("validating info paramaters failed: %w", err)
89+
90+
}
6291
options := registry.SearchOptions{
6392
All: showAll,
6493
KibanaVersion: kibanaVersion,
@@ -71,7 +100,22 @@ func statusCommandAction(cmd *cobra.Command, args []string) error {
71100
if err != nil {
72101
return err
73102
}
74-
return print(packageStatus, os.Stdout)
103+
return print(packageStatus, os.Stdout, extraParameters)
104+
}
105+
106+
func validateExtraInfoParameters(extraParameters []string) error {
107+
for _, param := range extraParameters {
108+
found := false
109+
for _, validParam := range availableExtraInfoParameters {
110+
if param == validParam {
111+
found = true
112+
}
113+
}
114+
if !found {
115+
return fmt.Errorf("parameter \"%s\" is not available (available ones: \"%s\")", param, strings.Join(availableExtraInfoParameters, ","))
116+
}
117+
}
118+
return nil
75119
}
76120

77121
func getPackageStatus(packageName string, options registry.SearchOptions) (*status.PackageStatus, error) {
@@ -89,67 +133,87 @@ func getPackageStatus(packageName string, options registry.SearchOptions) (*stat
89133
}
90134

91135
// print formats and prints package information into a table
92-
func print(p *status.PackageStatus, w io.Writer) error {
93-
bold := color.New(color.Bold)
94-
red := color.New(color.FgRed, color.Bold)
95-
cyan := color.New(color.FgCyan, color.Bold)
136+
func print(p *status.PackageStatus, w io.Writer, extraParameters []string) error {
96137
bold.Fprint(w, "Package: ")
97138
cyan.Fprintln(w, p.Name)
98139

99-
var environmentTable [][]string
100140
if p.Local != nil {
101141
bold.Fprint(w, "Owner: ")
102142
cyan.Fprintln(w, formatOwner(p))
103-
environmentTable = append(environmentTable, formatManifest("Local", *p.Local, nil))
104143
}
105-
environmentTable = append(environmentTable, formatManifests("Production", p.Production))
106144

107145
if p.PendingChanges != nil {
108-
bold.Fprint(w, "Next Version: ")
109-
red.Fprintln(w, p.PendingChanges.Version)
110-
bold.Fprintln(w, "Pending Changes:")
111-
var changelogTable [][]string
112-
for _, change := range p.PendingChanges.Changes {
113-
changelogTable = append(changelogTable, formatChangelogEntry(change))
114-
}
115-
table := tablewriter.NewWriter(w)
116-
table.SetHeader([]string{"Type", "Description", "Link"})
117-
table.SetHeaderColor(
118-
twColor(tablewriter.Colors{tablewriter.Bold}),
119-
twColor(tablewriter.Colors{tablewriter.Bold}),
120-
twColor(tablewriter.Colors{tablewriter.Bold}),
121-
)
122-
table.SetColumnColor(
123-
twColor(tablewriter.Colors{tablewriter.Bold, tablewriter.FgCyanColor}),
124-
tablewriter.Colors{},
125-
tablewriter.Colors{},
126-
)
127-
table.SetRowLine(true)
128-
table.AppendBulk(changelogTable)
129-
table.Render()
146+
renderPendingChanges(p, w)
130147
}
131148

132-
bold.Fprintln(w, "Package Versions:")
149+
renderPackageVersions(p, w, extraParameters)
150+
return nil
151+
}
152+
153+
// renderPendingChanges formats and prints pending changes in the package into a table
154+
func renderPendingChanges(p *status.PackageStatus, w io.Writer) {
155+
bold.Fprint(w, "Next Version: ")
156+
red.Fprintln(w, p.PendingChanges.Version)
157+
bold.Fprintln(w, "Pending Changes:")
158+
var changelogTable [][]string
159+
for _, change := range p.PendingChanges.Changes {
160+
changelogTable = append(changelogTable, formatChangelogEntry(change))
161+
}
133162
table := tablewriter.NewWriter(w)
134-
table.SetHeader([]string{"Environment", "Version", "Release", "Title", "Description"})
163+
table.SetHeader([]string{"Type", "Description", "Link"})
135164
table.SetHeaderColor(
136165
twColor(tablewriter.Colors{tablewriter.Bold}),
137166
twColor(tablewriter.Colors{tablewriter.Bold}),
138167
twColor(tablewriter.Colors{tablewriter.Bold}),
139-
twColor(tablewriter.Colors{tablewriter.Bold}),
140-
twColor(tablewriter.Colors{tablewriter.Bold}),
141168
)
142169
table.SetColumnColor(
170+
twColor(tablewriter.Colors{tablewriter.Bold, tablewriter.FgCyanColor}),
171+
tablewriter.Colors{},
172+
tablewriter.Colors{},
173+
)
174+
table.SetRowLine(true)
175+
table.AppendBulk(changelogTable)
176+
table.Render()
177+
}
178+
179+
// renderPackageVersions formats and prints local and production versions of the package into a table
180+
func renderPackageVersions(p *status.PackageStatus, w io.Writer, extraParameters []string) {
181+
var environmentTable [][]string
182+
if p.Local != nil {
183+
environmentTable = append(environmentTable, formatManifest("Local", *p.Local, nil, extraParameters))
184+
}
185+
environmentTable = append(environmentTable, formatManifests("Production", p.Production, extraParameters))
186+
187+
bold.Fprintln(w, "Package Versions:")
188+
table := tablewriter.NewWriter(w)
189+
headers := []string{"Environment", "Version", "Release", "Title", "Description"}
190+
headers = append(headers, extraParameters...)
191+
192+
table.SetHeader(headers)
193+
194+
headerColors := []tablewriter.Colors{}
195+
for i := 0; i < len(headers); i++ {
196+
headerColors = append(headerColors, twColor(tablewriter.Colors{tablewriter.Bold}))
197+
}
198+
199+
table.SetHeaderColor(headerColors...)
200+
201+
columnColors := []tablewriter.Colors{
143202
twColor(tablewriter.Colors{tablewriter.Bold, tablewriter.FgCyanColor}),
144203
twColor(tablewriter.Colors{tablewriter.Bold, tablewriter.FgRedColor}),
145204
tablewriter.Colors{},
146205
tablewriter.Colors{},
147206
tablewriter.Colors{},
148-
)
207+
}
208+
for i := 0; i < len(extraParameters); i++ {
209+
columnColors = append(columnColors, tablewriter.Colors{})
210+
}
211+
212+
table.SetColumnColor(columnColors...)
213+
149214
table.SetRowLine(true)
150215
table.AppendBulk(environmentTable)
151216
table.Render()
152-
return nil
153217
}
154218

155219
// formatOwner returns the name of the package owner
@@ -166,7 +230,7 @@ func formatChangelogEntry(change changelog.Entry) []string {
166230
}
167231

168232
// formatManifests returns a row of data ffor a set of versioned packaged manifests
169-
func formatManifests(environment string, manifests []packages.PackageManifest) []string {
233+
func formatManifests(environment string, manifests []packages.PackageManifest, extraParameters []string) []string {
170234
if len(manifests) == 0 {
171235
return []string{environment, "-", "-", "-", "-"}
172236
}
@@ -176,16 +240,29 @@ func formatManifests(environment string, manifests []packages.PackageManifest) [
176240
extraVersions = append(extraVersions, m.Version)
177241
}
178242
}
179-
return formatManifest(environment, manifests[len(manifests)-1], extraVersions)
243+
return formatManifest(environment, manifests[len(manifests)-1], extraVersions, extraParameters)
180244
}
181245

182246
// formatManifest returns a row of data for a given package manifest
183-
func formatManifest(environment string, manifest packages.PackageManifest, extraVersions []string) []string {
247+
func formatManifest(environment string, manifest packages.PackageManifest, extraVersions []string, extraParameters []string) []string {
184248
version := manifest.Version
185249
if len(extraVersions) > 0 {
186250
version = fmt.Sprintf("%s (%s)", version, strings.Join(extraVersions, ", "))
187251
}
188-
return []string{environment, version, releaseFromVersion(manifest.Version), manifest.Title, manifest.Description}
252+
253+
data := []string{environment, version, releaseFromVersion(manifest.Version), manifest.Title, manifest.Description}
254+
255+
for _, param := range extraParameters {
256+
switch param {
257+
case kibanaVersionParameter:
258+
data = append(data, manifest.Conditions.Kibana.Version)
259+
case categoriesParamter:
260+
data = append(data, strings.Join(manifest.Categories, ","))
261+
case elasticsearchSubscriptionParameter:
262+
data = append(data, manifest.Conditions.Elastic.Subscription)
263+
}
264+
}
265+
return data
189266
}
190267

191268
// twColor no-ops the color setting if we don't want to colorize the output

cmd/status_test.go

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import (
2020

2121
var generateFlag = flag.Bool("generate", false, "Write golden files")
2222

23-
func fooPackage(version string) packages.PackageManifest {
23+
func fooPackage(version, kibanaVersion string) packages.PackageManifest {
2424
return packages.PackageManifest{
2525
Name: "foo",
2626
Version: version,
@@ -29,11 +29,17 @@ func fooPackage(version string) packages.PackageManifest {
2929
Owner: packages.Owner{
3030
Github: "team",
3131
},
32+
Conditions: packages.Conditions{
33+
Kibana: packages.KibanaConditions{Version: kibanaVersion},
34+
},
35+
Categories: []string{
36+
"custom",
37+
},
3238
}
3339
}
3440

3541
func TestStatusFormatAndPrint(t *testing.T) {
36-
localPackage := fooPackage("2.0.0-rc1")
42+
localPackage := fooPackage("2.0.0-rc1", "^8.9.0")
3743
localPendingChanges := changelog.Revision{
3844
Version: "2.0.0-rc2",
3945
Changes: []changelog.Entry{
@@ -46,9 +52,10 @@ func TestStatusFormatAndPrint(t *testing.T) {
4652
}
4753

4854
cases := []struct {
49-
title string
50-
pkgStatus *status.PackageStatus
51-
expected string
55+
title string
56+
pkgStatus *status.PackageStatus
57+
extraParameters []string
58+
expected string
5259
}{
5360
{
5461
title: "no versions",
@@ -60,7 +67,7 @@ func TestStatusFormatAndPrint(t *testing.T) {
6067
pkgStatus: &status.PackageStatus{
6168
Name: "foo",
6269
Production: []packages.PackageManifest{
63-
fooPackage("1.0.0"),
70+
fooPackage("1.0.0", "^8.8.0"),
6471
},
6572
},
6673
expected: "./testdata/status-version-one-stage",
@@ -70,8 +77,8 @@ func TestStatusFormatAndPrint(t *testing.T) {
7077
pkgStatus: &status.PackageStatus{
7178
Name: "foo",
7279
Production: []packages.PackageManifest{
73-
fooPackage("1.0.0"),
74-
fooPackage("1.1.0-beta1"),
80+
fooPackage("1.0.0", "^8.8.0"),
81+
fooPackage("1.1.0-beta1", "^8.8.0"),
7582
},
7683
},
7784
expected: "./testdata/status-beta-versions",
@@ -81,9 +88,9 @@ func TestStatusFormatAndPrint(t *testing.T) {
8188
pkgStatus: &status.PackageStatus{
8289
Name: "foo",
8390
Production: []packages.PackageManifest{
84-
fooPackage("1.0.0"),
85-
fooPackage("1.1.0-beta1"),
86-
fooPackage("2.0.0-rc1"),
91+
fooPackage("1.0.0", "^8.8.0"),
92+
fooPackage("1.1.0-beta1", "^8.8.0"),
93+
fooPackage("2.0.0-rc1", "^8.8.0"),
8794
},
8895
},
8996
expected: "./testdata/status-release-candidate-versions",
@@ -93,9 +100,9 @@ func TestStatusFormatAndPrint(t *testing.T) {
93100
pkgStatus: &status.PackageStatus{
94101
Name: "foo",
95102
Production: []packages.PackageManifest{
96-
fooPackage("0.9.0"),
97-
fooPackage("1.0.0-preview1"),
98-
fooPackage("1.0.0-preview5"),
103+
fooPackage("0.9.0", "^8.6.0"),
104+
fooPackage("1.0.0-preview1", "^8.8.0"),
105+
fooPackage("1.0.0-preview5", "^8.8.0"),
99106
},
100107
},
101108
expected: "./testdata/status-preview-versions",
@@ -106,10 +113,10 @@ func TestStatusFormatAndPrint(t *testing.T) {
106113
Name: "foo",
107114
Local: &localPackage,
108115
Production: []packages.PackageManifest{
109-
fooPackage("1.0.0"),
110-
fooPackage("1.0.1"),
111-
fooPackage("1.0.2"),
112-
fooPackage("1.1.0-beta1"),
116+
fooPackage("1.0.0", "^8.8.0"),
117+
fooPackage("1.0.1", "^8.8.0"),
118+
fooPackage("1.0.2", "^8.8.0"),
119+
fooPackage("1.1.0-beta1", "^8.8.0"),
113120
},
114121
},
115122
expected: "./testdata/status-local-version-stage",
@@ -121,17 +128,32 @@ func TestStatusFormatAndPrint(t *testing.T) {
121128
Local: &localPackage,
122129
PendingChanges: &localPendingChanges,
123130
Production: []packages.PackageManifest{
124-
fooPackage("1.0.0"),
131+
fooPackage("1.0.0", "^8.8.0"),
125132
},
126133
},
127134
expected: "./testdata/status-pending-changes",
128135
},
136+
{
137+
title: "extra parameters",
138+
pkgStatus: &status.PackageStatus{
139+
Name: "foo",
140+
Local: &localPackage,
141+
Production: []packages.PackageManifest{
142+
fooPackage("1.0.0", "^8.8.0"),
143+
},
144+
},
145+
extraParameters: []string{
146+
"kibana.version",
147+
"categories",
148+
},
149+
expected: "./testdata/status-extra-parameters",
150+
},
129151
}
130152

131153
for _, c := range cases {
132154
t.Run(c.title, func(t *testing.T) {
133155
var buf bytes.Buffer
134-
err := print(c.pkgStatus, &buf)
156+
err := print(c.pkgStatus, &buf, c.extraParameters)
135157
require.NoError(t, err)
136158

137159
assertOutputWithFile(t, c.expected, buf.String())
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
Package: foo
2+
Owner: team
3+
Package Versions:
4+
+-------------+-----------+-------------------+-------+-----------------+----------------+------------+
5+
| ENVIRONMENT | VERSION | RELEASE | TITLE | DESCRIPTION | KIBANA VERSION | CATEGORIES |
6+
+-------------+-----------+-------------------+-------+-----------------+----------------+------------+
7+
| Local | 2.0.0-rc1 | Release Candidate | Foo | Foo integration | ^8.9.0 | custom |
8+
+-------------+-----------+-------------------+-------+-----------------+----------------+------------+
9+
| Production | 1.0.0 | GA | Foo | Foo integration | ^8.8.0 | custom |
10+
+-------------+-----------+-------------------+-------+-----------------+----------------+------------+

internal/cobraext/flags.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,9 @@ const (
173173
StatusKibanaVersionFlagName = "kibana-version"
174174
StatusKibanaVersionFlagDescription = "show packages for the given kibana version"
175175

176+
StatusExtraInfoFlagName = "info"
177+
StatusExtraInfoFlagDescription = "show additional information (comma-separated values: \"%s\")"
178+
176179
TestCoverageFlagName = "test-coverage"
177180
TestCoverageFlagDescription = "generate Cobertura test coverage reports"
178181

0 commit comments

Comments
 (0)