Skip to content

Commit efbf5b4

Browse files
committed
feat(list-packages): List codesphere packages
* Adds a wrapper for HTTP calls to the OMS Portal * Adds utility to print tables
1 parent ee3e570 commit efbf5b4

File tree

19 files changed

+1052
-25
lines changed

19 files changed

+1052
-25
lines changed

.mockery.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Copyright (c) Codesphere Inc.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
all: false
5+
dir: "{{.InterfaceDir}}"
6+
force-file-write: true
7+
filename: "mocks.go"
8+
formatter: gofmt
9+
log-level: info
10+
structname: "{{.Mock}}{{.InterfaceName}}"
11+
pkgname: "{{.SrcPackageName}}"
12+
recursive: false
13+
require-template-schema-exists: true
14+
template: testify
15+
template-schema: "{{.Template}}.schema.json"
16+
packages:
17+
github.com/codesphere-cloud/oms/internal/env:
18+
config:
19+
all: true
20+
interfaces:
21+
github.com/codesphere-cloud/oms/internal/portal:
22+
config:
23+
all: true
24+
interfaces:
25+
github.com/codesphere-cloud/oms/internal/util:
26+
config:
27+
all: true
28+
interfaces:

Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ build-cli:
66
build-service:
77
cd service && go build -v && mv service ../oms-service
88

9-
test: test-cli test-service
9+
test:
10+
go test -count=1 -v ./...
1011

1112
test-cli:
1213
# -count=1 to disable caching test results
@@ -30,4 +31,5 @@ ifeq (, $(shell which golangci-lint))
3031
endif
3132

3233
generate: install-build-deps
34+
mockery
3335
go generate ./...

cli/cmd/cmd_suite_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package cmd_test
2+
3+
import (
4+
"testing"
5+
6+
. "github.com/onsi/ginkgo/v2"
7+
. "github.com/onsi/gomega"
8+
)
9+
10+
func TestCmd(t *testing.T) {
11+
RegisterFailHandler(Fail)
12+
RunSpecs(t, "Cmd Suite")
13+
}

cli/cmd/list.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package cmd
2+
3+
import (
4+
"github.com/codesphere-cloud/cs-go/pkg/io"
5+
"github.com/spf13/cobra"
6+
)
7+
8+
type ListCmd struct {
9+
cmd *cobra.Command
10+
}
11+
12+
func AddListCmd(rootCmd *cobra.Command, opts GlobalOptions) {
13+
list := ListCmd{
14+
cmd: &cobra.Command{
15+
Use: "list",
16+
Short: "List resources available through OMS",
17+
Long: io.Long(`List resources managed by or available for OMS,
18+
eg. available Codesphere packages`),
19+
},
20+
}
21+
rootCmd.AddCommand(list.cmd)
22+
AddListPackagesCmd(list.cmd, opts)
23+
}

cli/cmd/list_packages.go

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package cmd
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/codesphere-cloud/oms/internal/portal"
7+
"github.com/codesphere-cloud/oms/internal/util"
8+
9+
"github.com/codesphere-cloud/cs-go/pkg/io"
10+
"github.com/jedib0t/go-pretty/v6/table"
11+
"github.com/spf13/cobra"
12+
)
13+
14+
type ListBuildsCmd struct {
15+
cmd *cobra.Command
16+
Opts ListBuildsOpts
17+
TableWriter util.TableWriter
18+
}
19+
20+
type ListBuildsOpts struct {
21+
GlobalOptions
22+
Internal bool
23+
}
24+
25+
func (c *ListBuildsCmd) RunE(_ *cobra.Command, args []string) error {
26+
p := portal.NewPortalClient()
27+
packages, err := p.ListCodespherePackages()
28+
if err != nil {
29+
return fmt.Errorf("failed to list codesphere packages: %w", err)
30+
}
31+
32+
c.PrintPackagesTable(packages)
33+
return nil
34+
}
35+
36+
func AddListPackagesCmd(list *cobra.Command, opts GlobalOptions) {
37+
builds := ListBuildsCmd{
38+
cmd: &cobra.Command{
39+
Use: "packages",
40+
Short: "List available packages",
41+
Long: io.Long(`List packages available for download via the OMS portal.`),
42+
},
43+
Opts: ListBuildsOpts{GlobalOptions: opts},
44+
TableWriter: util.GetTableWriter(),
45+
}
46+
list.AddCommand(builds.cmd)
47+
builds.cmd.RunE = builds.RunE
48+
builds.cmd.Flags().BoolVarP(&builds.Opts.Internal, "list-internal", "i", false, "List internal packages")
49+
_ = builds.cmd.Flags().MarkHidden("list-internal")
50+
}
51+
52+
func (c *ListBuildsCmd) PrintPackagesTable(packages portal.CodesphereBuilds) {
53+
c.TableWriter.AppendHeader(table.Row{"Int", "Version", "Build Date", "Hash", "Artifacts"})
54+
55+
for _, build := range packages.Builds {
56+
if !c.Opts.Internal && build.Internal {
57+
continue
58+
}
59+
60+
int := ""
61+
if build.Internal {
62+
int = "*"
63+
}
64+
65+
artifacts := ""
66+
for i, art := range build.Artifacts {
67+
if i > 0 {
68+
artifacts += ", "
69+
}
70+
artifacts = artifacts + art.Filename
71+
}
72+
73+
c.TableWriter.AppendRow(table.Row{int, build.Version, build.Date, build.Hash, artifacts})
74+
}
75+
c.TableWriter.Render()
76+
}

