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
This commit is contained in:
Tomas Kral
2022-03-23 12:15:41 +01:00
committed by GitHub
parent 7618e8f3e4
commit 614976a0bf
44 changed files with 296 additions and 1354 deletions

View File

@@ -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/

View File

@@ -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
```

View File

@@ -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 <component-type>`.
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.

View File

@@ -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)
}

View File

@@ -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)
}

View File

@@ -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 {

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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
}

View File

@@ -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

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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)

View File

@@ -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,
}
}

View File

@@ -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"
)

View File

@@ -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)
}

View File

@@ -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
}

View File

@@ -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 <registry name> <registry URL>' 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 <name> -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
}

View File

@@ -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
}

View File

@@ -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 <registry name> <registry URL>' 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)
}
}
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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)),

View File

@@ -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

View File

@@ -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 <registry name> <registry URL>` to add a registry\n")
return registry.DevfileStackList{}, errors.New("Registry is empty, please run `odo registry add <registry name> <registry URL>` 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)

View File

@@ -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
}

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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)
}

View File

@@ -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)
}
})
}

View File

@@ -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)
}

View File

@@ -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()

View File

@@ -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,

View File

@@ -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)

View File

@@ -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

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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 \

View File

@@ -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})
})
})
})

View File

@@ -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"

View File

@@ -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