Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(pipelines): Add environments #220

Merged
merged 5 commits into from
Nov 29, 2021
Merged
Changes from 1 commit
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
Prev Previous commit
Next Next commit
feat(pipelines): Add describe cmd
raulb committed Nov 29, 2021

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
commit e8d54b5681680a51b4ecd9d9f28ecea01d860335
88 changes: 88 additions & 0 deletions cmd/meroxa/root/pipelines/describe.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
Copyright © 2021 Meroxa Inc

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package pipelines

import (
"context"
"errors"

"github.com/meroxa/cli/cmd/meroxa/builder"
"github.com/meroxa/cli/log"
"github.com/meroxa/cli/utils"
"github.com/meroxa/meroxa-go/pkg/meroxa"
)

var (
_ builder.CommandWithDocs = (*Describe)(nil)
_ builder.CommandWithArgs = (*Describe)(nil)
_ builder.CommandWithClient = (*Describe)(nil)
_ builder.CommandWithLogger = (*Describe)(nil)
_ builder.CommandWithExecute = (*Describe)(nil)
)

type describeResourceClient interface {
GetPipelineByName(ctx context.Context, name string) (*meroxa.Pipeline, error)
}

type Describe struct {
client describeResourceClient
logger log.Logger

args struct {
Name string
}
}

func (d *Describe) Usage() string {
return "describe [NAME]"
}

func (d *Describe) Docs() builder.Docs {
return builder.Docs{
Short: "Describe pipeline",
}
}

func (d *Describe) Execute(ctx context.Context) error {
p, err := d.client.GetPipelineByName(ctx, d.args.Name)
if err != nil {
return err
}

d.logger.Info(ctx, utils.PipelineTable(p))

d.logger.JSON(ctx, p)

return nil
}

func (d *Describe) Client(client meroxa.Client) {
d.client = client
}

func (d *Describe) Logger(logger log.Logger) {
d.logger = logger
}

func (d *Describe) ParseArgs(args []string) error {
if len(args) < 1 {
return errors.New("requires pipeline name")
}

d.args.Name = args[0]
return nil
}
101 changes: 101 additions & 0 deletions cmd/meroxa/root/pipelines/describe_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
Copyright © 2021 Meroxa Inc

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package pipelines

import (
"context"
"encoding/json"
"errors"
"reflect"
"strings"
"testing"

"github.com/golang/mock/gomock"
"github.com/meroxa/cli/log"
"github.com/meroxa/cli/utils"
"github.com/meroxa/meroxa-go/pkg/meroxa"
"github.com/meroxa/meroxa-go/pkg/mock"
)

func TestDescribePipelineArgs(t *testing.T) {
tests := []struct {
args []string
err error
name string
}{
{args: nil, err: errors.New("requires pipeline name"), name: ""},
{args: []string{"pipeline-name"}, err: nil, name: "pipeline-name"},
}

for _, tt := range tests {
ar := &Describe{}
err := ar.ParseArgs(tt.args)

if err != nil && tt.err.Error() != err.Error() {
t.Fatalf("expected \"%s\" got \"%s\"", tt.err, err)
}

if tt.name != ar.args.Name {
t.Fatalf("expected \"%s\" got \"%s\"", tt.name, ar.args.Name)
}
}
}