cli/cmd/list_packages_test.go

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package cmd_test
2+
3+
import (
4+
"time"
5+
6+
"github.com/jedib0t/go-pretty/v6/table"
7+
. "github.com/onsi/ginkgo/v2"
8+
//. "github.com/onsi/gomega"
9+
"github.com/stretchr/testify/mock"
10+
11+
"github.com/codesphere-cloud/oms/cli/cmd"
12+
"github.com/codesphere-cloud/oms/internal/portal"
13+
"github.com/codesphere-cloud/oms/internal/util"
14+
)
15+
16+
var _ = Describe("ListPackages", func() {
17+
18+
var (
19+
mockTableWriter util.MockTableWriter
20+
c cmd.ListBuildsCmd
21+
internal bool
22+
buildDate time.Time
23+
)
24+
BeforeEach(func() {
25+
c = cmd.ListBuildsCmd{
26+
Opts: cmd.ListBuildsOpts{
27+
Internal: internal,
28+
},
29+
TableWriter: &mockTableWriter,
30+
}
31+
32+
buildDate, _ = time.Parse("2006-01-02", "2025-05-01")
33+
34+
// header is always appended
35+
mockTableWriter.EXPECT().AppendHeader(mock.Anything)
36+
mockTableWriter.EXPECT().Render().Return("")
37+
})
38+
39+
Context("Internal packages are excluded", func() {
40+
It("doesn't list internal packages, artifacts are separated by ,", func() {
41+
mockTableWriter.EXPECT().AppendRow(
42+
table.Row{"", "1.42", buildDate, "externalBuild", "installer.tar, installer2.tar"},
43+
)
44+
c.PrintPackagesTable(
45+
portal.CodesphereBuilds{
46+
Builds: []portal.CodesphereBuild{
47+
{
48+
Hash: "externalBuild",
49+
Version: "1.42",
50+
Date: buildDate,
51+
Internal: false,
52+
Artifacts: []portal.Artifact{
53+
{Filename: "installer.tar"},
54+
{Filename: "installer2.tar"},
55+
},
56+
},
57+
{
58+
Hash: "internalBuild",
59+
Internal: true,
60+
},
61+
},
62+
})
63+
})
64+
65+
})
66+
Context("Internal packages are included", func() {
67+
BeforeEach(func() {
68+
internal = true
69+
})
70+
It("marks internal packages with a *", func() {
71+
mockTableWriter.EXPECT().AppendRow(
72+
table.Row{"", "1.42", buildDate, "externalBuild", "installer.tar, installer2.tar"},
73+
)
74+
mockTableWriter.EXPECT().AppendRow(
75+
table.Row{"*", "master", buildDate, "internalBuild", "installer.tar, installer2.tar"},
76+
)
77+
c.PrintPackagesTable(
78+
portal.CodesphereBuilds{
79+
Builds: []portal.CodesphereBuild{
80+
{
81+
Hash: "externalBuild",
82+
Version: "1.42",
83+
Date: buildDate,
84+
Internal: false,
85+
Artifacts: []portal.Artifact{
86+
{Filename: "installer.tar"},
87+
{Filename: "installer2.tar"},
88+
},
89+
},
90+
{
91+
Hash: "internalBuild",
92+
Version: "master",
93+
Date: buildDate,
94+
Internal: true,
95+
Artifacts: []portal.Artifact{
96+
{Filename: "installer.tar"},
97+
{Filename: "installer2.tar"},
98+
},
99+
},
100+
},
101+
})
102+
})
103+
})
104+
})

