Skip to content

Commit 41d86ce

Browse files
authored
feat(clients): delete unused models (#3445)
1 parent 56b0b8e commit 41d86ce

10 files changed

+146
-13
lines changed

generators/src/main/java/com/algolia/codegen/AlgoliaCSharpGenerator.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import com.algolia.codegen.exceptions.*;
44
import com.algolia.codegen.utils.*;
5-
import com.algolia.codegen.utils.OneOf;
65
import com.samskivert.mustache.Mustache;
76
import io.swagger.v3.oas.models.OpenAPI;
87
import io.swagger.v3.oas.models.Operation;
@@ -142,6 +141,7 @@ public void processOpenAPI(OpenAPI openAPI) {
142141
@Override
143142
public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<ModelMap> models) {
144143
OperationsMap operations = super.postProcessOperationsWithModels(objs, models);
144+
ModelPruner.removeOrphans(this, operations, models);
145145
Helpers.removeHelpers(operations);
146146
GenericPropagator.propagateGenericsToOperations(operations, models);
147147
return operations;

generators/src/main/java/com/algolia/codegen/AlgoliaGoGenerator.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import com.algolia.codegen.exceptions.*;
44
import com.algolia.codegen.lambda.ScreamingSnakeCaseLambda;
55
import com.algolia.codegen.utils.*;
6-
import com.algolia.codegen.utils.OneOf;
76
import com.google.common.collect.ImmutableMap;
87
import com.google.common.collect.Iterables;
98
import com.samskivert.mustache.Mustache;
@@ -44,6 +43,8 @@ public void processOpts() {
4443
typeMapping.put("object", "map[string]any");
4544
typeMapping.put("AnyType", "any");
4645

46+
modelNameMapping.put("range", "modelRange");
47+
4748
apiTestTemplateFiles.clear();
4849
modelTestTemplateFiles.clear();
4950
apiDocTemplateFiles.clear();
@@ -132,6 +133,7 @@ public Map<String, ModelsMap> postProcessAllModels(Map<String, ModelsMap> objs)
132133
@Override
133134
public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<ModelMap> models) {
134135
OperationsMap operations = super.postProcessOperationsWithModels(objs, models);
136+
ModelPruner.removeOrphans(this, operations, models, true);
135137
Helpers.removeHelpers(operations);
136138
GenericPropagator.propagateGenericsToOperations(operations, models);
137139
return operations;

generators/src/main/java/com/algolia/codegen/AlgoliaJavaGenerator.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import com.algolia.codegen.exceptions.*;
44
import com.algolia.codegen.utils.*;
5-
import com.algolia.codegen.utils.OneOf;
65
import com.google.common.collect.ImmutableMap.Builder;
76
import com.samskivert.mustache.Mustache;
87
import com.samskivert.mustache.Mustache.Lambda;
@@ -96,6 +95,7 @@ public Map<String, ModelsMap> postProcessAllModels(Map<String, ModelsMap> objs)
9695
@Override
9796
public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<ModelMap> models) {
9897
OperationsMap operations = super.postProcessOperationsWithModels(objs, models);
98+
ModelPruner.removeOrphans(this, operations, models);
9999
Helpers.removeHelpers(operations);
100100
GenericPropagator.propagateGenericsToOperations(operations, models);
101101
return operations;

generators/src/main/java/com/algolia/codegen/AlgoliaKotlinGenerator.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package com.algolia.codegen;
22

33
import com.algolia.codegen.utils.*;
4-
import com.algolia.codegen.utils.OneOf;
54
import com.samskivert.mustache.Mustache;
65
import io.swagger.v3.oas.models.OpenAPI;
76
import io.swagger.v3.oas.models.Operation;
@@ -188,6 +187,7 @@ private static void jsonParent(Map<String, ModelsMap> models) {
188187
@Override
189188
public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<ModelMap> models) {
190189
OperationsMap operations = super.postProcessOperationsWithModels(objs, models);
190+
ModelPruner.removeOrphans(this, operations, models);
191191
Helpers.removeHelpers(operations);
192192
GenericPropagator.propagateGenericsToOperations(operations, models);
193193
return operations;

generators/src/main/java/com/algolia/codegen/AlgoliaPhpGenerator.java

+1
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ public CodegenOperation fromOperation(String path, String httpMethod, Operation
7777
@Override
7878
public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<ModelMap> models) {
7979
OperationsMap operations = super.postProcessOperationsWithModels(objs, models);
80+
ModelPruner.removeOrphans(this, operations, models);
8081
Helpers.removeHelpers(operations);
8182
return operations;
8283
}

generators/src/main/java/com/algolia/codegen/AlgoliaPythonGenerator.java

+1
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ public CodegenOperation fromOperation(String path, String httpMethod, Operation
120120
@Override
121121
public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<ModelMap> models) {
122122
OperationsMap operations = super.postProcessOperationsWithModels(objs, models);
123+
ModelPruner.removeOrphans(this, operations, models);
123124
Helpers.removeHelpers(operations);
124125

125126
List<Map<String, String>> imports = operations.getImports();

generators/src/main/java/com/algolia/codegen/AlgoliaRubyGenerator.java

+1
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ public CodegenOperation fromOperation(String path, String httpMethod, Operation
8282
@Override
8383
public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<ModelMap> models) {
8484
OperationsMap operations = super.postProcessOperationsWithModels(objs, models);
85+
ModelPruner.removeOrphans(this, operations, models);
8586
Helpers.removeHelpers(operations);
8687
return operations;
8788
}

generators/src/main/java/com/algolia/codegen/AlgoliaSwiftGenerator.java

+1-3
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@
44
import static org.openapitools.codegen.utils.StringUtils.camelize;
55

66
import com.algolia.codegen.exceptions.*;
7-
import com.algolia.codegen.utils.GenericPropagator;
8-
import com.algolia.codegen.utils.Helpers;
9-
import com.algolia.codegen.utils.OneOf;
7+
import com.algolia.codegen.utils.*;
108
import com.samskivert.mustache.Mustache;
119
import io.swagger.v3.oas.models.OpenAPI;
1210
import io.swagger.v3.oas.models.Operation;

generators/src/main/java/com/algolia/codegen/utils/GenericPropagator.java

+4-6
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99

1010
public class GenericPropagator {
1111

12-
public String language;
13-
1412
private static Set<String> primitiveModels = new HashSet<>(Arrays.asList("object", "array", "string", "boolean", "integer"));
1513

1614
// Only static use of this class
@@ -189,6 +187,10 @@ public static void propagateGenericsToModels(Map<String, ModelsMap> modelsMap, b
189187
}
190188
}
191189

190+
public static void propagateGenericsToModels(Map<String, ModelsMap> modelsMap) {
191+
propagateGenericsToModels(modelsMap, false);
192+
}
193+
192194
/** Mark operations with a generic return type with x-is-generic */
193195
public static void propagateGenericsToOperations(OperationsMap operations, List<ModelMap> allModels) {
194196
Map<String, CodegenModel> models = convertToMap(allModels);
@@ -207,8 +209,4 @@ public static void propagateGenericsToOperations(OperationsMap operations, List<
207209
}
208210
}
209211
}
210-
211-
public static void propagateGenericsToModels(Map<String, ModelsMap> modelsMap) {
212-
propagateGenericsToModels(modelsMap, false);
213-
}
214212
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
package com.algolia.codegen.utils;
2+
3+
import java.io.File;
4+
import java.util.*;
5+
import org.openapitools.codegen.*;
6+
import org.openapitools.codegen.model.ModelMap;
7+
import org.openapitools.codegen.model.OperationsMap;
8+
9+
public class ModelPruner {
10+
11+
private static Set<String> primitiveModels = new HashSet<>(Arrays.asList("object", "array", "string", "boolean", "integer"));
12+
13+
private Map<String, CodegenModel> models;
14+
private Set<String> visitedModels;
15+
16+
private ModelPruner(Map<String, CodegenModel> models) {
17+
this.visitedModels = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
18+
this.models = models;
19+
}
20+
21+
private CodegenModel getModel(String name) {
22+
name = name.replace("?", "");
23+
// openapi generator returns some weird error when looking for primitive type, so we filter them
24+
// by hand
25+
if (primitiveModels.contains(name)) {
26+
return null;
27+
}
28+
29+
return models.get(name);
30+
}
31+
32+
private CodegenModel propertyToModel(CodegenProperty prop) {
33+
return prop == null ? null : getModel(prop.openApiType);
34+
}
35+
36+
private void exploreProperties(CodegenModel model, List<CodegenProperty> properties) {
37+
for (CodegenProperty property : properties) {
38+
CodegenModel propModel = propertyToModel(property);
39+
if (propModel != null && !visitedModels.contains(propModel.name)) {
40+
visitedModels.add(property.openApiType);
41+
visitedModels.add(propModel.name);
42+
visitModelRecursive(propModel);
43+
}
44+
CodegenModel itemsModel = propertyToModel(property.mostInnerItems);
45+
if (itemsModel != null && !visitedModels.contains(itemsModel.name)) {
46+
// In csharp the real model name varies if its part of the modelMapping so we have to add
47+
// both
48+
visitedModels.add(property.mostInnerItems.openApiType);
49+
visitedModels.add(itemsModel.name);
50+
visitModelRecursive(itemsModel);
51+
}
52+
}
53+
}
54+
55+
private void visitModelRecursive(CodegenModel model) {
56+
exploreProperties(model, model.getVars());
57+
if (model.getComposedSchemas() != null && model.getComposedSchemas().getOneOf() != null) {
58+
exploreProperties(model, model.getComposedSchemas().getOneOf());
59+
}
60+
}
61+
62+
private static Map<String, CodegenModel> convertToMap(CodegenConfig config, List<ModelMap> models) {
63+
Map<String, CodegenModel> modelsMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
64+
for (ModelMap modelMap : models) {
65+
CodegenModel model = modelMap.getModel();
66+
67+
modelsMap.put(config.toModelName(model.name), model);
68+
}
69+
return modelsMap;
70+
}
71+
72+
private void exploreGraph(OperationsMap operations) {
73+
for (CodegenModel model : models.values()) {
74+
visitModelRecursive(model);
75+
}
76+
77+
for (CodegenOperation ope : operations.getOperations().getOperation()) {
78+
if (ope.returnType != null) {
79+
CodegenModel returnType = getModel(ope.returnBaseType);
80+
if (returnType != null) {
81+
visitedModels.add(returnType.name);
82+
}
83+
}
84+
for (CodegenParameter param : ope.allParams) {
85+
CodegenModel paramType = getModel(param.baseType != null ? param.baseType : param.dataType);
86+
if (paramType != null) {
87+
visitedModels.add(paramType.name);
88+
}
89+
CodegenModel itemsModel = propertyToModel(param.mostInnerItems);
90+
if (itemsModel != null) {
91+
visitedModels.add(itemsModel.name);
92+
}
93+
}
94+
}
95+
}
96+
97+
/** remove all the unused models, most likely the sub models of allOf */
98+
public static void removeOrphans(CodegenConfig config, OperationsMap operations, List<ModelMap> allModels, boolean keepError) {
99+
// visit all the models that are accessible from:
100+
// - the properties of a model (needs recursive search)
101+
// - the return type of an operation
102+
// - the parameters of an operation
103+
104+
ModelPruner modelPruner = new ModelPruner(convertToMap(config, allModels));
105+
Helpers.prettyPrint(modelPruner.models.keySet());
106+
modelPruner.exploreGraph(operations);
107+
108+
List<String> toRemove = new ArrayList<>();
109+
for (String modelName : modelPruner.models.keySet()) {
110+
if (keepError && modelName.equals("ErrorBase")) {
111+
continue;
112+
}
113+
if (!modelPruner.visitedModels.contains(modelName)) {
114+
toRemove.add(modelName);
115+
}
116+
}
117+
118+
String templateName = config.modelTemplateFiles().keySet().iterator().next();
119+
120+
for (String modelName : toRemove) {
121+
String filename = config.modelFilename(templateName, modelName);
122+
File file = new File(filename);
123+
if (file.exists()) {
124+
file.delete();
125+
}
126+
}
127+
}
128+
129+
public static void removeOrphans(CodegenConfig config, OperationsMap operations, List<ModelMap> allModels) {
130+
removeOrphans(config, operations, allModels, false);
131+
}
132+
}

0 commit comments

Comments
 (0)