func TestDescribePipelineExecution(t *testing.T) {
ctx := context.Background()
ctrl := gomock.NewController(t)
client := mock.NewMockClient(ctrl)
logger := log.NewTestLogger()

p := utils.GeneratePipelineWithEnvironment()
client.
EXPECT().
GetPipelineByName(
ctx,
p.Name,
).
Return(&p, nil)

dp := &Describe{
client: client,
logger: logger,
}
dp.args.Name = p.Name

err := dp.Execute(ctx)
if err != nil {
t.Fatalf("not expected error, got %q", err.Error())
}

gotLeveledOutput := logger.LeveledOutput()
wantLeveledOutput := utils.PipelineTable(&p)

if !strings.Contains(gotLeveledOutput, wantLeveledOutput) {
t.Fatalf("expected output:\n%s\ngot:\n%s", wantLeveledOutput, gotLeveledOutput)
}

gotJSONOutput := logger.JSONOutput()
var gotPipeline meroxa.Pipeline
err = json.Unmarshal([]byte(gotJSONOutput), &gotPipeline)
if err != nil {
t.Fatalf("not expected error, got %q", err.Error())
}

if !reflect.DeepEqual(gotPipeline, p) {
t.Fatalf("expected \"%v\", got \"%v\"", p, gotPipeline)
}
}
1 change: 1 addition & 0 deletions cmd/meroxa/root/pipelines/pipelines.go
Original file line number Diff line number Diff line change
@@ -46,6 +46,7 @@ func (*Pipelines) Docs() builder.Docs {
func (*Pipelines) SubCommands() []*cobra.Command {
return []*cobra.Command{
builder.BuildCobraCommand(&Create{}),
builder.BuildCobraCommand(&Describe{}),
builder.BuildCobraCommand(&List{}),
builder.BuildCobraCommand(&Remove{}),
builder.BuildCobraCommand(&Update{}),
1 change: 1 addition & 0 deletions docs/cmd/md/meroxa_pipelines.md
Original file line number Diff line number Diff line change
@@ -21,6 +21,7 @@ Manage pipelines on Meroxa

* [meroxa](meroxa.md) - The Meroxa CLI
* [meroxa pipelines create](meroxa_pipelines_create.md) - Create a pipeline
* [meroxa pipelines describe](meroxa_pipelines_describe.md) - Describe pipeline
* [meroxa pipelines list](meroxa_pipelines_list.md) - List pipelines
* [meroxa pipelines remove](meroxa_pipelines_remove.md) - Remove pipeline
* [meroxa pipelines update](meroxa_pipelines_update.md) - Update pipeline name, state or metadata
27 changes: 27 additions & 0 deletions docs/cmd/md/meroxa_pipelines_describe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
## meroxa pipelines describe

Describe pipeline

```
meroxa pipelines describe [NAME] [flags]
```

### Options

```
-h, --help help for describe
```

### Options inherited from parent commands

```
--cli-config-file string meroxa configuration file
--debug display any debugging information
--json output json
--timeout duration set the duration of the client timeout in seconds (default 10s)
```

### SEE ALSO

* [meroxa pipelines](meroxa_pipelines.md) - Manage pipelines on Meroxa

34 changes: 34 additions & 0 deletions docs/cmd/www/meroxa-pipelines-describe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
createdAt:
updatedAt:
title: "meroxa pipelines describe"
slug: meroxa-pipelines-describe
url: /cli/cmd/meroxa-pipelines-describe/
---
## meroxa pipelines describe

Describe pipeline

```
meroxa pipelines describe [NAME] [flags]
```

### Options

```
-h, --help help for describe
```

### Options inherited from parent commands

```
--cli-config-file string meroxa configuration file
--debug display any debugging information
--json output json
--timeout duration set the duration of the client timeout in seconds (default 10s)
```

### SEE ALSO

* [meroxa pipelines](/cli/cmd/meroxa-pipelines/) - Manage pipelines on Meroxa

1 change: 1 addition & 0 deletions docs/cmd/www/meroxa-pipelines.md
Original file line number Diff line number Diff line change
@@ -28,6 +28,7 @@ Manage pipelines on Meroxa

* [meroxa](/cli/cmd/meroxa/) - The Meroxa CLI
* [meroxa pipelines create](/cli/cmd/meroxa-pipelines-create/) - Create a pipeline
* [meroxa pipelines describe](/cli/cmd/meroxa-pipelines-describe/) - Describe pipeline
* [meroxa pipelines list](/cli/cmd/meroxa-pipelines-list/) - List pipelines
* [meroxa pipelines remove](/cli/cmd/meroxa-pipelines-remove/) - Remove pipeline
* [meroxa pipelines update](/cli/cmd/meroxa-pipelines-update/) - Update pipeline name, state or metadata
29 changes: 29 additions & 0 deletions etc/completion/meroxa.completion.sh
Original file line number Diff line number Diff line change
@@ -1369,6 +1369,34 @@ _meroxa_pipelines_create()
noun_aliases=()
}

_meroxa_pipelines_describe()
{
last_command="meroxa_pipelines_describe"

command_aliases=()

commands=()

flags=()
two_word_flags=()
local_nonpersistent_flags=()
flags_with_completion=()
flags_completion=()

flags+=("--help")
flags+=("-h")
flags+=("--cli-config-file=")
two_word_flags+=("--cli-config-file")
flags+=("--debug")
flags+=("--json")
flags+=("--timeout=")
two_word_flags+=("--timeout")

must_have_one_flag=()
must_have_one_noun=()
noun_aliases=()
}

_meroxa_pipelines_help()
{
last_command="meroxa_pipelines_help"
@@ -1498,6 +1526,7 @@ _meroxa_pipelines()

commands=()
commands+=("create")
commands+=("describe")
commands+=("help")
commands+=("list")
if [[ -z "${BASH_VERSION}" || "${BASH_VERSINFO[0]}" -gt 3 ]]; then
45 changes: 45 additions & 0 deletions etc/man/man1/meroxa-pipelines-describe.1
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
.nh
.TH "Meroxa" "1" "Nov 2021" "Meroxa CLI " "Meroxa Manual"

.SH NAME
.PP
meroxa\-pipelines\-describe \- Describe pipeline


.SH SYNOPSIS
.PP
\fBmeroxa pipelines describe [NAME] [flags]\fP


.SH DESCRIPTION
.PP
Describe pipeline


.SH OPTIONS
.PP
\fB\-h\fP, \fB\-\-help\fP[=false]
help for describe


.SH OPTIONS INHERITED FROM PARENT COMMANDS
.PP
\fB\-\-cli\-config\-file\fP=""
meroxa configuration file

.PP
\fB\-\-debug\fP[=false]
display any debugging information

.PP
\fB\-\-json\fP[=false]
output json

.PP
\fB\-\-timeout\fP=10s
set the duration of the client timeout in seconds


.SH SEE ALSO
.PP
\fBmeroxa\-pipelines(1)\fP
2 changes: 1 addition & 1 deletion etc/man/man1/meroxa-pipelines.1
Original file line number Diff line number Diff line change
@@ -42,4 +42,4 @@ Manage pipelines on Meroxa

.SH SEE ALSO
.PP
\fBmeroxa(1)\fP, \fBmeroxa\-pipelines\-create(1)\fP, \fBmeroxa\-pipelines\-list(1)\fP, \fBmeroxa\-pipelines\-remove(1)\fP, \fBmeroxa\-pipelines\-update(1)\fP
\fBmeroxa(1)\fP, \fBmeroxa\-pipelines\-create(1)\fP, \fBmeroxa\-pipelines\-describe(1)\fP, \fBmeroxa\-pipelines\-list(1)\fP, \fBmeroxa\-pipelines\-remove(1)\fP, \fBmeroxa\-pipelines\-update(1)\fP
46 changes: 46 additions & 0 deletions utils/display.go
Original file line number Diff line number Diff line change
@@ -122,6 +122,52 @@ func ResourceTable(res *meroxa.Resource) string {
return mainTable.String()
}

func PipelineTable(p *meroxa.Pipeline) string {
mainTable := simpletable.New()
mainTable.Body.Cells = [][]*simpletable.Cell{
{
{Align: simpletable.AlignRight, Text: "UUID:"},
{Text: p.UUID},
},
{
{Align: simpletable.AlignRight, Text: "ID:"},
{Text: fmt.Sprintf("%d", p.ID)},
},
{
{Align: simpletable.AlignRight, Text: "Name:"},
{Text: p.Name},
},
}

if p.Environment != nil {
if pU := p.Environment.UUID; pU != "" {
mainTable.Body.Cells = append(mainTable.Body.Cells, []*simpletable.Cell{
{Align: simpletable.AlignRight, Text: "Environment UUID:"},
{Text: pU},
})
}
if pN := p.Environment.Name; pN != "" {
mainTable.Body.Cells = append(mainTable.Body.Cells, []*simpletable.Cell{
{Align: simpletable.AlignRight, Text: "Environment Name:"},
{Text: pN},
})
}
}

mainTable.Body.Cells = append(mainTable.Body.Cells, []*simpletable.Cell{
{Align: simpletable.AlignRight, Text: "State:"},
{Text: strings.Title(string(p.State))},
})

mainTable.SetStyle(simpletable.StyleCompact)

return mainTable.String()
}

func PrintPipelineTable(pipeline *meroxa.Pipeline) {
fmt.Println(PipelineTable(pipeline))
}

func ResourcesTable(resources []*meroxa.Resource, hideHeaders bool) string {
if len(resources) != 0 {
table := simpletable.New()
63 changes: 63 additions & 0 deletions utils/display_test.go
Original file line number Diff line number Diff line change
@@ -444,6 +444,69 @@ func TestPipelinesTable(t *testing.T) {
}
}

func TestPipelineTable(t *testing.T) {
pipelineWithEnv := &meroxa.Pipeline{}

pipelineBase := &meroxa.Pipeline{
UUID: "6f380820-dfed-4a69-b708-10d134866a35",
ID: 0,
Name: "pipeline-base",
}

deepCopy(pipelineBase, pipelineWithEnv)
pipelineWithEnv.UUID = "038de172-c4b0-49d8-a1d9-26fbeaa2f726"
pipelineWithEnv.Environment = &meroxa.PipelineEnvironment{
UUID: "e56b1b2e-b6d7-455d-887e-84a0823d84a8",
Name: "my-environment",
}

tests := map[string]*meroxa.Pipeline{
"Base": pipelineBase,
"With_Environment": pipelineWithEnv,
}

tableHeaders := []string{"UUID", "ID", "Name", "State"}
var envHeader = "Environment"

for name, p := range tests {
t.Run(name, func(t *testing.T) {
out := CaptureOutput(func() {
PrintPipelineTable(p)
})

for _, header := range tableHeaders {
if !strings.Contains(out, header) {
t.Errorf("%q header is missing", header)
}
}

switch name {
case "Base":
if !strings.Contains(out, pipelineBase.Name) {
t.Errorf("%s, not found", pipelineBase.Name)
}
if !strings.Contains(out, strconv.Itoa(pipelineBase.ID)) {
t.Errorf("%d, not found", pipelineBase.ID)
}
if !strings.Contains(out, pipelineBase.UUID) {
t.Errorf("%s, not found", pipelineBase.UUID)
}
if strings.Contains(out, envHeader) {
t.Errorf("%q header is not necessary", envHeader)
}
case "With_Environment":
if !strings.Contains(out, envHeader) {
t.Errorf("%q header is missing", envHeader)
}
if !strings.Contains(out, pipelineWithEnv.Environment.Name) {
t.Errorf("expected environment name to be %q", pipelineWithEnv.Environment.Name)
}
}
fmt.Println(out)
})
}
}

func TestPipelinesTableWithoutHeaders(t *testing.T) {
pipeline := &meroxa.Pipeline{
ID: 0,
11 changes: 11 additions & 0 deletions utils/tests.go
Original file line number Diff line number Diff line change
@@ -19,6 +19,17 @@ func GeneratePipeline() meroxa.Pipeline {
}
}

func GeneratePipelineWithEnvironment() meroxa.Pipeline {
p := GeneratePipeline()

p.Environment = &meroxa.PipelineEnvironment{
UUID: "236d6e81-6a22-4805-b64f-3fa0a57fdbdc",
Name: "my-env",
}

return p
}

func GenerateResource() meroxa.Resource {
return meroxa.Resource{
ID: 1,