cli/cmd/root.go

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,38 +6,28 @@ package cmd
66
import (
77
"os"
88

9+
"github.com/codesphere-cloud/cs-go/pkg/io"
910
"github.com/spf13/cobra"
1011
)
1112

13+
type GlobalOptions struct {
14+
OmsPortalApiKey string
15+
}
16+
1217
// Execute adds all child commands to the root command and sets flags appropriately.
1318
// This is called by main.main(). It only needs to happen once to the rootCmd.
1419
func Execute() {
15-
// rootCmd represents the base command when called without any subcommands
20+
opts := GlobalOptions{}
1621
rootCmd := &cobra.Command{
17-
Use: "cli",
18-
Short: "A brief description of your application",
19-
Long: `A longer description that spans multiple lines and likely contains
20-
examples and usage of using your application. For example:
22+
Use: "oms",
23+
Short: "Codesphere Operations Management System (OMS)",
24+
Long: io.Long(`Codesphere Operations Management System (OMS)
2125
22-
Cobra is a CLI library for Go that empowers applications.
23-
This application is a tool to generate the needed files
24-
to quickly create a Cobra application.`,
25-
// Uncomment the following line if your bare application
26-
// has an action associated with it:
27-
// Run: func(cmd *cobra.Command, args []string) { },
26+
This command can be used to run common tasks related to managing codesphere installations,
27+
like downloading new versions.`),
2828
}
29-
// Here you will define your flags and configuration settings.
30-
// Cobra supports persistent flags, which, if defined here,
31-
// will be global for your application.
32-
33-
// rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.cli.yaml)")
34-
35-
// Cobra also supports local flags, which will only run
36-
// when this action is called directly.
37-
// rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
38-
39-
// Add child commands here
4029
AddInstallCmd(rootCmd)
30+
AddListCmd(rootCmd, opts)
4131

4232
err := rootCmd.Execute()
4333
if err != nil {

go.mod

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,32 @@
11
module github.com/codesphere-cloud/oms
22

3-
go 1.24.1
3+
go 1.24.2
44

5-
require github.com/spf13/cobra v1.9.1
5+
require (
6+
github.com/codesphere-cloud/cs-go v0.10.1
7+
github.com/jedib0t/go-pretty/v6 v6.6.7
8+
github.com/onsi/ginkgo/v2 v2.23.4
9+
github.com/onsi/gomega v1.37.0
10+
github.com/spf13/cobra v1.9.1
11+
github.com/stretchr/testify v1.10.0
12+
)
613

714
require (
15+
github.com/davecgh/go-spew v1.1.1 // indirect
16+
github.com/go-logr/logr v1.4.3 // indirect
17+
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
18+
github.com/google/go-cmp v0.7.0 // indirect
19+
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect
820
github.com/inconshreveable/mousetrap v1.1.0 // indirect
21+
github.com/mattn/go-runewidth v0.0.16 // indirect
22+
github.com/pmezard/go-difflib v1.0.0 // indirect
23+
github.com/rivo/uniseg v0.4.7 // indirect
924
github.com/spf13/pflag v1.0.6 // indirect
25+
github.com/stretchr/objx v0.5.2 // indirect
26+
go.uber.org/automaxprocs v1.6.0 // indirect
27+
golang.org/x/net v0.40.0 // indirect
28+
golang.org/x/sys v0.33.0 // indirect
29+
golang.org/x/text v0.25.0 // indirect
30+
golang.org/x/tools v0.31.0 // indirect
31+
gopkg.in/yaml.v3 v3.0.1 // indirect
1032
)

0 commit comments

Comments
 (0)