MCPcopy Create free account
hub / github.com/devfile/api / MergeDevWorkspaceTemplateSpec

Function MergeDevWorkspaceTemplateSpec

pkg/utils/overriding/merging.go:40–157  ·  view source on GitHub ↗

MergeDevWorkspaceTemplateSpec implements the merging logic of a main devfile content with flattened, already-overridden parent devfiles or plugins. On a `main` `DevWorkspaceTemplateSpec` (which is the core part of a devfile, without the `apiVersion` and `metadata`), it allows adding all the new over

(
	mainContent *dw.DevWorkspaceTemplateSpecContent,
	parentFlattenedContent *dw.DevWorkspaceTemplateSpecContent,
	pluginFlattenedContents ...*dw.DevWorkspaceTemplateSpecContent)

Source from the content-addressed store, hash-verified

38// The result is a transformed `DevWorkspaceTemplateSpec` object, that does not contain any `plugin` component
39// (since they are expected to be provided as flattened overridden devfiles in the arguments)
40func MergeDevWorkspaceTemplateSpec(
41 mainContent *dw.DevWorkspaceTemplateSpecContent,
42 parentFlattenedContent *dw.DevWorkspaceTemplateSpecContent,
43 pluginFlattenedContents ...*dw.DevWorkspaceTemplateSpecContent) (*dw.DevWorkspaceTemplateSpecContent, error) {
44
45 allContents := []*dw.DevWorkspaceTemplateSpecContent{}
46 if parentFlattenedContent != nil {
47 allContents = append(allContents, parentFlattenedContent)
48 }
49 if len(pluginFlattenedContents) > 0 {
50 allContents = append(allContents, pluginFlattenedContents...)
51 }
52 allContents = append(allContents, mainContent)
53
54 // Check for conflicts
55 if parentFlattenedContent != nil {
56 if err := ensureNoConflictWithParent(mainContent, parentFlattenedContent); err != nil {
57 return nil, err
58 }
59 }
60 if len(pluginFlattenedContents) > 0 {
61 if err := ensureNoConflictsWithPlugins(mainContent, pluginFlattenedContents...); err != nil {
62 return nil, err
63 }
64 if parentFlattenedContent != nil {
65 // also need to ensure no conflict between parent and plugins
66 if err := ensureNoConflictsWithPlugins(parentFlattenedContent, pluginFlattenedContents...); err != nil {
67 return nil, err
68 }
69 }
70 }
71
72 result := dw.DevWorkspaceTemplateSpecContent{}
73
74 // Merge top-level lists (Commands, Projects, Components, etc ...)
75
76 topLevelListsNames := result.GetToplevelLists()
77 topLevelListsByContent := []dw.TopLevelLists{}
78 for _, content := range allContents {
79 topLevelListsByContent = append(topLevelListsByContent, content.GetToplevelLists())
80 }
81
82 resultValue := reflect.ValueOf(&result).Elem()
83 for toplevelListName := range topLevelListsNames {
84 listType, fieldExists := resultValue.Type().FieldByName(toplevelListName)
85 if !fieldExists {
86 return nil, fmt.Errorf("field '%v' is unknown in %v struct (this should never happen)", toplevelListName, reflect.TypeOf(resultValue).Name())
87 }
88 if listType.Type.Kind() != reflect.Slice {
89 return nil, fmt.Errorf("field '%v' in %v struct is not a slice (this should never happen)", toplevelListName, reflect.TypeOf(resultValue).Name())
90 }
91 listElementType := listType.Type.Elem()
92 resultToplevelListValue := resultValue.FieldByName(toplevelListName)
93 for contentIndex, content := range allContents {
94 toplevelLists := topLevelListsByContent[contentIndex]
95 keyedList := toplevelLists[toplevelListName]
96 for _, keyed := range keyedList {
97 if content == mainContent {

Callers 3

TestMergingOnlyPluginsFunction · 0.85
TestMergingOnlyParentFunction · 0.85

Calls 6

GetToplevelListsMethod · 0.95
NameMethod · 0.80
PutMethod · 0.80
GetToplevelListsMethod · 0.65

Tested by 2

TestMergingOnlyPluginsFunction · 0.68
TestMergingOnlyParentFunction · 0.68