Skip to content
Open
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
2 changes: 2 additions & 0 deletions cmd/skpr/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/skpr/cli/cmd/skpr/logs"
"github.com/skpr/cli/cmd/skpr/mysql"
pkg "github.com/skpr/cli/cmd/skpr/package"
"github.com/skpr/cli/cmd/skpr/project"
"github.com/skpr/cli/cmd/skpr/purge"
"github.com/skpr/cli/cmd/skpr/release"
"github.com/skpr/cli/cmd/skpr/restore"
Expand Down Expand Up @@ -98,6 +99,7 @@ func main() {
cmd.AddCommand(logs.NewCommand())
cmd.AddCommand(mysql.NewCommand())
cmd.AddCommand(pkg.NewCommand())
cmd.AddCommand(project.NewCommand())
cmd.AddCommand(purge.NewCommand())
cmd.AddCommand(release.NewCommand())
cmd.AddCommand(restore.NewCommand())
Expand Down
26 changes: 26 additions & 0 deletions cmd/skpr/project/command.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package project

import (
"github.com/spf13/cobra"

"github.com/skpr/cli/cmd/skpr/project/get"
"github.com/skpr/cli/cmd/skpr/project/list"
"github.com/skpr/cli/cmd/skpr/project/set"
"github.com/skpr/cli/internal/command"
)

// NewCommand creates a new cobra.Command for 'config' sub command
func NewCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "project",
DisableFlagsInUseLine: true,
Short: "Manage projects",
GroupID: command.GroupLifecycle,
}

cmd.AddCommand(get.NewCommand())
cmd.AddCommand(list.NewCommand())
cmd.AddCommand(set.NewCommand())

return cmd
}
30 changes: 30 additions & 0 deletions cmd/skpr/project/get/command.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package get

import (
"github.com/spf13/cobra"

v1get "github.com/skpr/cli/internal/command/project/get"
)

var (
cmdExample = `
# Get project details
skpr project get`
)

// NewCommand creates a new cobra.Command for 'get' sub command
func NewCommand() *cobra.Command {
command := v1get.Command{}

cmd := &cobra.Command{
Use: "get",
DisableFlagsInUseLine: true,
Short: "Get contact for the current project.",
Example: cmdExample,
RunE: func(cmd *cobra.Command, args []string) error {
return command.Run(cmd.Context())
},
}

return cmd
}
24 changes: 24 additions & 0 deletions cmd/skpr/project/list/command.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package list

import (
"github.com/spf13/cobra"

v1list "github.com/skpr/cli/internal/command/project/list"
)

// NewCommand creates a new cobra.Command for 'list' sub command
func NewCommand() *cobra.Command {
command := v1list.Command{}

cmd := &cobra.Command{
Use: "list",
Args: cobra.NoArgs,
DisableFlagsInUseLine: true,
Short: "Overview of all projects",
RunE: func(cmd *cobra.Command, args []string) error {
return command.Run(cmd.Context())
},
}

return cmd
}
36 changes: 36 additions & 0 deletions cmd/skpr/project/set/command.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package set

import (
"github.com/spf13/cobra"

v1set "github.com/skpr/cli/internal/command/project/set"
)

var (
cmdExample = `
# Set the contact for the project.
skpr project set contact my-new-contact@example.com

# Set the tags for the project.
skpr project set tags "tag-a tag-b tag-c"`
)

// NewCommand creates a new cobra.Command for 'set' sub command
func NewCommand() *cobra.Command {
command := v1set.Command{}

cmd := &cobra.Command{
Use: "set <key> <value>",
Args: cobra.ExactArgs(2),
DisableFlagsInUseLine: true,
Short: "Set an attribute for the current project.",
Example: cmdExample,
RunE: func(cmd *cobra.Command, args []string) error {
command.Key = args[0]
command.Value = args[1]
return command.Run(cmd.Context())
},
}

return cmd
}
58 changes: 58 additions & 0 deletions internal/command/project/get/command.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package get

import (
"context"
"io"
"os"
"strings"

"github.com/skpr/api/pb"

"github.com/skpr/cli/internal/client"
"github.com/skpr/cli/internal/project"
"github.com/skpr/cli/internal/table"
)

// Command for getting a config.
type Command struct {
}

