-
Notifications
You must be signed in to change notification settings - Fork 6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1747 from wing328/add_golang
[Go] Add Go API client generator
- Loading branch information
Showing
17 changed files
with
1,298 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
#!/bin/sh | ||
|
||
SCRIPT="$0" | ||
|
||
while [ -h "$SCRIPT" ] ; do | ||
ls=`ls -ld "$SCRIPT"` | ||
link=`expr "$ls" : '.*-> \(.*\)$'` | ||
if expr "$link" : '/.*' > /dev/null; then | ||
SCRIPT="$link" | ||
else | ||
SCRIPT=`dirname "$SCRIPT"`/"$link" | ||
fi | ||
done | ||
|
||
if [ ! -d "${APP_DIR}" ]; then | ||
APP_DIR=`dirname "$SCRIPT"`/.. | ||
APP_DIR=`cd "${APP_DIR}"; pwd` | ||
fi | ||
|
||
executable="./modules/swagger-codegen-cli/target/swagger-codegen-cli.jar" | ||
|
||
if [ ! -f "$executable" ] | ||
then | ||
mvn clean package | ||
fi | ||
|
||
# if you've executed sbt assembly previously it will use that instead. | ||
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties" | ||
ags="$@ generate -t modules/swagger-codegen/src/main/resources/go -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l go -o samples/client/petstore/go" | ||
|
||
java $JAVA_OPTS -jar $executable $ags |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
set executable=.\modules\swagger-codegen-cli\target\swagger-codegen-cli.jar | ||
|
||
If Not Exist %executable% ( | ||
mvn clean package | ||
) | ||
|
||
set JAVA_OPTS=%JAVA_OPTS% -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties | ||
set ags=generate -t modules\swagger-codegen\src\main\resources\go -i modules\swagger-codegen\src\test\resources\2_0\petstore.json -l go -o samples\client\petstore\go | ||
|
||
java %JAVA_OPTS% -jar %executable% %ags% |
283 changes: 283 additions & 0 deletions
283
modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/GoClientCodegen.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,283 @@ | ||
package io.swagger.codegen.languages; | ||
|
||
import io.swagger.codegen.*; | ||
import io.swagger.models.properties.ArrayProperty; | ||
import io.swagger.models.properties.MapProperty; | ||
import io.swagger.models.properties.Property; | ||
|
||
import java.io.File; | ||
import java.util.*; | ||
|
||
import org.apache.commons.lang.StringUtils; | ||
|
||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
public class GoClientCodegen extends DefaultCodegen implements CodegenConfig { | ||
static Logger LOGGER = LoggerFactory.getLogger(GoClientCodegen.class); | ||
|
||
protected String packageName = "swagger"; | ||
protected String packageVersion = "1.0.0"; | ||
|
||
public CodegenType getTag() { | ||
return CodegenType.CLIENT; | ||
} | ||
|
||
public String getName() { | ||
return "go"; | ||
} | ||
|
||
public String getHelp() { | ||
return "Generates a Go client library (beta)."; | ||
} | ||
|
||
public GoClientCodegen() { | ||
super(); | ||
outputFolder = "generated-code/go"; | ||
modelTemplateFiles.put("model.mustache", ".go"); | ||
apiTemplateFiles.put("api.mustache", ".go"); | ||
templateDir = "go"; | ||
|
||
reservedWords = new HashSet<String> ( | ||
Arrays.asList( | ||
"break", "default", "func", "interface", "select", | ||
"case", "defer", "go", "map", "struct", | ||
"chan", "else", "goto", "package", "switch", | ||
"const", "fallthrough", "if", "range", "type", | ||
"continue", "for", "import", "return", "var") | ||
); | ||
|
||
defaultIncludes = new HashSet<String>( | ||
Arrays.asList( | ||
"map", | ||
"array") | ||
); | ||
|
||
languageSpecificPrimitives = new HashSet<String>( | ||
Arrays.asList( | ||
"string", | ||
"bool", | ||
"uint", | ||
"uint32", | ||
"uint64", | ||
"int", | ||
"int32", | ||
"int64", | ||
"float32", | ||
"float64", | ||
"complex64", | ||
"complex128", | ||
"rune", | ||
"byte") | ||
); | ||
|
||
instantiationTypes.clear(); | ||
/*instantiationTypes.put("array", "GoArray"); | ||
instantiationTypes.put("map", "GoMap");*/ | ||
|
||
typeMapping.clear(); | ||
typeMapping.put("integer", "int32"); | ||
typeMapping.put("long", "int64"); | ||
typeMapping.put("float", "float32"); | ||
typeMapping.put("double", "float64"); | ||
typeMapping.put("boolean", "bool"); | ||
typeMapping.put("string", "string"); | ||
typeMapping.put("Date", "time.Time"); | ||
typeMapping.put("DateTime", "time.Time"); | ||
typeMapping.put("password", "string"); | ||
typeMapping.put("File", "*os.File"); | ||
typeMapping.put("file", "*os.File"); | ||
// map binary to string as a workaround | ||
// the correct solution is to use []byte | ||
typeMapping.put("binary", "string"); | ||
|
||
importMapping = new HashMap<String, String>(); | ||
importMapping.put("time.Time", "time"); | ||
importMapping.put("*os.File", "os"); | ||
|
||
cliOptions.clear(); | ||
cliOptions.add(new CliOption(CodegenConstants.PACKAGE_NAME, "Go package name (convention: lowercase).") | ||
.defaultValue("swagger")); | ||
cliOptions.add(new CliOption(CodegenConstants.PACKAGE_VERSION, "Go package version.") | ||
.defaultValue("1.0.0")); | ||
|
||
} | ||
|
||
@Override | ||
public void processOpts() { | ||
//super.processOpts(); | ||
|
||
if (additionalProperties.containsKey(CodegenConstants.PACKAGE_NAME)) { | ||
setPackageName((String) additionalProperties.get(CodegenConstants.PACKAGE_NAME)); | ||
} | ||
else { | ||
setPackageName("swagger"); | ||
} | ||
|
||
if (additionalProperties.containsKey(CodegenConstants.PACKAGE_VERSION)) { | ||
setPackageVersion((String) additionalProperties.get(CodegenConstants.PACKAGE_VERSION)); | ||
} | ||
else { | ||
setPackageVersion("1.0.0"); | ||
} | ||
|
||
additionalProperties.put(CodegenConstants.PACKAGE_NAME, packageName); | ||
additionalProperties.put(CodegenConstants.PACKAGE_VERSION, packageVersion); | ||
|
||
modelPackage = packageName; | ||
apiPackage = packageName; | ||
|
||
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md")); | ||
} | ||
|
||
@Override | ||
public String escapeReservedWord(String name) { | ||
return "_" + name; | ||
} | ||
|
||
@Override | ||
public String apiFileFolder() { | ||
return outputFolder + File.separator + packageName; | ||
} | ||
|
||
public String modelFileFolder() { | ||
return outputFolder + File.separator + packageName; | ||
} | ||
|
||
@Override | ||
public String toVarName(String name) { | ||
// replace - with _ e.g. created-at => created_at | ||
name = name.replaceAll("-", "_"); | ||
|
||
// if it's all uppper case, do nothing | ||
if (name.matches("^[A-Z_]*$")) | ||
return name; | ||
|
||
// camelize (lower first character) the variable name | ||
// pet_id => PetId | ||
name = camelize(name); | ||
|
||
// for reserved word or word starting with number, append _ | ||
if(reservedWords.contains(name) || name.matches("^\\d.*")) | ||
name = escapeReservedWord(name); | ||
|
||
return name; | ||
} | ||
|
||
@Override | ||
public String toParamName(String name) { | ||
// should be the same as variable name | ||
return toVarName(name); | ||
} | ||
|
||
@Override | ||
public String toModelName(String name) { | ||
// model name cannot use reserved keyword, e.g. return | ||
if(reservedWords.contains(name)) | ||
throw new RuntimeException(name + " (reserved word) cannot be used as a model name"); | ||
|
||
// camelize the model name | ||
// phone_number => PhoneNumber | ||
return camelize(name); | ||
} | ||
|
||
@Override | ||
public String toModelFilename(String name) { | ||
// should be the same as the model name | ||
return toModelName(name); | ||
} | ||
|
||
@Override | ||
public String getTypeDeclaration(Property p) { | ||
if(p instanceof ArrayProperty) { | ||
ArrayProperty ap = (ArrayProperty) p; | ||
Property inner = ap.getItems(); | ||
return "[]" + getTypeDeclaration(inner); | ||
} | ||
else if (p instanceof MapProperty) { | ||
MapProperty mp = (MapProperty) p; | ||
Property inner = mp.getAdditionalProperties(); | ||
|
||
return getSwaggerType(p) + "[string]" + getTypeDeclaration(inner); | ||
} | ||
return super.getTypeDeclaration(p); | ||
} | ||
|
||
@Override | ||
public String getSwaggerType(Property p) { | ||
String swaggerType = super.getSwaggerType(p); | ||
String type = null; | ||
if(typeMapping.containsKey(swaggerType)) { | ||
type = typeMapping.get(swaggerType); | ||
if(languageSpecificPrimitives.contains(type)) | ||
return (type); | ||
} | ||
else | ||
type = swaggerType; | ||
return type; | ||
} | ||
|
||
@Override | ||
public String toOperationId(String operationId) { | ||
// method name cannot use reserved keyword, e.g. return | ||
if(reservedWords.contains(operationId)) | ||
throw new RuntimeException(operationId + " (reserved word) cannot be used as method name"); | ||
|
||
return camelize(operationId); | ||
} | ||
|
||
@Override | ||
public Map<String, Object> postProcessOperations(Map<String, Object> objs) { | ||
@SuppressWarnings("unchecked") | ||
Map<String, Object> objectMap = (Map<String, Object>) objs.get("operations"); | ||
@SuppressWarnings("unchecked") | ||
List<CodegenOperation> operations = (List<CodegenOperation>) objectMap.get("operation"); | ||
for (CodegenOperation operation : operations) { | ||
// http method verb conversion (e.g. PUT => Put) | ||
operation.httpMethod = camelize(operation.httpMethod.toLowerCase()); | ||
} | ||
|
||
// remove model imports to avoid error | ||
List<Map<String, String>> imports = (List<Map<String, String>>) objs.get("imports"); | ||
if (imports == null) | ||
return objs; | ||
|
||
Iterator<Map<String, String>> iterator = imports.iterator(); | ||
while (iterator.hasNext()) { | ||
String _import = iterator.next().get("import"); | ||
if (_import.startsWith(apiPackage())) | ||
iterator.remove(); | ||
} | ||
|
||
return objs; | ||
} | ||
|
||
@Override | ||
public Map<String, Object> postProcessModels(Map<String, Object> objs) { | ||
// remove model imports to avoid error | ||
List<Map<String, String>> imports = (List<Map<String, String>>) objs.get("imports"); | ||
final String prefix = modelPackage(); | ||
Iterator<Map<String, String>> iterator = imports.iterator(); | ||
while (iterator.hasNext()) { | ||
String _import = iterator.next().get("import"); | ||
if (_import.startsWith(prefix)) | ||
iterator.remove(); | ||
} | ||
return objs; | ||
} | ||
|
||
@Override | ||
protected boolean needToImport(String type) { | ||
return !defaultIncludes.contains(type) | ||
&& !languageSpecificPrimitives.contains(type); | ||
} | ||
|
||
public void setPackageName(String packageName) { | ||
this.packageName = packageName; | ||
} | ||
|
||
public void setPackageVersion(String packageVersion) { | ||
this.packageVersion = packageVersion; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 12 additions & 0 deletions
12
modules/swagger-codegen/src/main/resources/go/README.mustache
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# Go API client for {{packageName}} | ||
|
||
## Overview | ||
This API client was generated by the [swagger-codegen](https://github.com/swagger-api/swagger-codegen) project. By using the [swagger-spec](https://github.com/swagger-api/swagger-spec) from a remote server, you can easily generate an API client. | ||
|
||
|
||
## Installation | ||
Put the package under your project folder and add the following in import: | ||
``` | ||
"./{{packageName}}" | ||
``` | ||
|
Oops, something went wrong.