Skip to content

Commit

Permalink
display equivalent odo init command for odo init interactive (#6265)
Browse files Browse the repository at this point in the history
* display equivalent odo init command for odo init interactive

Signed-off-by: anandrkskd <anandrkskd@gmail.com>

* update the documentation to add the new returned values

Signed-off-by: anandrkskd <anandrkskd@gmail.com>

* update mock and functional tests

Signed-off-by: anandrkskd <anandrkskd@gmail.com>

Signed-off-by: anandrkskd <anandrkskd@gmail.com>
  • Loading branch information
anandrkskd authored Nov 3, 2022
1 parent 6ae0cef commit 26c1d9b
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 27 deletions.
14 changes: 7 additions & 7 deletions pkg/init/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -254,27 +254,27 @@ func (o InitClient) PersonalizeDevfileConfig(devfileobj parser.DevfileObj, flags
return backend.PersonalizeDevfileConfig(devfileobj)
}

func (o InitClient) SelectAndPersonalizeDevfile(flags map[string]string, contextDir string) (parser.DevfileObj, string, error) {
func (o InitClient) SelectAndPersonalizeDevfile(flags map[string]string, contextDir string) (parser.DevfileObj, string, *api.DevfileLocation, error) {
devfileLocation, err := o.SelectDevfile(flags, o.fsys, contextDir)
if err != nil {
return parser.DevfileObj{}, "", err
return parser.DevfileObj{}, "", nil, err
}

devfilePath, err := o.DownloadDevfile(devfileLocation, contextDir)
if err != nil {
return parser.DevfileObj{}, "", fmt.Errorf("unable to download devfile: %w", err)
return parser.DevfileObj{}, "", nil, fmt.Errorf("unable to download devfile: %w", err)
}

devfileObj, _, err := devfile.ParseDevfileAndValidate(parser.ParserArgs{Path: devfilePath, FlattenedDevfile: pointer.BoolPtr(false)})
if err != nil {
return parser.DevfileObj{}, "", fmt.Errorf("unable to parse devfile: %w", err)
return parser.DevfileObj{}, "", nil, fmt.Errorf("unable to parse devfile: %w", err)
}

devfileObj, err = o.PersonalizeDevfileConfig(devfileObj, flags, o.fsys, contextDir)
if err != nil {
return parser.DevfileObj{}, "", fmt.Errorf("failed to configure devfile: %w", err)
return parser.DevfileObj{}, "", nil, fmt.Errorf("failed to configure devfile: %w", err)
}
return devfileObj, devfilePath, nil
return devfileObj, devfilePath, devfileLocation, nil
}

func (o InitClient) InitDevfile(flags map[string]string, contextDir string,
Expand All @@ -292,7 +292,7 @@ func (o InitClient) InitDevfile(flags map[string]string, contextDir string,
preInitHandlerFunc(len(flags) == 0)
}

devfileObj, _, err := o.SelectAndPersonalizeDevfile(map[string]string{}, contextDir)
devfileObj, _, _, err := o.SelectAndPersonalizeDevfile(map[string]string{}, contextDir)
if err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/init/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,6 @@ type Client interface {
PersonalizeDevfileConfig(devfileobj parser.DevfileObj, flags map[string]string, fs filesystem.Filesystem, dir string) (parser.DevfileObj, error)

// SelectAndPersonalizeDevfile selects a devfile, then downloads, parse and personalize it
// Returns the devfile object and its path
SelectAndPersonalizeDevfile(flags map[string]string, contextDir string) (parser.DevfileObj, string, error)
// Returns the devfile object, its path and pointer to *api.devfileLocation
SelectAndPersonalizeDevfile(flags map[string]string, contextDir string) (parser.DevfileObj, string, *api.DevfileLocation, error)
}
7 changes: 4 additions & 3 deletions pkg/init/mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

39 changes: 24 additions & 15 deletions pkg/odo/cli/init/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/spf13/cobra"

"github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
"github.com/devfile/library/pkg/devfile"
"github.com/devfile/library/pkg/devfile/parser"

Expand Down Expand Up @@ -113,7 +114,7 @@ func (o *InitOptions) Validate(ctx context.Context) error {
// Run contains the logic for the odo command
func (o *InitOptions) Run(ctx context.Context) (err error) {

devfileObj, _, err := o.run(ctx)
devfileObj, _, name, devfileLocation, starterInfo, err := o.run(ctx)
if err != nil {
return err
}
Expand All @@ -123,6 +124,14 @@ Your new component '%s' is ready in the current directory.
To start editing your component, use 'odo dev' and open this folder in your favorite IDE.
Changes will be directly reflected on the cluster.`, devfileObj.Data.GetMetadata().Name)

if len(o.flags) == 0 {
automateCommad := fmt.Sprintf("odo init --name %s --devfile %s --devfile-registry %s", name, devfileLocation.Devfile, devfileLocation.DevfileRegistry)
if starterInfo != nil {
automateCommad = fmt.Sprintf("%s --starter %s", automateCommad, starterInfo.Name)
}
log.Infof("\nPort configuration using flag is currently not supported \n\nYou can automate this command by executing:\n %s\n", automateCommad)
}

if libdevfile.HasDeployCommand(devfileObj.Data) {
exitMessage += "\nTo deploy your component to a cluster use \"odo deploy\"."
}
Expand All @@ -133,7 +142,7 @@ Changes will be directly reflected on the cluster.`, devfileObj.Data.GetMetadata

// RunForJsonOutput is executed instead of Run when -o json flag is given
func (o *InitOptions) RunForJsonOutput(ctx context.Context) (out interface{}, err error) {
devfileObj, devfilePath, err := o.run(ctx)
devfileObj, devfilePath, _, _, _, err := o.run(ctx)
if err != nil {
return nil, err
}
Expand All @@ -146,8 +155,8 @@ func (o *InitOptions) RunForJsonOutput(ctx context.Context) (out interface{}, er
}, nil
}

// run downloads the devfile and starter project and returns the content and the path of the devfile
func (o *InitOptions) run(ctx context.Context) (devfileObj parser.DevfileObj, path string, err error) {
// run downloads the devfile and starter project and returns the content of the devfile, path of the devfile, name of the component, api.DevfileLocation object for DevfileRegistry info and StarterProject object
func (o *InitOptions) run(ctx context.Context) (devfileObj parser.DevfileObj, path string, name string, devfileLocation *api.DevfileLocation, starterInfo *v1alpha2.StarterProject, err error) {
var starterDownloaded bool

workingDir := odocontext.GetWorkingDirectory(ctx)
Expand All @@ -166,7 +175,7 @@ func (o *InitOptions) run(ctx context.Context) (devfileObj parser.DevfileObj, pa

isEmptyDir, err := location.DirIsEmpty(o.clientset.FS, workingDir)
if err != nil {
return parser.DevfileObj{}, "", err
return parser.DevfileObj{}, "", "", nil, nil, err
}

// Show a welcome message for when you initially run `odo init`.
Expand All @@ -183,49 +192,49 @@ func (o *InitOptions) run(ctx context.Context) (devfileObj parser.DevfileObj, pa
log.Info(messages.InteractiveModeEnabled)
}

devfileObj, devfilePath, err := o.clientset.InitClient.SelectAndPersonalizeDevfile(o.flags, workingDir)
devfileObj, devfilePath, devfileLocation, err := o.clientset.InitClient.SelectAndPersonalizeDevfile(o.flags, workingDir)
if err != nil {
return parser.DevfileObj{}, "", err
return parser.DevfileObj{}, "", "", nil, nil, err
}

starterInfo, err := o.clientset.InitClient.SelectStarterProject(devfileObj, o.flags, o.clientset.FS, workingDir)
starterInfo, err = o.clientset.InitClient.SelectStarterProject(devfileObj, o.flags, o.clientset.FS, workingDir)
if err != nil {
return parser.DevfileObj{}, "", err
return parser.DevfileObj{}, "", "", nil, nil, err
}

// Set the name in the devfile but do not write it yet to disk,
// because the starter project downloaded at the end might come bundled with a specific Devfile.
name, err := o.clientset.InitClient.PersonalizeName(devfileObj, o.flags)
name, err = o.clientset.InitClient.PersonalizeName(devfileObj, o.flags)
if err != nil {
return parser.DevfileObj{}, "", fmt.Errorf("failed to update the devfile's name: %w", err)
return parser.DevfileObj{}, "", "", nil, nil, fmt.Errorf("failed to update the devfile's name: %w", err)
}

if starterInfo != nil {
// WARNING: this will remove all the content of the destination directory, ie the devfile.yaml file
err = o.clientset.InitClient.DownloadStarterProject(starterInfo, workingDir)
if err != nil {
return parser.DevfileObj{}, "", fmt.Errorf("unable to download starter project %q: %w", starterInfo.Name, err)
return parser.DevfileObj{}, "", "", nil, nil, fmt.Errorf("unable to download starter project %q: %w", starterInfo.Name, err)
}
starterDownloaded = true

// in case the starter project contains a devfile, read it again
if _, err = o.clientset.FS.Stat(devfilePath); err == nil {
devfileObj, _, err = devfile.ParseDevfileAndValidate(parser.ParserArgs{Path: devfilePath, FlattenedDevfile: pointer.BoolPtr(false)})
if err != nil {
return parser.DevfileObj{}, "", err
return parser.DevfileObj{}, "", "", nil, nil, err
}
}
}
// WARNING: SetMetadataName writes the Devfile to disk
if err = devfileObj.SetMetadataName(name); err != nil {
return parser.DevfileObj{}, "", err
return parser.DevfileObj{}, "", "", nil, nil, err
}
scontext.SetComponentType(ctx, component.GetComponentTypeFromDevfileMetadata(devfileObj.Data.GetMetadata()))
scontext.SetLanguage(ctx, devfileObj.Data.GetMetadata().Language)
scontext.SetProjectType(ctx, devfileObj.Data.GetMetadata().ProjectType)
scontext.SetDevfileName(ctx, devfileObj.GetMetadataName())

return devfileObj, devfilePath, nil
return devfileObj, devfilePath, name, devfileLocation, starterInfo, nil
}

// NewCmdInit implements the odo command
Expand Down
30 changes: 30 additions & 0 deletions tests/integration/interactive_init_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,36 @@ var _ = Describe("odo init interactive command tests", Label(helper.LabelNoClust
Expect(helper.ListFilesInDir(commonVar.Context)).To(ContainElements("devfile.yaml"))
})

It("should print automation command with proper values", func() {
command := []string{"odo", "init"}
starter := "go-starter"
componentName := "my-go-app"
devfileName := "go"

output, err := helper.RunInteractive(command, nil, func(ctx helper.InteractiveContext) {

helper.ExpectString(ctx, "Select language")
helper.SendLine(ctx, "Go")

helper.ExpectString(ctx, "Select project type")
helper.SendLine(ctx, "")

helper.ExpectString(ctx, "Which starter project do you want to use")
helper.SendLine(ctx, starter)

helper.ExpectString(ctx, "Enter component name")
helper.SendLine(ctx, componentName)

helper.ExpectString(ctx, "Your new component 'my-go-app' is ready in the current directory")

})

Expect(err).To(BeNil())
Expect(output).To(ContainSubstring("odo init --name %s --devfile %s --devfile-registry DefaultDevfileRegistry --starter %s", componentName, devfileName, starter))
Expect(output).To(ContainSubstring("Your new component 'my-go-app' is ready in the current directory"))
Expect(helper.ListFilesInDir(commonVar.Context)).To(ContainElements("devfile.yaml"))
})

It("should download correct devfile", func() {

command := []string{"odo", "init"}
Expand Down

0 comments on commit 26c1d9b

Please sign in to comment.