Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Crystal] Allow double colons in model name #13736

Merged
merged 1 commit into from
Oct 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -84,27 +84,21 @@ public CrystalClientCodegen() {
SecurityFeature.BasicAuth,
SecurityFeature.BearerToken,
SecurityFeature.ApiKey,
SecurityFeature.OAuth2_Implicit
))
SecurityFeature.OAuth2_Implicit))
.excludeGlobalFeatures(
GlobalFeature.XMLStructureDefinitions,
GlobalFeature.Callbacks,
GlobalFeature.LinkObjects,
GlobalFeature.ParameterStyling,
GlobalFeature.ParameterizedServer,
GlobalFeature.MultiServer
)
GlobalFeature.MultiServer)
.includeSchemaSupportFeatures(
SchemaSupportFeature.Polymorphism
)
SchemaSupportFeature.Polymorphism)
.excludeParameterFeatures(
ParameterFeature.Cookie
)
ParameterFeature.Cookie)
.includeClientModificationFeatures(
ClientModificationFeature.BasePath,
ClientModificationFeature.UserAgent
)
);
ClientModificationFeature.UserAgent));

generatorMetadata = GeneratorMetadata.newBuilder(generatorMetadata)
.stability(Stability.BETA)
Expand All @@ -128,13 +122,14 @@ public CrystalClientCodegen() {
apiTestTemplateFiles.put("api_test.mustache", ".cr");

// TODO support auto-generated doc
//modelDocTemplateFiles.put("model_doc.mustache", ".md");
//apiDocTemplateFiles.put("api_doc.mustache", ".md");
// modelDocTemplateFiles.put("model_doc.mustache", ".md");
// apiDocTemplateFiles.put("api_doc.mustache", ".md");

// default HIDE_GENERATION_TIMESTAMP to true
hideGenerationTimestamp = Boolean.TRUE;

// reserved word. Ref: https://github.com/crystal-lang/crystal/wiki/Crystal-for-Rubyists#available-keywords
// reserved word. Ref:
// https://github.com/crystal-lang/crystal/wiki/Crystal-for-Rubyists#available-keywords
reservedWords = new HashSet<>(
Arrays.asList(
"abstract", "annotation", "do", "if", "nil?", "select", "union",
Expand All @@ -146,8 +141,7 @@ public CrystalClientCodegen() {
"break", "extend", "macro", "require", "true", "with",
"case", "false", "module", "rescue", "type", "yield",
"class", "for", "next", "responds_to?", "typeof",
"def", "fun", "nil", "return", "uninitialized")
);
"def", "fun", "nil", "return", "uninitialized"));

languageSpecificPrimitives.clear();
languageSpecificPrimitives.add("String");
Expand Down Expand Up @@ -194,37 +188,34 @@ public CrystalClientCodegen() {
cliOptions.removeIf(opt -> CodegenConstants.MODEL_PACKAGE.equals(opt.getOpt()) ||
CodegenConstants.API_PACKAGE.equals(opt.getOpt()));

cliOptions.add(new CliOption(SHARD_NAME, "shard name (e.g. twitter_client").
defaultValue("openapi_client"));
cliOptions.add(new CliOption(SHARD_NAME, "shard name (e.g. twitter_client").defaultValue("openapi_client"));

cliOptions.add(new CliOption(MODULE_NAME, "module name (e.g. TwitterClient").
defaultValue("OpenAPIClient"));
cliOptions.add(new CliOption(MODULE_NAME, "module name (e.g. TwitterClient").defaultValue("OpenAPIClient"));

cliOptions.add(new CliOption(SHARD_VERSION, "shard version.").defaultValue("1.0.0"));

cliOptions.add(new CliOption(SHARD_LICENSE, "shard license.").
defaultValue("unlicense"));
cliOptions.add(new CliOption(SHARD_LICENSE, "shard license.").defaultValue("unlicense"));

cliOptions.add(new CliOption(SHARD_HOMEPAGE, "shard homepage.").
defaultValue("http://org.openapitools"));
cliOptions.add(new CliOption(SHARD_HOMEPAGE, "shard homepage.").defaultValue("http://org.openapitools"));

cliOptions.add(new CliOption(SHARD_DESCRIPTION, "shard description.").
defaultValue("This shard maps to a REST API"));
cliOptions.add(
new CliOption(SHARD_DESCRIPTION, "shard description.").defaultValue("This shard maps to a REST API"));

cliOptions.add(new CliOption(SHARD_AUTHOR, "shard author (only one is supported)."));

cliOptions.add(new CliOption(SHARD_AUTHOR_EMAIL, "shard author email (only one is supported)."));

cliOptions.add(new CliOption(CodegenConstants.HIDE_GENERATION_TIMESTAMP, CodegenConstants.HIDE_GENERATION_TIMESTAMP_DESC).
defaultValue(Boolean.TRUE.toString()));
cliOptions.add(new CliOption(CodegenConstants.HIDE_GENERATION_TIMESTAMP,
CodegenConstants.HIDE_GENERATION_TIMESTAMP_DESC).defaultValue(Boolean.TRUE.toString()));
}

