Skip to content

Commit 4479c24

Browse files
authored
Display list of commands from the local devfile in odo describe component output (#6944)
* Add integration tests highlighting the expectations * Add and fill a 'Commands' field from the DevfileData struct returned by `describe` * Display commands in the human-readable output of 'odo describe' * Add documentation and sample outputs
1 parent 97644aa commit 4479c24

File tree

11 files changed

+411
-6
lines changed

11 files changed

+411
-6
lines changed

docs/website/docs/command-reference/describe-component.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,32 @@ Supported odo features:
3333
• Deploy: true
3434
• Debug: true
3535

36+
Commands:
37+
• my-install
38+
Type: exec
39+
Group: build
40+
Command Line: "npm install"
41+
Component: runtime
42+
Component Type: container
43+
• my-run
44+
Type: exec
45+
Group: run
46+
Command Line: "npm start"
47+
Component: runtime
48+
Component Type: container
49+
• build-image
50+
Type: apply
51+
Component: prod-image
52+
Component Type: image
53+
Image Name: devfile-nodejs-deploy:latest
54+
• deploy-deployment
55+
Type: apply
56+
Component: outerloop-deploy
57+
Component Type: kubernetes
58+
• deploy
59+
Type: composite
60+
Group: deploy
61+
3662
Container components:
3763
• runtime
3864

@@ -55,6 +81,7 @@ Kubernetes Routes:
5581
This command returns information extracted from the Devfile:
5682
- metadata (name, display name, project type, language, version, description and tags)
5783
- supported odo features, indicating if the Devfile defines necessary information to run `odo dev`, `odo dev --debug` and `odo deploy`
84+
- the list of commands, if any, along with some useful information about each command
5885
- the list of container components,
5986
- the list of Kubernetes components.
6087
- the list of forwarded ports if the component is running in Dev mode.

docs/website/docs/command-reference/json-output.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ When the `describe component` command is executed without parameter from a direc
139139
- the path of the Devfile,
140140
- the content of the Devfile,
141141
- supported `odo` features, indicating if the Devfile defines necessary information to run `odo dev`, `odo dev --debug` and `odo deploy`
142+
- the list of commands, if any, along with some useful information about each command
142143
- ingress or routes created in Deploy mode
143144
- the status of the component
144145
- the forwarded ports if odo is currently running in Dev mode,
@@ -155,6 +156,45 @@ odo describe component -o json
155156
"schemaVersion": "2.0.0",
156157
[ devfile.yaml file content ]
157158
},
159+
"commands": [
160+
{
161+
"name": "my-install",
162+
"type": "exec",
163+
"group": "build",
164+
"isDefault": true,
165+
"commandLine": "npm install",
166+
"component": "runtime",
167+
"componentType": "container"
168+
},
169+
{
170+
"name": "my-run",
171+
"type": "exec",
172+
"group": "run",
173+
"isDefault": true,
174+
"commandLine": "npm start",
175+
"component": "runtime",
176+
"componentType": "container"
177+
},
178+
{
179+
"name": "build-image",
180+
"type": "apply",
181+
"component": "prod-image",
182+
"componentType": "image",
183+
"imageName": "devfile-nodejs-deploy"
184+
},
185+
{
186+
"name": "deploy-deployment",
187+
"type": "apply",
188+
"component": "outerloop-deploy",
189+
"componentType": "kubernetes"
190+
},
191+
{
192+
"name": "deploy",
193+
"type": "composite",
194+
"group": "deploy",
195+
"isDefault": true
196+
}
197+
],
158198
"supportedOdoFeatures": {
159199
"dev": true,
160200
"deploy": false,

pkg/api/devfile-data.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import "github.com/devfile/library/v2/pkg/devfile/parser/data"
55
// DevfileData describes a devfile content
66
type DevfileData struct {
77
Devfile data.DevfileData `json:"devfile"`
8+
Commands []DevfileCommand `json:"commands,omitempty"`
89
SupportedOdoFeatures *SupportedOdoFeatures `json:"supportedOdoFeatures,omitempty"`
910
}
1011

@@ -14,3 +15,41 @@ type SupportedOdoFeatures struct {
1415
Deploy bool `json:"deploy"`
1516
Debug bool `json:"debug"`
1617
}
18+
19+
type DevfileCommand struct {
20+
Name string `json:"name,omitempty"`
21+
Type DevfileCommandType `json:"type,omitempty"`
22+
Group DevfileCommandGroup `json:"group,omitempty"`
23+
IsDefault *bool `json:"isDefault,omitempty"`
24+
CommandLine string `json:"commandLine,omitempty"`
25+
Component string `json:"component,omitempty"`
26+
ComponentType DevfileComponentType `json:"componentType,omitempty"`
27+
ImageName string `json:"imageName,omitempty"`
28+
}
29+
30+
type DevfileCommandType string
31+
32+
const (
33+
ExecCommandType DevfileCommandType = "exec"
34+
ApplyCommandType DevfileCommandType = "apply"
35+
CompositeCommandType DevfileCommandType = "composite"
36+
)
37+
38+
type DevfileCommandGroup string
39+
40+
const (
41+
BuildCommandGroup DevfileCommandGroup = "build"
42+
RunCommandGroup DevfileCommandGroup = "run"
43+
TestCommandGroup DevfileCommandGroup = "test"
44+
DebugCommandGroup DevfileCommandGroup = "debug"
45+
DeployCommandGroup DevfileCommandGroup = "deploy"
46+
)
47+
48+
type DevfileComponentType string
49+
50+
const (
51+
ImageComponentType DevfileComponentType = "image"
52+
ContainerComponentType DevfileComponentType = "container"
53+
KubernetesComponentType DevfileComponentType = "kubernetes"
54+
OpenshiftComponentType DevfileComponentType = "openshift"
55+
)

pkg/api/utils.go

Lines changed: 99 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,24 @@
11
package api
22

33
import (
4+
v1alpha2 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
45
"github.com/devfile/library/v2/pkg/devfile/parser"
56
"github.com/devfile/library/v2/pkg/devfile/parser/data"
7+
"github.com/devfile/library/v2/pkg/devfile/parser/data/v2/common"
8+
69
"github.com/redhat-developer/odo/pkg/libdevfile"
710
)
811

9-
func GetDevfileData(devfileObj parser.DevfileObj) *DevfileData {
12+
func GetDevfileData(devfileObj parser.DevfileObj) (*DevfileData, error) {
13+
commands, err := getDevfileCommands(devfileObj.Data)
14+
if err != nil {
15+
return nil, err
16+
}
1017
return &DevfileData{
1118
Devfile: devfileObj.Data,
19+
Commands: commands,
1220
SupportedOdoFeatures: getSupportedOdoFeatures(devfileObj.Data),
13-
}
21+
}, nil
1422
}
1523

1624
func getSupportedOdoFeatures(devfileData data.DevfileData) *SupportedOdoFeatures {
@@ -20,3 +28,92 @@ func getSupportedOdoFeatures(devfileData data.DevfileData) *SupportedOdoFeatures
2028
Debug: libdevfile.HasDebugCommand(devfileData),
2129
}
2230
}
31+
32+
func getDevfileCommands(devfileData data.DevfileData) ([]DevfileCommand, error) {
33+
commands, err := devfileData.GetCommands(common.DevfileOptions{})
34+
if err != nil {
35+
return nil, err
36+
}
37+
38+
toGroupFn := func(g *v1alpha2.CommandGroup) (group DevfileCommandGroup, isDefault *bool) {
39+
if g == nil {
40+
return "", nil
41+
}
42+
switch g.Kind {
43+
case v1alpha2.BuildCommandGroupKind:
44+
group = BuildCommandGroup
45+
case v1alpha2.RunCommandGroupKind:
46+
group = RunCommandGroup
47+
case v1alpha2.DebugCommandGroupKind:
48+
group = DebugCommandGroup
49+
case v1alpha2.TestCommandGroupKind:
50+
group = TestCommandGroup
51+
case v1alpha2.DeployCommandGroupKind:
52+
group = DeployCommandGroup
53+
}
54+
55+
return group, g.IsDefault
56+
}
57+
58+
var result []DevfileCommand
59+
for _, cmd := range commands {
60+
var (
61+
cmdType DevfileCommandType
62+
cmdComponent string
63+
cmdCompType DevfileComponentType
64+
cmdLine string
65+
)
66+
var cmdGroup *v1alpha2.CommandGroup
67+
switch {
68+
case cmd.Apply != nil:
69+
cmdType = ApplyCommandType
70+
cmdComponent = cmd.Apply.Component
71+
cmdGroup = cmd.Apply.Group
72+
case cmd.Exec != nil:
73+
cmdType = ExecCommandType
74+
cmdComponent = cmd.Exec.Component
75+
cmdGroup = cmd.Exec.Group
76+
cmdLine = cmd.Exec.CommandLine
77+
case cmd.Composite != nil:
78+
cmdType = CompositeCommandType
79+
cmdGroup = cmd.Composite.Group
80+
}
81+
82+
var imageName string
83+
var comp v1alpha2.Component
84+
if cmdComponent != "" {
85+
var ok bool
86+
comp, ok, err = libdevfile.FindComponentByName(devfileData, cmdComponent)
87+
if err != nil {
88+
return nil, err
89+
}
90+
if ok {
91+
switch {
92+
case comp.Kubernetes != nil:
93+
cmdCompType = KubernetesComponentType
94+
case comp.Openshift != nil:
95+
cmdCompType = OpenshiftComponentType
96+
case comp.Container != nil:
97+
cmdCompType = ContainerComponentType
98+
case comp.Image != nil:
99+
cmdCompType = ImageComponentType
100+
imageName = comp.Image.ImageName
101+
}
102+
}
103+
}
104+
g, isDefault := toGroupFn(cmdGroup)
105+
c := DevfileCommand{
106+
Name: cmd.Id,
107+
Type: cmdType,
108+
Group: g,
109+
IsDefault: isDefault,
110+
CommandLine: cmdLine,
111+
Component: cmdComponent,
112+
ComponentType: cmdCompType,
113+
ImageName: imageName,
114+
}
115+
result = append(result, c)
116+
}
117+
118+
return result, nil
119+
}

