Skip to content

Commit 0b765a4

Browse files
author
Reuven Harrison
authored
Dual-prefix (#121)
* prefix-base and prefix-revision * document prefix-base and prefix-revision * support -prefix for backwards compatibility
1 parent 0918738 commit 0b765a4

11 files changed

Lines changed: 161 additions & 14 deletions

File tree

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,11 @@ Usage of oasdiff:
5858
-format string
5959
output format: yaml, text or html (default "yaml")
6060
-prefix string
61-
if provided, paths in base spec will be compared with 'prefix'+paths in revision spec
61+
deprecated. use -prefix-revision instead
62+
-prefix-base string
63+
if provided, paths in original (base) spec will be prefixed with the given prefix before comparison
64+
-prefix-revision string
65+
if provided, paths in revised (revision) spec will be prefixed with the given prefix before comparison
6266
-revision string
6367
path of revised OpenAPI spec in YAML or JSON format
6468
-summary

data/prefix/simple1.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
info:
2+
title: Tufin
3+
version: 1.0.0
4+
openapi: 3.0.3
5+
paths:
6+
/api/test:
7+
get:
8+
responses:
9+
200:
10+
description: OK
11+
/api/test1:
12+
get:
13+
responses:
14+
201:
15+
description: OK
16+

data/prefix/simple2.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
info:
2+
title: Tufin
3+
version: 1.0.0
4+
openapi: 3.0.3
5+
paths:
6+
/tenant/api/test:
7+
get:
8+
responses:
9+
200:
10+
description: OK
11+
/tenant/api/test1:
12+
get:
13+
responses:
14+
201:
15+
description: OK
16+

data/prefix/simple3.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
info:
2+
title: Tufin
3+
version: 1.0.0
4+
openapi: 3.0.3
5+
paths:
6+
/tenant/api/test:
7+
get:
8+
responses:
9+
200:
10+
description: OK
11+
/other/api/test1:
12+
get:
13+
responses:
14+
201:
15+
description: OK
16+

diff/config.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ type Config struct {
77
IncludeExtensions StringSet
88
PathFilter string
99
FilterExtension string
10-
PathPrefix string
10+
PathPrefixBase string
11+
PathPrefixRevision string
1112
BreakingOnly bool
1213
}
1314

diff/diff_prefix_test.go

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package diff_test
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/getkin/kin-openapi/openapi3"
8+
"github.com/stretchr/testify/require"
9+
"github.com/tufin/oasdiff/diff"
10+
)
11+
12+
func getPrefixFile(file string) string {
13+
return fmt.Sprintf("../data/prefix/%s", file)
14+
}
15+
16+
func TestPrefix_NoArgs(t *testing.T) {
17+
loader := openapi3.NewLoader()
18+
19+
s1, err := loader.LoadFromFile(getPrefixFile("simple1.yaml"))
20+
require.NoError(t, err)
21+
22+
s2, err := loader.LoadFromFile(getPrefixFile("simple2.yaml"))
23+
require.NoError(t, err)
24+
25+
dd, err := diff.Get(&diff.Config{}, s1, s2)
26+
require.NoError(t, err)
27+
require.NotEmpty(t, dd)
28+
}
29+
30+
func TestPrefix_BasePrefix(t *testing.T) {
31+
loader := openapi3.NewLoader()
32+
33+
s1, err := loader.LoadFromFile(getPrefixFile("simple1.yaml"))
34+
require.NoError(t, err)
35+
36+
s2, err := loader.LoadFromFile(getPrefixFile("simple2.yaml"))
37+
require.NoError(t, err)
38+
39+
dd, err := diff.Get(&diff.Config{
40+
PathPrefixBase: "/tenant",
41+
}, s1, s2)
42+
require.NoError(t, err)
43+
require.Empty(t, dd)
44+
}
45+
46+
func TestPrefix_RevisionPrefix(t *testing.T) {
47+
loader := openapi3.NewLoader()
48+
49+
s1, err := loader.LoadFromFile(getPrefixFile("simple2.yaml"))
50+
require.NoError(t, err)
51+
52+
s2, err := loader.LoadFromFile(getPrefixFile("simple1.yaml"))
53+
require.NoError(t, err)
54+
55+
dd, err := diff.Get(&diff.Config{
56+
PathPrefixRevision: "/tenant",
57+
}, s1, s2)
58+
require.NoError(t, err)
59+
require.Empty(t, dd)
60+
}
61+
62+
func TestPrefix_BasePrefixModified(t *testing.T) {
63+
loader := openapi3.NewLoader()
64+
65+
s1, err := loader.LoadFromFile(getPrefixFile("simple1.yaml"))
66+
require.NoError(t, err)
67+
68+
s2, err := loader.LoadFromFile(getPrefixFile("simple3.yaml"))
69+
require.NoError(t, err)
70+
71+
dd, err := diff.Get(&diff.Config{
72+
PathPrefixBase: "/other",
73+
}, s1, s2)
74+
require.NoError(t, err)
75+
require.NotEmpty(t, dd)
76+
}

