1 package backend
2
3 import (
4 "context"
5 "fmt"
6 "strconv"
7 "strings"
8
9 "github.com/redhat-developer/odo/pkg/log"
10
11 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
12 "github.com/devfile/library/v2/pkg/devfile/parser"
13
14 "github.com/redhat-developer/odo/pkg/alizer"
15 "github.com/redhat-developer/odo/pkg/api"
16 "github.com/redhat-developer/odo/pkg/init/asker"
17 "github.com/redhat-developer/odo/pkg/testingutil/filesystem"
18 )
19
20 type AlizerBackend struct {
21 askerClient asker.Asker
22 alizerClient alizer.Client
23 }
24
25 var _ InitBackend = (*AlizerBackend)(nil)
26
27 func NewAlizerBackend(askerClient asker.Asker, alizerClient alizer.Client) *AlizerBackend {
28 return &AlizerBackend{
29 askerClient: askerClient,
30 alizerClient: alizerClient,
31 }
32 }
33
34 func (o *AlizerBackend) Validate(flags map[string]string, fs filesystem.Filesystem, dir string) error {
35 return nil
36 }
37
38 func archList(archs []string) string {
39 if len(archs) == 0 {
40 return "all"
41 }
42 return strings.Join(archs, ", ")
43 }
44
45
46 func (o *AlizerBackend) SelectDevfile(ctx context.Context, flags map[string]string, fs filesystem.Filesystem, dir string) (*api.DetectionResult, error) {
47 type result struct {
48 location *api.DetectionResult
49 err error
50 }
51 var (
52 resultChan = make(chan result)
53 )
54 go func() {
55 location, err := func() (location *api.DetectionResult, err error) {
56 spinner := log.Spinnerf("Determining a Devfile for the current directory")
57 defer spinner.End(err == nil)
58 detected, err := o.alizerClient.DetectFramework(ctx, dir)
59 if err != nil {
60 return nil, err
61 }
62
63 msg := fmt.Sprintf("Based on the files in the current directory odo detected\nSupported architectures: %s\nLanguage: %s\nProject type: %s",
64 archList(detected.Architectures), detected.Type.Language, detected.Type.ProjectType)
65
66 appPorts, err := o.alizerClient.DetectPorts(dir)
67 if err != nil {
68 return nil, err
69 }
70 spinner.End(true)
71 appPortsAsString := make([]string, 0, len(appPorts))
72 for _, p := range appPorts {
73 appPortsAsString = append(appPortsAsString, strconv.Itoa(p))
74 }
75 if len(appPorts) > 0 {
76 msg += fmt.Sprintf("\nApplication ports: %s", strings.Join(appPortsAsString, ", "))
77 }
78
79 fmt.Println(msg)
80 fmt.Printf("The devfile \"%s:%s\" from the registry %q will be downloaded.\n", detected.Type.Name, detected.DefaultVersion, detected.Registry.Name)
81 confirm, err := o.askerClient.AskCorrect()
82 if err != nil {
83 return nil, err
84 }
85 if !confirm {
86 return nil, nil
87 }
88 return alizer.NewDetectionResult(detected.Type, detected.Registry, appPorts, detected.DefaultVersion, ""), nil
89 }()
90 resultChan <- result{
91 location: location,
92 err: err,
93 }
94 }()
95
96 select {
97 case res := <-resultChan:
98 return res.location, res.err
99 case <-ctx.Done():
100 return nil, fmt.Errorf("interrupted: %w", ctx.Err())
101 }
102 }
103
104 func (o *AlizerBackend) SelectStarterProject(devfile parser.DevfileObj, flags map[string]string) (starter *v1alpha2.StarterProject, err error) {
105 return nil, nil
106 }
107
108 func (o *AlizerBackend) PersonalizeName(devfile parser.DevfileObj, flags map[string]string) (string, error) {
109
110 path := devfile.Ctx.GetAbsPath()
111 if path == "" {
112 return "", fmt.Errorf("cannot determine the absolute path of the directory")
113 }
114 return o.alizerClient.DetectName(path)
115 }
116
117 func (o *AlizerBackend) PersonalizeDevfileConfig(devfile parser.DevfileObj) (parser.DevfileObj, error) {
118 return devfile, nil
119 }
120
121 func (o *AlizerBackend) HandleApplicationPorts(devfileobj parser.DevfileObj, ports []int, flags map[string]string) (parser.DevfileObj, error) {
122 return devfileobj, nil
123 }
124
View as plain text