Skip to content

Commit 75a6aee

Browse files
committed
feature: add metadata differences
1 parent 8dab028 commit 75a6aee

File tree

14 files changed

+228
-83
lines changed

14 files changed

+228
-83
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.qdesrame.openapi.diff.compare;
2+
3+
import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged;
4+
5+
import com.qdesrame.openapi.diff.model.ChangedMetadata;
6+
import com.qdesrame.openapi.diff.model.DiffContext;
7+
import io.swagger.v3.oas.models.Components;
8+
import java.util.Optional;
9+
10+
public class MetadataDiff {
11+
12+
private Components leftComponents;
13+
private Components rightComponents;
14+
private OpenApiDiff openApiDiff;
15+
16+
public MetadataDiff(OpenApiDiff openApiDiff) {
17+
this.openApiDiff = openApiDiff;
18+
this.leftComponents =
19+
openApiDiff.getOldSpecOpenApi() != null
20+
? openApiDiff.getOldSpecOpenApi().getComponents()
21+
: null;
22+
this.rightComponents =
23+
openApiDiff.getNewSpecOpenApi() != null
24+
? openApiDiff.getNewSpecOpenApi().getComponents()
25+
: null;
26+
}
27+
28+
public Optional<ChangedMetadata> diff(String left, String right, DiffContext context) {
29+
return isChanged(new ChangedMetadata().setLeft(left).setRight(right));
30+
}
31+
}

