Skip to content

Commit 93d2dcb

Browse files
chore: better merging logic
1 parent d7e9be5 commit 93d2dcb

File tree

1 file changed

+59
-63
lines changed
  • protoc-gen-openapiv3/internal/genopenapiv3

1 file changed

+59
-63
lines changed

protoc-gen-openapiv3/internal/genopenapiv3/merge.go

Lines changed: 59 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,12 @@ func MergeOpenAPISpecs(specs ...*openapi3.T) (*openapi3.T, error) {
5353
if spec.Paths != nil {
5454
for path, pathItem := range spec.Paths.Map() {
5555
if existingPathItem, exists := merged.Paths.Map()[path]; exists {
56-
mergedPathItem, err := mergePathItems(existingPathItem, pathItem)
56+
err := mergePathItems(existingPathItem, pathItem)
5757
if err != nil {
5858
return nil, fmt.Errorf("error merging path %s from spec %d: %v", path, i, err)
5959
}
6060

61-
merged.Paths.Set(path, mergedPathItem)
6261
} else {
63-
6462
merged.Paths.Set(path, pathItem)
6563
}
6664
}
@@ -89,89 +87,49 @@ func MergeOpenAPISpecs(specs ...*openapi3.T) (*openapi3.T, error) {
8987
return merged, nil
9088
}
9189

92-
// mergePathItems merges two path items, combining their operations
93-
func mergePathItems(existing, new *openapi3.PathItem) (*openapi3.PathItem, error) {
94-
merged := &openapi3.PathItem{
95-
Ref: existing.Ref,
96-
Summary: existing.Summary,
97-
Description: existing.Description,
98-
Servers: existing.Servers,
99-
Parameters: existing.Parameters,
100-
}
101-
102-
// Copy existing operations
103-
if existing.Get != nil {
104-
merged.Get = existing.Get
105-
}
106-
if existing.Put != nil {
107-
merged.Put = existing.Put
108-
}
109-
if existing.Post != nil {
110-
merged.Post = existing.Post
111-
}
112-
if existing.Delete != nil {
113-
merged.Delete = existing.Delete
114-
}
115-
if existing.Options != nil {
116-
merged.Options = existing.Options
117-
}
118-
if existing.Head != nil {
119-
merged.Head = existing.Head
120-
}
121-
if existing.Patch != nil {
122-
merged.Patch = existing.Patch
123-
}
124-
if existing.Trace != nil {
125-
merged.Trace = existing.Trace
126-
}
127-
128-
// Add new operations (overwrite existing operations with new ones)
90+
func mergePathItems(existing, new *openapi3.PathItem) error {
91+
// TODO: error and log warn when new one overrides existing one
12992
if new.Get != nil {
130-
merged.Get = new.Get
93+
existing.Get = new.Get
13194
}
13295
if new.Put != nil {
133-
merged.Put = new.Put
96+
existing.Put = new.Put
13497
}
13598
if new.Post != nil {
136-
merged.Post = new.Post
99+
existing.Post = new.Post
137100
}
138101
if new.Delete != nil {
139-
merged.Delete = new.Delete
102+
existing.Delete = new.Delete
140103
}
141104
if new.Options != nil {
142-
merged.Options = new.Options
105+
existing.Options = new.Options
143106
}
144107
if new.Head != nil {
145-
merged.Head = new.Head
108+
existing.Head = new.Head
146109
}
147110
if new.Patch != nil {
148-
merged.Patch = new.Patch
111+
existing.Patch = new.Patch
149112
}
150113
if new.Trace != nil {
151-
merged.Trace = new.Trace
114+
existing.Trace = new.Trace
152115
}
153116

154-
// Merge parameters
155117
if new.Parameters != nil {
156-
merged.Parameters = append(merged.Parameters, new.Parameters...)
118+
existing.Parameters = mergeParameters(existing.Parameters, new.Parameters)
157119
}
158120

159-
// Merge servers
160121
if new.Servers != nil {
161-
merged.Servers = append(merged.Servers, new.Servers...)
122+
existing.Servers = append(existing.Servers, new.Servers...)
162123
}
163124

164-
return merged, nil
125+
return nil
165126
}
166127

167-
// mergeComponents merges components from source into target
168128
func mergeComponents(target, source *openapi3.Components, specIndex int) error {
169-
// Merge schemas
170129
if source.Schemas != nil {
171130
maps.Copy(target.Schemas, source.Schemas)
172131
}
173132

174-
// Merge parameters
175133
if source.Parameters != nil {
176134
for name, param := range source.Parameters {
177135
if _, exists := target.Parameters[name]; exists {
@@ -181,7 +139,6 @@ func mergeComponents(target, source *openapi3.Components, specIndex int) error {
181139
}
182140
}
183141

184-
// Merge headers
185142
if source.Headers != nil {
186143
for name, header := range source.Headers {
187144
if _, exists := target.Headers[name]; exists {
@@ -191,7 +148,6 @@ func mergeComponents(target, source *openapi3.Components, specIndex int) error {
191148
}
192149
}
193150

194-
// Merge request bodies
195151
if source.RequestBodies != nil {
196152
for name, requestBody := range source.RequestBodies {
197153
if _, exists := target.RequestBodies[name]; exists {
@@ -201,7 +157,6 @@ func mergeComponents(target, source *openapi3.Components, specIndex int) error {
201157
}
202158
}
203159

204-
// Merge responses
205160
if source.Responses != nil {
206161
for name, response := range source.Responses {
207162
if _, exists := target.Responses[name]; exists {
@@ -211,7 +166,6 @@ func mergeComponents(target, source *openapi3.Components, specIndex int) error {
211166
}
212167
}
213168

214-
// Merge security schemes
215169
if source.SecuritySchemes != nil {
216170
for name, securityScheme := range source.SecuritySchemes {
217171
if _, exists := target.SecuritySchemes[name]; exists {
@@ -221,7 +175,6 @@ func mergeComponents(target, source *openapi3.Components, specIndex int) error {
221175
}
222176
}
223177

224-
// Merge examples
225178
if source.Examples != nil {
226179
for name, example := range source.Examples {
227180
if _, exists := target.Examples[name]; exists {
@@ -231,7 +184,6 @@ func mergeComponents(target, source *openapi3.Components, specIndex int) error {
231184
}
232185
}
233186

234-
// Merge links
235187
if source.Links != nil {
236188
for name, link := range source.Links {
237189
if _, exists := target.Links[name]; exists {
@@ -241,7 +193,6 @@ func mergeComponents(target, source *openapi3.Components, specIndex int) error {
241193
}
242194
}
243195

244-
// Merge callbacks
245196
if source.Callbacks != nil {
246197
for name, callback := range source.Callbacks {
247198
if _, exists := target.Callbacks[name]; exists {
@@ -253,3 +204,48 @@ func mergeComponents(target, source *openapi3.Components, specIndex int) error {
253204

254205
return nil
255206
}
207+
208+
func mergeParameters(existing, new openapi3.Parameters) openapi3.Parameters {
209+
if len(existing) == 0 {
210+
return new
211+
}
212+
if len(new) == 0 {
213+
return existing
214+
}
215+
216+
paramMap := make(map[string]*openapi3.ParameterRef)
217+
var result openapi3.Parameters
218+
219+
for _, param := range existing {
220+
if param != nil && param.Value != nil {
221+
key := getParameterKey(param.Value)
222+
paramMap[key] = param
223+
result = append(result, param)
224+
}
225+
}
226+
227+
for _, param := range new {
228+
if param != nil && param.Value != nil {
229+
key := getParameterKey(param.Value)
230+
if existingParam, exists := paramMap[key]; exists {
231+
for i, resultParam := range result {
232+
if resultParam == existingParam {
233+
result[i] = param
234+
break
235+
}
236+
}
237+
paramMap[key] = param
238+
} else {
239+
// Add new parameter
240+
paramMap[key] = param
241+
result = append(result, param)
242+
}
243+
}
244+
}
245+
246+
return result
247+
}
248+
249+
func getParameterKey(param *openapi3.Parameter) string {
250+
return param.Name + ":" + param.In
251+
}

0 commit comments

Comments
 (0)