// Run the command.
func (cmd *Command) Run(ctx context.Context) error {
ctx, client, err := client.New(ctx)
if err != nil {
return err
}

resp, err := client.Project().Get(ctx, &pb.ProjectGetRequest{})
if err != nil {
return err
}

err = Print(os.Stdout, resp.Project)
if err != nil {
return err
}

return nil
}

// Print the table...
func Print(w io.Writer, item *pb.Project) error {
header := []string{
"Attribute",
"Value",
}

rows := [][]string{
{"ID", item.ID},
{"Name", item.Name},
{"Contact", item.Contact},
{"Version", item.Version},
{"Environments", strings.Join(project.ListEnvironmentsByName(item), ", ")},
{"Size", item.Size},
{"Tags", strings.Join(item.Tags, ", ")},
}

return table.Print(w, header, rows)
}
80 changes: 80 additions & 0 deletions internal/command/project/list/command.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package set

import (
"context"
"fmt"
"io"
"os"
"sort"
"strings"

"github.com/pkg/errors"
"github.com/skpr/api/pb"

"github.com/skpr/cli/internal/client"
"github.com/skpr/cli/internal/project"
"github.com/skpr/cli/internal/table"
)

// Command for setting config.
type Command struct {
Key string
Value string
}

// Run the command.
func (cmd *Command) Run(ctx context.Context) error {
ctx, client, err := client.New(ctx)
if err != nil {
return err
}

resp, err := client.Project().List(ctx, &pb.ProjectListRequest{})
if err != nil {
return errors.Wrap(err, "Could not list projects")
}

return Print(os.Stdout, resp.Projects)
}

// Print the table...
func Print(w io.Writer, list []*pb.Project) error {
if len(list) == 0 {
fmt.Fprintln(w, "No projects found")
return nil
}

sortProjects(list)

header := []string{
"Name",
"Contact",
"Version",
"Environments",
"Size",
"Tags",
}

var rows [][]string

for _, item := range list {
rows = append(rows, []string{
item.Name,
item.Contact,
item.Version,
strings.Join(project.ListEnvironmentsByName(item), ", "),
item.Size,
strings.Join(item.Tags, ", "),
})
}

return table.Print(w, header, rows)
}

// sortEnvs sorts the list putting the production envs last.
func sortProjects(list []*pb.Project) {
// Ensure prod environments are listed last.
sort.Slice(list, func(i, j int) bool {
return list[i].Name < list[j].Name
})
}
48 changes: 48 additions & 0 deletions internal/command/project/set/command.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package set

import (
"context"
"fmt"
"strings"

"github.com/skpr/api/pb"

"github.com/skpr/cli/internal/client"
)

// Command for setting config.
type Command struct {
Key string
Value string
}

// Run the command.
func (cmd *Command) Run(ctx context.Context) error {
ctx, client, err := client.New(ctx)
if err != nil {
return err
}

switch cmd.Key {
case "contact":
req := &pb.SetContactRequest{
Contact: cmd.Value,
}
_, err = client.Project().SetContact(ctx, req)
if err != nil {
return err
}
case "tags":
req := &pb.SetTagsRequest{
Tags: strings.Fields(cmd.Value),
}
_, err = client.Project().SetTags(ctx, req)
if err != nil {
return err
}
default:
return fmt.Errorf("invalid key. Currently supported keys are: contact, tags")
}

return nil
}
19 changes: 19 additions & 0 deletions internal/project/project.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package project

import (
"sort"

"github.com/skpr/api/pb"
)

// ListEnvironmentsByName lists them in printable order.
func ListEnvironmentsByName(project *pb.Project) []string {
environments := []string{
project.Environments.Prod,
}

sort.Strings(project.Environments.NonProd)
environments = append(environments, project.Environments.NonProd...)

return environments
}
27 changes: 27 additions & 0 deletions internal/project/project_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package project

import (
"testing"

"github.com/skpr/api/pb"
"github.com/stretchr/testify/assert"
)

func TestSort(t *testing.T) {
item := pb.Project{
Environments: &pb.ProjectEnvironments{
Prod: "prod",
NonProd: []string{
"dev",
"training",
"stg",
"bvt",
},
},
}

out := ListEnvironmentsByName(&item)
expected := []string{"prod", "bvt", "dev", "stg", "training"}

assert.Equal(t, expected, out)
}