Skip to content

Commit 04361c9

Browse files
authored
Detect devfiles only for main language in case of no component found (#22)
* Detect devfiles only from main language after analysis Signed-off-by: thepetk <[email protected]> * Add tests for getMainLanguage Signed-off-by: thepetk <[email protected]> * Add test cases for selectDevfileByLanguage Signed-off-by: thepetk <[email protected]> * Add extra test cases for devfile recognizer Signed-off-by: thepetk <[email protected]> * Add extra case to selectDevfilesFromTypes Signed-off-by: thepetk <[email protected]> --------- Signed-off-by: thepetk <[email protected]>
1 parent 27607db commit 04361c9

File tree

2 files changed

+263
-2
lines changed

2 files changed

+263
-2
lines changed

pkg/apis/recognizer/devfile_recognizer.go

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,29 @@ func SelectDevFilesFromTypes(path string, devfileTypes []model.DevfileType) ([]i
4545
if err != nil {
4646
return []int{}, err
4747
}
48-
devfile, err := SelectDevfileUsingLanguagesFromTypes(languages, devfileTypes)
48+
mainLanguage, err := getMainLanguage(languages)
49+
if err != nil {
50+
return []int{}, err
51+
}
52+
devfiles, err := selectDevfilesByLanguage(mainLanguage, devfileTypes)
4953
if err != nil {
5054
return []int{}, errors.New("No valid devfile found for project in " + path)
5155
}
52-
return []int{devfile}, nil
56+
return devfiles, nil
57+
}
58+
59+
func getMainLanguage(languages []model.Language) (model.Language, error) {
60+
if len(languages) == 0 {
61+
return model.Language{}, fmt.Errorf("cannot detect main language due to empty languages list")
62+
}
63+
64+
mainLanguage := languages[0]
65+
for _, language := range languages {
66+
if language.Weight > mainLanguage.Weight {
67+
mainLanguage = language
68+
}
69+
}
70+
return mainLanguage, nil
5371
}
5472

5573
func selectDevfilesFromComponentsDetectedInPath(path string, devfileTypes []model.DevfileType) []int {

pkg/apis/recognizer/devfile_recognizer_test.go

Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,249 @@ func TestMatchDevfiles(t *testing.T) {
266266
}
267267
}
268268

269+
func TestSelectDevFilesFromTypes(t *testing.T) {
270+
tests := []struct {
271+
name string
272+
path string
273+
expectedDevfileTypeName string
274+
devfilesToRemove []model.DevfileType
275+
expectingErr bool
276+
}{
277+
{
278+
name: "Case 1: Match devfile success",
279+
path: "../../../resources/projects/beego",
280+
expectedDevfileTypeName: "go",
281+
devfilesToRemove: []model.DevfileType{},
282+
expectingErr: false,
283+
}, {
284+
name: "Case 1: Match devfile with language analysis success",
285+
path: "../../../resources/projects/beego",
286+
expectedDevfileTypeName: "",
287+
devfilesToRemove: []model.DevfileType{
288+
{
289+
Name: "go",
290+
},
291+
},
292+
expectingErr: true,
293+
}, {
294+
name: "Case 2: No Match",
295+
path: "../../../resources/projects/notexisting",
296+
expectedDevfileTypeName: "",
297+
devfilesToRemove: []model.DevfileType{},
298+
expectingErr: true,
299+
},
300+
}
301+
302+
for _, tc := range tests {
303+
t.Run(tc.name, func(tt *testing.T) {
304+
devfileTypes := getDevfileTypes()
305+
filteredDevfileTypes := []model.DevfileType{}
306+
for _, devfileType := range devfileTypes {
307+
removeDevfileType := false
308+
for _, typeToRemove := range tc.devfilesToRemove {
309+
if devfileType.Name == typeToRemove.Name {
310+
removeDevfileType = true
311+
}
312+
}
313+
if !removeDevfileType {
314+
filteredDevfileTypes = append(filteredDevfileTypes, devfileType)
315+
}
316+
}
317+
devfileTypeIndexes, err := SelectDevFilesFromTypes(tc.path, filteredDevfileTypes)
318+
errExist := err != nil
319+
if tc.expectingErr {
320+
assert.EqualValues(t, tc.expectingErr, errExist)
321+
} else {
322+
index := devfileTypeIndexes[0]
323+
assert.EqualValues(t, tc.expectedDevfileTypeName, devfileTypes[index].Name)
324+
}
325+
})
326+
}
327+
}
328+
329+
func Test_selectDevfilesFromComponents(t *testing.T) {
330+
tests := []struct {
331+
name string
332+
path string
333+
components []model.Component
334+
expectedDevfileTypeName string
335+
}{
336+
{
337+
name: "Case 1: Match devfile success",
338+
path: "../../../resources/projects/beego",
339+
components: []model.Component{
340+
{
341+
Name: "go",
342+
Languages: []model.Language{
343+
{
344+
Name: "Go",
345+
},
346+
},
347+
},
348+
},
349+
expectedDevfileTypeName: "go",
350+
}, {
351+
name: "Case 2: No Match",
352+
path: "../../../resources/projects/notexisting",
353+
components: []model.Component{},
354+
expectedDevfileTypeName: "",
355+
},
356+
}
357+
358+
for _, tc := range tests {
359+
t.Run(tc.name, func(tt *testing.T) {
360+
devfileTypes := getDevfileTypes()
361+
devfileTypeIndexes := selectDevfilesFromComponents(tc.components, devfileTypes)
362+
if tc.expectedDevfileTypeName == "" {
363+
assert.EqualValues(t, 0, len(devfileTypeIndexes))
364+
} else {
365+
index := devfileTypeIndexes[0]
366+
assert.EqualValues(t, tc.expectedDevfileTypeName, devfileTypes[index].Name)
367+
}
368+
})
369+
}
370+
}
371+
372+
func Test_selectDevfilesFromComponentsDetectedInPath(t *testing.T) {
373+
tests := []struct {
374+
name string
375+
path string
376+
expectedDevfileTypeName string
377+
expectingErr bool
378+
}{
379+
{
380+
name: "Case 1: Match devfile success",
381+
path: "../../../resources/projects/beego",
382+
expectedDevfileTypeName: "go",
383+
}, {
384+
name: "Case 2: No Match",
385+
path: "../../../resources/projects/notexisting",
386+
expectedDevfileTypeName: "",
387+
},
388+
}
389+
390+
for _, tc := range tests {
391+
t.Run(tc.name, func(tt *testing.T) {
392+
devfileTypes := getDevfileTypes()
393+
devfileTypeIndexes := selectDevfilesFromComponentsDetectedInPath(tc.path, devfileTypes)
394+
if tc.expectedDevfileTypeName == "" {
395+
assert.EqualValues(t, 0, len(devfileTypeIndexes))
396+
} else {
397+
index := devfileTypeIndexes[0]
398+
assert.EqualValues(t, tc.expectedDevfileTypeName, devfileTypes[index].Name)
399+
}
400+
})
401+
}
402+
}
403+
404+
func Test_selectDevfilesByLanguage(t *testing.T) {
405+
language := model.Language{
406+
Name: "LanguageOne",
407+
Frameworks: []string{"Framework"},
408+
}
409+
otherLanguage := model.Language{
410+
Name: "otherLanguage",
411+
Frameworks: []string{"otherFramework"},
412+
}
413+
devfileTypeOne := model.DevfileType{
414+
Name: language.Frameworks[0],
415+
Language: language.Name,
416+
ProjectType: language.Frameworks[0],
417+
Tags: []string{},
418+
}
419+
devfileTypeTwo := model.DevfileType{
420+
Name: "LanguageTwo",
421+
Language: language.Name,
422+
ProjectType: language.Name,
423+
Tags: []string{},
424+
}
425+
tests := []struct {
426+
name string
427+
language model.Language
428+
devfileTypes []model.DevfileType
429+
expectedIndexes []int
430+
expectingErr bool
431+
}{
432+
{
433+
name: "Case1: Simple match by language",
434+
language: language,
435+
devfileTypes: []model.DevfileType{devfileTypeOne},
436+
expectedIndexes: []int{0},
437+
expectingErr: false,
438+
}, {
439+
name: "Case2: Match by framework",
440+
language: language,
441+
devfileTypes: []model.DevfileType{devfileTypeTwo, devfileTypeOne},
442+
expectedIndexes: []int{1},
443+
expectingErr: false,
444+
}, {
445+
name: "Case3: No Match",
446+
language: otherLanguage,
447+
devfileTypes: []model.DevfileType{devfileTypeTwo, devfileTypeOne},
448+
expectedIndexes: []int{},
449+
expectingErr: true,
450+
},
451+
}
452+
for _, tc := range tests {
453+
t.Run(tc.name, func(tt *testing.T) {
454+
result, err := selectDevfilesByLanguage(tc.language, tc.devfileTypes)
455+
if tc.expectingErr {
456+
if err == nil {
457+
tt.Errorf("No error raised for case %s", tc.name)
458+
}
459+
} else {
460+
assert.EqualValues(t, tc.expectedIndexes, result)
461+
}
462+
})
463+
}
464+
}
465+
466+
func Test_getMainLanguage(t *testing.T) {
467+
languageOne := model.Language{
468+
Name: "LanguageOne",
469+
Weight: 0.60,
470+
}
471+
languageTwo := model.Language{
472+
Name: "LanguageTwo",
473+
Weight: 0.40,
474+
}
475+
tests := []struct {
476+
name string
477+
languages []model.Language
478+
expectedLanguage model.Language
479+
expectingErr bool
480+
}{
481+
{
482+
name: "Case1: First greater weight than second",
483+
languages: []model.Language{languageOne, languageTwo},
484+
expectedLanguage: languageOne,
485+
expectingErr: false,
486+
}, {
487+
name: "Case2: First smaller weight than second",
488+
languages: []model.Language{languageTwo, languageOne},
489+
expectedLanguage: languageOne,
490+
expectingErr: false,
491+
}, {
492+
name: "Case3: EmptyList",
493+
languages: []model.Language{},
494+
expectedLanguage: languageOne,
495+
expectingErr: true,
496+
},
497+
}
498+
for _, tc := range tests {
499+
t.Run(tc.name, func(tt *testing.T) {
500+
mainLanguage, err := getMainLanguage(tc.languages)
501+
if tc.expectingErr {
502+
if err == nil {
503+
tt.Errorf("No error raised for case %s", tc.name)
504+
}
505+
} else {
506+
assert.EqualValues(t, tc.expectedLanguage, mainLanguage)
507+
}
508+
})
509+
}
510+
}
511+
269512
func getExceptedVersionsUrl(url, minSchemaVersion, maxSchemaVersion string, err error) string {
270513
if err != nil {
271514
return ""

0 commit comments

Comments
 (0)