@Override
public void processOpts() {
super.processOpts();

if (StringUtils.isEmpty(System.getenv("CRYSTAL_POST_PROCESS_FILE"))) {
LOGGER.info("Hint: Environment variable 'CRYSTAL_POST_PROCESS_FILE' (optional) not defined. E.g. to format the source code, please try 'export CRYSTAL_POST_PROCESS_FILE=\"/usr/local/bin/crystal tool format\"' (Linux/Mac)");
LOGGER.info(
"Hint: Environment variable 'CRYSTAL_POST_PROCESS_FILE' (optional) not defined. E.g. to format the source code, please try 'export CRYSTAL_POST_PROCESS_FILE=\"/usr/local/bin/crystal tool format\"' (Linux/Mac)");
}

if (additionalProperties.containsKey(SHARD_NAME)) {
Expand Down Expand Up @@ -313,12 +304,14 @@ public String getName() {

@Override
public String apiFileFolder() {
return outputFolder + File.separator + srcFolder + File.separator + shardName + File.separator + apiPackage.replace("/", File.separator);
return outputFolder + File.separator + srcFolder + File.separator + shardName + File.separator
+ apiPackage.replace("/", File.separator);
}

@Override
public String modelFileFolder() {
return outputFolder + File.separator + srcFolder + File.separator + shardName + File.separator + modelPackage.replace("/", File.separator);
return outputFolder + File.separator + srcFolder + File.separator + shardName + File.separator
+ modelPackage.replace("/", File.separator);
}

@Override
Expand Down Expand Up @@ -364,7 +357,7 @@ public String getSchemaType(Schema schema) {
@Override
public String toModelName(final String name) {
String modelName;
modelName = sanitizeName(name);
modelName = sanitizeModelName(name);

if (!StringUtils.isEmpty(modelNamePrefix)) {
modelName = modelNamePrefix + "_" + modelName;
Expand Down Expand Up @@ -393,6 +386,15 @@ public String toModelName(final String name) {
return camelize(modelName);
}

public String sanitizeModelName(String modelName) {
String[] parts = modelName.split("::");
ArrayList<String> new_parts = new ArrayList<String>();
for (String part : parts) {
new_parts.add(sanitizeName(part));
}
return String.join("::", new_parts);
}

@Override
public String toModelFilename(String name) {
return underscore(toModelName(name));
Expand Down Expand Up @@ -510,7 +512,8 @@ public String toOperationId(String operationId) {

// operationId starts with a number
if (operationId.matches("^\\d.*")) {
LOGGER.warn("{} (starting with a number) cannot be used as method name. Renamed to {}", operationId, underscore(sanitizeName("call_" + operationId)));
LOGGER.warn("{} (starting with a number) cannot be used as method name. Renamed to {}", operationId,
underscore(sanitizeName("call_" + operationId)));
operationId = "call_" + operationId;
}

Expand Down Expand Up @@ -609,7 +612,8 @@ public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<Mo
return objs;
}

private String constructExampleCode(CodegenParameter codegenParameter, HashMap<String, CodegenModel> modelMaps, HashMap<String, Integer> processedModelMap) {
private String constructExampleCode(CodegenParameter codegenParameter, HashMap<String, CodegenModel> modelMaps,
HashMap<String, Integer> processedModelMap) {
if (codegenParameter.isArray) { // array
if (codegenParameter.items == null) {
return "[]";
Expand Down Expand Up @@ -669,13 +673,15 @@ private String constructExampleCode(CodegenParameter codegenParameter, HashMap<S
if (modelMaps.containsKey(codegenParameter.dataType)) {
return constructExampleCode(modelMaps.get(codegenParameter.dataType), modelMaps, processedModelMap);
} else {
//LOGGER.error("Error in constructing examples. Failed to look up the model " + codegenParameter.dataType);
// LOGGER.error("Error in constructing examples. Failed to look up the model " +
// codegenParameter.dataType);
return "TODO";
}
}
}

private String constructExampleCode(CodegenProperty codegenProperty, HashMap<String, CodegenModel> modelMaps, HashMap<String, Integer> processedModelMap) {
private String constructExampleCode(CodegenProperty codegenProperty, HashMap<String, CodegenModel> modelMaps,
HashMap<String, Integer> processedModelMap) {
if (codegenProperty.isArray) { // array
return "[" + constructExampleCode(codegenProperty.items, modelMaps, processedModelMap) + "]";
} else if (codegenProperty.isMap) {
Expand Down Expand Up @@ -735,14 +741,17 @@ private String constructExampleCode(CodegenProperty codegenProperty, HashMap<Str
if (modelMaps.containsKey(codegenProperty.dataType)) {
return constructExampleCode(modelMaps.get(codegenProperty.dataType), modelMaps, processedModelMap);
} else {
//LOGGER.error("Error in constructing examples. Failed to look up the model " + codegenParameter.dataType);
// LOGGER.error("Error in constructing examples. Failed to look up the model " +
// codegenParameter.dataType);
return "TODO";
}
}
}

private String constructExampleCode(CodegenModel codegenModel, HashMap<String, CodegenModel> modelMaps, HashMap<String, Integer> processedModelMap) {
// break infinite recursion. Return, in case a model is already processed in the current context.
private String constructExampleCode(CodegenModel codegenModel, HashMap<String, CodegenModel> modelMaps,
HashMap<String, Integer> processedModelMap) {
// break infinite recursion. Return, in case a model is already processed in the
// current context.
String model = codegenModel.name;
if (processedModelMap.containsKey(model)) {
int count = processedModelMap.get(model);
Expand All @@ -754,7 +763,8 @@ private String constructExampleCode(CodegenModel codegenModel, HashMap<String, C
throw new RuntimeException("Invalid count when constructing example: " + count);
}
} else if (codegenModel.isEnum) {
List<Map<String, String>> enumVars = (List<Map<String, String>>) codegenModel.allowableValues.get("enumVars");
List<Map<String, String>> enumVars = (List<Map<String, String>>) codegenModel.allowableValues
.get("enumVars");
return moduleName + "::" + codegenModel.classname + "::" + enumVars.get(0).get("name");
} else if (codegenModel.oneOf != null && !codegenModel.oneOf.isEmpty()) {
String subModel = (String) codegenModel.oneOf.toArray()[0];
Expand All @@ -766,7 +776,8 @@ private String constructExampleCode(CodegenModel codegenModel, HashMap<String, C

List<String> propertyExamples = new ArrayList<>();
for (CodegenProperty codegenProperty : codegenModel.requiredVars) {
propertyExamples.add(codegenProperty.name + ": " + constructExampleCode(codegenProperty, modelMaps, processedModelMap));
propertyExamples.add(
codegenProperty.name + ": " + constructExampleCode(codegenProperty, modelMaps, processedModelMap));
}
String example = moduleName + "::" + toModelName(model) + ".new";
if (!propertyExamples.isEmpty()) {
Expand Down Expand Up @@ -826,7 +837,8 @@ public String toDefaultValue(Schema p) {
LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
return "Date.parse(\"" + String.format(Locale.ROOT, localDate.toString(), "") + "\")";
} else if (p.getDefault() instanceof java.time.OffsetDateTime) {
return "Time.parse(\"" + String.format(Locale.ROOT, ((java.time.OffsetDateTime) p.getDefault()).atZoneSameInstant(ZoneId.systemDefault()).toString(), "") + "\")";
return "Time.parse(\"" + String.format(Locale.ROOT, ((java.time.OffsetDateTime) p.getDefault())
.atZoneSameInstant(ZoneId.systemDefault()).toString(), "") + "\")";
} else {
return "\"" + escapeText((String.valueOf(p.getDefault()))) + "\"";
}
Expand Down Expand Up @@ -901,14 +913,16 @@ public void postProcessFile(File file, String fileType) {
Process p = Runtime.getRuntime().exec(command);
int exitValue = p.waitFor();
if (exitValue != 0) {
try (InputStreamReader inputStreamReader = new InputStreamReader(p.getErrorStream(), StandardCharsets.UTF_8);
BufferedReader br = new BufferedReader(inputStreamReader)) {
try (InputStreamReader inputStreamReader = new InputStreamReader(p.getErrorStream(),
StandardCharsets.UTF_8);
BufferedReader br = new BufferedReader(inputStreamReader)) {
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
LOGGER.error("Error running the command ({}). Exit value: {}, Error output: {}", command, exitValue, sb);
LOGGER.error("Error running the command ({}). Exit value: {}, Error output: {}", command,
exitValue, sb);
}
} else {
LOGGER.info("Successfully executed: {}", command);
Expand All @@ -922,5 +936,7 @@ public void postProcessFile(File file, String fileType) {
}

@Override
public GeneratorLanguage generatorLanguage() { return GeneratorLanguage.CRYSTAL; }
public GeneratorLanguage generatorLanguage() {
return GeneratorLanguage.CRYSTAL;
}
}
Loading