Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .mockery.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Copyright (c) Codesphere Inc.
# SPDX-License-Identifier: Apache-2.0

all: false
dir: "{{.InterfaceDir}}"
force-file-write: true
filename: "mocks.go"
formatter: gofmt
log-level: info
structname: "{{.Mock}}{{.InterfaceName}}"
pkgname: "{{.SrcPackageName}}"
recursive: false
require-template-schema-exists: true
template: testify
template-schema: "{{.Template}}.schema.json"
packages:
github.com/codesphere-cloud/oms/internal/env:
config:
all: true
interfaces:
github.com/codesphere-cloud/oms/internal/portal:
config:
all: true
interfaces:
github.com/codesphere-cloud/oms/internal/util:
config:
all: true
interfaces:
4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ build-cli:
build-service:
cd service && go build -v && mv service ../oms-service

test: test-cli test-service
test:
go test -count=1 -v ./...

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

generate: install-build-deps
mockery
go generate ./...
13 changes: 13 additions & 0 deletions cli/cmd/cmd_suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package cmd_test

import (
"testing"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

func TestCmd(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Cmd Suite")
}
23 changes: 23 additions & 0 deletions cli/cmd/list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package cmd

import (
"github.com/codesphere-cloud/cs-go/pkg/io"
"github.com/spf13/cobra"
)

type ListCmd struct {
cmd *cobra.Command
}

func AddListCmd(rootCmd *cobra.Command, opts GlobalOptions) {
list := ListCmd{
cmd: &cobra.Command{
Use: "list",
Short: "List resources available through OMS",
Long: io.Long(`List resources managed by or available for OMS,
eg. available Codesphere packages`),
},
}
rootCmd.AddCommand(list.cmd)
AddListPackagesCmd(list.cmd, opts)
}
78 changes: 78 additions & 0 deletions cli/cmd/list_packages.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package cmd

import (
"fmt"

"github.com/codesphere-cloud/oms/internal/portal"
"github.com/codesphere-cloud/oms/internal/util"

"github.com/codesphere-cloud/cs-go/pkg/io"
"github.com/jedib0t/go-pretty/v6/table"
"github.com/spf13/cobra"
)

type ListBuildsCmd struct {
cmd *cobra.Command
Opts ListBuildsOpts
TableWriter util.TableWriter
}

type ListBuildsOpts struct {
GlobalOptions
Internal bool
}

func (c *ListBuildsCmd) RunE(_ *cobra.Command, args []string) error {
p := portal.NewPortalClient()
packages, err := p.ListCodespherePackages()
if err != nil {
return fmt.Errorf("failed to list codesphere packages: %w", err)
}

c.PrintPackagesTable(packages)
return nil
}

func AddListPackagesCmd(list *cobra.Command, opts GlobalOptions) {
builds := ListBuildsCmd{
cmd: &cobra.Command{
Use: "packages",
Short: "List available packages",
Long: io.Long(`List packages available for download via the OMS portal.`),
},
Opts: ListBuildsOpts{GlobalOptions: opts},
TableWriter: util.GetTableWriter(),
}

builds.cmd.RunE = builds.RunE
builds.cmd.Flags().BoolVarP(&builds.Opts.Internal, "list-internal", "i", false, "List internal packages")
_ = builds.cmd.Flags().MarkHidden("list-internal")

list.AddCommand(builds.cmd)
}

func (c *ListBuildsCmd) PrintPackagesTable(packages portal.CodesphereBuilds) {
c.TableWriter.AppendHeader(table.Row{"Int", "Version", "Build Date", "Hash", "Artifacts"})

for _, build := range packages.Builds {
if !c.Opts.Internal && build.Internal {
continue
}

int := ""
if build.Internal {
int = "*"
}

artifacts := ""
for i, art := range build.Artifacts {
if i > 0 {
artifacts += ", "
}
artifacts = artifacts + art.Filename
}

c.TableWriter.AppendRow(table.Row{int, build.Version, build.Date, build.Hash, artifacts})
}
c.TableWriter.Render()
}
104 changes: 104 additions & 0 deletions cli/cmd/list_packages_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package cmd_test

import (
"time"

"github.com/jedib0t/go-pretty/v6/table"
. "github.com/onsi/ginkgo/v2"
//. "github.com/onsi/gomega"
"github.com/stretchr/testify/mock"

"github.com/codesphere-cloud/oms/cli/cmd"
"github.com/codesphere-cloud/oms/internal/portal"
"github.com/codesphere-cloud/oms/internal/util"
)

var _ = Describe("ListPackages", func() {

var (
mockTableWriter util.MockTableWriter
c cmd.ListBuildsCmd
internal bool
buildDate time.Time
)
BeforeEach(func() {
c = cmd.ListBuildsCmd{
Opts: cmd.ListBuildsOpts{
Internal: internal,
},
TableWriter: &mockTableWriter,
}

buildDate, _ = time.Parse("2006-01-02", "2025-05-01")

// header is always appended
mockTableWriter.EXPECT().AppendHeader(mock.Anything)
mockTableWriter.EXPECT().Render().Return("")
})

Context("Internal packages are excluded", func() {
It("doesn't list internal packages, artifacts are separated by ,", func() {
mockTableWriter.EXPECT().AppendRow(
table.Row{"", "1.42", buildDate, "externalBuild", "installer.tar, installer2.tar"},
)
c.PrintPackagesTable(
portal.CodesphereBuilds{
Builds: []portal.CodesphereBuild{
{
Hash: "externalBuild",
Version: "1.42",
Date: buildDate,
Internal: false,
Artifacts: []portal.Artifact{
{Filename: "installer.tar"},
{Filename: "installer2.tar"},
},
},
{
Hash: "internalBuild",
Internal: true,
},
},
})
})

})
Context("Internal packages are included", func() {
BeforeEach(func() {
internal = true
})
It("marks internal packages with a *", func() {
mockTableWriter.EXPECT().AppendRow(
table.Row{"", "1.42", buildDate, "externalBuild", "installer.tar, installer2.tar"},
)
mockTableWriter.EXPECT().AppendRow(
table.Row{"*", "master", buildDate, "internalBuild", "installer.tar, installer2.tar"},
)
c.PrintPackagesTable(
portal.CodesphereBuilds{
Builds: []portal.CodesphereBuild{
{
Hash: "externalBuild",
Version: "1.42",
Date: buildDate,
Internal: false,
Artifacts: []portal.Artifact{
{Filename: "installer.tar"},
{Filename: "installer2.tar"},
},
},
{
Hash: "internalBuild",
Version: "master",
Date: buildDate,
Internal: true,
Artifacts: []portal.Artifact{
{Filename: "installer.tar"},
{Filename: "installer2.tar"},
},
},
},
})
})
})
})
34 changes: 12 additions & 22 deletions cli/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,38 +6,28 @@ package cmd
import (
"os"

"github.com/codesphere-cloud/cs-go/pkg/io"
"github.com/spf13/cobra"
)

type GlobalOptions struct {
OmsPortalApiKey string
}

// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
// rootCmd represents the base command when called without any subcommands
opts := GlobalOptions{}
rootCmd := &cobra.Command{
Use: "cli",
Short: "A brief description of your application",
Long: `A longer description that spans multiple lines and likely contains
examples and usage of using your application. For example:
Use: "oms",
Short: "Codesphere Operations Management System (OMS)",
Long: io.Long(`Codesphere Operations Management System (OMS)

Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
// Uncomment the following line if your bare application
// has an action associated with it:
// Run: func(cmd *cobra.Command, args []string) { },
This command can be used to run common tasks related to managing codesphere installations,
like downloading new versions.`),
}
// Here you will define your flags and configuration settings.
// Cobra supports persistent flags, which, if defined here,
// will be global for your application.

// rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.cli.yaml)")

// Cobra also supports local flags, which will only run
// when this action is called directly.
// rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")

// Add child commands here
AddInstallCmd(rootCmd)
AddListCmd(rootCmd, opts)

err := rootCmd.Execute()
if err != nil {
Expand Down
26 changes: 24 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,10 +1,32 @@
module github.com/codesphere-cloud/oms

go 1.24.1
go 1.24.2

require github.com/spf13/cobra v1.9.1
require (
github.com/codesphere-cloud/cs-go v0.10.1
github.com/jedib0t/go-pretty/v6 v6.6.7
github.com/onsi/ginkgo/v2 v2.23.4
github.com/onsi/gomega v1.37.0
github.com/spf13/cobra v1.9.1
github.com/stretchr/testify v1.10.0
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
github.com/google/go-cmp v0.7.0 // indirect
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/spf13/pflag v1.0.6 // indirect
github.com/stretchr/objx v0.5.2 // indirect
go.uber.org/automaxprocs v1.6.0 // indirect
golang.org/x/net v0.40.0 // indirect
golang.org/x/sys v0.33.0 // indirect
golang.org/x/text v0.25.0 // indirect
golang.org/x/tools v0.31.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
Loading