diff/diff_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ func TestSchemaDiff_MediaType_MultiEntries(t *testing.T) {
269269

270270
func TestSchemaDiff_AnyOfModified(t *testing.T) {
271271
require.False(t,
272-
d(t, &diff.Config{PathPrefix: "/prefix"}, 4, 2).PathsDiff.Modified["/prefix/api/{domain}/{project}/badges/security-score/"].OperationsDiff.Modified["GET"].ParametersDiff.Modified[openapi3.ParameterInQuery]["token"].SchemaDiff.AnyOfDiff.Empty())
272+
d(t, &diff.Config{PathPrefixRevision: "/prefix"}, 4, 2).PathsDiff.Modified["/prefix/api/{domain}/{project}/badges/security-score/"].OperationsDiff.Modified["GET"].ParametersDiff.Modified[openapi3.ParameterInQuery]["token"].SchemaDiff.AnyOfDiff.Empty())
273273
}
274274

275275
func TestSchemaDiff_WithExamples(t *testing.T) {
@@ -284,7 +284,7 @@ func TestSchemaDiff_WithExamples(t *testing.T) {
284284

285285
func TestSchemaDiff_MinDiff(t *testing.T) {
286286

287-
dd := d(t, &diff.Config{PathPrefix: "/prefix"}, 4, 2)
287+
dd := d(t, &diff.Config{PathPrefixRevision: "/prefix"}, 4, 2)
288288

289289
require.Nil(t,
290290
dd.PathsDiff.Modified["/prefix/api/{domain}/{project}/badges/security-score/"].OperationsDiff.Modified["GET"].ParametersDiff.Modified[openapi3.ParameterInPath]["domain"].SchemaDiff.MinDiff.From)

diff/endpoints_diff.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ func getEndpointsDiffInternal(config *Config, state *state, paths1, paths2 opena
7878

7979
result := newEndpointsDiff()
8080

81-
addedPaths, deletedPaths, otherPaths := getPathItemsDiff(paths1, paths2, config.PathPrefix)
81+
addedPaths, deletedPaths, otherPaths := getPathItemsDiff(paths1, paths2, config)
8282

8383
for path, pathItem := range addedPaths {
8484
for method := range pathItem.Operations() {

diff/path_items_diff.go

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,18 @@ type pathItemPair struct {
1313

1414
type pathItemPairs map[string]*pathItemPair
1515

16-
func getPathItemsDiff(paths1, paths2 openapi3.Paths, prefix string) (openapi3.Paths, openapi3.Paths, pathItemPairs) {
16+
func getPathItemsDiff(paths1, paths2 openapi3.Paths, config *Config) (openapi3.Paths, openapi3.Paths, pathItemPairs) {
17+
return getPathItemsDiffInternal(addPrefix(paths1, config.PathPrefixBase), addPrefix(paths2, config.PathPrefixRevision))
18+
}
19+
20+
func getPathItemsDiffInternal(paths1, paths2 openapi3.Paths) (openapi3.Paths, openapi3.Paths, pathItemPairs) {
1721

1822
added := openapi3.Paths{}
1923
deleted := openapi3.Paths{}
2024
other := pathItemPairs{}
2125

2226
for endpoint1, pathItem1 := range paths1 {
23-
if pathItem2, ok := findEndpoint(strings.TrimPrefix(endpoint1, prefix), paths2); ok {
27+
if pathItem2, ok := findEndpoint(endpoint1, paths2); ok {
2428
other[endpoint1] = &pathItemPair{
2529
PathItem1: pathItem1,
2630
PathItem2: pathItem2,
@@ -31,16 +35,20 @@ func getPathItemsDiff(paths1, paths2 openapi3.Paths, prefix string) (openapi3.Pa
3135
}
3236

3337
for endpoint2, pathItem2 := range paths2 {
34-
if _, ok := findEndpoint(addPrefix(endpoint2, prefix), paths1); !ok {
38+
if _, ok := findEndpoint(endpoint2, paths1); !ok {
3539
added[endpoint2] = pathItem2
3640
}
3741
}
3842

3943
return added, deleted, other
4044
}
4145

42-
func addPrefix(s string, prefix string) string {
43-
return prefix + s
46+
func addPrefix(paths openapi3.Paths, prefix string) openapi3.Paths {
47+
result := make(openapi3.Paths, len(paths))
48+
for path, pathItem := range paths {
49+
result[prefix+path] = pathItem
50+
}
51+
return result
4452
}
4553

4654
func findEndpoint(entrypoint string, paths openapi3.Paths) (*openapi3.PathItem, bool) {

diff/paths_diff.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ func getPathsDiffInternal(config *Config, state *state, paths1, paths2 openapi3.
6868

6969
result := newPathsDiff()
7070

71-
addedPaths, deletedPaths, otherPaths := getPathItemsDiff(paths1, paths2, config.PathPrefix)
71+
addedPaths, deletedPaths, otherPaths := getPathItemsDiff(paths1, paths2, config)
7272

7373
for endpoint := range addedPaths {
7474
result.addAddedPath(endpoint)

0 commit comments

Comments
 (0)