This repository was archived by the owner on Apr 1, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 244
Expand file tree
/
Copy pathalizer.go
More file actions
155 lines (136 loc) · 4.63 KB
/
alizer.go
File metadata and controls
155 lines (136 loc) · 4.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package alizer
import (
"context"
"fmt"
"os"
"path/filepath"
"github.com/devfile/alizer/pkg/apis/model"
"github.com/devfile/alizer/pkg/apis/recognizer"
"k8s.io/klog/v2"
"github.com/redhat-developer/odo/pkg/api"
"github.com/redhat-developer/odo/pkg/registry"
"github.com/redhat-developer/odo/pkg/util"
)
type Alizer struct {
registryClient registry.Client
}
var _ Client = (*Alizer)(nil)
func NewAlizerClient(registryClient registry.Client) *Alizer {
return &Alizer{
registryClient: registryClient,
}
}
// DetectFramework uses the alizer library in order to detect the devfile
// to use depending on the files in the path
func (o *Alizer) DetectFramework(ctx context.Context, path string) (DetectedFramework, error) {
types := []model.DevfileType{}
components, err := o.registryClient.ListDevfileStacks(ctx, "", "", "", false, false)
if err != nil {
return DetectedFramework{}, err
}
for _, component := range components.Items {
types = append(types, model.DevfileType{
Name: component.Name,
Language: component.Language,
ProjectType: component.ProjectType,
Tags: component.Tags,
})
}
typ, err := recognizer.SelectDevFileFromTypes(path, types)
if err != nil {
return DetectedFramework{}, err
}
// Get the default stack version that will be downloaded
var defaultVersion string
for _, version := range components.Items[typ].Versions {
if version.IsDefault {
defaultVersion = version.Version
}
}
return DetectedFramework{
Type: types[typ],
DefaultVersion: defaultVersion,
Registry: components.Items[typ].Registry,
Architectures: components.Items[typ].Architectures,
}, nil
}
// DetectName retrieves the name of the project (if available).
// If source code is detected:
// 1. Detect the name (pom.xml for java, package.json for nodejs, etc.)
// 2. If unable to detect the name, use the directory name
//
// If no source is detected:
// 1. Use the directory name
//
// Last step. Sanitize the name so it's valid for a component name
//
// Use:
// import "github.com/redhat-developer/alizer/pkg/apis/recognizer"
// components, err := recognizer.DetectComponents("./")
//
// In order to detect the name, the name will first try to find out the name based on the program (pom.xml, etc.) but then if not, it will use the dir name.
func (o *Alizer) DetectName(path string) (string, error) {
if path == "" {
return "", fmt.Errorf("path is empty")
}
// Check if the path exists using os.Stat
dir, err := os.Stat(path)
if err != nil {
return "", err
}
// Check to see if the path is a directory, and fail if it is not
if !dir.IsDir() {
return "", fmt.Errorf("alizer DetectName %q path is not a directory", path)
}
// Step 1.
// Get the name of the directory from the devfile absolute path
// Use that path with Alizer to get the name of the project,
// if unable to find the name, we will use the directory name
components, err := recognizer.DetectComponents(path)
if err != nil {
return "", err
}
klog.V(4).Infof("Found components: %v", components)
// Take the first name that is found
var detectedName string
if len(components) > 0 {
detectedName = components[0].Name
}
// Step 2. If unable to detect the name, we will use the directory name.
// Alizer will not correctly default to the directory name when unable to detect it via pom.xml, package.json, etc.
// So we must do it ourselves
// The directory name SHOULD be the path (we use a previous check to see if it's "itsdir"
if detectedName == "" {
detectedName = filepath.Base(path)
}
// Step 3. Sanitize the name
// Make sure that detectedName conforms with Kubernetes naming rules
// If not, we will use the directory name
name := util.GetDNS1123Name(detectedName)
klog.V(4).Infof("Path: %s, Detected name: %s, Sanitized name: %s", path, detectedName, name)
if name == "" {
return "", fmt.Errorf("unable to sanitize name to DNS1123 format: %q", name)
}
return name, nil
}
func (o *Alizer) DetectPorts(path string) ([]int, error) {
//TODO(rm3l): Find a better way not to call recognizer.DetectComponents multiple times (in DetectFramework, DetectName and DetectPorts)
components, err := recognizer.DetectComponents(path)
if err != nil {
return nil, err
}
if len(components) == 0 {
klog.V(4).Infof("no components found at path %q", path)
return nil, nil
}
return components[0].Ports, nil
}
func NewDetectionResult(typ model.DevfileType, registry api.Registry, appPorts []int, devfileVersion, name string) *api.DetectionResult {
return &api.DetectionResult{
Devfile: typ.Name,
DevfileRegistry: registry.Name,
ApplicationPorts: appPorts,
DevfileVersion: devfileVersion,
Name: name,
}
}