From 614976a0bf02008335c3ea2d4e88033c4c0446bf Mon Sep 17 00:00:00 2001 From: Tomas Kral Date: Wed, 23 Mar 2022 12:15:41 +0100 Subject: [PATCH] remove odo catalog command (#5577) * remove odo catalog command - move devfile registry relevant code to pkg/registry * remove odo catalog page form docs * remove a few forgotten uses of catalog from clientset.go * fix typos in docs --- Makefile | 4 - .../command-reference/catalog.md | 172 ------------- .../version-3.0.0/command-reference/init.md | 7 +- pkg/catalog/interface.go | 11 - pkg/catalog/mock_catalog.go | 80 ------ pkg/component/component.go | 8 +- pkg/component/delete/mock.go | 75 +++--- pkg/init/asker/asker.go | 12 +- pkg/init/asker/interface.go | 4 +- pkg/init/asker/mock.go | 6 +- pkg/init/backend/alizer.go | 20 +- pkg/init/backend/alizer_test.go | 46 ++-- pkg/init/backend/interactive.go | 23 +- pkg/init/backend/interactive_test.go | 71 +++--- pkg/init/init.go | 11 +- pkg/init/init_test.go | 2 +- pkg/init/registry/registry.go | 32 --- pkg/odo/cli/catalog/catalog.go | 40 --- pkg/odo/cli/catalog/describe/component.go | 236 ------------------ pkg/odo/cli/catalog/describe/describe.go | 29 --- pkg/odo/cli/catalog/list/components.go | 125 ---------- pkg/odo/cli/catalog/list/list.go | 29 --- pkg/odo/cli/catalog/search/component.go | 95 ------- pkg/odo/cli/catalog/search/search.go | 29 --- pkg/odo/cli/cli.go | 4 +- pkg/odo/cli/component/create.go | 4 +- pkg/odo/cli/component/create_methods.go | 26 +- pkg/odo/cli/component/list.go | 4 +- pkg/odo/cli/component/ui/ui.go | 7 +- .../genericclioptions/clientset/clientset.go | 18 +- pkg/odo/util/completion/completionhandlers.go | 12 +- .../devfile_component_type_list.go | 8 +- .../devfile_component_type_list_test.go | 26 +- pkg/{init => }/registry/interface.go | 2 + pkg/{init => }/registry/mock.go | 32 ++- .../catalog.go => registry/registry.go} | 81 +++--- .../registry_test.go} | 10 +- pkg/{catalog => registry}/types.go | 14 +- .../types_with_details.go | 6 +- .../types_with_details_test.go | 32 +-- scripts/mockgen.sh | 8 +- .../devfile/cmd_devfile_catalog_test.go | 151 ----------- tests/integration/devfile/utils/utils.go | 22 -- tests/integration/generic_test.go | 16 -- 44 files changed, 296 insertions(+), 1354 deletions(-) delete mode 100644 docs/website/versioned_docs/version-3.0.0/command-reference/catalog.md delete mode 100644 pkg/catalog/interface.go delete mode 100644 pkg/catalog/mock_catalog.go delete mode 100644 pkg/init/registry/registry.go delete mode 100644 pkg/odo/cli/catalog/catalog.go delete mode 100644 pkg/odo/cli/catalog/describe/component.go delete mode 100644 pkg/odo/cli/catalog/describe/describe.go delete mode 100644 pkg/odo/cli/catalog/list/components.go delete mode 100644 pkg/odo/cli/catalog/list/list.go delete mode 100644 pkg/odo/cli/catalog/search/component.go delete mode 100644 pkg/odo/cli/catalog/search/search.go rename pkg/{catalog => registry}/devfile_component_type_list.go (77%) rename pkg/{catalog => registry}/devfile_component_type_list_test.go (83%) rename pkg/{init => }/registry/interface.go (83%) rename pkg/{init => }/registry/mock.go (70%) rename pkg/{catalog/catalog.go => registry/registry.go} (76%) rename pkg/{catalog/catalog_test.go => registry/registry_test.go} (95%) rename pkg/{catalog => registry}/types.go (56%) rename pkg/{catalog => registry}/types_with_details.go (91%) rename pkg/{catalog => registry}/types_with_details_test.go (83%) delete mode 100644 tests/integration/devfile/cmd_devfile_catalog_test.go diff --git a/Makefile b/Makefile index d986404cf..33d7939ea 100644 --- a/Makefile +++ b/Makefile @@ -183,10 +183,6 @@ test-cmd-pref-config: install ## Run odo preference and config command tests test-plugin-handler: install ## Run odo plugin handler tests $(RUN_GINKGO) $(GINKGO_FLAGS) -focus="odo plugin functionality" tests/integration/ -.PHONY: test-cmd-devfile-catalog -test-cmd-devfile-catalog: install ## Run odo catalog devfile command tests - $(RUN_GINKGO) $(GINKGO_FLAGS) -focus="odo devfile catalog command tests" tests/integration/devfile/ - .PHONY: test-cmd-devfile-list test-cmd-devfile-list: install ## Run odo list devfile command tests $(RUN_GINKGO) $(GINKGO_FLAGS) -focus="odo list with devfile" tests/integration/devfile/ diff --git a/docs/website/versioned_docs/version-3.0.0/command-reference/catalog.md b/docs/website/versioned_docs/version-3.0.0/command-reference/catalog.md deleted file mode 100644 index 842e2e8b8..000000000 --- a/docs/website/versioned_docs/version-3.0.0/command-reference/catalog.md +++ /dev/null @@ -1,172 +0,0 @@ ---- -title: odo catalog -sidebar_position: 2 ---- - -odo uses different *catalogs* to deploy *components* and *services*. - -## Components - -odo uses the portable *devfile* format to describe the components. It can connect to various devfile registries to download devfiles for different languages and frameworks. See [`odo registry`](/docs/command-reference/registry) for more information. - -### Listing components - -You can list all the *devfiles* available on the different registries with the command: - -``` -odo catalog list components -``` - -Example: - -``` -$ odo catalog list components -Odo Devfile Components: -NAME DESCRIPTION REGISTRY -go Stack with the latest Go version DefaultDevfileRegistry -java-maven Upstream Maven and OpenJDK 11 DefaultDevfileRegistry -nodejs Stack with Node.js 14 DefaultDevfileRegistry -php-laravel Stack with Laravel 8 DefaultDevfileRegistry -python Python Stack with Python 3.7 DefaultDevfileRegistry -[...] -``` - -### Getting information about a component - -You can get more information about a specific component with the command: - -``` -odo catalog describe component -``` - -Example: - -``` -$ odo catalog describe component nodejs -* Registry: DefaultDevfileRegistry - -Starter Projects: ---- -name: nodejs-starter -attributes: {} -description: "" -subdir: "" -projectsource: - sourcetype: "" - git: - gitlikeprojectsource: - commonprojectsource: {} - checkoutfrom: null - remotes: - origin: https://github.com/odo-devfiles/nodejs-ex.git - zip: null - custom: null -``` - -*Registry* is the registry from which the devfile is retrieved. - -*Starter projects* are sample projects in the same language and framework of the devfile, that can help you start a new project. See [`odo create`](/docs/command-reference/create) for more information on creating a project from a starter project. - -## Services - -odo can deploy *services* with the help of *operators*. - -Only operators deployed with the help of the [*Operator Lifecycle Manager*](https://olm.operatorframework.io/) are supported by odo. See [Installing the Operator Lifecycle Manager (OLM)](/docs/getting-started/cluster-setup/kubernetes#installing-the-operator-lifecycle-manager-olm) for more information. - - -### Listing services - -You can get the list of available operators and their associated services with the command: - -``` -odo catalog list services -``` - -Example: - -``` -$ odo catalog list services -Services available through Operators -NAME CRDs -postgresql-operator.v0.1.1 Backup, Database -redis-operator.v0.8.0 RedisCluster, Redis -``` - -In this example, you can see that two operators are installed in the cluster. The `postgresql-operator.v0.1.1` operator can deploy services related to PostgreSQL: `Backup` and `Database`. The `redis-operator.v0.8.0` operator can deploy services related to Redis: `RedisCluster` and `Redis`. - -> Note: To get a list of all the available operators, odo fetches the `ClusterServiceVersion` (`CSV`) resources of the current namespace that are in a *Succeeded* phase. For operators that support cluster-wide access, when a new namespace is created, these resources are automatically added to it, but it may take some time before they are in the *Succeeded* phase, and odo may return an empty list until the resources are ready. - -### Searching services - -You can search for a specific service by a keyword with the command: - -``` -odo catalog search service -``` - -Example: - -``` -$ odo catalog search service postgre -Services available through Operators -NAME CRDs -postgresql-operator.v0.1.1 Backup, Database -``` - -You may see a similar list that contains only the relevant operators, whose name contains the searched keyword. - -### Getting information about a service - -You can get more information about a specific service with the command: - -``` -odo catalog describe service -``` - -Example: - -``` -$ odo catalog describe service postgresql-operator.v0.1.1/Database -KIND: Database -VERSION: v1alpha1 - -DESCRIPTION: - Database is the Schema for the the Database Database API - -FIELDS: - awsAccessKeyId (string) - AWS S3 accessKey/token ID - - Key ID of AWS S3 storage. Default Value: nil Required to create the Secret - with the data to allow send the backup files to AWS S3 storage. -[...] -``` - -A service is represented in the cluster by a `CustomResourceDefinition` (commonly named `CRD`). This command will display the details about this CRD such as `kind`, `version`, and the list of fields available to define an instance of this custom resource. - -The list of fields is extracted from the *OpenAPI schema* included in the `CRD`. This information is optional in a `CRD`, and if it is not present, it is extracted from the `ClusterServiceVersion` (`CSV`) representing the service instead. - -It is also possible to request description of operator backed service without providing crd type information. Let us say you want to describe redis operator on cluster without CRD, you can do - -```shell -odo catalog describe service redis-operator.v0.8.0 -NAME: redis-operator.v0.8.0 -DESCRIPTION: - - A Golang based redis operator that will make/oversee Redis - standalone/cluster mode setup on top of the Kubernetes. It can create a - redis cluster setup with best practices on Cloud as well as the Bare metal - environment. Also, it provides an in-built monitoring capability using - -... (cut short for beverity) - - Logging Operator is licensed under [Apache License, Version - 2.0](https://github.com/OT-CONTAINER-KIT/redis-operator/blob/master/LICENSE) - - -CRDs: - NAME DESCRIPTION - RedisCluster Redis Cluster - Redis Redis - -``` diff --git a/docs/website/versioned_docs/version-3.0.0/command-reference/init.md b/docs/website/versioned_docs/version-3.0.0/command-reference/init.md index 657ae14b5..9ff998fbd 100644 --- a/docs/website/versioned_docs/version-3.0.0/command-reference/init.md +++ b/docs/website/versioned_docs/version-3.0.0/command-reference/init.md @@ -13,7 +13,7 @@ The command can be exectued in two flavors, either interactive or non-interactiv ## Interactive mode In interactive mode, you will be guided to choose: -- a devfile from the list of devfiles present in the registry or registries referenced (using the `odo registry` command), +- a devfile from the list of devfiles present in the registry or registries referenced (using the `odo preference registry` command), - a starter project referenced by the selected devfile, - a name for the component present in the devfile. @@ -21,11 +21,12 @@ In interactive mode, you will be guided to choose: In non-interactive mode, you will have to specify from the command-line the information needed to get a devfile. -If you want to download a devfile from a registry, you must specify the devfile name with the `--devfile` flag. To list the available devfiles from all registries, use `odo catalog list component`. The devfile with the specified name will be searched in the registries referenced (using `odo registry`), and the first one matching will be downloaded. If you want to download the devfile from a specific registry in the list or referenced registries, you can use the `--devfile-registry` flag to specify the name of this registry. +If you want to download a devfile from a registry, you must specify the devfile name with the `--devfile` flag. The devfile with the specified name will be searched in the registries referenced (using `odo preference registry`), and the first one matching will be downloaded. If you want to download the devfile from a specific registry in the list or referenced registries, you can use the `--devfile-registry` flag to specify the name of this registry. By default odo uses official devfile registry [registry.devfile.io](https://registry.devfile.io). You can use registry's [web interface](https://registry.devfile.io/viewer) to view its content. + If you prefer to download a devfile from an URL or from the local filesystem, you can use the `--devfile-path` instead. -The `--starter` flag indicates the name of the starter project (as referenced in the selected devfile), that you want to use to start your development. To see the available starter projects for a component type, use `odo catalog describe component `. +The `--starter` flag indicates the name of the starter project (as referenced in the selected devfile), that you want to use to start your development. To see the available starter projects for devfile stacks in the official devfile registry use its [web interface](https://registry.devfile.io/viewer) to view its content. The required `--name` flag indicates how the component initialized by this command should be named. diff --git a/pkg/catalog/interface.go b/pkg/catalog/interface.go deleted file mode 100644 index ffaffb435..000000000 --- a/pkg/catalog/interface.go +++ /dev/null @@ -1,11 +0,0 @@ -package catalog - -import ( - "github.com/redhat-developer/odo/pkg/kclient" -) - -type Client interface { - GetDevfileRegistries(registryName string) ([]Registry, error) - ListDevfileComponents(registryName string) (DevfileComponentTypeList, error) - SearchComponent(client kclient.ClientInterface, name string) ([]string, error) -} diff --git a/pkg/catalog/mock_catalog.go b/pkg/catalog/mock_catalog.go deleted file mode 100644 index 058cca611..000000000 --- a/pkg/catalog/mock_catalog.go +++ /dev/null @@ -1,80 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: pkg/catalog/interface.go - -// Package catalog is a generated GoMock package. -package catalog - -import ( - reflect "reflect" - - gomock "github.com/golang/mock/gomock" - kclient "github.com/redhat-developer/odo/pkg/kclient" -) - -// MockClient is a mock of Client interface. -type MockClient struct { - ctrl *gomock.Controller - recorder *MockClientMockRecorder -} - -// MockClientMockRecorder is the mock recorder for MockClient. -type MockClientMockRecorder struct { - mock *MockClient -} - -// NewMockClient creates a new mock instance. -func NewMockClient(ctrl *gomock.Controller) *MockClient { - mock := &MockClient{ctrl: ctrl} - mock.recorder = &MockClientMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockClient) EXPECT() *MockClientMockRecorder { - return m.recorder -} - -// GetDevfileRegistries mocks base method. -func (m *MockClient) GetDevfileRegistries(registryName string) ([]Registry, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetDevfileRegistries", registryName) - ret0, _ := ret[0].([]Registry) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetDevfileRegistries indicates an expected call of GetDevfileRegistries. -func (mr *MockClientMockRecorder) GetDevfileRegistries(registryName interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDevfileRegistries", reflect.TypeOf((*MockClient)(nil).GetDevfileRegistries), registryName) -} - -// ListDevfileComponents mocks base method. -func (m *MockClient) ListDevfileComponents(registryName string) (DevfileComponentTypeList, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ListDevfileComponents", registryName) - ret0, _ := ret[0].(DevfileComponentTypeList) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// ListDevfileComponents indicates an expected call of ListDevfileComponents. -func (mr *MockClientMockRecorder) ListDevfileComponents(registryName interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDevfileComponents", reflect.TypeOf((*MockClient)(nil).ListDevfileComponents), registryName) -} - -// SearchComponent mocks base method. -func (m *MockClient) SearchComponent(client kclient.ClientInterface, name string) ([]string, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SearchComponent", client, name) - ret0, _ := ret[0].([]string) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// SearchComponent indicates an expected call of SearchComponent. -func (mr *MockClientMockRecorder) SearchComponent(client, name interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SearchComponent", reflect.TypeOf((*MockClient)(nil).SearchComponent), client, name) -} diff --git a/pkg/component/component.go b/pkg/component/component.go index 03ab651ad..f6da369a0 100644 --- a/pkg/component/component.go +++ b/pkg/component/component.go @@ -120,10 +120,10 @@ func ApplyConfig(client kclient.ClientInterface, envSpecificInfo envinfo.EnvSpec }) } -// ListDevfileComponents returns the devfile component matching a selector. +// ListDevfileStacks returns the devfile component matching a selector. // The selector could be about selecting components part of an application. // There are helpers in "applabels" package for this. -func ListDevfileComponents(client kclient.ClientInterface, selector string) (ComponentList, error) { +func ListDevfileStacks(client kclient.ClientInterface, selector string) (ComponentList, error) { var deploymentList []v1.Deployment var components []Component @@ -153,7 +153,7 @@ func ListDevfileComponents(client kclient.ClientInterface, selector string) (Com // List lists all the devfile components in active application func List(client kclient.ClientInterface, applicationSelector string) (ComponentList, error) { - devfileList, err := ListDevfileComponents(client, applicationSelector) + devfileList, err := ListDevfileStacks(client, applicationSelector) if err != nil { return ComponentList{}, nil } @@ -252,7 +252,7 @@ func getComponentFrom(info localConfigProvider.LocalConfigProvider, componentTyp return Component{}, nil } -func ListDevfileComponentsInPath(client kclient.ClientInterface, paths []string) ([]Component, error) { +func ListDevfileStacksInPath(client kclient.ClientInterface, paths []string) ([]Component, error) { var components []Component var err error for _, path := range paths { diff --git a/pkg/component/delete/mock.go b/pkg/component/delete/mock.go index 63934c646..038bb54b8 100644 --- a/pkg/component/delete/mock.go +++ b/pkg/component/delete/mock.go @@ -5,36 +5,65 @@ package delete import ( + reflect "reflect" + parser "github.com/devfile/library/pkg/devfile/parser" gomock "github.com/golang/mock/gomock" unstructured "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - reflect "reflect" ) -// MockClient is a mock of Client interface +// MockClient is a mock of Client interface. type MockClient struct { ctrl *gomock.Controller recorder *MockClientMockRecorder } -// MockClientMockRecorder is the mock recorder for MockClient +// MockClientMockRecorder is the mock recorder for MockClient. type MockClientMockRecorder struct { mock *MockClient } -// NewMockClient creates a new mock instance +// NewMockClient creates a new mock instance. func NewMockClient(ctrl *gomock.Controller) *MockClient { mock := &MockClient{ctrl: ctrl} mock.recorder = &MockClientMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockClient) EXPECT() *MockClientMockRecorder { return m.recorder } -// ListResourcesToDelete mocks base method +// DeleteResources mocks base method. +func (m *MockClient) DeleteResources(arg0 []unstructured.Unstructured) []unstructured.Unstructured { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteResources", arg0) + ret0, _ := ret[0].([]unstructured.Unstructured) + return ret0 +} + +// DeleteResources indicates an expected call of DeleteResources. +func (mr *MockClientMockRecorder) DeleteResources(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteResources", reflect.TypeOf((*MockClient)(nil).DeleteResources), arg0) +} + +// ExecutePreStopEvents mocks base method. +func (m *MockClient) ExecutePreStopEvents(devfileObj parser.DevfileObj, appName string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ExecutePreStopEvents", devfileObj, appName) + ret0, _ := ret[0].(error) + return ret0 +} + +// ExecutePreStopEvents indicates an expected call of ExecutePreStopEvents. +func (mr *MockClientMockRecorder) ExecutePreStopEvents(devfileObj, appName interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ExecutePreStopEvents", reflect.TypeOf((*MockClient)(nil).ExecutePreStopEvents), devfileObj, appName) +} + +// ListResourcesToDelete mocks base method. func (m *MockClient) ListResourcesToDelete(componentName, namespace string) ([]unstructured.Unstructured, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ListResourcesToDelete", componentName, namespace) @@ -43,41 +72,13 @@ func (m *MockClient) ListResourcesToDelete(componentName, namespace string) ([]u return ret0, ret1 } -// ListResourcesToDelete indicates an expected call of ListResourcesToDelete +// ListResourcesToDelete indicates an expected call of ListResourcesToDelete. func (mr *MockClientMockRecorder) ListResourcesToDelete(componentName, namespace interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListResourcesToDelete", reflect.TypeOf((*MockClient)(nil).ListResourcesToDelete), componentName, namespace) } -// DeleteResources mocks base method -func (m *MockClient) DeleteResources(arg0 []unstructured.Unstructured) []unstructured.Unstructured { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DeleteResources", arg0) - ret0, _ := ret[0].([]unstructured.Unstructured) - return ret0 -} - -// DeleteResources indicates an expected call of DeleteResources -func (mr *MockClientMockRecorder) DeleteResources(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteResources", reflect.TypeOf((*MockClient)(nil).DeleteResources), arg0) -} - -// ExecutePreStopEvents mocks base method -func (m *MockClient) ExecutePreStopEvents(devfileObj parser.DevfileObj, appName string) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ExecutePreStopEvents", devfileObj, appName) - ret0, _ := ret[0].(error) - return ret0 -} - -// ExecutePreStopEvents indicates an expected call of ExecutePreStopEvents -func (mr *MockClientMockRecorder) ExecutePreStopEvents(devfileObj, appName interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ExecutePreStopEvents", reflect.TypeOf((*MockClient)(nil).ExecutePreStopEvents), devfileObj, appName) -} - -// ListResourcesToDeleteFromDevfile mocks base method +// ListResourcesToDeleteFromDevfile mocks base method. func (m *MockClient) ListResourcesToDeleteFromDevfile(devfileObj parser.DevfileObj, appName string) (bool, []unstructured.Unstructured, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ListResourcesToDeleteFromDevfile", devfileObj, appName) @@ -87,7 +88,7 @@ func (m *MockClient) ListResourcesToDeleteFromDevfile(devfileObj parser.DevfileO return ret0, ret1, ret2 } -// ListResourcesToDeleteFromDevfile indicates an expected call of ListResourcesToDeleteFromDevfile +// ListResourcesToDeleteFromDevfile indicates an expected call of ListResourcesToDeleteFromDevfile. func (mr *MockClientMockRecorder) ListResourcesToDeleteFromDevfile(devfileObj, appName interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListResourcesToDeleteFromDevfile", reflect.TypeOf((*MockClient)(nil).ListResourcesToDeleteFromDevfile), devfileObj, appName) diff --git a/pkg/init/asker/asker.go b/pkg/init/asker/asker.go index e5c2f38a4..d9cc940bd 100644 --- a/pkg/init/asker/asker.go +++ b/pkg/init/asker/asker.go @@ -2,11 +2,11 @@ package asker import ( "fmt" - "github.com/AlecAivazis/survey/v2" - "github.com/redhat-developer/odo/pkg/log" "sort" - "github.com/redhat-developer/odo/pkg/catalog" + "github.com/AlecAivazis/survey/v2" + "github.com/redhat-developer/odo/pkg/log" + "github.com/redhat-developer/odo/pkg/registry" ) type Survey struct{} @@ -29,7 +29,7 @@ func (o *Survey) AskLanguage(langs []string) (string, error) { return answer, nil } -func (o *Survey) AskType(types catalog.TypesWithDetails) (back bool, _ catalog.DevfileComponentType, _ error) { +func (o *Survey) AskType(types registry.TypesWithDetails) (back bool, _ registry.DevfileStack, _ error) { stringTypes := types.GetOrderedLabels() stringTypes = append(stringTypes, "** GO BACK **") question := &survey.Select{ @@ -39,10 +39,10 @@ func (o *Survey) AskType(types catalog.TypesWithDetails) (back bool, _ catalog.D var answerPos int err := survey.AskOne(question, &answerPos) if err != nil { - return false, catalog.DevfileComponentType{}, err + return false, registry.DevfileStack{}, err } if answerPos == len(stringTypes)-1 { - return true, catalog.DevfileComponentType{}, nil + return true, registry.DevfileStack{}, nil } compType, err := types.GetAtOrderedPosition(answerPos) return false, compType, err diff --git a/pkg/init/asker/interface.go b/pkg/init/asker/interface.go index 2fce6efdd..7f7f512d0 100644 --- a/pkg/init/asker/interface.go +++ b/pkg/init/asker/interface.go @@ -3,7 +3,7 @@ package asker import ( - "github.com/redhat-developer/odo/pkg/catalog" + "github.com/redhat-developer/odo/pkg/registry" ) // Asker interactively asks for information to the user @@ -13,7 +13,7 @@ type Asker interface { // AskType asks for a Devfile type, or to go back. back is returned as true if the user selected to go back, // or the selected type is returned - AskType(types catalog.TypesWithDetails) (back bool, _ catalog.DevfileComponentType, _ error) + AskType(types registry.TypesWithDetails) (back bool, _ registry.DevfileStack, _ error) // AskStarterProject asks for an optional project, from a list of projects. If no project is selected, false is returned. // Or the index of the selected project is returned diff --git a/pkg/init/asker/mock.go b/pkg/init/asker/mock.go index f08edf5cb..a4047447e 100644 --- a/pkg/init/asker/mock.go +++ b/pkg/init/asker/mock.go @@ -8,7 +8,7 @@ import ( reflect "reflect" gomock "github.com/golang/mock/gomock" - catalog "github.com/redhat-developer/odo/pkg/catalog" + registry "github.com/redhat-developer/odo/pkg/registry" ) // MockAsker is a mock of Asker interface. @@ -157,11 +157,11 @@ func (mr *MockAskerMockRecorder) AskStarterProject(projects interface{}) *gomock } // AskType mocks base method. -func (m *MockAsker) AskType(types catalog.TypesWithDetails) (bool, catalog.DevfileComponentType, error) { +func (m *MockAsker) AskType(types registry.TypesWithDetails) (bool, registry.DevfileStack, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "AskType", types) ret0, _ := ret[0].(bool) - ret1, _ := ret[1].(catalog.DevfileComponentType) + ret1, _ := ret[1].(registry.DevfileStack) ret2, _ := ret[2].(error) return ret0, ret1, ret2 } diff --git a/pkg/init/backend/alizer.go b/pkg/init/backend/alizer.go index aa512d014..b00652eaf 100644 --- a/pkg/init/backend/alizer.go +++ b/pkg/init/backend/alizer.go @@ -7,20 +7,20 @@ import ( "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2" "github.com/devfile/library/pkg/devfile/parser" "github.com/redhat-developer/alizer/go/pkg/apis/recognizer" - "github.com/redhat-developer/odo/pkg/catalog" "github.com/redhat-developer/odo/pkg/init/asker" + "github.com/redhat-developer/odo/pkg/registry" "github.com/redhat-developer/odo/pkg/testingutil/filesystem" ) type AlizerBackend struct { - askerClient asker.Asker - catalogClient catalog.Client + askerClient asker.Asker + registryClient registry.Client } -func NewAlizerBackend(askerClient asker.Asker, catalogClient catalog.Client) *AlizerBackend { +func NewAlizerBackend(askerClient asker.Asker, registryClient registry.Client) *AlizerBackend { return &AlizerBackend{ - askerClient: askerClient, - catalogClient: catalogClient, + askerClient: askerClient, + registryClient: registryClient, } } @@ -30,11 +30,11 @@ func (o *AlizerBackend) Validate(flags map[string]string, fs filesystem.Filesyst // detectFramework uses the alizer library in order to detect the devfile // to use depending on the files in the path -func (o *AlizerBackend) detectFramework(path string) (recognizer.DevFileType, catalog.Registry, error) { +func (o *AlizerBackend) detectFramework(path string) (recognizer.DevFileType, registry.Registry, error) { types := []recognizer.DevFileType{} - components, err := o.catalogClient.ListDevfileComponents("") + components, err := o.registryClient.ListDevfileStacks("") if err != nil { - return recognizer.DevFileType{}, catalog.Registry{}, err + return recognizer.DevFileType{}, registry.Registry{}, err } for _, component := range components.Items { types = append(types, recognizer.DevFileType{ @@ -46,7 +46,7 @@ func (o *AlizerBackend) detectFramework(path string) (recognizer.DevFileType, ca } typ, err := recognizer.SelectDevFileFromTypes(path, types) if err != nil { - return recognizer.DevFileType{}, catalog.Registry{}, err + return recognizer.DevFileType{}, registry.Registry{}, err } // TODO(feloy): This part won't be necessary when SelectDevFileFromTypes returns the index diff --git a/pkg/init/backend/alizer_test.go b/pkg/init/backend/alizer_test.go index f10dfee54..6200411b1 100644 --- a/pkg/init/backend/alizer_test.go +++ b/pkg/init/backend/alizer_test.go @@ -7,8 +7,8 @@ import ( "testing" "github.com/golang/mock/gomock" - "github.com/redhat-developer/odo/pkg/catalog" "github.com/redhat-developer/odo/pkg/init/asker" + "github.com/redhat-developer/odo/pkg/registry" "github.com/redhat-developer/odo/pkg/testingutil/filesystem" ) @@ -20,13 +20,13 @@ func GetTestProjectPath(folder string) string { return filepath.Join(basepath, "..", "..", "..", "tests/examples/source/", folder) } -var types = []catalog.DevfileComponentType{ +var types = []registry.DevfileStack{ { Name: "java-maven", Language: "java", ProjectType: "maven", Tags: []string{"Java", "Maven"}, - Registry: catalog.Registry{ + Registry: registry.Registry{ Name: "registry1", }, }, @@ -35,7 +35,7 @@ var types = []catalog.DevfileComponentType{ Language: "java", ProjectType: "quarkus", Tags: []string{"Java", "Quarkus"}, - Registry: catalog.Registry{ + Registry: registry.Registry{ Name: "registry1", }, }, @@ -44,7 +44,7 @@ var types = []catalog.DevfileComponentType{ Language: "java", ProjectType: "wildfly", Tags: []string{"Java", "WildFly"}, - Registry: catalog.Registry{ + Registry: registry.Registry{ Name: "registry2", }, }, @@ -53,7 +53,7 @@ var types = []catalog.DevfileComponentType{ Language: "javascript", ProjectType: "nodejs", Tags: []string{"NodeJS", "Express", "ubi8"}, - Registry: catalog.Registry{ + Registry: registry.Registry{ Name: "registry2", }, }, @@ -62,12 +62,12 @@ var types = []catalog.DevfileComponentType{ Language: "python", ProjectType: "python", Tags: []string{"Python", "pip"}, - Registry: catalog.Registry{ + Registry: registry.Registry{ Name: "registry3", }, }, } -var list = catalog.DevfileComponentTypeList{ +var list = registry.DevfileStackList{ Items: types, } @@ -115,9 +115,9 @@ func TestDetectFramework(t *testing.T) { t.Run(tt.name, func(t *testing.T) { ctrl := gomock.NewController(t) askerClient := asker.NewMockAsker(ctrl) - catalogClient := catalog.NewMockClient(ctrl) - catalogClient.EXPECT().ListDevfileComponents("").Return(list, nil) - alizerClient := NewAlizerBackend(askerClient, catalogClient) + registryClient := registry.NewMockClient(ctrl) + registryClient.EXPECT().ListDevfileStacks("").Return(list, nil) + alizerClient := NewAlizerBackend(askerClient, registryClient) // Run function DetectFramework detected, registry, err := alizerClient.detectFramework(tt.args.path) @@ -138,8 +138,8 @@ func TestDetectFramework(t *testing.T) { func TestAlizerBackend_SelectDevfile(t *testing.T) { type fields struct { - askerClient func(ctrl *gomock.Controller) asker.Asker - catalogClient func(ctrl *gomock.Controller) catalog.Client + askerClient func(ctrl *gomock.Controller) asker.Asker + registryClient func(ctrl *gomock.Controller) registry.Client } type args struct { flags map[string]string @@ -161,10 +161,10 @@ func TestAlizerBackend_SelectDevfile(t *testing.T) { askerClient.EXPECT().AskCorrect().Return(true, nil) return askerClient }, - catalogClient: func(ctrl *gomock.Controller) catalog.Client { - catalogClient := catalog.NewMockClient(ctrl) - catalogClient.EXPECT().ListDevfileComponents("").Return(list, nil) - return catalogClient + registryClient: func(ctrl *gomock.Controller) registry.Client { + registryClient := registry.NewMockClient(ctrl) + registryClient.EXPECT().ListDevfileStacks("").Return(list, nil) + return registryClient }, }, args: args{ @@ -184,10 +184,10 @@ func TestAlizerBackend_SelectDevfile(t *testing.T) { askerClient.EXPECT().AskCorrect().Return(false, nil) return askerClient }, - catalogClient: func(ctrl *gomock.Controller) catalog.Client { - catalogClient := catalog.NewMockClient(ctrl) - catalogClient.EXPECT().ListDevfileComponents("").Return(list, nil) - return catalogClient + registryClient: func(ctrl *gomock.Controller) registry.Client { + registryClient := registry.NewMockClient(ctrl) + registryClient.EXPECT().ListDevfileStacks("").Return(list, nil) + return registryClient }, }, args: args{ @@ -202,8 +202,8 @@ func TestAlizerBackend_SelectDevfile(t *testing.T) { t.Run(tt.name, func(t *testing.T) { ctrl := gomock.NewController(t) o := &AlizerBackend{ - askerClient: tt.fields.askerClient(ctrl), - catalogClient: tt.fields.catalogClient(ctrl), + askerClient: tt.fields.askerClient(ctrl), + registryClient: tt.fields.registryClient(ctrl), } gotLocation, err := o.SelectDevfile(tt.args.flags, tt.args.fs, tt.args.dir) if (err != nil) != tt.wantErr { diff --git a/pkg/init/backend/interactive.go b/pkg/init/backend/interactive.go index 8b5cb08e9..ececc600c 100644 --- a/pkg/init/backend/interactive.go +++ b/pkg/init/backend/interactive.go @@ -2,16 +2,17 @@ package backend import ( "fmt" + "sort" + "strconv" + "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2" "github.com/devfile/library/pkg/devfile/parser" parsercommon "github.com/devfile/library/pkg/devfile/parser/data/v2/common" "github.com/fatih/color" - "github.com/redhat-developer/odo/pkg/log" - "sort" - "strconv" - "github.com/redhat-developer/odo/pkg/catalog" "github.com/redhat-developer/odo/pkg/init/asker" + "github.com/redhat-developer/odo/pkg/log" + "github.com/redhat-developer/odo/pkg/registry" "github.com/redhat-developer/odo/pkg/testingutil/filesystem" ) @@ -23,14 +24,14 @@ const ( // InteractiveBackend is a backend that will ask information interactively using the `asker` package type InteractiveBackend struct { - askerClient asker.Asker - catalogClient catalog.Client + askerClient asker.Asker + registryClient registry.Client } -func NewInteractiveBackend(askerClient asker.Asker, catalogClient catalog.Client) *InteractiveBackend { +func NewInteractiveBackend(askerClient asker.Asker, registryClient registry.Client) *InteractiveBackend { return &InteractiveBackend{ - askerClient: askerClient, - catalogClient: catalogClient, + askerClient: askerClient, + registryClient: registryClient, } } @@ -40,13 +41,13 @@ func (o *InteractiveBackend) Validate(flags map[string]string, fs filesystem.Fil func (o *InteractiveBackend) SelectDevfile(flags map[string]string, _ filesystem.Filesystem, _ string) (*DevfileLocation, error) { result := &DevfileLocation{} - devfileEntries, _ := o.catalogClient.ListDevfileComponents("") + devfileEntries, _ := o.registryClient.ListDevfileStacks("") langs := devfileEntries.GetLanguages() state := STATE_ASK_LANG var lang string var err error - var details catalog.DevfileComponentType + var details registry.DevfileStack loop: for { switch state { diff --git a/pkg/init/backend/interactive_test.go b/pkg/init/backend/interactive_test.go index d088a0a14..bd8ffa4a5 100644 --- a/pkg/init/backend/interactive_test.go +++ b/pkg/init/backend/interactive_test.go @@ -1,26 +1,25 @@ package backend import ( - "github.com/redhat-developer/odo/pkg/testingutil" "reflect" "testing" - "github.com/golang/mock/gomock" + "github.com/redhat-developer/odo/pkg/init/asker" + "github.com/redhat-developer/odo/pkg/registry" + "github.com/redhat-developer/odo/pkg/testingutil" "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2" "github.com/devfile/library/pkg/devfile/parser" parsercontext "github.com/devfile/library/pkg/devfile/parser/context" "github.com/devfile/library/pkg/devfile/parser/data" "github.com/devfile/library/pkg/testingutil/filesystem" - - "github.com/redhat-developer/odo/pkg/catalog" - "github.com/redhat-developer/odo/pkg/init/asker" + "github.com/golang/mock/gomock" ) func TestInteractiveBackend_SelectDevfile(t *testing.T) { type fields struct { buildAsker func(ctrl *gomock.Controller) asker.Asker - buildCatalogClient func(ctrl *gomock.Controller) catalog.Client + buildCatalogClient func(ctrl *gomock.Controller) registry.Client } tests := []struct { name string @@ -34,17 +33,17 @@ func TestInteractiveBackend_SelectDevfile(t *testing.T) { buildAsker: func(ctrl *gomock.Controller) asker.Asker { client := asker.NewMockAsker(ctrl) client.EXPECT().AskLanguage(gomock.Any()).Return("java", nil) - client.EXPECT().AskType(gomock.Any()).Return(false, catalog.DevfileComponentType{ + client.EXPECT().AskType(gomock.Any()).Return(false, registry.DevfileStack{ Name: "a-devfile-name", - Registry: catalog.Registry{ + Registry: registry.Registry{ Name: "MyRegistry1", }, }, nil) return client }, - buildCatalogClient: func(ctrl *gomock.Controller) catalog.Client { - client := catalog.NewMockClient(ctrl) - client.EXPECT().ListDevfileComponents(gomock.Any()) + buildCatalogClient: func(ctrl *gomock.Controller) registry.Client { + client := registry.NewMockClient(ctrl) + client.EXPECT().ListDevfileStacks(gomock.Any()) return client }, }, @@ -59,19 +58,19 @@ func TestInteractiveBackend_SelectDevfile(t *testing.T) { buildAsker: func(ctrl *gomock.Controller) asker.Asker { client := asker.NewMockAsker(ctrl) client.EXPECT().AskLanguage(gomock.Any()).Return("java", nil) - client.EXPECT().AskType(gomock.Any()).Return(true, catalog.DevfileComponentType{}, nil) + client.EXPECT().AskType(gomock.Any()).Return(true, registry.DevfileStack{}, nil) client.EXPECT().AskLanguage(gomock.Any()).Return("go", nil) - client.EXPECT().AskType(gomock.Any()).Return(false, catalog.DevfileComponentType{ + client.EXPECT().AskType(gomock.Any()).Return(false, registry.DevfileStack{ Name: "a-devfile-name", - Registry: catalog.Registry{ + Registry: registry.Registry{ Name: "MyRegistry1", }, }, nil) return client }, - buildCatalogClient: func(ctrl *gomock.Controller) catalog.Client { - client := catalog.NewMockClient(ctrl) - client.EXPECT().ListDevfileComponents(gomock.Any()) + buildCatalogClient: func(ctrl *gomock.Controller) registry.Client { + client := registry.NewMockClient(ctrl) + client.EXPECT().ListDevfileStacks(gomock.Any()) return client }, }, @@ -85,8 +84,8 @@ func TestInteractiveBackend_SelectDevfile(t *testing.T) { t.Run(tt.name, func(t *testing.T) { ctrl := gomock.NewController(t) o := &InteractiveBackend{ - askerClient: tt.fields.buildAsker(ctrl), - catalogClient: tt.fields.buildCatalogClient(ctrl), + askerClient: tt.fields.buildAsker(ctrl), + registryClient: tt.fields.buildCatalogClient(ctrl), } got, err := o.SelectDevfile(map[string]string{}, nil, "") if (err != nil) != tt.wantErr { @@ -102,8 +101,8 @@ func TestInteractiveBackend_SelectDevfile(t *testing.T) { func TestInteractiveBackend_SelectStarterProject(t *testing.T) { type fields struct { - asker func(ctrl *gomock.Controller) asker.Asker - catalogClient catalog.Client + asker func(ctrl *gomock.Controller) asker.Asker + registryClient registry.Client } type args struct { devfile func() parser.DevfileObj @@ -181,8 +180,8 @@ func TestInteractiveBackend_SelectStarterProject(t *testing.T) { askerClient = tt.fields.asker(ctrl) } o := &InteractiveBackend{ - askerClient: askerClient, - catalogClient: tt.fields.catalogClient, + askerClient: askerClient, + registryClient: tt.fields.registryClient, } got1, err := o.SelectStarterProject(tt.args.devfile(), tt.args.flags) if (err != nil) != tt.wantErr { @@ -199,8 +198,8 @@ func TestInteractiveBackend_SelectStarterProject(t *testing.T) { func TestInteractiveBackend_PersonalizeName(t *testing.T) { type fields struct { - asker func(ctrl *gomock.Controller) asker.Asker - catalogClient catalog.Client + asker func(ctrl *gomock.Controller) asker.Asker + registryClient registry.Client } type args struct { devfile func(fs filesystem.Filesystem) parser.DevfileObj @@ -246,8 +245,8 @@ func TestInteractiveBackend_PersonalizeName(t *testing.T) { askerClient = tt.fields.asker(ctrl) } o := &InteractiveBackend{ - askerClient: askerClient, - catalogClient: tt.fields.catalogClient, + askerClient: askerClient, + registryClient: tt.fields.registryClient, } fs := filesystem.NewFakeFs() devfile := tt.args.devfile(fs) @@ -268,8 +267,8 @@ func TestInteractiveBackend_PersonalizeDevfileconfig(t *testing.T) { container1 := "runtime" type fields struct { - asker func(ctrl *gomock.Controller, configuration asker.DevfileConfiguration) asker.Asker - catalogClient catalog.Client + asker func(ctrl *gomock.Controller, configuration asker.DevfileConfiguration) asker.Asker + registryClient registry.Client } type args struct { devfileobj func(fs filesystem.Filesystem) parser.DevfileObj @@ -301,7 +300,7 @@ func TestInteractiveBackend_PersonalizeDevfileconfig(t *testing.T) { client.EXPECT().AskContainerName(append(configuration.GetContainers(), "NONE - configuration is correct")).Return("NONE - configuration is correct", nil).After(containerConfigDone) return client }, - catalogClient: nil, + registryClient: nil, }, args: args{ key: "5000", @@ -339,7 +338,7 @@ func TestInteractiveBackend_PersonalizeDevfileconfig(t *testing.T) { client.EXPECT().AskContainerName(append(configuration.GetContainers(), "NONE - configuration is correct")).Return("NONE - configuration is correct", nil).After(containerConfigDone) return client }, - catalogClient: nil, + registryClient: nil, }, args: args{ devfileobj: func(fs filesystem.Filesystem) parser.DevfileObj { @@ -375,7 +374,7 @@ func TestInteractiveBackend_PersonalizeDevfileconfig(t *testing.T) { client.EXPECT().AskContainerName(append(configuration.GetContainers(), "NONE - configuration is correct")).Return("NONE - configuration is correct", nil).After(containerConfigDone) return client }, - catalogClient: nil, + registryClient: nil, }, args: args{ devfileobj: func(fs filesystem.Filesystem) parser.DevfileObj { @@ -414,7 +413,7 @@ func TestInteractiveBackend_PersonalizeDevfileconfig(t *testing.T) { client.EXPECT().AskContainerName(append(configuration.GetContainers(), "NONE - configuration is correct")).Return("NONE - configuration is correct", nil).After(containerConfigDone) return client }, - catalogClient: nil, + registryClient: nil, }, args: args{ devfileobj: func(fs filesystem.Filesystem) parser.DevfileObj { @@ -445,7 +444,7 @@ func TestInteractiveBackend_PersonalizeDevfileconfig(t *testing.T) { }, nil).MaxTimes(1) return client }, - catalogClient: nil, + registryClient: nil, }, args: args{ devfileobj: func(fs filesystem.Filesystem) parser.DevfileObj { @@ -482,8 +481,8 @@ func TestInteractiveBackend_PersonalizeDevfileconfig(t *testing.T) { } o := &InteractiveBackend{ - askerClient: askerClient, - catalogClient: tt.fields.catalogClient, + askerClient: askerClient, + registryClient: tt.fields.registryClient, } if err = o.PersonalizeDevfileconfig(devfile); (err != nil) != tt.wantErr { t.Errorf("PersonalizeDevfileconfig() error = %v, wantErr %v", err, tt.wantErr) diff --git a/pkg/init/init.go b/pkg/init/init.go index 6e765db0f..1da7da8ea 100644 --- a/pkg/init/init.go +++ b/pkg/init/init.go @@ -13,13 +13,12 @@ import ( dfutil "github.com/devfile/library/pkg/util" "k8s.io/utils/pointer" - "github.com/redhat-developer/odo/pkg/catalog" "github.com/redhat-developer/odo/pkg/devfile/location" "github.com/redhat-developer/odo/pkg/init/asker" "github.com/redhat-developer/odo/pkg/init/backend" - "github.com/redhat-developer/odo/pkg/init/registry" "github.com/redhat-developer/odo/pkg/log" "github.com/redhat-developer/odo/pkg/preference" + "github.com/redhat-developer/odo/pkg/registry" "github.com/redhat-developer/odo/pkg/segment" "github.com/redhat-developer/odo/pkg/testingutil/filesystem" ) @@ -34,20 +33,18 @@ type InitClient struct { fsys filesystem.Filesystem preferenceClient preference.Client registryClient registry.Client - catalogClient catalog.Client } -func NewInitClient(fsys filesystem.Filesystem, preferenceClient preference.Client, registryClient registry.Client, catalogClient catalog.Client) *InitClient { +func NewInitClient(fsys filesystem.Filesystem, preferenceClient preference.Client, registryClient registry.Client) *InitClient { // We create the asker client and the backends here and not at the CLI level, as we want to hide these details to the CLI askerClient := asker.NewSurveyAsker() return &InitClient{ flagsBackend: backend.NewFlagsBackend(preferenceClient), - interactiveBackend: backend.NewInteractiveBackend(askerClient, catalogClient), - alizerBackend: backend.NewAlizerBackend(askerClient, catalogClient), + interactiveBackend: backend.NewInteractiveBackend(askerClient, registryClient), + alizerBackend: backend.NewAlizerBackend(askerClient, registryClient), fsys: fsys, preferenceClient: preferenceClient, registryClient: registryClient, - catalogClient: catalogClient, } } diff --git a/pkg/init/init_test.go b/pkg/init/init_test.go index bc35ffbbf..01f51f229 100644 --- a/pkg/init/init_test.go +++ b/pkg/init/init_test.go @@ -7,8 +7,8 @@ import ( "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2" "github.com/golang/mock/gomock" "github.com/redhat-developer/odo/pkg/init/backend" - "github.com/redhat-developer/odo/pkg/init/registry" "github.com/redhat-developer/odo/pkg/preference" + "github.com/redhat-developer/odo/pkg/registry" "github.com/redhat-developer/odo/pkg/testingutil/filesystem" ) diff --git a/pkg/init/registry/registry.go b/pkg/init/registry/registry.go deleted file mode 100644 index 2efeefb63..000000000 --- a/pkg/init/registry/registry.go +++ /dev/null @@ -1,32 +0,0 @@ -package registry - -import ( - devfilev1 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2" - dfutil "github.com/devfile/library/pkg/util" - "github.com/devfile/registry-support/registry-library/library" - - "github.com/redhat-developer/odo/pkg/component" - "github.com/redhat-developer/odo/pkg/util" -) - -type RegistryClient struct{} - -func NewRegistryClient() RegistryClient { - return RegistryClient{} -} - -// PullStackFromRegistry pulls stack from registry with all stack resources (all media types) to the destination directory -func (o RegistryClient) PullStackFromRegistry(registry string, stack string, destDir string, options library.RegistryOptions) error { - return library.PullStackFromRegistry(registry, stack, destDir, options) -} - -// DownloadFileInMemory uses the url to download the file and return bytes -func (o RegistryClient) DownloadFileInMemory(params dfutil.HTTPRequestParams) ([]byte, error) { - return util.DownloadFileInMemory(params) -} - -// DownloadStarterProject downloads a starter project referenced in devfile -// This will first remove the content of the contextDir -func (o RegistryClient) DownloadStarterProject(starterProject *devfilev1.StarterProject, decryptedToken string, contextDir string, verbose bool) error { - return component.DownloadStarterProject(starterProject, decryptedToken, contextDir, verbose) -} diff --git a/pkg/odo/cli/catalog/catalog.go b/pkg/odo/cli/catalog/catalog.go deleted file mode 100644 index 1aa5cfd12..000000000 --- a/pkg/odo/cli/catalog/catalog.go +++ /dev/null @@ -1,40 +0,0 @@ -package catalog - -import ( - "fmt" - - "github.com/redhat-developer/odo/pkg/odo/cli/catalog/describe" - "github.com/redhat-developer/odo/pkg/odo/cli/catalog/list" - "github.com/redhat-developer/odo/pkg/odo/cli/catalog/search" - odoutil "github.com/redhat-developer/odo/pkg/odo/util" - - "github.com/spf13/cobra" -) - -// RecommendedCommandName is the recommended catalog command name -const RecommendedCommandName = "catalog" - -// NewCmdCatalog implements the odo catalog command -func NewCmdCatalog(name, fullName string) *cobra.Command { - catalogDescribeCmd := describe.NewCmdCatalogDescribe(describe.RecommendedCommandName, odoutil.GetFullName(fullName, describe.RecommendedCommandName)) - catalogSearchCmd := search.NewCmdCatalogSearch(search.RecommendedCommandName, odoutil.GetFullName(fullName, search.RecommendedCommandName)) - catalogListCmd := list.NewCmdCatalogList(list.RecommendedCommandName, odoutil.GetFullName(fullName, list.RecommendedCommandName)) - - catalogCmd := &cobra.Command{ - Use: fmt.Sprintf("%s [options]", name), - Short: "Catalog related operations", - Long: "Catalog related operations", - Example: fmt.Sprintf("%s\n%s\n%s", - catalogListCmd.Example, - catalogSearchCmd.Example, - catalogDescribeCmd.Example), - } - - catalogCmd.AddCommand(catalogSearchCmd, catalogListCmd, catalogDescribeCmd) - - // Add a defined annotation in order to appear in the help menu - catalogCmd.Annotations = map[string]string{"command": "main"} - catalogCmd.SetUsageTemplate(odoutil.CmdUsageTemplate) - - return catalogCmd -} diff --git a/pkg/odo/cli/catalog/describe/component.go b/pkg/odo/cli/catalog/describe/component.go deleted file mode 100644 index d48dd5f60..000000000 --- a/pkg/odo/cli/catalog/describe/component.go +++ /dev/null @@ -1,236 +0,0 @@ -package describe - -import ( - "fmt" - "net/url" - "os" - "path" - "strings" - "text/tabwriter" - - "github.com/spf13/cobra" - "gopkg.in/yaml.v2" - - "github.com/redhat-developer/odo/pkg/catalog" - "github.com/redhat-developer/odo/pkg/devfile/validate" - "github.com/redhat-developer/odo/pkg/log" - "github.com/redhat-developer/odo/pkg/machineoutput" - "github.com/redhat-developer/odo/pkg/odo/cmdline" - "github.com/redhat-developer/odo/pkg/odo/genericclioptions" - "github.com/redhat-developer/odo/pkg/odo/genericclioptions/clientset" - - devfilev1 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2" - "github.com/devfile/library/pkg/devfile/parser" - "github.com/devfile/library/pkg/devfile/parser/data" - parsercommon "github.com/devfile/library/pkg/devfile/parser/data/v2/common" - "github.com/redhat-developer/odo/pkg/devfile" - - ktemplates "k8s.io/kubectl/pkg/util/templates" -) - -const componentRecommendedCommandName = "component" - -var ( - componentExample = ktemplates.Examples(` # Describe a component - %[1]s nodejs`) - - componentLongDesc = ktemplates.LongDesc(`Describe a component type. -This describes the component and its associated starter projects. -`) -) - -// DescribeComponentOptions encapsulates the options for the odo catalog describe component command -type DescribeComponentOptions struct { - // Context - *genericclioptions.Context - - // Clients - clientset *clientset.Clientset - - // Parameters - componentName string - - // devfile components with name that matches componentName - devfileComponents []catalog.DevfileComponentType -} - -// NewDescribeComponentOptions creates a new DescribeComponentOptions instance -func NewDescribeComponentOptions() *DescribeComponentOptions { - return &DescribeComponentOptions{} -} - -func (o *DescribeComponentOptions) SetClientset(clientset *clientset.Clientset) { - o.clientset = clientset -} - -// Complete completes DescribeComponentOptions after they've been created -func (o *DescribeComponentOptions) Complete(cmdline cmdline.Cmdline, args []string) (err error) { - o.componentName = args[0] - - o.Context, err = genericclioptions.New(genericclioptions.NewCreateParameters(cmdline).IsOffline()) - if err != nil { - return err - } - - catalogDevfileList, err := o.clientset.CatalogClient.ListDevfileComponents("") - if catalogDevfileList.DevfileRegistries == nil { - log.Warning("Please run 'odo registry add ' to add registry for listing devfile components\n") - } - if err != nil { - return err - } - - o.devfileComponents = listDevfileComponentsByName(catalogDevfileList, o.componentName) - return nil -} - -// Validate validates the DescribeComponentOptions based on completed values -func (o *DescribeComponentOptions) Validate() (err error) { - if len(o.devfileComponents) == 0 { - return fmt.Errorf("No components with the name \"%s\" found", o.componentName) - } - - return nil -} - -// DevfileComponentDescription represents the JSON output of Devfile component description -// used in odo catalog describe component -o json -type DevfileComponentDescription struct { - RegistryName string `json:"RegistryName"` - Devfile data.DevfileData `json:"Devfile"` -} - -// Run contains the logic for the command associated with DescribeComponentOptions -func (o *DescribeComponentOptions) Run() (err error) { - w := tabwriter.NewWriter(os.Stdout, 5, 2, 3, ' ', tabwriter.TabIndent) - if log.IsJSON() { - if len(o.devfileComponents) > 0 { - out := []DevfileComponentDescription{} - - for _, devfileComponent := range o.devfileComponents { - devObj, err := GetDevfile(devfileComponent) - if err != nil { - return err - } - out = append(out, DevfileComponentDescription{RegistryName: devfileComponent.Registry.Name, Devfile: devObj.Data}) - } - machineoutput.OutputSuccess(out) - } - } else { - if len(o.devfileComponents) > 1 { - log.Warningf("There are multiple components named \"%s\" in different multiple devfile registries.\n", o.componentName) - } - if len(o.devfileComponents) > 0 { - fmt.Fprintln(w, "Devfile Component(s):") - - for _, devfileComponent := range o.devfileComponents { - fmt.Fprintln(w, "\n* Registry: "+devfileComponent.Registry.Name) - - devObj, err := GetDevfile(devfileComponent) - if err != nil { - return err - } - - projects, err := devObj.Data.GetStarterProjects(parsercommon.DevfileOptions{}) - if err != nil { - return err - } - // only print project info if there is at least one project in the devfile - err = o.PrintDevfileStarterProjects(w, projects, devObj) - if err != nil { - return err - } - } - } else { - fmt.Fprintln(w, "There are no Odo devfile components with the name \""+o.componentName+"\"") - } - } - - return nil -} - -// NewCmdCatalogDescribeComponent implements the odo catalog describe component command -func NewCmdCatalogDescribeComponent(name, fullName string) *cobra.Command { - o := NewDescribeComponentOptions() - command := &cobra.Command{ - Use: name, - Short: "Describe a component", - Long: componentLongDesc, - Example: fmt.Sprintf(componentExample, fullName), - Args: cobra.ExactArgs(1), - Annotations: map[string]string{"machineoutput": "json"}, - Run: func(cmd *cobra.Command, args []string) { - genericclioptions.GenericRun(o, cmd, args) - }, - } - clientset.Add(command, clientset.CATALOG) - return command -} - -// listDevfileComponentsByName lists all the devfile components that have the same name as the specified component -func listDevfileComponentsByName(catalogDevfileList catalog.DevfileComponentTypeList, componentName string) []catalog.DevfileComponentType { - var components []catalog.DevfileComponentType - for _, devfileComponent := range catalogDevfileList.Items { - if devfileComponent.Name == componentName { - components = append(components, devfileComponent) - } - } - return components -} - -// GetDevfile downloads the devfile in memory and return the devfile object -func GetDevfile(devfileComponent catalog.DevfileComponentType) (parser.DevfileObj, error) { - devObj, err := getDevFileNoValidation(devfileComponent) - if err != nil { - return devObj, err - } - - err = validate.ValidateDevfileData(devObj.Data) - if err != nil { - return devObj, err - } - return devObj, nil -} - -func getDevFileNoValidation(devfileComponent catalog.DevfileComponentType) (parser.DevfileObj, error) { - if strings.Contains(devfileComponent.Registry.URL, "github") { - devObj, err := devfile.ParseAndValidateFromURL(devfileComponent.Registry.URL + devfileComponent.Link) - if err != nil { - return devObj, fmt.Errorf("Failed to download devfile.yaml from Github-based registry for devfile component: %s: %w", devfileComponent.Name, err) - } - return devObj, nil - } - registryURL, err := url.Parse(devfileComponent.Registry.URL) - if err != nil { - return parser.DevfileObj{}, fmt.Errorf("Failed to parse registry URL for devfile component: %s: %w", devfileComponent.Name, err) - } - registryURL.Path = path.Join(registryURL.Path, "devfiles", devfileComponent.Name) - devObj, err := devfile.ParseAndValidateFromURL(registryURL.String()) - if err != nil { - return devObj, fmt.Errorf("Failed to download devfile.yaml from OCI-based registry for devfile component: %s: %w", devfileComponent.Name, err) - } - return devObj, nil -} - -// PrintDevfileStarterProjects prints all the starter projects in a devfile -// If no starter projects exists in the devfile, it prints the whole devfile -func (o *DescribeComponentOptions) PrintDevfileStarterProjects(w *tabwriter.Writer, projects []devfilev1.StarterProject, devObj parser.DevfileObj) error { - if len(projects) > 0 { - fmt.Fprintln(w, "\nStarter Projects:") - for _, project := range projects { - yamlData, err := yaml.Marshal(project) - if err != nil { - return fmt.Errorf("Failed to marshal devfile object into yaml: %w", err) - } - fmt.Printf("---\n%s", string(yamlData)) - } - } else { - fmt.Fprintln(w, "The Odo devfile component \""+o.componentName+"\" has no starter projects.") - yamlData, err := yaml.Marshal(devObj) - if err != nil { - return fmt.Errorf("Failed to marshal devfile object into yaml: %w", err) - } - fmt.Printf("---\n%s", string(yamlData)) - } - return nil -} diff --git a/pkg/odo/cli/catalog/describe/describe.go b/pkg/odo/cli/catalog/describe/describe.go deleted file mode 100644 index c0457bf46..000000000 --- a/pkg/odo/cli/catalog/describe/describe.go +++ /dev/null @@ -1,29 +0,0 @@ -package describe - -import ( - "fmt" - - "github.com/redhat-developer/odo/pkg/odo/util" - "github.com/spf13/cobra" -) - -// RecommendedCommandName is the recommended command name -const RecommendedCommandName = "describe" - -// NewCmdCatalogDescribe implements the odo catalog describe command -func NewCmdCatalogDescribe(name, fullName string) *cobra.Command { - component := NewCmdCatalogDescribeComponent(componentRecommendedCommandName, util.GetFullName(fullName, componentRecommendedCommandName)) - catalogDescribeCmd := &cobra.Command{ - Use: name, - Short: "Describe catalog item", - Long: "Describe the given catalog item from OpenShift", - Args: cobra.ExactArgs(1), - Example: fmt.Sprintf("%s\n", component.Example), - } - catalogDescribeCmd.AddCommand( - component, - ) - - return catalogDescribeCmd - -} diff --git a/pkg/odo/cli/catalog/list/components.go b/pkg/odo/cli/catalog/list/components.go deleted file mode 100644 index 6226fe76f..000000000 --- a/pkg/odo/cli/catalog/list/components.go +++ /dev/null @@ -1,125 +0,0 @@ -package list - -import ( - "fmt" - "io" - "os" - "text/tabwriter" - - "github.com/redhat-developer/odo/pkg/catalog" - "github.com/redhat-developer/odo/pkg/log" - "github.com/redhat-developer/odo/pkg/machineoutput" - "github.com/redhat-developer/odo/pkg/odo/cmdline" - "github.com/redhat-developer/odo/pkg/odo/genericclioptions" - "github.com/redhat-developer/odo/pkg/odo/genericclioptions/clientset" - "github.com/redhat-developer/odo/pkg/util" - - "github.com/spf13/cobra" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -const componentsRecommendedCommandName = "components" - -var componentsExample = ` # Get the supported components - %[1]s` - -// ListComponentsOptions encapsulates the options for the odo catalog list components command -type ListComponentsOptions struct { - // No context needed - - // Clients - clientset *clientset.Clientset - - // list of known devfiles - catalogDevfileList catalog.DevfileComponentTypeList -} - -// NewListComponentsOptions creates a new ListComponentsOptions instance -func NewListComponentsOptions() *ListComponentsOptions { - return &ListComponentsOptions{} -} - -func (o *ListComponentsOptions) SetClientset(clientset *clientset.Clientset) { - o.clientset = clientset -} - -// Complete completes ListComponentsOptions after they've been created -func (o *ListComponentsOptions) Complete(cmdline cmdline.Cmdline, args []string) (err error) { - o.catalogDevfileList, err = o.clientset.CatalogClient.ListDevfileComponents("") - if err != nil { - return err - } - - if o.catalogDevfileList.DevfileRegistries == nil { - log.Warning("Please run 'odo registry add ' to add registry for listing devfile components\n") - } - - return nil -} - -// Validate validates the ListComponentsOptions based on completed values -func (o *ListComponentsOptions) Validate() error { - if len(o.catalogDevfileList.Items) == 0 { - return fmt.Errorf("no deployable components found") - } - return nil -} - -type catalogList struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - Items []catalog.DevfileComponentType `json:"items,omitempty"` -} - -// Run contains the logic for the command associated with ListComponentsOptions -func (o *ListComponentsOptions) Run() (err error) { - if log.IsJSON() { - combinedList := catalogList{ - TypeMeta: metav1.TypeMeta{ - Kind: "List", - APIVersion: "odo.dev/v1alpha1", - }, - Items: o.catalogDevfileList.Items, - } - machineoutput.OutputSuccess(combinedList) - } else { - w := tabwriter.NewWriter(os.Stdout, 5, 2, 3, ' ', tabwriter.TabIndent) - if len(o.catalogDevfileList.Items) != 0 { - fmt.Fprintln(w, "Odo Devfile Components:") - fmt.Fprintln(w, "NAME", "\t", "DESCRIPTION", "\t", "REGISTRY") - - o.printDevfileCatalogList(w, o.catalogDevfileList.Items, "") - } - w.Flush() - } - return -} - -// NewCmdCatalogListComponents implements the odo catalog list components command -func NewCmdCatalogListComponents(name, fullName string) *cobra.Command { - o := NewListComponentsOptions() - - var componentListCmd = &cobra.Command{ - Use: name, - Short: "List all components", - Long: "List all available component types from OpenShift's Image Builder", - Example: fmt.Sprintf(componentsExample, fullName), - Annotations: map[string]string{"machineoutput": "json"}, - Run: func(cmd *cobra.Command, args []string) { - genericclioptions.GenericRun(o, cmd, args) - }, - } - clientset.Add(componentListCmd, clientset.CATALOG) - - return componentListCmd -} - -func (o *ListComponentsOptions) printDevfileCatalogList(w io.Writer, catalogDevfileList []catalog.DevfileComponentType, supported string) { - for _, devfileComponent := range catalogDevfileList { - if supported != "" { - fmt.Fprintln(w, devfileComponent.Name, "\t", util.TruncateString(devfileComponent.Description, 60, "..."), "\t", devfileComponent.Registry.Name, "\t", supported) - } else { - fmt.Fprintln(w, devfileComponent.Name, "\t", util.TruncateString(devfileComponent.Description, 60, "..."), "\t", devfileComponent.Registry.Name) - } - } -} diff --git a/pkg/odo/cli/catalog/list/list.go b/pkg/odo/cli/catalog/list/list.go deleted file mode 100644 index 56a9b729b..000000000 --- a/pkg/odo/cli/catalog/list/list.go +++ /dev/null @@ -1,29 +0,0 @@ -package list - -import ( - "fmt" - - "github.com/redhat-developer/odo/pkg/odo/util" - "github.com/spf13/cobra" -) - -// RecommendedCommandName is the recommended command name -const RecommendedCommandName = "list" - -// NewCmdCatalogList implements the odo catalog list command -func NewCmdCatalogList(name, fullName string) *cobra.Command { - components := NewCmdCatalogListComponents(componentsRecommendedCommandName, util.GetFullName(fullName, componentsRecommendedCommandName)) - - catalogListCmd := &cobra.Command{ - Use: name, - Short: "List all available component types.", - Long: "List all available component types from OpenShift", - Example: fmt.Sprintf("%s\n", components.Example), - } - - catalogListCmd.AddCommand( - components, - ) - - return catalogListCmd -} diff --git a/pkg/odo/cli/catalog/search/component.go b/pkg/odo/cli/catalog/search/component.go deleted file mode 100644 index a2423db9c..000000000 --- a/pkg/odo/cli/catalog/search/component.go +++ /dev/null @@ -1,95 +0,0 @@ -package search - -import ( - "fmt" - "os" - "text/tabwriter" - - "github.com/redhat-developer/odo/pkg/odo/cmdline" - "github.com/redhat-developer/odo/pkg/odo/genericclioptions" - "github.com/redhat-developer/odo/pkg/odo/genericclioptions/clientset" - - "github.com/spf13/cobra" -) - -const componentRecommendedCommandName = "component" - -var componentExample = ` # Search for a component - %[1]s python` - -// SearchComponentOptions encapsulates the options for the odo catalog describe service command -type SearchComponentOptions struct { - // Context - *genericclioptions.Context - - // Clients - clientset *clientset.Clientset - - // Parameters - searchTerm string - - // components matching the search query - components []string -} - -// NewSearchComponentOptions creates a new SearchComponentOptions instance -func NewSearchComponentOptions() *SearchComponentOptions { - return &SearchComponentOptions{} -} - -func (o *SearchComponentOptions) SetClientset(clientset *clientset.Clientset) { - o.clientset = clientset -} - -// Complete completes SearchComponentOptions after they've been created -func (o *SearchComponentOptions) Complete(cmdline cmdline.Cmdline, args []string) (err error) { - o.Context, err = genericclioptions.New(genericclioptions.NewCreateParameters(cmdline)) - if err != nil { - return err - } - o.searchTerm = args[0] - - o.components, err = o.clientset.CatalogClient.SearchComponent(o.KClient, o.searchTerm) - return err -} - -// Validate validates the SearchComponentOptions based on completed values -func (o *SearchComponentOptions) Validate() error { - if len(o.components) == 0 { - return fmt.Errorf("no component matched the query: %s", o.searchTerm) - } - - return nil -} - -// Run contains the logic for the command associated with SearchComponentOptions -func (o *SearchComponentOptions) Run() error { - w := tabwriter.NewWriter(os.Stdout, 5, 2, 3, ' ', tabwriter.TabIndent) - fmt.Fprintln(w, "NAME") - for _, component := range o.components { - fmt.Fprintln(w, component) - } - w.Flush() - return nil -} - -// NewCmdCatalogSearchComponent implements the odo catalog search component command -func NewCmdCatalogSearchComponent(name, fullName string) *cobra.Command { - o := NewSearchComponentOptions() - command := &cobra.Command{ - Use: name, - Short: "Search component type in catalog", - Long: `Search component type in catalog. - -This searches for a partial match for the given search term in all the available -components. -`, - Args: cobra.ExactArgs(1), - Example: fmt.Sprintf(componentExample, fullName), - Run: func(cmd *cobra.Command, args []string) { - genericclioptions.GenericRun(o, cmd, args) - }, - } - clientset.Add(command, clientset.CATALOG) - return command -} diff --git a/pkg/odo/cli/catalog/search/search.go b/pkg/odo/cli/catalog/search/search.go deleted file mode 100644 index 0e2464697..000000000 --- a/pkg/odo/cli/catalog/search/search.go +++ /dev/null @@ -1,29 +0,0 @@ -package search - -import ( - "fmt" - - "github.com/redhat-developer/odo/pkg/odo/util" - "github.com/spf13/cobra" -) - -// RecommendedCommandName is the recommended command name -const RecommendedCommandName = "search" - -// NewCmdCatalogSearch implements the odo catalog search command -func NewCmdCatalogSearch(name, fullName string) *cobra.Command { - component := NewCmdCatalogSearchComponent(componentRecommendedCommandName, util.GetFullName(fullName, componentRecommendedCommandName)) - catalogSearchCmd := &cobra.Command{ - Use: name, - Short: "Search available component & service types.", - Long: `Search available component & service types.. - -This searches for a partial match for the given search term in all the available -components & services. -`, - Example: fmt.Sprintf("%s\n", component.Example), - } - catalogSearchCmd.AddCommand(component) - - return catalogSearchCmd -} diff --git a/pkg/odo/cli/cli.go b/pkg/odo/cli/cli.go index 7defc0854..23f8a09c1 100644 --- a/pkg/odo/cli/cli.go +++ b/pkg/odo/cli/cli.go @@ -3,16 +3,15 @@ package cli import ( "flag" "fmt" - "github.com/redhat-developer/odo/pkg/odo/cli/dev" "os" "strings" "unicode" "github.com/redhat-developer/odo/pkg/odo/cli/build_images" - "github.com/redhat-developer/odo/pkg/odo/cli/catalog" "github.com/redhat-developer/odo/pkg/odo/cli/component" _delete "github.com/redhat-developer/odo/pkg/odo/cli/delete" "github.com/redhat-developer/odo/pkg/odo/cli/deploy" + "github.com/redhat-developer/odo/pkg/odo/cli/dev" _init "github.com/redhat-developer/odo/pkg/odo/cli/init" "github.com/redhat-developer/odo/pkg/odo/cli/login" "github.com/redhat-developer/odo/pkg/odo/cli/logout" @@ -178,7 +177,6 @@ func odoRootCmd(name, fullName string) *cobra.Command { cobra.AddTemplateFunc("ModifyAdditionalFlags", modifyAdditionalFlags) rootCmdList := append([]*cobra.Command{}, - catalog.NewCmdCatalog(catalog.RecommendedCommandName, util.GetFullName(fullName, catalog.RecommendedCommandName)), component.NewCmdComponent(component.RecommendedCommandName, util.GetFullName(fullName, component.RecommendedCommandName)), component.NewCmdCreate(component.CreateRecommendedCommandName, util.GetFullName(fullName, component.CreateRecommendedCommandName)), component.NewCmdList(component.ListRecommendedCommandName, util.GetFullName(fullName, component.ListRecommendedCommandName)), diff --git a/pkg/odo/cli/component/create.go b/pkg/odo/cli/component/create.go index beda5705e..84c2038e5 100644 --- a/pkg/odo/cli/component/create.go +++ b/pkg/odo/cli/component/create.go @@ -10,7 +10,6 @@ import ( "github.com/spf13/cobra" "github.com/zalando/go-keyring" - "github.com/redhat-developer/odo/pkg/catalog" odoDevfile "github.com/redhat-developer/odo/pkg/devfile" "github.com/redhat-developer/odo/pkg/devfile/location" "github.com/redhat-developer/odo/pkg/envinfo" @@ -22,6 +21,7 @@ import ( "github.com/redhat-developer/odo/pkg/odo/genericclioptions/clientset" odoutil "github.com/redhat-developer/odo/pkg/odo/util" "github.com/redhat-developer/odo/pkg/odo/util/completion" + "github.com/redhat-developer/odo/pkg/registry" scontext "github.com/redhat-developer/odo/pkg/segment/context" "github.com/redhat-developer/odo/pkg/util" @@ -66,7 +66,7 @@ type DevfileMetadata struct { componentName string componentNamespace string devfileLink string - devfileRegistry catalog.Registry + devfileRegistry registry.Registry devfilePath devfilePath userCreatedDevfile bool starter string diff --git a/pkg/odo/cli/component/create_methods.go b/pkg/odo/cli/component/create_methods.go index 53706103b..aafa5c637 100644 --- a/pkg/odo/cli/component/create_methods.go +++ b/pkg/odo/cli/component/create_methods.go @@ -9,7 +9,6 @@ import ( "github.com/zalando/go-keyring" - "github.com/redhat-developer/odo/pkg/catalog" "github.com/redhat-developer/odo/pkg/component" "github.com/redhat-developer/odo/pkg/kclient" "github.com/redhat-developer/odo/pkg/log" @@ -18,6 +17,7 @@ import ( "github.com/redhat-developer/odo/pkg/odo/cmdline" odoutil "github.com/redhat-developer/odo/pkg/odo/util" "github.com/redhat-developer/odo/pkg/preference" + "github.com/redhat-developer/odo/pkg/registry" "github.com/redhat-developer/odo/pkg/segment" "github.com/redhat-developer/odo/pkg/testingutil/filesystem" "github.com/redhat-developer/odo/pkg/util" @@ -262,47 +262,47 @@ func conflictCheckForDevfileFlag(args []string, registryName string) error { // validateAndFetchRegistry validates if the provided registryName exists and returns the devfile listed in the registy; // if the registryName is "", then it returns devfiles of all the available registries -func validateAndFetchRegistry(registryName string) (catalog.DevfileComponentTypeList, error) { +func validateAndFetchRegistry(registryName string) (registry.DevfileStackList, error) { // TODO(feloy) Get from DI prefClient, err := preference.NewClient() if err != nil { odoutil.LogErrorAndExit(err, "unable to set preference, something is wrong with odo, kindly raise an issue at https://github.com/redhat-developer/odo/issues/new?template=Bug.md") } - catalogClient := catalog.NewCatalogClient(filesystem.DefaultFs{}, prefClient) + registryClient := registry.NewRegistryClient(filesystem.DefaultFs{}, prefClient) // Validate if the component type is available if registryName != "" { registryExistSpinner := log.Spinnerf("Checking if the registry %q exists", registryName) defer registryExistSpinner.End(false) - registryList, e := catalogClient.GetDevfileRegistries(registryName) + registryList, e := registryClient.GetDevfileRegistries(registryName) if e != nil { - return catalog.DevfileComponentTypeList{}, fmt.Errorf("failed to get registry: %w", e) + return registry.DevfileStackList{}, fmt.Errorf("failed to get registry: %w", e) } if len(registryList) == 0 { - return catalog.DevfileComponentTypeList{}, fmt.Errorf("registry %s doesn't exist, please specify a valid registry via --registry", registryName) + return registry.DevfileStackList{}, fmt.Errorf("registry %s doesn't exist, please specify a valid registry via --registry", registryName) } registryExistSpinner.End(true) } klog.V(4).Infof("Fetching the available devfile components") // Get available devfile components for checking devfile compatibility - catalogDevfileList, err := catalogClient.ListDevfileComponents(registryName) + catalogDevfileList, err := registryClient.ListDevfileStacks(registryName) if err != nil { - return catalog.DevfileComponentTypeList{}, err + return registry.DevfileStackList{}, err } if registryName != "" && catalogDevfileList.Items == nil { - return catalog.DevfileComponentTypeList{}, fmt.Errorf("can't create devfile component from registry %s", registryName) + return registry.DevfileStackList{}, fmt.Errorf("can't create devfile component from registry %s", registryName) } if len(catalogDevfileList.DevfileRegistries) == 0 { - return catalog.DevfileComponentTypeList{}, errors.New("Registry is empty, please run `odo registry add ` to add a registry\n") + return registry.DevfileStackList{}, errors.New("Registry is empty, please run `odo registry add ` to add a registry\n") } return catalogDevfileList, nil } // findDevfileFromRegistry finds the devfile and returns necessary information related to it -func findDevfileFromRegistry(catalogDevfileList catalog.DevfileComponentTypeList, registryName, componentType string) (devfileLink string, devfileRegistry catalog.Registry, err error) { +func findDevfileFromRegistry(catalogDevfileList registry.DevfileStackList, registryName, componentType string) (devfileLink string, devfileRegistry registry.Registry, err error) { devfileExistSpinner := log.Spinnerf("Checking if the devfile for %q exists on available registries", componentType) defer devfileExistSpinner.End(false) if registryName != "" { @@ -316,11 +316,11 @@ func findDevfileFromRegistry(catalogDevfileList catalog.DevfileComponentTypeList return devfileComponent.Link, devfileComponent.Registry, nil } } - return "", catalog.Registry{}, fmt.Errorf("devfile component type %q is not supported, please run `odo catalog list components` for a list of supported devfile component types", componentType) + return "", registry.Registry{}, fmt.Errorf("devfile component type %q is not supported, please run `odo catalog list components` for a list of supported devfile component types", componentType) } // fetchDevfileFromRegistry fetches the required devfile from the list catalogDevfileList -func fetchDevfileFromRegistry(registry catalog.Registry, devfileLink, devfilePath, componentType, componentContext string, prefClient preference.Client) (err error) { +func fetchDevfileFromRegistry(registry registry.Registry, devfileLink, devfilePath, componentType, componentContext string, prefClient preference.Client) (err error) { // Download devfile from registry registrySpinner := log.Spinnerf("Creating a devfile component from registry %q", registry.Name) defer registrySpinner.End(false) diff --git a/pkg/odo/cli/component/list.go b/pkg/odo/cli/component/list.go index 60077ec39..b113330dc 100644 --- a/pkg/odo/cli/component/list.go +++ b/pkg/odo/cli/component/list.go @@ -135,7 +135,7 @@ func (lo *ListOptions) Run() error { if len(lo.pathFlag) != 0 { - devfileComps, err := component.ListDevfileComponentsInPath(lo.KClient, filepath.SplitList(lo.pathFlag)) + devfileComps, err := component.ListDevfileStacksInPath(lo.KClient, filepath.SplitList(lo.pathFlag)) if err != nil { return err } @@ -173,7 +173,7 @@ func (lo *ListOptions) Run() error { currentComponentState := component.StateTypeNotPushed if lo.KClient != nil { - devfileComponentsOut, err := component.ListDevfileComponents(lo.KClient, selector) + devfileComponentsOut, err := component.ListDevfileStacks(lo.KClient, selector) if err != nil { return err } diff --git a/pkg/odo/cli/component/ui/ui.go b/pkg/odo/cli/component/ui/ui.go index 673325f31..7ca0a8056 100644 --- a/pkg/odo/cli/component/ui/ui.go +++ b/pkg/odo/cli/component/ui/ui.go @@ -4,9 +4,10 @@ import ( "sort" devfilev1 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2" - "github.com/redhat-developer/odo/pkg/catalog" "github.com/redhat-developer/odo/pkg/odo/cli/ui" "github.com/redhat-developer/odo/pkg/odo/util/validation" + "github.com/redhat-developer/odo/pkg/registry" + "gopkg.in/AlecAivazis/survey.v1" ) @@ -47,7 +48,7 @@ func SelectStarterProject(projects []devfilev1.StarterProject) string { } // SelectDevfileComponentType lets the user to select the devfile component type in the prompt -func SelectDevfileComponentType(options []catalog.DevfileComponentType) string { +func SelectDevfileComponentType(options []registry.DevfileStack) string { var componentType string prompt := &survey.Select{ Message: "Which devfile component type do you wish to create", @@ -82,7 +83,7 @@ func EnterDevfileComponentProject(defaultComponentNamespace string) string { return name } -func getDevfileComponentTypeNameCandidates(options []catalog.DevfileComponentType) []string { +func getDevfileComponentTypeNameCandidates(options []registry.DevfileStack) []string { result := make([]string, len(options)) for i, option := range options { result[i] = option.Name diff --git a/pkg/odo/genericclioptions/clientset/clientset.go b/pkg/odo/genericclioptions/clientset/clientset.go index af8ecbdc0..92704098d 100644 --- a/pkg/odo/genericclioptions/clientset/clientset.go +++ b/pkg/odo/genericclioptions/clientset/clientset.go @@ -15,21 +15,18 @@ import ( "github.com/redhat-developer/odo/pkg/dev" "github.com/spf13/cobra" - "github.com/redhat-developer/odo/pkg/catalog" _delete "github.com/redhat-developer/odo/pkg/component/delete" "github.com/redhat-developer/odo/pkg/deploy" _init "github.com/redhat-developer/odo/pkg/init" - "github.com/redhat-developer/odo/pkg/init/registry" "github.com/redhat-developer/odo/pkg/kclient" "github.com/redhat-developer/odo/pkg/preference" "github.com/redhat-developer/odo/pkg/project" + "github.com/redhat-developer/odo/pkg/registry" "github.com/redhat-developer/odo/pkg/testingutil/filesystem" "github.com/redhat-developer/odo/pkg/watch" ) const ( - // CATALOG instantiates client for pkg/catalog - CATALOG = "DEP_CATALOG" // DELETE_COMPONENT instantiates client for pkg/component/delete DELETE_COMPONENT = "DEP_DELETE_COMPONENT" // DEPLOY instantiates client for pkg/deploy @@ -48,7 +45,7 @@ const ( PREFERENCE = "DEP_PREFERENCE" // PROJECT instantiates client for pkg/project PROJECT = "DEP_PROJECT" - // REGISTRY instantiates client for pkg/init/registry + // REGISTRY instantiates client for pkg/registry REGISTRY = "DEP_REGISTRY" // WATCH instantiates client for pkg/watch WATCH = "DEP_WATCH" @@ -59,17 +56,15 @@ const ( // subdeps defines the sub-dependencies // Clients will be created only once and be reused for sub-dependencies var subdeps map[string][]string = map[string][]string{ - CATALOG: {FILESYSTEM, PREFERENCE}, DELETE_COMPONENT: {KUBERNETES}, DEPLOY: {KUBERNETES}, DEV: {WATCH}, - INIT: {FILESYSTEM, PREFERENCE, REGISTRY, CATALOG}, + INIT: {FILESYSTEM, PREFERENCE, REGISTRY}, PROJECT: {KUBERNETES_NULLABLE}, /* Add sub-dependencies here, if any */ } type Clientset struct { - CatalogClient catalog.Client DeleteClient _delete.Client DeployClient deploy.Client DevClient dev.Client @@ -123,16 +118,13 @@ func Fetch(command *cobra.Command) (*Clientset, error) { } } if isDefined(command, REGISTRY) { - dep.RegistryClient = registry.NewRegistryClient() + dep.RegistryClient = registry.NewRegistryClient(dep.FS, dep.PreferenceClient) } if isDefined(command, WATCH) { dep.WatchClient = watch.NewWatchClient() } /* With sub-dependencies */ - if isDefined(command, CATALOG) { - dep.CatalogClient = catalog.NewCatalogClient(dep.FS, dep.PreferenceClient) - } if isDefined(command, DELETE_COMPONENT) { dep.DeleteClient = _delete.NewDeleteComponentClient(dep.KubernetesClient) } @@ -140,7 +132,7 @@ func Fetch(command *cobra.Command) (*Clientset, error) { dep.DeployClient = deploy.NewDeployClient(dep.KubernetesClient) } if isDefined(command, INIT) { - dep.InitClient = _init.NewInitClient(dep.FS, dep.PreferenceClient, dep.RegistryClient, dep.CatalogClient) + dep.InitClient = _init.NewInitClient(dep.FS, dep.PreferenceClient, dep.RegistryClient) } if isDefined(command, PROJECT) { dep.ProjectClient = project.NewClient(dep.KubernetesClient) diff --git a/pkg/odo/util/completion/completionhandlers.go b/pkg/odo/util/completion/completionhandlers.go index 48bb0def5..c37b2e324 100644 --- a/pkg/odo/util/completion/completionhandlers.go +++ b/pkg/odo/util/completion/completionhandlers.go @@ -2,14 +2,14 @@ package completion import ( applabels "github.com/redhat-developer/odo/pkg/application/labels" - "github.com/redhat-developer/odo/pkg/preference" - "github.com/redhat-developer/odo/pkg/testingutil/filesystem" - - "github.com/posener/complete" - "github.com/redhat-developer/odo/pkg/catalog" "github.com/redhat-developer/odo/pkg/component" "github.com/redhat-developer/odo/pkg/odo/genericclioptions" odoutil "github.com/redhat-developer/odo/pkg/odo/util" + "github.com/redhat-developer/odo/pkg/preference" + "github.com/redhat-developer/odo/pkg/registry" + "github.com/redhat-developer/odo/pkg/testingutil/filesystem" + + "github.com/posener/complete" "github.com/spf13/cobra" ) @@ -52,7 +52,7 @@ var CreateCompletionHandler = func(cmd *cobra.Command, args parsedArgs, context if err != nil { odoutil.LogErrorAndExit(err, "unable to set preference, something is wrong with odo, kindly raise an issue at https://github.com/redhat-developer/odo/issues/new?template=Bug.md") } - components, _ := catalog.NewCatalogClient(filesystem.DefaultFs{}, prefClient).ListDevfileComponents("") + components, _ := registry.NewRegistryClient(filesystem.DefaultFs{}, prefClient).ListDevfileStacks("") for _, devfile := range components.Items { if args.commands[devfile.Name] { return nil diff --git a/pkg/catalog/devfile_component_type_list.go b/pkg/registry/devfile_component_type_list.go similarity index 77% rename from pkg/catalog/devfile_component_type_list.go rename to pkg/registry/devfile_component_type_list.go index a348a6e2c..0b1bcdfae 100644 --- a/pkg/catalog/devfile_component_type_list.go +++ b/pkg/registry/devfile_component_type_list.go @@ -1,10 +1,10 @@ -package catalog +package registry import "sort" // GetLanguages returns the list of unique languages, ordered by name, // from a list of registry items -func (o *DevfileComponentTypeList) GetLanguages() []string { +func (o *DevfileStackList) GetLanguages() []string { languagesMap := map[string]bool{} for _, item := range o.Items { languagesMap[item.Language] = true @@ -20,14 +20,14 @@ func (o *DevfileComponentTypeList) GetLanguages() []string { // GetProjectTypes returns the list of project types and associated details // from a list of registry items -func (o *DevfileComponentTypeList) GetProjectTypes(language string) TypesWithDetails { +func (o *DevfileStackList) GetProjectTypes(language string) TypesWithDetails { types := TypesWithDetails{} for _, item := range o.Items { if item.Language != language { continue } if _, found := types[item.DisplayName]; !found { - types[item.DisplayName] = []DevfileComponentType{} + types[item.DisplayName] = []DevfileStack{} } types[item.DisplayName] = append(types[item.DisplayName], item) } diff --git a/pkg/catalog/devfile_component_type_list_test.go b/pkg/registry/devfile_component_type_list_test.go similarity index 83% rename from pkg/catalog/devfile_component_type_list_test.go rename to pkg/registry/devfile_component_type_list_test.go index 414da3b26..ab9e7ca23 100644 --- a/pkg/catalog/devfile_component_type_list_test.go +++ b/pkg/registry/devfile_component_type_list_test.go @@ -1,13 +1,13 @@ -package catalog +package registry import ( "reflect" "testing" ) -func TestDevfileComponentTypeList_GetLanguages(t *testing.T) { +func TestDevfileStackList_GetLanguages(t *testing.T) { type fields struct { - Items []DevfileComponentType + Items []DevfileStack } tests := []struct { name string @@ -21,7 +21,7 @@ func TestDevfileComponentTypeList_GetLanguages(t *testing.T) { { name: "some devfiles", fields: fields{ - Items: []DevfileComponentType{ + Items: []DevfileStack{ { Name: "devfile4", DisplayName: "first devfile for lang3", @@ -61,19 +61,19 @@ func TestDevfileComponentTypeList_GetLanguages(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - o := &DevfileComponentTypeList{ + o := &DevfileStackList{ Items: tt.fields.Items, } if got := o.GetLanguages(); !reflect.DeepEqual(got, tt.want) { - t.Errorf("DevfileComponentTypeList.GetLanguages() = %v, want %v", got, tt.want) + t.Errorf("DevfileStackList.GetLanguages() = %v, want %v", got, tt.want) } }) } } -func TestDevfileComponentTypeList_GetProjectTypes(t *testing.T) { +func TestDevfileStackList_GetProjectTypes(t *testing.T) { type fields struct { - Items []DevfileComponentType + Items []DevfileStack } type args struct { language string @@ -91,7 +91,7 @@ func TestDevfileComponentTypeList_GetProjectTypes(t *testing.T) { { name: "project types for lang1", fields: fields{ - Items: []DevfileComponentType{ + Items: []DevfileStack{ { Name: "devfile4", DisplayName: "first devfile for lang3", @@ -138,7 +138,7 @@ func TestDevfileComponentTypeList_GetProjectTypes(t *testing.T) { language: "lang1", }, want: TypesWithDetails{ - "first devfile for lang1": []DevfileComponentType{ + "first devfile for lang1": []DevfileStack{ { Name: "devfile1", DisplayName: "first devfile for lang1", @@ -156,7 +156,7 @@ func TestDevfileComponentTypeList_GetProjectTypes(t *testing.T) { }, }, }, - "second devfile for lang1": []DevfileComponentType{ + "second devfile for lang1": []DevfileStack{ { Name: "devfile2", DisplayName: "second devfile for lang1", @@ -171,11 +171,11 @@ func TestDevfileComponentTypeList_GetProjectTypes(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - o := &DevfileComponentTypeList{ + o := &DevfileStackList{ Items: tt.fields.Items, } if got := o.GetProjectTypes(tt.args.language); !reflect.DeepEqual(got, tt.want) { - t.Errorf("DevfileComponentTypeList.GetProjectTypes() = \n%+v, want \n%+v", got, tt.want) + t.Errorf("DevfileStackList.GetProjectTypes() = \n%+v, want \n%+v", got, tt.want) } }) } diff --git a/pkg/init/registry/interface.go b/pkg/registry/interface.go similarity index 83% rename from pkg/init/registry/interface.go rename to pkg/registry/interface.go index ea015dfcf..6f3396bc2 100644 --- a/pkg/init/registry/interface.go +++ b/pkg/registry/interface.go @@ -11,4 +11,6 @@ type Client interface { PullStackFromRegistry(registry string, stack string, destDir string, options library.RegistryOptions) error DownloadFileInMemory(params dfutil.HTTPRequestParams) ([]byte, error) DownloadStarterProject(starterProject *devfilev1.StarterProject, decryptedToken string, contextDir string, verbose bool) error + GetDevfileRegistries(registryName string) ([]Registry, error) + ListDevfileStacks(registryName string) (DevfileStackList, error) } diff --git a/pkg/init/registry/mock.go b/pkg/registry/mock.go similarity index 70% rename from pkg/init/registry/mock.go rename to pkg/registry/mock.go index 5c281afba..931785ae1 100644 --- a/pkg/init/registry/mock.go +++ b/pkg/registry/mock.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: pkg/init/registry/interface.go +// Source: pkg/registry/interface.go // Package registry is a generated GoMock package. package registry @@ -65,6 +65,36 @@ func (mr *MockClientMockRecorder) DownloadStarterProject(starterProject, decrypt return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadStarterProject", reflect.TypeOf((*MockClient)(nil).DownloadStarterProject), starterProject, decryptedToken, contextDir, verbose) } +// GetDevfileRegistries mocks base method. +func (m *MockClient) GetDevfileRegistries(registryName string) ([]Registry, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetDevfileRegistries", registryName) + ret0, _ := ret[0].([]Registry) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetDevfileRegistries indicates an expected call of GetDevfileRegistries. +func (mr *MockClientMockRecorder) GetDevfileRegistries(registryName interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDevfileRegistries", reflect.TypeOf((*MockClient)(nil).GetDevfileRegistries), registryName) +} + +// ListDevfileStacks mocks base method. +func (m *MockClient) ListDevfileStacks(registryName string) (DevfileStackList, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListDevfileStacks", registryName) + ret0, _ := ret[0].(DevfileStackList) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListDevfileStacks indicates an expected call of ListDevfileStacks. +func (mr *MockClientMockRecorder) ListDevfileStacks(registryName interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDevfileStacks", reflect.TypeOf((*MockClient)(nil).ListDevfileStacks), registryName) +} + // PullStackFromRegistry mocks base method. func (m *MockClient) PullStackFromRegistry(registry, stack, destDir string, options library.RegistryOptions) error { m.ctrl.T.Helper() diff --git a/pkg/catalog/catalog.go b/pkg/registry/registry.go similarity index 76% rename from pkg/catalog/catalog.go rename to pkg/registry/registry.go index b303c296a..36a7a53fa 100644 --- a/pkg/catalog/catalog.go +++ b/pkg/registry/registry.go @@ -1,4 +1,4 @@ -package catalog +package registry import ( "encoding/json" @@ -7,36 +7,52 @@ import ( "strings" "sync" - "github.com/zalando/go-keyring" - + devfilev1 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2" dfutil "github.com/devfile/library/pkg/util" indexSchema "github.com/devfile/registry-support/index/generator/schema" - registryLibrary "github.com/devfile/registry-support/registry-library/library" - - "github.com/redhat-developer/odo/pkg/kclient" - "github.com/redhat-developer/odo/pkg/log" + "github.com/devfile/registry-support/registry-library/library" registryUtil "github.com/redhat-developer/odo/pkg/odo/cli/preference/registry/util" + "github.com/zalando/go-keyring" + + "github.com/redhat-developer/odo/pkg/component" + "github.com/redhat-developer/odo/pkg/log" "github.com/redhat-developer/odo/pkg/preference" "github.com/redhat-developer/odo/pkg/segment" "github.com/redhat-developer/odo/pkg/testingutil/filesystem" "github.com/redhat-developer/odo/pkg/util" ) -type CatalogClient struct { +type RegistryClient struct { fsys filesystem.Filesystem preferenceClient preference.Client } -func NewCatalogClient(fsys filesystem.Filesystem, preferenceClient preference.Client) *CatalogClient { - return &CatalogClient{ +func NewRegistryClient(fsys filesystem.Filesystem, preferenceClient preference.Client) RegistryClient { + return RegistryClient{ fsys: fsys, preferenceClient: preferenceClient, } } +// PullStackFromRegistry pulls stack from registry with all stack resources (all media types) to the destination directory +func (o RegistryClient) PullStackFromRegistry(registry string, stack string, destDir string, options library.RegistryOptions) error { + return library.PullStackFromRegistry(registry, stack, destDir, options) +} + +// DownloadFileInMemory uses the url to download the file and return bytes +func (o RegistryClient) DownloadFileInMemory(params dfutil.HTTPRequestParams) ([]byte, error) { + return util.DownloadFileInMemory(params) +} + +// DownloadStarterProject downloads a starter project referenced in devfile +// This will first remove the content of the contextDir +func (o RegistryClient) DownloadStarterProject(starterProject *devfilev1.StarterProject, decryptedToken string, contextDir string, verbose bool) error { + return component.DownloadStarterProject(starterProject, decryptedToken, contextDir, verbose) +} + // GetDevfileRegistries gets devfile registries from preference file, // if registry name is specified return the specific registry, otherwise return all registries -func (o *CatalogClient) GetDevfileRegistries(registryName string) ([]Registry, error) { +func (o RegistryClient) GetDevfileRegistries(registryName string) ([]Registry, error) { var devfileRegistries []Registry hasName := len(registryName) != 0 @@ -71,9 +87,9 @@ func (o *CatalogClient) GetDevfileRegistries(registryName string) ([]Registry, e return devfileRegistries, nil } -// ListDevfileComponents lists all the available devfile components -func (o *CatalogClient) ListDevfileComponents(registryName string) (DevfileComponentTypeList, error) { - catalogDevfileList := &DevfileComponentTypeList{} +// ListDevfileStacks lists all the available devfile stacks in devfile registry +func (o RegistryClient) ListDevfileStacks(registryName string) (DevfileStackList, error) { + catalogDevfileList := &DevfileStackList{} var err error // TODO: consider caching registry information for better performance since it should be fairly stable over time @@ -92,13 +108,13 @@ func (o *CatalogClient) ListDevfileComponents(registryName string) (DevfileCompo // The 2D slice index is the priority of the registry (highest priority has highest index) // and the element is the devfile slice that belongs to the registry - registrySlice := make([][]DevfileComponentType, len(catalogDevfileList.DevfileRegistries)) + registrySlice := make([][]DevfileStack, len(catalogDevfileList.DevfileRegistries)) for regPriority, reg := range catalogDevfileList.DevfileRegistries { // Load the devfile registry index.json registry := reg // Needed to prevent the lambda from capturing the value registryPriority := regPriority // Needed to prevent the lambda from capturing the value retrieveRegistryIndices.Add(util.ConcurrentTask{ToRun: func(errChannel chan error) { - registryDevfiles, err := getRegistryDevfiles(o.preferenceClient, registry) + registryDevfiles, err := getRegistryStacks(o.preferenceClient, registry) if err != nil { log.Warningf("Registry %s is not set up properly with error: %v, please check the registry URL and credential (refer `odo registry update --help`)\n", registry.Name, err) return @@ -120,27 +136,6 @@ func (o *CatalogClient) ListDevfileComponents(registryName string) (DevfileCompo return *catalogDevfileList, nil } -// SearchComponent searches for the component -//TODO: Fix this to return devfile components -func (o *CatalogClient) SearchComponent(client kclient.ClientInterface, name string) ([]string, error) { - //var result []string - //componentList, err := ListDevfileComponents(client) - //if err != nil { - // return nil, fmt.Errorf("unable to list components: %w", err) - //} - // - //// do a partial search in all the components - //for _, component := range componentList.Items { - // // we only show components that contain the search term and that have at least non-hidden tag - // // since a component with all hidden tags is not shown in the odo catalog list components either - // if strings.Contains(component.ObjectMeta.Name, name) && len(component.Spec.NonHiddenTags) > 0 { - // result = append(result, component.ObjectMeta.Name) - // } - //} - - return []string{}, nil -} - // convertURL converts GitHub regular URL to GitHub raw URL, do nothing if the URL is not GitHub URL // For example: // GitHub regular URL: https://github.com/elsony/devfile-registry/tree/johnmcollier-crw @@ -175,11 +170,11 @@ func convertURL(URL string) (string, error) { const indexPath = "/devfiles/index.json" -// getRegistryDevfiles retrieves the registry's index devfile entries -func getRegistryDevfiles(preferenceClient preference.Client, registry Registry) ([]DevfileComponentType, error) { +// getRegistryStacks retrieves the registry's index devfile stack entries +func getRegistryStacks(preferenceClient preference.Client, registry Registry) ([]DevfileStack, error) { if !strings.Contains(registry.URL, "github") { // OCI-based registry - devfileIndex, err := registryLibrary.GetRegistryIndex(registry.URL, segment.GetRegistryOptions(), indexSchema.StackDevfileType) + devfileIndex, err := library.GetRegistryIndex(registry.URL, segment.GetRegistryOptions(), indexSchema.StackDevfileType) if err != nil { return nil, err } @@ -230,10 +225,10 @@ func getRegistryDevfiles(preferenceClient preference.Client, registry Registry) return createRegistryDevfiles(registry, devfileIndex) } -func createRegistryDevfiles(registry Registry, devfileIndex []indexSchema.Schema) ([]DevfileComponentType, error) { - registryDevfiles := make([]DevfileComponentType, 0, len(devfileIndex)) +func createRegistryDevfiles(registry Registry, devfileIndex []indexSchema.Schema) ([]DevfileStack, error) { + registryDevfiles := make([]DevfileStack, 0, len(devfileIndex)) for _, devfileIndexEntry := range devfileIndex { - stackDevfile := DevfileComponentType{ + stackDevfile := DevfileStack{ Name: devfileIndexEntry.Name, DisplayName: devfileIndexEntry.DisplayName, Description: devfileIndexEntry.Description, diff --git a/pkg/catalog/catalog_test.go b/pkg/registry/registry_test.go similarity index 95% rename from pkg/catalog/catalog_test.go rename to pkg/registry/registry_test.go index 058b508e4..af248eb95 100644 --- a/pkg/catalog/catalog_test.go +++ b/pkg/registry/registry_test.go @@ -1,4 +1,4 @@ -package catalog +package registry import ( "io/ioutil" @@ -74,7 +74,7 @@ OdoSettings: for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { prefClient, _ := preference.NewClient() - catClient := NewCatalogClient(filesystem.NewFakeFs(), prefClient) + catClient := NewRegistryClient(filesystem.NewFakeFs(), prefClient) got, err := catClient.GetDevfileRegistries(tt.registryName) if err != nil { t.Errorf("Error message is %v", err) @@ -124,12 +124,12 @@ func TestGetRegistryDevfiles(t *testing.T) { tests := []struct { name string registry Registry - want []DevfileComponentType + want []DevfileStack }{ { name: "Test NodeJS devfile index", registry: Registry{Name: registryName, URL: server.URL}, - want: []DevfileComponentType{ + want: []DevfileStack{ { Name: "nodejs", DisplayName: "NodeJS Angular Web Application", @@ -150,7 +150,7 @@ func TestGetRegistryDevfiles(t *testing.T) { t.Run(tt.name, func(t *testing.T) { ctrl := gomock.NewController(t) prefClient := preference.NewMockClient(ctrl) - got, err := getRegistryDevfiles(prefClient, tt.registry) + got, err := getRegistryStacks(prefClient, tt.registry) if !reflect.DeepEqual(got, tt.want) { t.Errorf("Got: %v, want: %v", got, tt.want) diff --git a/pkg/catalog/types.go b/pkg/registry/types.go similarity index 56% rename from pkg/catalog/types.go rename to pkg/registry/types.go index e7758ccde..82c3b6482 100644 --- a/pkg/catalog/types.go +++ b/pkg/registry/types.go @@ -1,4 +1,4 @@ -package catalog +package registry // Registry is the main struct of devfile registry type Registry struct { @@ -7,8 +7,8 @@ type Registry struct { Secure bool } -// DevfileComponentType is the main struct for devfile catalog components -type DevfileComponentType struct { +// DevfileStack is the main struct for devfile catalog components +type DevfileStack struct { Name string DisplayName string Description string @@ -19,11 +19,11 @@ type DevfileComponentType struct { ProjectType string } -// DevfileComponentTypeList lists all the DevfileComponentType's -type DevfileComponentTypeList struct { +// DevfileStackList lists all the Devfile Stacks +type DevfileStackList struct { DevfileRegistries []Registry - Items []DevfileComponentType + Items []DevfileStack } // TypesWithDetails is the list of project types in devfile registries, and their associated devfiles -type TypesWithDetails map[string][]DevfileComponentType +type TypesWithDetails map[string][]DevfileStack diff --git a/pkg/catalog/types_with_details.go b/pkg/registry/types_with_details.go similarity index 91% rename from pkg/catalog/types_with_details.go rename to pkg/registry/types_with_details.go index a4220c78c..4b35303b0 100644 --- a/pkg/catalog/types_with_details.go +++ b/pkg/registry/types_with_details.go @@ -1,4 +1,4 @@ -package catalog +package registry import ( "errors" @@ -25,7 +25,7 @@ func (types TypesWithDetails) GetOrderedLabels() []string { // GetAtOrderedPosition returns the project type at the given position, // when the list of project types is ordered by GetOrderedLabels -func (types TypesWithDetails) GetAtOrderedPosition(pos int) (DevfileComponentType, error) { +func (types TypesWithDetails) GetAtOrderedPosition(pos int) (DevfileStack, error) { sortedTypes := sortTypes(types) for _, typ := range sortedTypes { detailsList := types[typ] @@ -35,7 +35,7 @@ func (types TypesWithDetails) GetAtOrderedPosition(pos int) (DevfileComponentTyp } return detailsList[pos], nil } - return DevfileComponentType{}, errors.New("index not found") + return DevfileStack{}, errors.New("index not found") } func sortTypes(types TypesWithDetails) []string { diff --git a/pkg/catalog/types_with_details_test.go b/pkg/registry/types_with_details_test.go similarity index 83% rename from pkg/catalog/types_with_details_test.go rename to pkg/registry/types_with_details_test.go index 1a317af27..7a20b4706 100644 --- a/pkg/catalog/types_with_details_test.go +++ b/pkg/registry/types_with_details_test.go @@ -1,4 +1,4 @@ -package catalog +package registry import ( "reflect" @@ -14,7 +14,7 @@ func TestTypesWithDetails_GetOrderedLabels(t *testing.T) { { name: "some entries", types: TypesWithDetails{ - "second devfile for lang1": []DevfileComponentType{ + "second devfile for lang1": []DevfileStack{ { Name: "devfile2", Registry: Registry{ @@ -22,7 +22,7 @@ func TestTypesWithDetails_GetOrderedLabels(t *testing.T) { }, }, }, - "first devfile for lang1": []DevfileComponentType{ + "first devfile for lang1": []DevfileStack{ { Name: "devfile1", Registry: Registry{ @@ -61,13 +61,13 @@ func TestTypesWithDetails_GetAtOrderedPosition(t *testing.T) { name string types TypesWithDetails args args - want DevfileComponentType + want DevfileStack wantErr bool }{ { name: "get a pos 0", types: TypesWithDetails{ - "second devfile for lang1": []DevfileComponentType{ + "second devfile for lang1": []DevfileStack{ { Name: "devfile2", Registry: Registry{ @@ -75,7 +75,7 @@ func TestTypesWithDetails_GetAtOrderedPosition(t *testing.T) { }, }, }, - "first devfile for lang1": []DevfileComponentType{ + "first devfile for lang1": []DevfileStack{ { Name: "devfile1", Registry: Registry{ @@ -93,7 +93,7 @@ func TestTypesWithDetails_GetAtOrderedPosition(t *testing.T) { args: args{ pos: 0, }, - want: DevfileComponentType{ + want: DevfileStack{ Name: "devfile1", Registry: Registry{ Name: "Registry1", @@ -104,7 +104,7 @@ func TestTypesWithDetails_GetAtOrderedPosition(t *testing.T) { { name: "get a pos 1", types: TypesWithDetails{ - "second devfile for lang1": []DevfileComponentType{ + "second devfile for lang1": []DevfileStack{ { Name: "devfile2", Registry: Registry{ @@ -112,7 +112,7 @@ func TestTypesWithDetails_GetAtOrderedPosition(t *testing.T) { }, }, }, - "first devfile for lang1": []DevfileComponentType{ + "first devfile for lang1": []DevfileStack{ { Name: "devfile1", Registry: Registry{ @@ -130,7 +130,7 @@ func TestTypesWithDetails_GetAtOrderedPosition(t *testing.T) { args: args{ pos: 1, }, - want: DevfileComponentType{ + want: DevfileStack{ Name: "devfile1", Registry: Registry{ Name: "Registry2", @@ -141,7 +141,7 @@ func TestTypesWithDetails_GetAtOrderedPosition(t *testing.T) { { name: "get a pos 2", types: TypesWithDetails{ - "second devfile for lang1": []DevfileComponentType{ + "second devfile for lang1": []DevfileStack{ { Name: "devfile2", Registry: Registry{ @@ -149,7 +149,7 @@ func TestTypesWithDetails_GetAtOrderedPosition(t *testing.T) { }, }, }, - "first devfile for lang1": []DevfileComponentType{ + "first devfile for lang1": []DevfileStack{ { Name: "devfile1", Registry: Registry{ @@ -167,7 +167,7 @@ func TestTypesWithDetails_GetAtOrderedPosition(t *testing.T) { args: args{ pos: 2, }, - want: DevfileComponentType{ + want: DevfileStack{ Name: "devfile2", Registry: Registry{ Name: "Registry1", @@ -178,7 +178,7 @@ func TestTypesWithDetails_GetAtOrderedPosition(t *testing.T) { { name: "get a pos 4: not found", types: TypesWithDetails{ - "second devfile for lang1": []DevfileComponentType{ + "second devfile for lang1": []DevfileStack{ { Name: "devfile2", Registry: Registry{ @@ -186,7 +186,7 @@ func TestTypesWithDetails_GetAtOrderedPosition(t *testing.T) { }, }, }, - "first devfile for lang1": []DevfileComponentType{ + "first devfile for lang1": []DevfileStack{ { Name: "devfile1", Registry: Registry{ @@ -204,7 +204,7 @@ func TestTypesWithDetails_GetAtOrderedPosition(t *testing.T) { args: args{ pos: 4, }, - want: DevfileComponentType{}, + want: DevfileStack{}, wantErr: true, }} for _, tt := range tests { diff --git a/scripts/mockgen.sh b/scripts/mockgen.sh index 35bc33b58..ed9c3fa0f 100755 --- a/scripts/mockgen.sh +++ b/scripts/mockgen.sh @@ -43,10 +43,6 @@ mockgen -source=pkg/init/backend/interface.go \ -package backend \ -destination pkg/init/backend/mock.go -mockgen -source=pkg/catalog/interface.go \ - -package catalog \ - -destination pkg/catalog/mock_catalog.go - mockgen -source=pkg/init/asker/interface.go \ -package asker \ -destination pkg/init/asker/mock.go @@ -55,9 +51,9 @@ mockgen -source=pkg/init/interface.go \ -package init \ -destination pkg/init/mock.go -mockgen -source=pkg/init/registry/interface.go \ +mockgen -source=pkg/registry/interface.go \ -package registry \ - -destination pkg/init/registry/mock.go + -destination pkg/registry/mock.go mockgen -source=pkg/deploy/interface.go \ -package deploy \ diff --git a/tests/integration/devfile/cmd_devfile_catalog_test.go b/tests/integration/devfile/cmd_devfile_catalog_test.go deleted file mode 100644 index 790899c9c..000000000 --- a/tests/integration/devfile/cmd_devfile_catalog_test.go +++ /dev/null @@ -1,151 +0,0 @@ -package devfile - -import ( - "encoding/json" - "os" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - "github.com/redhat-developer/odo/tests/helper" -) - -var _ = Describe("odo devfile catalog command tests", func() { - - var commonVar helper.CommonVar - - // This is run before every Spec (It) - var _ = BeforeEach(func() { - commonVar = helper.CommonBeforeEach() - helper.Chdir(commonVar.Context) - - // For some reason on TravisCI, there are flakes with regards to registrycachetime and doing - // odo catalog list components. - // TODO: Investigate this more. - helper.Cmd("odo", "preference", "set", "registrycachetime", "0").ShouldPass() - }) - - // This is run after every Spec (It) - var _ = AfterEach(func() { - helper.CommonAfterEach(commonVar) - }) - - It("should list components successfully even with an invalid kubeconfig path or path points to existing directory", func() { - originalKC := os.Getenv("KUBECONFIG") - - err := os.Setenv("KUBECONFIG", "/idonotexist") - Expect(err).ToNot(HaveOccurred()) - helper.Cmd("odo", "catalog", "list", "components").ShouldPass() - - err = os.Setenv("KUBECONFIG", commonVar.Context) - Expect(err).ToNot(HaveOccurred()) - helper.Cmd("odo", "catalog", "list", "components").ShouldPass() - - err = os.Setenv("KUBECONFIG", originalKC) - Expect(err).ToNot(HaveOccurred()) - }) - - When("executing catalog list components", func() { - - var output string - - BeforeEach(func() { - output = helper.Cmd("odo", "catalog", "list", "components").ShouldPass().Out() - }) - - It("should list all supported devfile components", func() { - wantOutput := []string{ - "Odo Devfile Components", - "NAME", - "java-springboot", - "java-openliberty", - "java-quarkus", - "DESCRIPTION", - "REGISTRY", - "DefaultDevfileRegistry", - } - helper.MatchAllInOutput(output, wantOutput) - }) - - }) - - When("executing catalog list components with -o json flag", func() { - - var output string - - BeforeEach(func() { - output = helper.Cmd("odo", "catalog", "list", "components", "-o", "json").ShouldPass().Out() - }) - - It("should list devfile components in json format", func() { - var outputData interface{} - unmarshalErr := json.Unmarshal([]byte(output), &outputData) - Expect(unmarshalErr).NotTo(HaveOccurred(), "Output is not a valid JSON") - - wantOutput := []string{ - "odo.dev/v1alpha1", - "items", - "java-openliberty", - "java-springboot", - "nodejs", - "java-quarkus", - "java-maven", - } - helper.MatchAllInOutput(output, wantOutput) - }) - }) - - When("executing catalog describe component with -o json", func() { - - var output string - BeforeEach(func() { - output = helper.Cmd("odo", "catalog", "describe", "component", "nodejs", "-o", "json").ShouldPass().Out() - }) - - It("should display a valid JSON", func() { - var outputData interface{} - unmarshalErr := json.Unmarshal([]byte(output), &outputData) - Expect(unmarshalErr).NotTo(HaveOccurred(), "Output is not a valid JSON") - }) - }) - - When("adding a registry that is not set up properly", func() { - - var output string - - BeforeEach(func() { - helper.Cmd("odo", "preference", "registry", "add", "fake", "http://fake").ShouldPass() - output = helper.Cmd("odo", "catalog", "list", "components").ShouldPass().Out() - }) - - AfterEach(func() { - helper.Cmd("odo", "preference", "registry", "delete", "fake", "-f").ShouldPass() - }) - - It("should list components from valid registry", func() { - helper.MatchAllInOutput(output, []string{ - "Odo Devfile Components", - "java-springboot", - "java-quarkus", - }) - }) - }) - - When("adding multiple registries", func() { - - const registryName string = "RegistryName" - // Use staging OCI-based registry for tests to avoid overload - const addRegistryURL string = "https://registry.stage.devfile.io" - - var output string - - BeforeEach(func() { - helper.Cmd("odo", "preference", "registry", "add", registryName, addRegistryURL).ShouldPass() - output = helper.Cmd("odo", "catalog", "describe", "component", "nodejs").ShouldPass().Out() - - }) - - It("should print multiple devfiles from different registries", func() { - helper.MatchAllInOutput(output, []string{"name: nodejs-starter", "Registry: " + registryName}) - }) - }) -}) diff --git a/tests/integration/devfile/utils/utils.go b/tests/integration/devfile/utils/utils.go index 9ec28fe30..a4d8e6c85 100644 --- a/tests/integration/devfile/utils/utils.go +++ b/tests/integration/devfile/utils/utils.go @@ -1,7 +1,6 @@ package utils import ( - "encoding/json" "fmt" "index/suffixarray" "os" @@ -246,27 +245,6 @@ func DeleteLocalConfig(args ...string) { helper.MatchAllInOutput(output, expectedOutput) } -// VerifyCatalogListComponent verifies components inside wantOutput exists or not -// in Devfile Component list -func VerifyCatalogListComponent(output string, cmpName []string) error { - var data map[string]interface{} - listItems := []string{"items"} - - if err := json.Unmarshal([]byte(output), &data); err != nil { - return err - } - - for _, items := range listItems { - outputBytes, err := json.Marshal(data[items]) - if err != nil { - return err - } - output = string(outputBytes) - helper.MatchAllInOutput(output, cmpName) - } - return nil -} - // VerifyContainerSyncEnv verifies the sync env in the container func VerifyContainerSyncEnv(podName, containerName, namespace, projectSourceValue, projectsRootValue string, cliRunner helper.CliRunner) { envProjectsRoot, envProjectSource := "PROJECTS_ROOT", "PROJECT_SOURCE" diff --git a/tests/integration/generic_test.go b/tests/integration/generic_test.go index 540cf70e5..231dc18bb 100644 --- a/tests/integration/generic_test.go +++ b/tests/integration/generic_test.go @@ -52,22 +52,6 @@ var _ = Describe("odo generic", func() { }) - Context("When executing catalog list without component directory", func() { - It("should list all component catalogs", func() { - stdOut := helper.Cmd("odo", "catalog", "list", "components").ShouldPass().Out() - helper.MatchAllInOutput(stdOut, []string{"nodejs", "python", "php", "go", "java"}) - }) - - }) - - Context("check catalog component search functionality", func() { - It("check that a component does not exist", func() { - componentRandomName := helper.RandString(7) - output := helper.Cmd("odo", "catalog", "search", "component", componentRandomName).ShouldFail().Err() - Expect(output).To(ContainSubstring("no component matched the query: " + componentRandomName)) - }) - }) - // Test machine readable output Context("when creating project -o json", func() { var projectName string