pkg/component/describe/describe.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import (
99
"github.com/devfile/library/v2/pkg/devfile/generator"
1010
"github.com/devfile/library/v2/pkg/devfile/parser"
1111
"github.com/devfile/library/v2/pkg/devfile/parser/data/v2/common"
12+
"k8s.io/klog"
13+
1214
"github.com/redhat-developer/odo/pkg/api"
1315
"github.com/redhat-developer/odo/pkg/component"
1416
"github.com/redhat-developer/odo/pkg/kclient"
@@ -20,7 +22,6 @@ import (
2022
odocontext "github.com/redhat-developer/odo/pkg/odo/context"
2123
"github.com/redhat-developer/odo/pkg/podman"
2224
"github.com/redhat-developer/odo/pkg/state"
23-
"k8s.io/klog"
2425
)
2526

2627
// DescribeDevfileComponent describes the component defined by the devfile in the current directory
@@ -36,6 +37,11 @@ func DescribeDevfileComponent(
3637
componentName = odocontext.GetComponentName(ctx)
3738
)
3839

40+
devfileData, err := api.GetDevfileData(*devfileObj)
41+
if err != nil {
42+
return api.Component{}, nil, err
43+
}
44+
3945
isPlatformFeatureEnabled := feature.IsEnabled(ctx, feature.GenericPlatformFlag)
4046
platform := fcontext.GetPlatform(ctx, "")
4147
switch platform {
@@ -115,7 +121,7 @@ func DescribeDevfileComponent(
115121

116122
cmp := api.Component{
117123
DevfilePath: devfilePath,
118-
DevfileData: api.GetDevfileData(*devfileObj),
124+
DevfileData: devfileData,
119125
DevForwardedPorts: forwardedPorts,
120126
RunningIn: api.MergeRunningModes(runningOn),
121127
RunningOn: runningOn,

pkg/libdevfile/libdevfile.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,20 @@ func GetContainerComponentsForCommand(devfileObj parser.DevfileObj, cmd v1alpha2
451451
}
452452
}
453453

454+
// FindComponentByName returns the Devfile component that matches the specified name.
455+
func FindComponentByName(d data.DevfileData, n string) (v1alpha2.Component, bool, error) {
456+
comps, err := d.GetComponents(common.DevfileOptions{})
457+
if err != nil {
458+
return v1alpha2.Component{}, false, err
459+
}
460+
for _, c := range comps {
461+
if c.Name == n {
462+
return c, true, nil
463+
}
464+
}
465+
return v1alpha2.Component{}, false, nil
466+
}
467+
454468
// GetK8sManifestsWithVariablesSubstituted returns the full content of either a Kubernetes or an Openshift
455469
// Devfile component, either Inlined or referenced via a URI.
456470
// No matter how the component is defined, it returns the content with all variables substituted

pkg/odo/cli/describe/component.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/devfile/library/v2/pkg/devfile/parser/data/v2/common"
1212
"github.com/spf13/cobra"
1313
ktemplates "k8s.io/kubectl/pkg/util/templates"
14+
"k8s.io/utils/pointer"
1415

1516
"github.com/redhat-developer/odo/pkg/api"
1617
"github.com/redhat-developer/odo/pkg/component/describe"
@@ -192,6 +193,36 @@ func printHumanReadableOutput(ctx context.Context, cmp api.Component, devfileObj
192193
}
193194
fmt.Println()
194195

196+
if cmp.DevfileData != nil && len(cmp.DevfileData.Commands) != 0 {
197+
log.Info("Commands:")
198+
for _, cmd := range cmp.DevfileData.Commands {
199+
item := cmd.Name
200+
if pointer.BoolDeref(cmd.IsDefault, false) {
201+
item = log.Sbold(cmd.Name)
202+
}
203+
if cmd.Type != "" {
204+
item += fmt.Sprintf("\n Type: %s", cmd.Type)
205+
}
206+
if cmd.Group != "" {
207+
item += fmt.Sprintf("\n Group: %s", cmd.Group)
208+
}
209+
if cmd.CommandLine != "" {
210+
item += fmt.Sprintf("\n Command Line: %q", cmd.CommandLine)
211+
}
212+
if cmd.Component != "" {
213+
item += fmt.Sprintf("\n Component: %s", cmd.Component)
214+
}
215+
if cmd.ComponentType != "" {
216+
item += fmt.Sprintf("\n Component Type: %s", cmd.ComponentType)
217+
}
218+
if cmd.ImageName != "" {
219+
item += fmt.Sprintf("\n Image Name: %s", cmd.ImageName)
220+
}
221+
log.Printf(item)
222+
}
223+
}
224+
fmt.Println()
225+
195226
err := listComponentsNames("Container components:", devfileObj, v1alpha2.ContainerComponentType)
196227
if err != nil {
197228
return err

pkg/odo/cli/init/init.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,9 +161,13 @@ func (o *InitOptions) RunForJsonOutput(ctx context.Context) (out interface{}, er
161161
if err != nil {
162162
return nil, err
163163
}
164+
devfileData, err := api.GetDevfileData(devfileObj)
165+
if err != nil {
166+
return nil, err
167+
}
164168
return api.Component{
165169
DevfilePath: devfilePath,
166-
DevfileData: api.GetDevfileData(devfileObj),
170+
DevfileData: devfileData,
167171
DevForwardedPorts: []api.ForwardedPort{},
168172
RunningIn: api.NewRunningModes(),
169173
ManagedBy: "odo",

pkg/registry/registry.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -445,5 +445,10 @@ func (o RegistryClient) retrieveDevfileDataFromRegistry(ctx context.Context, reg
445445

446446
// Convert DevfileObj to DevfileData
447447
// use api.GetDevfileData to get supported features
448-
return *api.GetDevfileData(devfileObj), nil
448+
devfileData, err := api.GetDevfileData(devfileObj)
449+
if err != nil {
450+
return api.DevfileData{}, err
451+
}
452+
453+
return *devfileData, nil
449454
}

0 commit comments

Comments
 (0)