forked from Jonathan-Rosenberg/oasdiff
-
Notifications
You must be signed in to change notification settings - Fork 1
/
schemas_diff.go
130 lines (102 loc) · 3.35 KB
/
schemas_diff.go
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
package diff
import (
"github.com/getkin/kin-openapi/openapi3"
"github.com/treeverse/oasdiff/utils"
)
// SchemasDiff describes the changes between a pair of sets of schema objects: https://swagger.io/specification/#schema-object
type SchemasDiff struct {
Added utils.StringList `json:"added,omitempty" yaml:"added,omitempty"`
Deleted utils.StringList `json:"deleted,omitempty" yaml:"deleted,omitempty"`
Modified ModifiedSchemas `json:"modified,omitempty" yaml:"modified,omitempty"`
Base openapi3.Schemas `json:"-" yaml:"-"`
Revision openapi3.Schemas `json:"-" yaml:"-"`
}
// Empty indicates whether a change was found in this element
func (schemasDiff *SchemasDiff) Empty() bool {
if schemasDiff == nil {
return true
}
return len(schemasDiff.Added) == 0 &&
len(schemasDiff.Deleted) == 0 &&
len(schemasDiff.Modified) == 0
}
func newSchemasDiff() *SchemasDiff {
return &SchemasDiff{
Added: utils.StringList{},
Deleted: utils.StringList{},
Modified: ModifiedSchemas{},
}
}
type schemaRefPair struct {
SchemaRef1 *openapi3.SchemaRef
SchemaRef2 *openapi3.SchemaRef
}
type schemaRefPairs map[string]*schemaRefPair
func getSchemasDiff(config *Config, state *state, schemas1, schemas2 openapi3.Schemas) (*SchemasDiff, error) {
diff, err := getSchemasDiffInternal(config, state, schemas1, schemas2)
if err != nil {
return nil, err
}
if diff.Empty() {
return nil, nil
}
return diff, nil
}
func getSchemasDiffInternal(config *Config, state *state, schemas1, schemas2 openapi3.Schemas) (*SchemasDiff, error) {
result := newSchemasDiff()
addedSchemas, deletedSchemas, otherSchemas := diffSchemas(schemas1, schemas2)
for schema := range addedSchemas {
result.addAddedSchema(schema)
}
for schema := range deletedSchemas {
result.addDeletedSchema(schema)
}
for schemaName, schemaRefPair := range otherSchemas {
err := result.addModifiedSchema(config, state, schemaName, schemaRefPair.SchemaRef1, schemaRefPair.SchemaRef2)
if err != nil {
return nil, err
}
}
result.Base = schemas1
result.Revision = schemas2
return result, nil
}
func diffSchemas(schemas1, schemas2 openapi3.Schemas) (openapi3.Schemas, openapi3.Schemas, schemaRefPairs) {
added := openapi3.Schemas{}
deleted := openapi3.Schemas{}
other := schemaRefPairs{}
for schemaName1, schemaRef1 := range schemas1 {
schemaRef2, ok := schemas2[schemaName1]
if !ok {
deleted[schemaName1] = schemaRef1
continue
}
other[schemaName1] = &schemaRefPair{
SchemaRef1: schemaRef1,
SchemaRef2: schemaRef2,
}
}
for schemaName2, schemaRef2 := range schemas2 {
_, ok := schemas1[schemaName2]
if !ok {
added[schemaName2] = schemaRef2
}
}
return added, deleted, other
}
func (schemasDiff *SchemasDiff) addAddedSchema(schema string) {
schemasDiff.Added = append(schemasDiff.Added, schema)
}
func (schemasDiff *SchemasDiff) addDeletedSchema(schema string) {
schemasDiff.Deleted = append(schemasDiff.Deleted, schema)
}
func (schemasDiff *SchemasDiff) addModifiedSchema(config *Config, state *state, schemaName string, schemaRef1, schemaRef2 *openapi3.SchemaRef) error {
return schemasDiff.Modified.addSchemaDiff(config, state, schemaName, schemaRef1, schemaRef2)
}
func (schemasDiff *SchemasDiff) getSummary() *SummaryDetails {
return &SummaryDetails{
Added: len(schemasDiff.Added),
Deleted: len(schemasDiff.Deleted),
Modified: len(schemasDiff.Modified),
}
}