From 22c203bdd6b7d3037d1ea9db8d30b9a204db34ce Mon Sep 17 00:00:00 2001 From: Yuvraj <10830562+evalsocket@users.noreply.github.com> Date: Mon, 15 Feb 2021 23:02:51 +0530 Subject: [PATCH] Feature/goreleaser (#27) --- .../.github.com/workflow/pull_request.yaml | 0 .../PULL_REQUEST_TEMPLATE.md | 0 flytectl/.github/workflows/build.yaml | 31 +++++++++ flytectl/.github/workflows/release.yml | 38 +++++++++++ flytectl/.goreleaser.yml | 62 +++-------------- flytectl/README.md | 2 +- .../lyft/golang_support_tools/tools.go | 2 +- flytectl/cmd/core/cmd.go | 1 + flytectl/cmd/core/cmd_ctx.go | 2 +- flytectl/cmd/get/execution.go | 17 ++--- flytectl/cmd/get/execution_test.go | 36 +++++----- flytectl/cmd/get/get.go | 2 +- flytectl/cmd/get/get_test.go | 17 ++--- flytectl/cmd/get/launch_plan.go | 15 ++--- flytectl/cmd/get/named_entity.go | 6 +- flytectl/cmd/get/project.go | 12 ++-- flytectl/cmd/get/task.go | 15 +++-- flytectl/cmd/get/workflow.go | 9 +-- flytectl/cmd/register/files.go | 33 +++++----- ...esconfig_flags.go => filesconfig_flags.go} | 17 ++--- ...lags_test.go => filesconfig_flags_test.go} | 38 +++++------ flytectl/cmd/register/register.go | 4 +- flytectl/cmd/register/register_test.go | 7 +- flytectl/cmd/register/register_util.go | 66 +++++++++++-------- flytectl/cmd/root.go | 9 +-- flytectl/cmd/update/project.go | 6 +- flytectl/cmd/update/project_test.go | 29 ++++---- flytectl/cmd/update/projectconfig_flags.go | 2 +- flytectl/cmd/update/update.go | 4 +- flytectl/cmd/update/update_test.go | 7 +- flytectl/docs/source/generate_docs.go | 1 - flytectl/install.sh | 8 +-- flytectl/pkg/adminutils/iterator.go | 2 +- flytectl/pkg/printer/printer.go | 10 ++- flytectl/pkg/printer/printer_test.go | 3 +- flytectl/pull_request_template.md | 26 -------- 36 files changed, 280 insertions(+), 259 deletions(-) delete mode 100644 flytectl/.github.com/workflow/pull_request.yaml rename flytectl/{.github.com => .github}/PULL_REQUEST_TEMPLATE.md (100%) create mode 100644 flytectl/.github/workflows/build.yaml create mode 100644 flytectl/.github/workflows/release.yml rename flytectl/cmd/register/{registerfilesconfig_flags.go => filesconfig_flags.go} (55%) rename flytectl/cmd/register/{registerfilesconfig_flags_test.go => filesconfig_flags_test.go} (70%) delete mode 100644 flytectl/pull_request_template.md diff --git a/flytectl/.github.com/workflow/pull_request.yaml b/flytectl/.github.com/workflow/pull_request.yaml deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/flytectl/.github.com/PULL_REQUEST_TEMPLATE.md b/flytectl/.github/PULL_REQUEST_TEMPLATE.md similarity index 100% rename from flytectl/.github.com/PULL_REQUEST_TEMPLATE.md rename to flytectl/.github/PULL_REQUEST_TEMPLATE.md diff --git a/flytectl/.github/workflows/build.yaml b/flytectl/.github/workflows/build.yaml new file mode 100644 index 0000000000..4b78569361 --- /dev/null +++ b/flytectl/.github/workflows/build.yaml @@ -0,0 +1,31 @@ +name: build + +on: + pull_request: + push: + +jobs: + build: + name: Run tests and lint + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Unit Tests + uses: cedrickring/golang-action@1.5.2 + env: + GO111MODULE: "on" + with: + args: make install && make test_unit_codecov + - name: Push CodeCov + uses: codecov/codecov-action@v1 + with: + file: coverage.txt + flags: unittests + fail_ci_if_error: true + - name: Lint + uses: cedrickring/golang-action@1.5.2 + env: + GO111MODULE: "on" + with: + args: make install && make lint \ No newline at end of file diff --git a/flytectl/.github/workflows/release.yml b/flytectl/.github/workflows/release.yml new file mode 100644 index 0000000000..7d30bdb666 --- /dev/null +++ b/flytectl/.github/workflows/release.yml @@ -0,0 +1,38 @@ +name: releaser +on: + push: + tags: + - 'v*' + +jobs: + create-release: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Unit Tests + uses: cedrickring/golang-action@1.5.2 + env: + GO111MODULE: "on" + with: + args: make install && make test_unit_codecov + - name: Push CodeCov + uses: codecov/codecov-action@v1 + with: + file: coverage.txt + flags: unittests + fail_ci_if_error: true + - name: Lint + uses: cedrickring/golang-action@1.5.2 + env: + GO111MODULE: "on" + with: + args: make install && make lint + + - name: Run GoReleaser + uses: goreleaser/goreleaser-action@v2 + with: + version: latest + args: release --rm-dist --debug + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/flytectl/.goreleaser.yml b/flytectl/.goreleaser.yml index 6f8f237da5..18ace3b56b 100644 --- a/flytectl/.goreleaser.yml +++ b/flytectl/.goreleaser.yml @@ -11,7 +11,7 @@ builds: - windows - darwin ldflags: - - -s -w -X github.com/lyft/flytestdlib/version.Version={{.Version}} -X github.com/lyft/flytestdlib/version.Build={{.ShortCommit}} -X github.com/lyft/flytestdlib/version.BuildTime={{.Date}} + - -s -w -X github.com/flyteorg/flytestdlib/version.Version={{.Version}} -X github.com/flyteorg/flytestdlib/version.Build={{.ShortCommit}} -X github.com/flyteorg/flytestdlib/version.BuildTime={{.Date}} archives: - replacements: darwin: macOS @@ -38,7 +38,7 @@ scoop: # Repository to push the app manifest to. bucket: - owner: lyft + owner: flyteorg name: flytectl # Git author used to commit to the repository. @@ -49,7 +49,7 @@ scoop: # Your app's homepage. # Default is empty. - homepage: "https://godoc.org/github.com/lyft/flytectl" + homepage: "https://godoc.org/github.com/flyteorg/flytectl" # Your app's description. # Default is empty. @@ -61,19 +61,12 @@ scoop: # Persist data between application updates persist: - - "data" - "config.toml" brews: - # Name template of the recipe # Default to project name name: flytectl - # IDs of the archives to use. - # Defaults to all. - # ids: - # - foo - # - bar - # GOARM to specify which 32-bit arm version to use if there are multiple versions # from the build section. Brew formulas support atm only one 32-bit version. # Default is 6 for all artifacts or each id if there a multiple versions. @@ -83,21 +76,14 @@ brews: # same kind. We will probably unify this in the next major version like it is done with scoop. # Github repository to push the tap to. - github: - owner: github-user - name: homebrew-tap - - # OR Gitlab - # gitlab: - # owner: gitlab-user - # name: homebrew-tap - - # Gitea is not supported yet, but the support coming + tap: + owner: flyteorg + name: flytectl # Template for the url which is determined by the given Token (github or gitlab) # Default for github is "https://github.com///releases/download/{{ .Tag }}/{{ .ArtifactName }}" # Default for gitlab is "https://gitlab.com///uploads/{{ .ArtifactUploadHash }}/{{ .ArtifactName }}" - url_template: "http://github.com/lyft/flytectl/releases/{{ .Tag }}/{{ .ArtifactName }}" + url_template: "http://github.com/flyteorg/flytectl/releases/{{ .Tag }}/{{ .ArtifactName }}" # Allows you to set a custom download strategy. Note that you'll need # to implement the strategy and add it to your tap repository. @@ -112,12 +98,8 @@ brews: # Git author used to commit to the repository. # Defaults are shown. commit_author: - name: goreleaserbot - email: goreleaser@carlosbecker.com - - # Folder inside the repository to put the formula. - # Default is the root folder. - folder: Formula + name: flytebot + email: flytebot@flyte.org # Caveats for the user of your binary. # Default is empty. @@ -125,7 +107,7 @@ brews: # Your app's homepage. # Default is empty. - homepage: "https://godoc.org/github.com/lyft/flytectl" + homepage: "https://flytectl.readthedocs.io/en/latest" # Your app's description. # Default is empty. @@ -139,30 +121,6 @@ brews: # Default is false. skip_upload: auto - # Custom block for brew. - # Can be used to specify alternate downloads for devel or head releases. - # Default is empty. - # custom_block: | - # head "https://github.com/some/package.git" - # ... - - # Packages your package depends on. - # dependencies: - # - name: git - # - name: zsh - # type: optional - - # Packages that conflict with your package. - # conflicts: - # - svn - # - bash - - # Specify for packages that run as a service. - # Default is empty. - # plist: | - # - # ... - # So you can `brew test` your formula. # Default is empty. test: system "#{bin}/program --version" diff --git a/flytectl/README.md b/flytectl/README.md index fd022104df..a1a2af7292 100644 --- a/flytectl/README.md +++ b/flytectl/README.md @@ -21,7 +21,7 @@ Generating docs locally can be accomplished by running make gendocs from within ## Installation ```bash -curl -s https://raw.githubusercontent.com/lyft/flytectl/master/install.sh | bash +curl -s https://raw.githubusercontent.com/flyteorg/flytectl/master/install.sh | bash ``` ## Contributing diff --git a/flytectl/boilerplate/lyft/golang_support_tools/tools.go b/flytectl/boilerplate/lyft/golang_support_tools/tools.go index 4310b39d79..88ff645233 100644 --- a/flytectl/boilerplate/lyft/golang_support_tools/tools.go +++ b/flytectl/boilerplate/lyft/golang_support_tools/tools.go @@ -3,8 +3,8 @@ package tools import ( + _ "github.com/alvaroloes/enumer" _ "github.com/golangci/golangci-lint/cmd/golangci-lint" _ "github.com/lyft/flytestdlib/cli/pflags" _ "github.com/vektra/mockery/cmd/mockery" - _ "github.com/alvaroloes/enumer" ) diff --git a/flytectl/cmd/core/cmd.go b/flytectl/cmd/core/cmd.go index c625fd2072..aa76d00112 100644 --- a/flytectl/cmd/core/cmd.go +++ b/flytectl/cmd/core/cmd.go @@ -3,6 +3,7 @@ package cmdcore import ( "context" "fmt" + "github.com/spf13/pflag" "github.com/lyft/flyteidl/clients/go/admin" diff --git a/flytectl/cmd/core/cmd_ctx.go b/flytectl/cmd/core/cmd_ctx.go index bf593b2b4c..347e75c3fe 100644 --- a/flytectl/cmd/core/cmd_ctx.go +++ b/flytectl/cmd/core/cmd_ctx.go @@ -13,7 +13,7 @@ type CommandContext struct { } func NewCommandContext(adminClient service.AdminServiceClient, out io.Writer) CommandContext { - return CommandContext{adminClient: adminClient, out : out} + return CommandContext{adminClient: adminClient, out: out} } func (c CommandContext) AdminClient() service.AdminServiceClient { diff --git a/flytectl/cmd/get/execution.go b/flytectl/cmd/get/execution.go index 4491ef03dc..0c22e5674e 100644 --- a/flytectl/cmd/get/execution.go +++ b/flytectl/cmd/get/execution.go @@ -2,6 +2,7 @@ package get import ( "context" + "github.com/lyft/flyteidl/gen/pb-go/flyteidl/core" "github.com/golang/protobuf/proto" @@ -13,7 +14,7 @@ import ( "github.com/lyft/flytectl/pkg/printer" ) -const( +const ( executionShort = "Gets execution resources" executionLong = ` Retrieves all the executions within project and domain.(execution,executions can be used interchangeably in these commands) @@ -49,12 +50,12 @@ Usage ) var executionColumns = []printer.Column{ - {"Name", "$.id.name"}, - {"Workflow Name", "$.closure.workflowId.name"}, - {"Type", "$.closure.workflowId.resourceType"}, - {"Phase", "$.closure.phase"}, - {"Started", "$.closure.startedAt"}, - {"Elapsed Time", "$.closure.duration"}, + {Header: "Name", JSONPath: "$.id.name"}, + {Header: "Workflow Name", JSONPath: "$.closure.workflowId.name"}, + {Header: "Type", JSONPath: "$.closure.workflowId.resourceType"}, + {Header: "Phase", JSONPath: "$.closure.phase"}, + {Header: "Started", JSONPath: "$.closure.startedAt"}, + {Header: "Elapsed Time", JSONPath: "$.closure.duration"}, } func ExecutionToProtoMessages(l []*admin.Execution) []proto.Message { @@ -67,7 +68,7 @@ func ExecutionToProtoMessages(l []*admin.Execution) []proto.Message { func getExecutionFunc(ctx context.Context, args []string, cmdCtx cmdCore.CommandContext) error { adminPrinter := printer.Printer{} - var executions []* admin.Execution + var executions []*admin.Execution if len(args) > 0 { name := args[0] execution, err := cmdCtx.AdminClient().GetExecution(ctx, &admin.WorkflowExecutionGetRequest{ diff --git a/flytectl/cmd/get/execution_test.go b/flytectl/cmd/get/execution_test.go index b7a83cbef6..33cccd465f 100644 --- a/flytectl/cmd/get/execution_test.go +++ b/flytectl/cmd/get/execution_test.go @@ -3,14 +3,15 @@ package get import ( "context" "errors" + "io" + "testing" + "github.com/lyft/flytectl/cmd/config" cmdCore "github.com/lyft/flytectl/cmd/core" "github.com/lyft/flyteidl/clients/go/admin/mocks" "github.com/lyft/flyteidl/gen/pb-go/flyteidl/admin" "github.com/lyft/flyteidl/gen/pb-go/flyteidl/core" "github.com/stretchr/testify/assert" - "io" - "testing" ) const projectValue = "dummyProject" @@ -20,12 +21,13 @@ const launchPlanNameValue = "lp_name" const launchPlanVersionValue = "lp_version" const workflowNameValue = "wf_name" const workflowVersionValue = "wf_version" +const output = "json" func TestListExecutionFunc(t *testing.T) { ctx := context.Background() config.GetConfig().Project = projectValue config.GetConfig().Domain = domainValue - config.GetConfig().Output = "json" + config.GetConfig().Output = output var args []string mockClient := new(mocks.AdminServiceClient) mockOutStream := new(io.Writer) @@ -61,8 +63,7 @@ func TestListExecutionFunc(t *testing.T) { Phase: core.WorkflowExecution_SUCCEEDED, }, } - var executions []*admin.Execution - executions = append(executions, executionResponse) + executions := []*admin.Execution{executionResponse} executionList := &admin.ExecutionList{ Executions: executions, } @@ -76,7 +77,7 @@ func TestListExecutionFuncWithError(t *testing.T) { ctx := context.Background() config.GetConfig().Project = projectValue config.GetConfig().Domain = domainValue - config.GetConfig().Output = "json" + config.GetConfig().Output = output var args []string mockClient := new(mocks.AdminServiceClient) mockOutStream := new(io.Writer) @@ -88,7 +89,7 @@ func TestListExecutionFuncWithError(t *testing.T) { Domain: domainValue, }, } - executionResponse := &admin.Execution{ + _ = &admin.Execution{ Id: &core.WorkflowExecutionIdentifier{ Project: projectValue, Domain: domainValue, @@ -112,12 +113,10 @@ func TestListExecutionFuncWithError(t *testing.T) { Phase: core.WorkflowExecution_SUCCEEDED, }, } - var executions []*admin.Execution - executions = append(executions, executionResponse) - mockClient.OnListExecutionsMatch(ctx, execListRequest).Return(nil, errors.New("Executions NotFound.")) + mockClient.OnListExecutionsMatch(ctx, execListRequest).Return(nil, errors.New("executions NotFound")) err := getExecutionFunc(ctx, args, cmdCtx) assert.NotNil(t, err) - assert.Equal(t, err, errors.New("Executions NotFound.")) + assert.Equal(t, err, errors.New("executions NotFound")) mockClient.AssertCalled(t, "ListExecutions", ctx, execListRequest) } @@ -125,7 +124,7 @@ func TestGetExecutionFunc(t *testing.T) { ctx := context.Background() config.GetConfig().Project = projectValue config.GetConfig().Domain = domainValue - config.GetConfig().Output = "json" + config.GetConfig().Output = output mockClient := new(mocks.AdminServiceClient) mockOutStream := new(io.Writer) cmdCtx := cmdCore.NewCommandContext(mockClient, *mockOutStream) @@ -160,8 +159,6 @@ func TestGetExecutionFunc(t *testing.T) { Phase: core.WorkflowExecution_SUCCEEDED, }, } - var executions []*admin.Execution - executions = append(executions, executionResponse) args := []string{executionNameValue} mockClient.OnGetExecutionMatch(ctx, execGetRequest).Return(executionResponse, nil) err := getExecutionFunc(ctx, args, cmdCtx) @@ -173,7 +170,7 @@ func TestGetExecutionFuncWithError(t *testing.T) { ctx := context.Background() config.GetConfig().Project = projectValue config.GetConfig().Domain = domainValue - config.GetConfig().Output = "json" + config.GetConfig().Output = output mockClient := new(mocks.AdminServiceClient) mockOutStream := new(io.Writer) cmdCtx := cmdCore.NewCommandContext(mockClient, *mockOutStream) @@ -184,7 +181,7 @@ func TestGetExecutionFuncWithError(t *testing.T) { Name: executionNameValue, }, } - executionResponse := &admin.Execution{ + _ = &admin.Execution{ Id: &core.WorkflowExecutionIdentifier{ Project: projectValue, Domain: domainValue, @@ -208,12 +205,11 @@ func TestGetExecutionFuncWithError(t *testing.T) { Phase: core.WorkflowExecution_SUCCEEDED, }, } - var executions []*admin.Execution - executions = append(executions, executionResponse) + args := []string{executionNameValue} - mockClient.OnGetExecutionMatch(ctx, execGetRequest).Return(nil, errors.New("Execution NotFound.")) + mockClient.OnGetExecutionMatch(ctx, execGetRequest).Return(nil, errors.New("execution NotFound")) err := getExecutionFunc(ctx, args, cmdCtx) assert.NotNil(t, err) - assert.Equal(t, err, errors.New("Execution NotFound.")) + assert.Equal(t, err, errors.New("execution NotFound")) mockClient.AssertCalled(t, "GetExecution", ctx, execGetRequest) } diff --git a/flytectl/cmd/get/get.go b/flytectl/cmd/get/get.go index c19a593280..2fd6806c5a 100644 --- a/flytectl/cmd/get/get.go +++ b/flytectl/cmd/get/get.go @@ -22,7 +22,7 @@ func CreateGetCommand() *cobra.Command { getCmd := &cobra.Command{ Use: "get", Short: getCmdShort, - Long: getCmdLong, + Long: getCmdLong, } getResourcesFuncs := map[string]cmdcore.CommandEntry{ diff --git a/flytectl/cmd/get/get_test.go b/flytectl/cmd/get/get_test.go index 8602d161c7..243a6a97da 100644 --- a/flytectl/cmd/get/get_test.go +++ b/flytectl/cmd/get/get_test.go @@ -2,15 +2,16 @@ package get import ( "fmt" - "github.com/stretchr/testify/assert" "sort" "testing" + + "github.com/stretchr/testify/assert" ) func TestCreateGetCommand(t *testing.T) { getCommand := CreateGetCommand() - assert.Equal(t, getCommand.Use , "get") - assert.Equal(t, getCommand.Short , "Retrieve various resource.") + assert.Equal(t, getCommand.Use, "get") + assert.Equal(t, getCommand.Short, "Used for fetching various flyte resources including tasks/workflows/launchplans/executions/project.") fmt.Println(getCommand.Commands()) assert.Equal(t, len(getCommand.Commands()), 5) cmdNouns := getCommand.Commands() @@ -20,17 +21,17 @@ func TestCreateGetCommand(t *testing.T) { }) assert.Equal(t, cmdNouns[0].Use, "execution") assert.Equal(t, cmdNouns[0].Aliases, []string{"executions"}) - assert.Equal(t, cmdNouns[0].Short, "Retrieves execution resources.") + assert.Equal(t, cmdNouns[0].Short, "Gets execution resources") assert.Equal(t, cmdNouns[1].Use, "launchplan") assert.Equal(t, cmdNouns[1].Aliases, []string{"launchplans"}) - assert.Equal(t, cmdNouns[1].Short, "Retrieves launchplan resources.") + assert.Equal(t, cmdNouns[1].Short, "Gets launch plan resources") assert.Equal(t, cmdNouns[2].Use, "project") assert.Equal(t, cmdNouns[2].Aliases, []string{"projects"}) - assert.Equal(t, cmdNouns[2].Short, "Retrieves project resources.") + assert.Equal(t, cmdNouns[2].Short, "Gets project resources") assert.Equal(t, cmdNouns[3].Use, "task") assert.Equal(t, cmdNouns[3].Aliases, []string{"tasks"}) - assert.Equal(t, cmdNouns[3].Short, "Retrieves task resources.") + assert.Equal(t, cmdNouns[3].Short, "Gets task resources") assert.Equal(t, cmdNouns[4].Use, "workflow") assert.Equal(t, cmdNouns[4].Aliases, []string{"workflows"}) - assert.Equal(t, cmdNouns[4].Short, "Retrieves workflow resources.") + assert.Equal(t, cmdNouns[4].Short, "Gets workflow resources") } diff --git a/flytectl/cmd/get/launch_plan.go b/flytectl/cmd/get/launch_plan.go index ff8e1ce912..8706a36271 100644 --- a/flytectl/cmd/get/launch_plan.go +++ b/flytectl/cmd/get/launch_plan.go @@ -2,6 +2,7 @@ package get import ( "context" + "github.com/golang/protobuf/proto" "github.com/lyft/flytectl/cmd/config" cmdCore "github.com/lyft/flytectl/cmd/core" @@ -11,8 +12,7 @@ import ( "github.com/lyft/flytestdlib/logger" ) -const( - +const ( launchPlanShort = "Gets launch plan resources" launchPlanLong = ` Retrieves all the launch plans within project and domain.(launchplan,launchplans can be used interchangeably in these commands) @@ -48,11 +48,11 @@ Usage ) var launchplanColumns = []printer.Column{ - {"Version", "$.id.version"}, - {"Name", "$.id.name"}, - {"Type", "$.closure.compiledTask.template.type"}, - {"State", "$.spec.state"}, - {"Schedule", "$.spec.entityMetadata.schedule"}, + {Header: "Version", JSONPath: "$.id.version"}, + {Header: "Name", JSONPath: "$.id.name"}, + {Header: "Type", JSONPath: "$.closure.compiledTask.template.type"}, + {Header: "State", JSONPath: "$.spec.state"}, + {Header: "Schedule", JSONPath: "$.spec.entityMetadata.schedule"}, } func LaunchplanToProtoMessages(l []*admin.LaunchPlan) []proto.Message { @@ -93,5 +93,4 @@ func getLaunchPlanFunc(ctx context.Context, args []string, cmdCtx cmdCore.Comman } logger.Debugf(ctx, "Retrieved %v launch plans", len(launchPlans)) return launchPlanPrinter.Print(config.GetConfig().MustOutputFormat(), entityColumns, adminutils.NamedEntityToProtoMessage(launchPlans)...) - return nil } diff --git a/flytectl/cmd/get/named_entity.go b/flytectl/cmd/get/named_entity.go index a8bc1e60c9..b636145790 100644 --- a/flytectl/cmd/get/named_entity.go +++ b/flytectl/cmd/get/named_entity.go @@ -5,7 +5,7 @@ import ( ) var entityColumns = []printer.Column{ - {"Domain", "$.domain"}, - {"Name", "$.name"}, - {"Project", "$.project"}, + {Header: "Domain", JSONPath: "$.domain"}, + {Header: "Name", JSONPath: "$.name"}, + {Header: "Project", JSONPath: "$.project"}, } diff --git a/flytectl/cmd/get/project.go b/flytectl/cmd/get/project.go index 6b68011ea3..8307a6e627 100644 --- a/flytectl/cmd/get/project.go +++ b/flytectl/cmd/get/project.go @@ -12,9 +12,9 @@ import ( "github.com/lyft/flytectl/pkg/printer" ) -const( -projectShort = "Gets project resources" -projectLong = ` +const ( + projectShort = "Gets project resources" + projectLong = ` Retrieves all the projects.(project,projects can be used interchangeably in these commands) :: @@ -48,9 +48,9 @@ Usage ) var projectColumns = []printer.Column{ - {"ID", "$.id"}, - {"Name", "$.name"}, - {"Description", "$.description"}, + {Header: "ID", JSONPath: "$.id"}, + {Header: "Name", JSONPath: "$.name"}, + {Header: "Description", JSONPath: "$.description"}, } func ProjectToProtoMessages(l []*admin.Project) []proto.Message { diff --git a/flytectl/cmd/get/task.go b/flytectl/cmd/get/task.go index ddc28fb0b9..96631d1741 100644 --- a/flytectl/cmd/get/task.go +++ b/flytectl/cmd/get/task.go @@ -2,6 +2,7 @@ package get import ( "context" + "github.com/golang/protobuf/proto" "github.com/lyft/flytestdlib/logger" @@ -14,7 +15,7 @@ import ( "github.com/lyft/flyteidl/gen/pb-go/flyteidl/admin" ) -const( +const ( taskShort = "Gets task resources" taskLong = ` Retrieves all the task within project and domain.(task,tasks can be used interchangeably in these commands) @@ -50,12 +51,12 @@ Usage ) var taskColumns = []printer.Column{ - {"Version", "$.id.version"}, - {"Name", "$.id.name"}, - {"Type", "$.closure.compiledTask.template.type"}, - {"Discoverable", "$.closure.compiledTask.template.metadata.discoverable"}, - {"Discovery Version", "$.closure.compiledTask.template.metadata.discoveryVersion"}, - {"Created At", "$.closure.createdAt"}, + {Header: "Version", JSONPath: "$.id.version"}, + {Header: "Name", JSONPath: "$.id.name"}, + {Header: "Type", JSONPath: "$.closure.compiledTask.template.type"}, + {Header: "Discoverable", JSONPath: "$.closure.compiledTask.template.metadata.discoverable"}, + {Header: "Discovery Version", JSONPath: "$.closure.compiledTask.template.metadata.discoveryVersion"}, + {Header: "Created At", JSONPath: "$.closure.createdAt"}, } func TaskToProtoMessages(l []*admin.Task) []proto.Message { diff --git a/flytectl/cmd/get/workflow.go b/flytectl/cmd/get/workflow.go index d6a8d9172b..857df5bf5b 100644 --- a/flytectl/cmd/get/workflow.go +++ b/flytectl/cmd/get/workflow.go @@ -2,6 +2,7 @@ package get import ( "context" + "github.com/golang/protobuf/proto" "github.com/lyft/flytestdlib/logger" @@ -13,7 +14,7 @@ import ( "github.com/lyft/flyteidl/gen/pb-go/flyteidl/admin" ) -const( +const ( workflowShort = "Gets workflow resources" workflowLong = ` Retrieves all the workflows within project and domain.(workflow,workflows can be used interchangeably in these commands) @@ -49,9 +50,9 @@ Usage ) var workflowColumns = []printer.Column{ - {"Version", "$.id.version"}, - {"Name", "$.id.name"}, - {"Created At", "$.closure.createdAt"}, + {Header: "Version", JSONPath: "$.id.version"}, + {Header: "Name", JSONPath: "$.id.name"}, + {Header: "Created At", JSONPath: "$.closure.createdAt"}, } func WorkflowToProtoMessages(l []*admin.Workflow) []proto.Message { diff --git a/flytectl/cmd/register/files.go b/flytectl/cmd/register/files.go index 821f034cd8..b53ed63097 100644 --- a/flytectl/cmd/register/files.go +++ b/flytectl/cmd/register/files.go @@ -4,14 +4,15 @@ import ( "context" "encoding/json" "fmt" + "io/ioutil" + "sort" + cmdCore "github.com/lyft/flytectl/cmd/core" "github.com/lyft/flytectl/pkg/printer" "github.com/lyft/flytestdlib/logger" - "io/ioutil" - "sort" ) -const( +const ( registerFilesShort = "Registers file resources" registerFilesLong = ` Registers all the serialized protobuf files including tasks, workflows and launchplans with default v1 version. @@ -51,47 +52,49 @@ func registerFromFilesFunc(ctx context.Context, args []string, cmdCtx cmdCore.Co files := args sort.Strings(files) logger.Infof(ctx, "Parsing files... Total(%v)", len(files)) - logger.Infof(ctx, "Params version %v", filesConfig.version) - var registerResults [] RegisterResult + logger.Infof(ctx, "Params version %v", filesConfig.Version) + var registerResults []Result adminPrinter := printer.Printer{} - fastFail := !filesConfig.skipOnError + fastFail := !filesConfig.SkipOnError logger.Infof(ctx, "Fail fast %v", fastFail) var _err error - for i := 0; i< len(files) && !(fastFail && _err != nil) ; i++ { + for i := 0; i < len(files) && !(fastFail && _err != nil); i++ { absFilePath := files[i] - var registerResult RegisterResult + var registerResult Result logger.Infof(ctx, "Parsing %v", absFilePath) fileContents, err := ioutil.ReadFile(absFilePath) if err != nil { - registerResult = RegisterResult{Name: absFilePath, Status: "Failed", Info: fmt.Sprintf("Error reading file due to %v", err)} + registerResult = Result{Name: absFilePath, Status: "Failed", Info: fmt.Sprintf("Error reading file due to %v", err)} registerResults = append(registerResults, registerResult) _err = err continue } spec, err := unMarshalContents(ctx, fileContents, absFilePath) if err != nil { - registerResult = RegisterResult{Name: absFilePath, Status: "Failed", Info: fmt.Sprintf("Error unmarshalling file due to %v", err)} + registerResult = Result{Name: absFilePath, Status: "Failed", Info: fmt.Sprintf("Error unmarshalling file due to %v", err)} registerResults = append(registerResults, registerResult) _err = err continue } if err := hydrateSpec(spec); err != nil { - registerResult = RegisterResult{Name: absFilePath, Status: "Failed", Info: fmt.Sprintf("Error hydrating spec due to %v", err)} + registerResult = Result{Name: absFilePath, Status: "Failed", Info: fmt.Sprintf("Error hydrating spec due to %v", err)} registerResults = append(registerResults, registerResult) _err = err continue } - logger.Debugf(ctx, "Hydrated spec : %v", getJsonSpec(spec)) + logger.Debugf(ctx, "Hydrated spec : %v", getJSONSpec(spec)) if err := register(ctx, spec, cmdCtx); err != nil { - registerResult = RegisterResult{Name: absFilePath, Status: "Failed", Info: fmt.Sprintf("Error registering file due to %v", err)} + registerResult = Result{Name: absFilePath, Status: "Failed", Info: fmt.Sprintf("Error registering file due to %v", err)} registerResults = append(registerResults, registerResult) _err = err continue } - registerResult = RegisterResult{Name: absFilePath, Status: "Success", Info: "Successfully registered file"} + registerResult = Result{Name: absFilePath, Status: "Success", Info: "Successfully registered file"} registerResults = append(registerResults, registerResult) } payload, _ := json.Marshal(registerResults) - adminPrinter.JSONToTable(payload, projectColumns) + if err := adminPrinter.JSONToTable(payload, projectColumns); err != nil { + return err + } return nil } diff --git a/flytectl/cmd/register/registerfilesconfig_flags.go b/flytectl/cmd/register/filesconfig_flags.go similarity index 55% rename from flytectl/cmd/register/registerfilesconfig_flags.go rename to flytectl/cmd/register/filesconfig_flags.go index 97c5884485..a631183709 100755 --- a/flytectl/cmd/register/registerfilesconfig_flags.go +++ b/flytectl/cmd/register/filesconfig_flags.go @@ -5,15 +5,16 @@ package register import ( "encoding/json" - "fmt" "reflect" + "fmt" + "github.com/spf13/pflag" ) // If v is a pointer, it will get its element value or the zero value of the element type. // If v is not a pointer, it will return it as is. -func (RegisterFilesConfig) elemValueOrNil(v interface{}) interface{} { +func (FilesConfig) elemValueOrNil(v interface{}) interface{} { if t := reflect.TypeOf(v); t.Kind() == reflect.Ptr { if reflect.ValueOf(v).IsNil() { return reflect.Zero(t.Elem()).Interface() @@ -27,7 +28,7 @@ func (RegisterFilesConfig) elemValueOrNil(v interface{}) interface{} { return v } -func (RegisterFilesConfig) mustMarshalJSON(v json.Marshaler) string { +func (FilesConfig) mustMarshalJSON(v json.Marshaler) string { raw, err := v.MarshalJSON() if err != nil { panic(err) @@ -36,11 +37,11 @@ func (RegisterFilesConfig) mustMarshalJSON(v json.Marshaler) string { return string(raw) } -// GetPFlagSet will return strongly types pflags for all fields in RegisterFilesConfig and its nested types. The format of the +// GetPFlagSet will return strongly types pflags for all fields in FilesConfig and its nested types. The format of the // flags is json-name.json-sub-name... etc. -func (cfg RegisterFilesConfig) GetPFlagSet(prefix string) *pflag.FlagSet { - cmdFlags := pflag.NewFlagSet("RegisterFilesConfig", pflag.ExitOnError) - cmdFlags.StringVarP(&(filesConfig.version),fmt.Sprintf("%v%v", prefix, "version"), "v", "v1", "version of the entity to be registered with flyte.") - cmdFlags.BoolVarP(&(filesConfig.skipOnError), fmt.Sprintf("%v%v", prefix, "skipOnError"), "s", *new(bool), "fail fast when registering files.") +func (cfg FilesConfig) GetPFlagSet(prefix string) *pflag.FlagSet { + cmdFlags := pflag.NewFlagSet("FilesConfig", pflag.ExitOnError) + cmdFlags.String(fmt.Sprintf("%v%v", prefix, "version"), *new(string), "version of the entity to be registered with flyte.") + cmdFlags.Bool(fmt.Sprintf("%v%v", prefix, "skipOnError"), *new(bool), "fail fast when registering files.") return cmdFlags } diff --git a/flytectl/cmd/register/registerfilesconfig_flags_test.go b/flytectl/cmd/register/filesconfig_flags_test.go similarity index 70% rename from flytectl/cmd/register/registerfilesconfig_flags_test.go rename to flytectl/cmd/register/filesconfig_flags_test.go index 9c055e83e4..163852ee41 100755 --- a/flytectl/cmd/register/registerfilesconfig_flags_test.go +++ b/flytectl/cmd/register/filesconfig_flags_test.go @@ -14,22 +14,22 @@ import ( "github.com/stretchr/testify/assert" ) -var dereferencableKindsRegisterFilesConfig = map[reflect.Kind]struct{}{ +var dereferencableKindsFilesConfig = map[reflect.Kind]struct{}{ reflect.Array: {}, reflect.Chan: {}, reflect.Map: {}, reflect.Ptr: {}, reflect.Slice: {}, } // Checks if t is a kind that can be dereferenced to get its underlying type. -func canGetElementRegisterFilesConfig(t reflect.Kind) bool { - _, exists := dereferencableKindsRegisterFilesConfig[t] +func canGetElementFilesConfig(t reflect.Kind) bool { + _, exists := dereferencableKindsFilesConfig[t] return exists } // This decoder hook tests types for json unmarshaling capability. If implemented, it uses json unmarshal to build the // object. Otherwise, it'll just pass on the original data. -func jsonUnmarshalerHookRegisterFilesConfig(_, to reflect.Type, data interface{}) (interface{}, error) { +func jsonUnmarshalerHookFilesConfig(_, to reflect.Type, data interface{}) (interface{}, error) { unmarshalerType := reflect.TypeOf((*json.Unmarshaler)(nil)).Elem() if to.Implements(unmarshalerType) || reflect.PtrTo(to).Implements(unmarshalerType) || - (canGetElementRegisterFilesConfig(to.Kind()) && to.Elem().Implements(unmarshalerType)) { + (canGetElementFilesConfig(to.Kind()) && to.Elem().Implements(unmarshalerType)) { raw, err := json.Marshal(data) if err != nil { @@ -50,7 +50,7 @@ func jsonUnmarshalerHookRegisterFilesConfig(_, to reflect.Type, data interface{} return data, nil } -func decode_RegisterFilesConfig(input, result interface{}) error { +func decode_FilesConfig(input, result interface{}) error { config := &mapstructure.DecoderConfig{ TagName: "json", WeaklyTypedInput: true, @@ -58,7 +58,7 @@ func decode_RegisterFilesConfig(input, result interface{}) error { DecodeHook: mapstructure.ComposeDecodeHookFunc( mapstructure.StringToTimeDurationHookFunc(), mapstructure.StringToSliceHookFunc(","), - jsonUnmarshalerHookRegisterFilesConfig, + jsonUnmarshalerHookFilesConfig, ), } @@ -70,7 +70,7 @@ func decode_RegisterFilesConfig(input, result interface{}) error { return decoder.Decode(input) } -func join_RegisterFilesConfig(arr interface{}, sep string) string { +func join_FilesConfig(arr interface{}, sep string) string { listValue := reflect.ValueOf(arr) strs := make([]string, 0, listValue.Len()) for i := 0; i < listValue.Len(); i++ { @@ -80,22 +80,22 @@ func join_RegisterFilesConfig(arr interface{}, sep string) string { return strings.Join(strs, sep) } -func testDecodeJson_RegisterFilesConfig(t *testing.T, val, result interface{}) { - assert.NoError(t, decode_RegisterFilesConfig(val, result)) +func testDecodeJson_FilesConfig(t *testing.T, val, result interface{}) { + assert.NoError(t, decode_FilesConfig(val, result)) } -func testDecodeSlice_RegisterFilesConfig(t *testing.T, vStringSlice, result interface{}) { - assert.NoError(t, decode_RegisterFilesConfig(vStringSlice, result)) +func testDecodeSlice_FilesConfig(t *testing.T, vStringSlice, result interface{}) { + assert.NoError(t, decode_FilesConfig(vStringSlice, result)) } -func TestRegisterFilesConfig_GetPFlagSet(t *testing.T) { - val := RegisterFilesConfig{} +func TestFilesConfig_GetPFlagSet(t *testing.T) { + val := FilesConfig{} cmdFlags := val.GetPFlagSet("") assert.True(t, cmdFlags.HasFlags()) } -func TestRegisterFilesConfig_SetFlags(t *testing.T) { - actual := RegisterFilesConfig{} +func TestFilesConfig_SetFlags(t *testing.T) { + actual := FilesConfig{} cmdFlags := actual.GetPFlagSet("") assert.True(t, cmdFlags.HasFlags()) @@ -103,7 +103,7 @@ func TestRegisterFilesConfig_SetFlags(t *testing.T) { t.Run("DefaultValue", func(t *testing.T) { // Test that default value is set properly if vString, err := cmdFlags.GetString("version"); err == nil { - assert.Equal(t, string("v1"), vString) + assert.Equal(t, string(*new(string)), vString) } else { assert.FailNow(t, err.Error()) } @@ -114,7 +114,7 @@ func TestRegisterFilesConfig_SetFlags(t *testing.T) { cmdFlags.Set("version", testValue) if vString, err := cmdFlags.GetString("version"); err == nil { - testDecodeJson_RegisterFilesConfig(t, fmt.Sprintf("%v", vString), &actual.version) + testDecodeJson_FilesConfig(t, fmt.Sprintf("%v", vString), &actual.Version) } else { assert.FailNow(t, err.Error()) @@ -136,7 +136,7 @@ func TestRegisterFilesConfig_SetFlags(t *testing.T) { cmdFlags.Set("skipOnError", testValue) if vBool, err := cmdFlags.GetBool("skipOnError"); err == nil { - testDecodeJson_RegisterFilesConfig(t, fmt.Sprintf("%v", vBool), &actual.skipOnError) + testDecodeJson_FilesConfig(t, fmt.Sprintf("%v", vBool), &actual.SkipOnError) } else { assert.FailNow(t, err.Error()) diff --git a/flytectl/cmd/register/register.go b/flytectl/cmd/register/register.go index 62263a3387..3a46653b12 100644 --- a/flytectl/cmd/register/register.go +++ b/flytectl/cmd/register/register.go @@ -16,8 +16,8 @@ If the entities are already registered with flyte for the same version then regi ` ) -// RegisterCommand will return register command -func RegisterCommand() *cobra.Command { +// RemoteRegisterCommand will return register command +func RemoteRegisterCommand() *cobra.Command { registerCmd := &cobra.Command{ Use: "register", Short: registerCmdShort, diff --git a/flytectl/cmd/register/register_test.go b/flytectl/cmd/register/register_test.go index 99e4a6964f..476e7b31bc 100644 --- a/flytectl/cmd/register/register_test.go +++ b/flytectl/cmd/register/register_test.go @@ -2,13 +2,14 @@ package register import ( "fmt" - "github.com/stretchr/testify/assert" "sort" "testing" + + "github.com/stretchr/testify/assert" ) func TestRegisterCommand(t *testing.T) { - registerCommand := RegisterCommand() + registerCommand := RemoteRegisterCommand() assert.Equal(t, registerCommand.Use, "register") assert.Equal(t, registerCommand.Short, "Registers tasks/workflows/launchplans from list of generated serialized files.") fmt.Println(registerCommand.Commands()) @@ -20,5 +21,5 @@ func TestRegisterCommand(t *testing.T) { }) assert.Equal(t, cmdNouns[0].Use, "files") assert.Equal(t, cmdNouns[0].Aliases, []string{"file"}) - assert.Equal(t, cmdNouns[0].Short, "Retrieves files resources.") + assert.Equal(t, cmdNouns[0].Short, "Registers file resources") } diff --git a/flytectl/cmd/register/register_util.go b/flytectl/cmd/register/register_util.go index 5149fd1e21..d9a5aaff52 100644 --- a/flytectl/cmd/register/register_util.go +++ b/flytectl/cmd/register/register_util.go @@ -2,8 +2,8 @@ package register import ( "context" - "errors" "fmt" + "github.com/golang/protobuf/jsonpb" "github.com/golang/protobuf/proto" "github.com/lyft/flytectl/cmd/config" @@ -14,12 +14,12 @@ import ( "github.com/lyft/flytestdlib/logger" ) -//go:generate pflags RegisterFilesConfig +//go:generate pflags FilesConfig var ( - filesConfig = &RegisterFilesConfig{ - version: "v1", - skipOnError: false, + filesConfig = &FilesConfig{ + Version: "v1", + SkipOnError: false, } ) @@ -27,21 +27,22 @@ const registrationProjectPattern = "{{ registration.project }}" const registrationDomainPattern = "{{ registration.domain }}" const registrationVersionPattern = "{{ registration.version }}" -type RegisterFilesConfig struct { - version string `json:"version" pflag:",version of the entity to be registered with flyte."` - skipOnError bool `json:"skipOnError" pflag:",fail fast when registering files."` +// FilesConfig +type FilesConfig struct { + Version string `json:"version" pflag:",version of the entity to be registered with flyte."` + SkipOnError bool `json:"skipOnError" pflag:",fail fast when registering files."` } -type RegisterResult struct { +type Result struct { Name string Status string Info string } var projectColumns = []printer.Column{ - {"Name", "$.Name"}, - {"Status", "$.Status"}, - {"Additional Info", "$.Info"}, + {Header: "Name", JSONPath: "$.Name"}, + {Header: "Status", JSONPath: "$.Status"}, + {Header: "Additional Info", JSONPath: "$.Info"}, } func unMarshalContents(ctx context.Context, fileContents []byte, fname string) (proto.Message, error) { @@ -60,12 +61,12 @@ func unMarshalContents(ctx context.Context, fileContents []byte, fname string) ( return launchPlan, nil } logger.Debugf(ctx, "Failed to unmarshal file %v for launch plan type", fname) - return nil, errors.New(fmt.Sprintf("Failed unmarshalling file %v", fname)) + return nil, fmt.Errorf("failed unmarshalling file %v", fname) } func register(ctx context.Context, message proto.Message, cmdCtx cmdCore.CommandContext) error { - switch message.(type) { + switch v := message.(type) { case *admin.LaunchPlan: launchPlan := message.(*admin.LaunchPlan) _, err := cmdCtx.AdminClient().CreateLaunchPlan(ctx, &admin.LaunchPlanCreateRequest{ @@ -74,7 +75,7 @@ func register(ctx context.Context, message proto.Message, cmdCtx cmdCore.Command Project: config.GetConfig().Project, Domain: config.GetConfig().Domain, Name: launchPlan.Id.Name, - Version: filesConfig.version, + Version: filesConfig.Version, }, Spec: launchPlan.Spec, }) @@ -87,7 +88,7 @@ func register(ctx context.Context, message proto.Message, cmdCtx cmdCore.Command Project: config.GetConfig().Project, Domain: config.GetConfig().Domain, Name: workflowSpec.Template.Id.Name, - Version: filesConfig.version, + Version: filesConfig.Version, }, Spec: workflowSpec, }) @@ -100,19 +101,19 @@ func register(ctx context.Context, message proto.Message, cmdCtx cmdCore.Command Project: config.GetConfig().Project, Domain: config.GetConfig().Domain, Name: taskSpec.Template.Id.Name, - Version: filesConfig.version, + Version: filesConfig.Version, }, Spec: taskSpec, }) return err default: - return errors.New(fmt.Sprintf("Failed registering unknown entity %v", message)) + return fmt.Errorf("Failed registering unknown entity %v", v) } } func hydrateNode(node *core.Node) error { targetNode := node.Target - switch targetNode.(type) { + switch v := targetNode.(type) { case *core.Node_TaskNode: taskNodeWrapper := targetNode.(*core.Node_TaskNode) taskNodeReference := taskNodeWrapper.TaskNode.Reference.(*core.TaskNode_ReferenceId) @@ -127,27 +128,34 @@ func hydrateNode(node *core.Node) error { launchPlanNodeReference := workflowNodeWrapper.WorkflowNode.Reference.(*core.WorkflowNode_LaunchplanRef) hydrateIdentifier(launchPlanNodeReference.LaunchplanRef) default: - errors.New(fmt.Sprintf("Unknown type %T", workflowNodeWrapper.WorkflowNode.Reference)) + return fmt.Errorf("unknown type %T", workflowNodeWrapper.WorkflowNode.Reference) } case *core.Node_BranchNode: branchNodeWrapper := targetNode.(*core.Node_BranchNode) - hydrateNode(branchNodeWrapper.BranchNode.IfElse.Case.ThenNode) + if err := hydrateNode(branchNodeWrapper.BranchNode.IfElse.Case.ThenNode); err != nil { + return fmt.Errorf("failed to hydrateNode") + } if len(branchNodeWrapper.BranchNode.IfElse.Other) > 0 { for _, ifBlock := range branchNodeWrapper.BranchNode.IfElse.Other { - hydrateNode(ifBlock.ThenNode) + if err := hydrateNode(ifBlock.ThenNode); err != nil { + return fmt.Errorf("failed to hydrateNode") + } } } switch branchNodeWrapper.BranchNode.IfElse.Default.(type) { case *core.IfElseBlock_ElseNode: elseNodeReference := branchNodeWrapper.BranchNode.IfElse.Default.(*core.IfElseBlock_ElseNode) - hydrateNode(elseNodeReference.ElseNode) + if err := hydrateNode(elseNodeReference.ElseNode); err != nil { + return fmt.Errorf("failed to hydrateNode") + } + case *core.IfElseBlock_Error: // Do nothing. default: - return errors.New(fmt.Sprintf("Unknown type %T", branchNodeWrapper.BranchNode.IfElse.Default)) + return fmt.Errorf("unknown type %T", branchNodeWrapper.BranchNode.IfElse.Default) } default: - return errors.New(fmt.Sprintf("Unknown type %T", targetNode)) + return fmt.Errorf("unknown type %T", v) } return nil } @@ -160,12 +168,12 @@ func hydrateIdentifier(identifier *core.Identifier) { identifier.Domain = config.GetConfig().Domain } if identifier.Version == "" || identifier.Version == registrationVersionPattern { - identifier.Version = filesConfig.version + identifier.Version = filesConfig.Version } } func hydrateSpec(message proto.Message) error { - switch message.(type) { + switch v := message.(type) { case *admin.LaunchPlan: launchPlan := message.(*admin.LaunchPlan) hydrateIdentifier(launchPlan.Spec.WorkflowId) @@ -189,12 +197,12 @@ func hydrateSpec(message proto.Message) error { taskSpec := message.(*admin.TaskSpec) hydrateIdentifier(taskSpec.Template.Id) default: - return errors.New(fmt.Sprintf("Unknown type %T", message)) + return fmt.Errorf("Unknown type %T", v) } return nil } -func getJsonSpec(message proto.Message) string { +func getJSONSpec(message proto.Message) string { marshaller := jsonpb.Marshaler{ EnumsAsInts: false, EmitDefaults: true, diff --git a/flytectl/cmd/root.go b/flytectl/cmd/root.go index c92fb30d56..b666b29b90 100644 --- a/flytectl/cmd/root.go +++ b/flytectl/cmd/root.go @@ -3,6 +3,7 @@ package cmd import ( "context" "fmt" + "github.com/lyft/flytectl/cmd/get" "github.com/lyft/flytectl/cmd/register" "github.com/lyft/flytectl/cmd/update" @@ -24,9 +25,9 @@ var ( func newRootCmd() *cobra.Command { rootCmd := &cobra.Command{ PersistentPreRunE: initConfig, - Long : "flytectl is CLI tool written in go to interact with flyteadmin service", - Short: "flyetcl CLI tool", - Use : "flytectl", + Long: "flytectl is CLI tool written in go to interact with flyteadmin service", + Short: "flyetcl CLI tool", + Use: "flytectl", } rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", @@ -43,7 +44,7 @@ func newRootCmd() *cobra.Command { rootCmd.AddCommand(versionCmd) rootCmd.AddCommand(get.CreateGetCommand()) rootCmd.AddCommand(update.CreateUpdateCommand()) - rootCmd.AddCommand(register.RegisterCommand()) + rootCmd.AddCommand(register.RemoteRegisterCommand()) config.GetConfig() return rootCmd diff --git a/flytectl/cmd/update/project.go b/flytectl/cmd/update/project.go index 9ccbb4ee29..c421dddd2b 100644 --- a/flytectl/cmd/update/project.go +++ b/flytectl/cmd/update/project.go @@ -3,6 +3,7 @@ package update import ( "context" "fmt" + "github.com/lyft/flytectl/cmd/config" cmdCore "github.com/lyft/flytectl/cmd/core" "github.com/lyft/flyteidl/gen/pb-go/flyteidl/admin" @@ -16,7 +17,7 @@ type ProjectConfig struct { ArchiveProject bool `json:"archiveProject" pflag:",Archives the project specified as argument."` } -const( +const ( projectShort = "Updates project resources" projectLong = ` Updates the project according the flags passed.Allows you to archive or activate a project. @@ -80,8 +81,7 @@ func updateProjectsFunc(ctx context.Context, args []string, cmdCtx cmdCore.Comma archiveProject := projectConfig.ArchiveProject activateProject := projectConfig.ActivateProject if activateProject == archiveProject { - fmt.Printf(errInvalidUpdate) - return nil + return fmt.Errorf(errInvalidUpdate) } projectState := admin.Project_ACTIVE if archiveProject { diff --git a/flytectl/cmd/update/project_test.go b/flytectl/cmd/update/project_test.go index cf9fe7678b..c11986b6fa 100644 --- a/flytectl/cmd/update/project_test.go +++ b/flytectl/cmd/update/project_test.go @@ -4,15 +4,16 @@ import ( "bytes" "context" "errors" + "io" + "log" + "os" + "testing" + "github.com/lyft/flytectl/cmd/config" cmdCore "github.com/lyft/flytectl/cmd/core" "github.com/lyft/flyteidl/clients/go/admin/mocks" "github.com/lyft/flyteidl/gen/pb-go/flyteidl/admin" "github.com/stretchr/testify/assert" - "io" - "log" - "os" - "testing" ) const projectValue = "dummyProject" @@ -56,8 +57,9 @@ func teardownAndVerify(t *testing.T, expectedLog string) { os.Stdout = stdOut os.Stderr = stderr var buf bytes.Buffer - io.Copy(&buf, reader) - assert.Equal(t, expectedLog, buf.String()) + if _, err := io.Copy(&buf, reader); err != nil { + assert.Equal(t, expectedLog, buf.String()) + } } func modifyProjectFlags(archiveProject *bool, newArchiveVal bool, activateProject *bool, newActivateVal bool) { @@ -70,7 +72,8 @@ func TestActivateProjectFunc(t *testing.T) { defer teardownAndVerify(t, "Project dummyProject updated to ACTIVE state\n") modifyProjectFlags(&(projectConfig.ArchiveProject), false, &(projectConfig.ActivateProject), true) mockClient.OnUpdateProjectMatch(ctx, projectUpdateRequest).Return(nil, nil) - updateProjectsFunc(ctx, args, cmdCtx) + err := updateProjectsFunc(ctx, args, cmdCtx) + assert.Nil(t, err) mockClient.AssertCalled(t, "UpdateProject", ctx, projectUpdateRequest) } @@ -79,7 +82,8 @@ func TestActivateProjectFuncWithError(t *testing.T) { defer teardownAndVerify(t, "Project dummyProject failed to get updated to ACTIVE state due to Error Updating Project\n") modifyProjectFlags(&(projectConfig.ArchiveProject), false, &(projectConfig.ActivateProject), true) mockClient.OnUpdateProjectMatch(ctx, projectUpdateRequest).Return(nil, errors.New("Error Updating Project")) - updateProjectsFunc(ctx, args, cmdCtx) + err := updateProjectsFunc(ctx, args, cmdCtx) + assert.Nil(t, err) mockClient.AssertCalled(t, "UpdateProject", ctx, projectUpdateRequest) } @@ -106,7 +110,8 @@ func TestArchiveProjectFuncWithError(t *testing.T) { State: admin.Project_ARCHIVED, } mockClient.OnUpdateProjectMatch(ctx, projectUpdateRequest).Return(nil, errors.New("Error Updating Project")) - updateProjectsFunc(ctx, args, cmdCtx) + err := updateProjectsFunc(ctx, args, cmdCtx) + assert.Nil(t, err) mockClient.AssertCalled(t, "UpdateProject", ctx, projectUpdateRequest) } @@ -116,7 +121,8 @@ func TestEmptyProjectInput(t *testing.T) { config.GetConfig().Project = "" modifyProjectFlags(&(projectConfig.ArchiveProject), false, &(projectConfig.ActivateProject), true) mockClient.OnUpdateProjectMatch(ctx, projectUpdateRequest).Return(nil, nil) - updateProjectsFunc(ctx, args, cmdCtx) + err := updateProjectsFunc(ctx, args, cmdCtx) + assert.Nil(t, err) mockClient.AssertNotCalled(t, "UpdateProject", ctx, projectUpdateRequest) } @@ -125,6 +131,7 @@ func TestInvalidInput(t *testing.T) { defer teardownAndVerify(t, "Invalid state passed. Specify either activate or archive\n") modifyProjectFlags(&(projectConfig.ArchiveProject), false, &(projectConfig.ActivateProject), false) mockClient.OnUpdateProjectMatch(ctx, projectUpdateRequest).Return(nil, nil) - updateProjectsFunc(ctx, args, cmdCtx) + err := updateProjectsFunc(ctx, args, cmdCtx) + assert.NotNil(t, err) mockClient.AssertNotCalled(t, "UpdateProject", ctx, projectUpdateRequest) } diff --git a/flytectl/cmd/update/projectconfig_flags.go b/flytectl/cmd/update/projectconfig_flags.go index e214a4fe1f..f56579fe9f 100755 --- a/flytectl/cmd/update/projectconfig_flags.go +++ b/flytectl/cmd/update/projectconfig_flags.go @@ -41,7 +41,7 @@ func (ProjectConfig) mustMarshalJSON(v json.Marshaler) string { // flags is json-name.json-sub-name... etc. func (cfg ProjectConfig) GetPFlagSet(prefix string) *pflag.FlagSet { cmdFlags := pflag.NewFlagSet("ProjectConfig", pflag.ExitOnError) - cmdFlags.BoolVarP(&(projectConfig.ActivateProject), fmt.Sprintf("%v%v", prefix, "activateProject"),"t", *new(bool), "Activates the project specified as argument.") + cmdFlags.BoolVarP(&(projectConfig.ActivateProject), fmt.Sprintf("%v%v", prefix, "activateProject"), "t", *new(bool), "Activates the project specified as argument.") cmdFlags.BoolVarP(&(projectConfig.ArchiveProject), fmt.Sprintf("%v%v", prefix, "archiveProject"), "a", *new(bool), "Archives the project specified as argument.") return cmdFlags } diff --git a/flytectl/cmd/update/update.go b/flytectl/cmd/update/update.go index 791deb5c9d..f165512740 100644 --- a/flytectl/cmd/update/update.go +++ b/flytectl/cmd/update/update.go @@ -12,7 +12,7 @@ const ( updateShort = ` Used for updating flyte resources eg: project. ` - updatecmdLong = ` + updatecmdLong = ` Currently this command only provides subcommands to update project. Takes input project which need to be archived or unarchived. Name of the project to be updated is mandatory field. Example update project to activate it. @@ -27,7 +27,7 @@ func CreateUpdateCommand() *cobra.Command { updateCmd := &cobra.Command{ Use: updateUse, Short: updateShort, - Long: updatecmdLong, + Long: updatecmdLong, } updateResourcesFuncs := map[string]cmdcore.CommandEntry{ diff --git a/flytectl/cmd/update/update_test.go b/flytectl/cmd/update/update_test.go index 749d00a6a0..816c094875 100644 --- a/flytectl/cmd/update/update_test.go +++ b/flytectl/cmd/update/update_test.go @@ -1,15 +1,16 @@ package update import ( - "github.com/stretchr/testify/assert" "sort" "testing" + + "github.com/stretchr/testify/assert" ) func TestUpdateCommand(t *testing.T) { updateCommand := CreateUpdateCommand() - assert.Equal(t, updateCommand.Use , "update") - assert.Equal(t, updateCommand.Short , "Update various resources.") + assert.Equal(t, updateCommand.Use, "update") + assert.Equal(t, updateCommand.Short, "\nUsed for updating flyte resources eg: project.\n") assert.Equal(t, len(updateCommand.Commands()), 1) cmdNouns := updateCommand.Commands() // Sort by Use value. diff --git a/flytectl/docs/source/generate_docs.go b/flytectl/docs/source/generate_docs.go index 458b597c8b..4bfb6667ef 100644 --- a/flytectl/docs/source/generate_docs.go +++ b/flytectl/docs/source/generate_docs.go @@ -7,4 +7,3 @@ func main() { panic(err) } } - diff --git a/flytectl/install.sh b/flytectl/install.sh index bee7affdf3..8cd6b6ebd1 100644 --- a/flytectl/install.sh +++ b/flytectl/install.sh @@ -1,18 +1,18 @@ #!/bin/sh set -e -# Code generated by godownloader on 2020-10-10T20:07:34Z. DO NOT EDIT. +# Code generated by godownloader on 2021-02-08T20:29:16Z. DO NOT EDIT. # usage() { this=$1 cat < - -## Follow-up issue -_NA_ -OR -_https://github.com/lyft/flyte/issues/_