src/main/java/com/qdesrame/openapi/diff/compare/OpenApiDiff.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public class OpenApiDiff {
4343
private OAuthFlowsDiff oAuthFlowsDiff;
4444
private OAuthFlowDiff oAuthFlowDiff;
4545
private ExtensionsDiff extensionsDiff;
46+
private MetadataDiff metadataDiff;
4647

4748
private OpenAPI oldSpecOpenApi;
4849
private OpenAPI newSpecOpenApi;
@@ -88,6 +89,7 @@ private void initializeFields() {
8889
this.oAuthFlowsDiff = new OAuthFlowsDiff(this);
8990
this.oAuthFlowDiff = new OAuthFlowDiff(this);
9091
this.extensionsDiff = new ExtensionsDiff(this);
92+
this.metadataDiff = new MetadataDiff(this);
9193
}
9294

9395
private ChangedOpenApi compare() {

src/main/java/com/qdesrame/openapi/diff/compare/OperationDiff.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,14 @@ public Optional<ChangedOperation> diff(
2424
ChangedOperation changedOperation =
2525
new ChangedOperation(context.getUrl(), context.getMethod(), oldOperation, newOperation);
2626

27-
changedOperation.setSummary(newOperation.getSummary());
27+
openApiDiff
28+
.getMetadataDiff()
29+
.diff(oldOperation.getSummary(), newOperation.getSummary(), context)
30+
.ifPresent(changedOperation::setSummary);
31+
openApiDiff
32+
.getMetadataDiff()
33+
.diff(oldOperation.getDescription(), newOperation.getDescription(), context)
34+
.ifPresent(changedOperation::setDescription);
2835
changedOperation.setDeprecated(
2936
!Boolean.TRUE.equals(oldOperation.getDeprecated())
3037
&& Boolean.TRUE.equals(newOperation.getDeprecated()));
@@ -34,7 +41,7 @@ public Optional<ChangedOperation> diff(
3441
.getRequestBodyDiff()
3542
.diff(
3643
oldOperation.getRequestBody(), newOperation.getRequestBody(), context.copyAsRequest())
37-
.ifPresent(changedOperation::setChangedRequestBody);
44+
.ifPresent(changedOperation::setRequestBody);
3845
}
3946

4047
openApiDiff
@@ -43,27 +50,27 @@ public Optional<ChangedOperation> diff(
4350
.ifPresent(
4451
params -> {
4552
removePathParameters(context.getParameters(), params);
46-
changedOperation.setChangedParameters(params);
53+
changedOperation.setParameters(params);
4754
});
4855

4956
if (oldOperation.getResponses() != null || newOperation.getResponses() != null) {
5057
openApiDiff
5158
.getApiResponseDiff()
5259
.diff(oldOperation.getResponses(), newOperation.getResponses(), context.copyAsResponse())
53-
.ifPresent(changedOperation::setChangedApiResponse);
60+
.ifPresent(changedOperation::setApiResponses);
5461
}
5562

5663
if (oldOperation.getSecurity() != null || newOperation.getSecurity() != null) {
5764
openApiDiff
5865
.getSecurityRequirementsDiff()
5966
.diff(oldOperation.getSecurity(), newOperation.getSecurity(), context)
60-
.ifPresent(changedOperation::setChangedSecurityRequirements);
67+
.ifPresent(changedOperation::setSecurityRequirements);
6168
}
6269

6370
openApiDiff
6471
.getExtensionsDiff()
6572
.diff(oldOperation.getExtensions(), newOperation.getExtensions(), context)
66-
.ifPresent(changedOperation::setChangedExtensions);
73+
.ifPresent(changedOperation::setExtensions);
6774

6875
return isChanged(changedOperation);
6976
}

src/main/java/com/qdesrame/openapi/diff/model/Changed.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.qdesrame.openapi.diff.model;
22

3+
import java.util.Optional;
4+
35
public interface Changed {
46
DiffResult isChanged();
57

@@ -18,4 +20,8 @@ default boolean isUnchanged() {
1820
default boolean isDifferent() {
1921
return isChanged().isDifferent();
2022
}
23+
24+
static DiffResult result(Changed changed) {
25+
return Optional.ofNullable(changed).map(Changed::isChanged).orElse(DiffResult.NO_CHANGES);
26+
}
2127
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.qdesrame.openapi.diff.model;
2+
3+
import java.util.Objects;
4+
import lombok.Getter;
5+
import lombok.Setter;
6+
import lombok.experimental.Accessors;
7+
8+
@Getter
9+
@Setter
10+
@Accessors(chain = true)
11+
public class ChangedMetadata implements Changed {
12+
13+
private String left;
14+
private String right;
15+
16+
@Override
17+
public DiffResult isChanged() {
18+
if (Objects.equals(left, right)) {
19+
return DiffResult.NO_CHANGES;
20+
}
21+
return DiffResult.METADATA;
22+
}
23+
}
Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.qdesrame.openapi.diff.model;
22

3+
import static com.qdesrame.openapi.diff.model.Changed.result;
4+
35
import com.qdesrame.openapi.diff.model.schema.ChangedExtensions;
46
import com.qdesrame.openapi.diff.utils.ChangedUtils;
57
import io.swagger.v3.oas.models.Operation;
@@ -14,13 +16,14 @@ public class ChangedOperation implements Changed {
1416
private PathItem.HttpMethod httpMethod;
1517
private Operation oldOperation;
1618
private Operation newOperation;
17-
private String summary;
19+
private ChangedMetadata summary;
20+
private ChangedMetadata description;
1821
private boolean deprecated;
19-
private ChangedParameters changedParameters;
20-
private ChangedRequestBody changedRequestBody;
21-
private ChangedApiResponse changedApiResponse;
22-
private ChangedSecurityRequirements changedSecurityRequirements;
23-
private ChangedExtensions changedExtensions;
22+
private ChangedParameters parameters;
23+
private ChangedRequestBody requestBody;
24+
private ChangedApiResponse apiResponses;
25+
private ChangedSecurityRequirements securityRequirements;
26+
private ChangedExtensions extensions;
2427

2528
public ChangedOperation(
2629
String pathUrl,
@@ -37,38 +40,55 @@ public ChangedOperation(
3740
public DiffResult isChanged() {
3841
// TODO BETTER HANDLING FOR DEPRECIATION
3942
if (!deprecated
40-
&& isChangedParam().isUnchanged()
41-
&& isChangedRequest().isUnchanged()
42-
&& isChangedResponse().isUnchanged()
43-
&& isChangedSecurity().isUnchanged()
44-
&& ChangedUtils.isUnchanged(changedExtensions)) {
43+
&& resultParameters().isUnchanged()
44+
&& resultRequestBody().isUnchanged()
45+
&& resultApiResponses().isUnchanged()
46+
&& resultSecurityRequirements().isUnchanged()
47+
&& resultExtensions().isUnchanged()
48+
&& resultDescription().isUnchanged()
49+
&& resultSummary().isUnchanged()) {
4550
return DiffResult.NO_CHANGES;
4651
}
47-
if (isChangedParam().isCompatible()
48-
&& isChangedRequest().isCompatible()
49-
&& isChangedResponse().isCompatible()
50-
&& isChangedSecurity().isCompatible()
51-
&& ChangedUtils.isCompatible(changedExtensions)) {
52+
if (resultDescription().isMetaChanged()
53+
|| resultSummary().isMetaChanged()
54+
|| resultExtensions().isMetaChanged()) {
55+
return DiffResult.METADATA;
56+
}
57+
if (resultParameters().isCompatible()
58+
&& resultRequestBody().isCompatible()
59+
&& resultApiResponses().isCompatible()
60+
&& resultSecurityRequirements().isCompatible()
61+
&& ChangedUtils.isCompatible(extensions)) {
5262
return DiffResult.COMPATIBLE;
5363
}
5464
return DiffResult.INCOMPATIBLE;
5565
}
5666

57-
public DiffResult isChangedParam() {
58-
return changedParameters == null ? DiffResult.NO_CHANGES : changedParameters.isChanged();
67+
public DiffResult resultParameters() {
68+
return result(parameters);
69+
}
70+
71+
public DiffResult resultApiResponses() {
72+
return result(apiResponses);
73+
}
74+
75+
public DiffResult resultRequestBody() {
76+
return requestBody == null ? DiffResult.NO_CHANGES : requestBody.isChanged();
77+
}
78+
79+
public DiffResult resultSecurityRequirements() {
80+
return securityRequirements == null ? DiffResult.NO_CHANGES : securityRequirements.isChanged();
5981
}
6082

61-
public DiffResult isChangedResponse() {
62-
return changedApiResponse == null ? DiffResult.NO_CHANGES : changedApiResponse.isChanged();
83+
public DiffResult resultDescription() {
84+
return result(description);
6385
}
6486

65-
public DiffResult isChangedRequest() {
66-
return changedRequestBody == null ? DiffResult.NO_CHANGES : changedRequestBody.isChanged();
87+
public DiffResult resultSummary() {
88+
return result(summary);
6789
}
6890

69-
public DiffResult isChangedSecurity() {
70-
return changedSecurityRequirements == null
71-
? DiffResult.NO_CHANGES
72-
: changedSecurityRequirements.isChanged();
91+
public DiffResult resultExtensions() {
92+
return result(extensions);
7393
}
7494
}
Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,41 @@
11
package com.qdesrame.openapi.diff.model;
22

33
public enum DiffResult {
4-
NO_CHANGES("no_changes"),
5-
COMPATIBLE("compatible"),
6-
INCOMPATIBLE("incompatible"),
7-
UNKNOWN("unknown");
4+
NO_CHANGES("no_changes", 0),
5+
METADATA("metadata", 1),
6+
COMPATIBLE("compatible", 2),
7+
UNKNOWN("unknown", 3),
8+
INCOMPATIBLE("incompatible", 4);
89

910
private final String value;
11+
private final int weight;
1012

11-
DiffResult(String value) {
13+
DiffResult(String value, int weight) {
1214
this.value = value;
15+
this.weight = weight;
1316
}
1417

1518
public String getValue() {
1619
return value;
1720
}
1821

1922
public boolean isUnchanged() {
20-
return this.equals(NO_CHANGES);
23+
return this.weight == 0;
2124
}
2225

2326
public boolean isDifferent() {
24-
return !this.equals(NO_CHANGES);
27+
return this.weight > 0;
2528
}
2629

2730
public boolean isIncompatible() {
28-
return !this.equals(NO_CHANGES) && !this.equals(COMPATIBLE);
31+
return this.weight > 2;
2932
}
3033

3134
public boolean isCompatible() {
32-
return this.equals(NO_CHANGES) || this.equals(COMPATIBLE);
35+
return this.weight <= 2;
36+
}
37+
38+
public boolean isMetaChanged() {
39+
return this.weight == 1;
3340
}
3441
}

src/main/java/com/qdesrame/openapi/diff/output/ConsoleRender.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import io.swagger.v3.oas.models.responses.ApiResponse;
66
import java.util.List;
77
import java.util.Map;
8+
import java.util.Optional;
89
import org.apache.commons.httpclient.HttpStatus;
910
import org.apache.commons.lang3.StringUtils;
1011

@@ -58,29 +59,30 @@ private String ol_changed(List<ChangedOperation> operations) {
5859
for (ChangedOperation operation : operations) {
5960
String pathUrl = operation.getPathUrl();
6061
String method = operation.getHttpMethod().toString();
61-
String desc = operation.getSummary();
62+
String desc =
63+
Optional.ofNullable(operation.getSummary()).map(ChangedMetadata::getRight).orElse("");
6264

6365
StringBuilder ul_detail = new StringBuilder();
64-
if (operation.isChangedParam().isDifferent()) {
66+
if (operation.resultParameters().isDifferent()) {
6567
ul_detail
6668
.append(StringUtils.repeat(' ', 2))
6769
.append("Parameter:")
6870
.append(System.lineSeparator())
69-
.append(ul_param(operation.getChangedParameters()));
71+
.append(ul_param(operation.getParameters()));
7072
}
71-
if (operation.isChangedRequest().isDifferent()) {
73+
if (operation.resultRequestBody().isDifferent()) {
7274
ul_detail
7375
.append(StringUtils.repeat(' ', 2))
7476
.append("Request:")
7577
.append(System.lineSeparator())
76-
.append(ul_content(operation.getChangedRequestBody().getChangedContent(), true));
78+
.append(ul_content(operation.getRequestBody().getChangedContent(), true));
7779
}
78-
if (operation.isChangedResponse().isDifferent()) {
80+
if (operation.resultApiResponses().isDifferent()) {
7981
ul_detail
8082
.append(StringUtils.repeat(' ', 2))
8183
.append("Return Type:")
8284
.append(System.lineSeparator())
83-
.append(ul_response(operation.getChangedApiResponse()));
85+
.append(ul_response(operation.getApiResponses()));
8486
}
8587
sb.append(itemEndpoint(method, pathUrl, desc)).append(ul_detail);
8688
}

src/main/java/com/qdesrame/openapi/diff/output/HtmlRender.java

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import j2html.tags.ContainerTag;
1010
import java.util.List;
1111
import java.util.Map;
12+
import java.util.Optional;
1213

1314
public class HtmlRender implements Render {
1415

@@ -116,22 +117,25 @@ private ContainerTag ol_changed(List<ChangedOperation> changedOperations) {
116117
for (ChangedOperation changedOperation : changedOperations) {
117118
String pathUrl = changedOperation.getPathUrl();
118119
String method = changedOperation.getHttpMethod().toString();
119-
String desc = changedOperation.getSummary();
120+
String desc =
121+
Optional.ofNullable(changedOperation.getSummary())
122+
.map(ChangedMetadata::getRight)
123+
.orElse("");
120124

121125
ContainerTag ul_detail = ul().withClass("detail");
122-
if (changedOperation.isChangedParam().isDifferent()) {
126+
if (changedOperation.resultParameters().isDifferent()) {
123127
ul_detail.with(
124-
li().with(h3("Parameters")).with(ul_param(changedOperation.getChangedParameters())));
128+
li().with(h3("Parameters")).with(ul_param(changedOperation.getParameters())));
125129
}
126-
if (changedOperation.isChangedRequest().isDifferent()) {
130+
if (changedOperation.resultRequestBody().isDifferent()) {
127131
ul_detail.with(
128132
li().with(h3("Request"))
129-
.with(ul_request(changedOperation.getChangedRequestBody().getChangedContent())));
133+
.with(ul_request(changedOperation.getRequestBody().getChangedContent())));
130134
} else {
131135
}
132-
if (changedOperation.isChangedResponse().isDifferent()) {
136+
if (changedOperation.resultApiResponses().isDifferent()) {
133137
ul_detail.with(
134-
li().with(h3("Response")).with(ul_response(changedOperation.getChangedApiResponse())));
138+
li().with(h3("Response")).with(ul_response(changedOperation.getApiResponses())));
135139
}
136140
ol.with(
137141
li().with(span(method).withClass(method))

0 commit comments

Comments
 (0)