mirror of
https://github.com/OpenAPITools/openapi-generator.git
synced 2025-05-12 12:40:53 +00:00
Added shell scripts, batch files to generate Eiffel Petstore samples. Added Setup CI (travis, shippable, etc) to cover the Eiffel Petstore samples. Refactored part of the code into an Abstract Eiffel base class, which can be later used in Eiffel server stub generators. Added Eiffel Style guide to the contribution guidelines so that Eiffel contributors know what to follow in terms of code style Fixed code generator issues. Updated mustaches templates.
This commit is contained in:
parent
9b6115ec65
commit
fa73e56c17
@ -42,6 +42,7 @@ Code change should conform to the programming style guide of the respective lang
|
||||
- C++ (Tizen): https://wiki.tizen.org/Native_Platform_Coding_Idiom_and_Style_Guide#C.2B.2B_Coding_Style
|
||||
- Clojure: https://github.com/bbatsov/clojure-style-guide
|
||||
- Elixir: https://github.com/christopheradams/elixir_style_guide
|
||||
- Eiffel: https://www.eiffel.org/doc/eiffel/Coding%20Standards
|
||||
- Erlang: https://github.com/inaka/erlang_guidelines
|
||||
- Haskell: https://github.com/tibbe/haskell-style-guide/blob/master/haskell-style.md
|
||||
- Java: https://google.github.io/styleguide/javaguide.html
|
||||
|
31
bin/eiffel-petstore.sh
Normal file
31
bin/eiffel-petstore.sh
Normal file
@ -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/eiffel -i modules/swagger-codegen/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -l eiffel -o samples/client/petstore/eiffel/"
|
||||
|
||||
java $JAVA_OPTS -jar $executable $ags
|
10
bin/windows/eiffel-petstore.bat
Normal file
10
bin/windows/eiffel-petstore.bat
Normal file
@ -0,0 +1,10 @@
|
||||
set executable=.\modules\swagger-codegen-cli\target\swagger-codegen-cli.jar
|
||||
|
||||
If Not Exist %executable% (
|
||||
mvn clean package
|
||||
)
|
||||
|
||||
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M -DloggerPath=conf/log4j.properties
|
||||
set ags=generate -i modules\swagger-codegen\src\test\resources\2_0\petstore.yaml -l eiffel -o samples\client\petstore\eiffel
|
||||
|
||||
java %JAVA_OPTS% -jar %executable% %ags%
|
@ -0,0 +1,507 @@
|
||||
package io.swagger.codegen.languages;
|
||||
|
||||
import static com.google.common.base.Strings.isNullOrEmpty;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
import io.swagger.codegen.CliOption;
|
||||
import io.swagger.codegen.CodegenConfig;
|
||||
import io.swagger.codegen.CodegenConstants;
|
||||
import io.swagger.codegen.CodegenModel;
|
||||
import io.swagger.codegen.CodegenOperation;
|
||||
import io.swagger.codegen.CodegenParameter;
|
||||
import io.swagger.codegen.CodegenProperty;
|
||||
import io.swagger.codegen.DefaultCodegen;
|
||||
import io.swagger.codegen.utils.ModelUtils;
|
||||
import io.swagger.models.properties.ArrayProperty;
|
||||
import io.swagger.models.properties.MapProperty;
|
||||
import io.swagger.models.properties.Property;
|
||||
|
||||
public abstract class AbstractEiffelCogegen extends DefaultCodegen implements CodegenConfig {
|
||||
|
||||
private final Set<String> parentModels = new HashSet<>();
|
||||
private final Multimap<String, CodegenModel> childrenByParent = ArrayListMultimap.create();
|
||||
|
||||
public AbstractEiffelCogegen(){
|
||||
super();
|
||||
setReservedWordsLowerCase(Arrays.asList(
|
||||
// language reserved words
|
||||
"across", "agent", "alias", "all", "and", "as", "assign", "attribute", "check", "class", "convert",
|
||||
"create", "Current", "debug", "deferred", "do", "else", "elseif", "end", "ensure", "expanded", "export",
|
||||
"external", "False", "feature", "from", "frozen", "if", "implies", "inherit", "inspect", "invariant",
|
||||
"like", "local", "loop", "not", "note", "obsolete", "old", "once", "only", "or", "Precursor",
|
||||
"redefine", "rename", "require", "rescue", "Result", "retry", "select", "separate", "then", "True",
|
||||
"TUPLE", "undefine", "until", "variant", "Void", "when", "xor"));
|
||||
|
||||
defaultIncludes = new HashSet<String>(Arrays.asList("map", "array"));
|
||||
|
||||
languageSpecificPrimitives = new HashSet<String>(
|
||||
Arrays.asList("BOOLEAN", "INTEGER_8", "INTEGER_16", "INTEGER_32", "INTEGER_64", "NATURAL_8",
|
||||
"NATURAL_16", "NATURAL_32", "NATURAL_64", "REAL_32", "REAL_64"));
|
||||
|
||||
instantiationTypes.clear();
|
||||
|
||||
typeMapping.clear();
|
||||
typeMapping.put("integer", "INTEGER_32");
|
||||
typeMapping.put("long", "INTEGER_64");
|
||||
typeMapping.put("number", "REAL_32");
|
||||
typeMapping.put("float", "REAL_32");
|
||||
typeMapping.put("double", "REAL_64");
|
||||
typeMapping.put("boolean", "BOOLEAN");
|
||||
typeMapping.put("string", "STRING_32");
|
||||
typeMapping.put("UUID", "UUID"); //
|
||||
typeMapping.put("date", "DATE");
|
||||
typeMapping.put("DateTime", "DATE_TIME");
|
||||
typeMapping.put("date-time", "DATE_TIME");
|
||||
typeMapping.put("password", "STRING");
|
||||
typeMapping.put("File", "FILE");
|
||||
typeMapping.put("file", "FILE");
|
||||
typeMapping.put("binary", "STRING_32");
|
||||
typeMapping.put("ByteArray", "ARRAY [NATURAL_8]");
|
||||
typeMapping.put("object", "ANY");
|
||||
typeMapping.put("map", "STRING_TABLE");
|
||||
typeMapping.put("array", "LIST");
|
||||
typeMapping.put("list", "LIST");
|
||||
|
||||
instantiationTypes.put("array", "ARRAYED_LIST");
|
||||
instantiationTypes.put("list", "ARRAYED_LIST");
|
||||
instantiationTypes.put("map", "STRING_TABLE");
|
||||
|
||||
|
||||
cliOptions.clear();
|
||||
cliOptions.add(new CliOption(CodegenConstants.PACKAGE_NAME, "Eiffel Cluster name (convention: lowercase).")
|
||||
.defaultValue("swagger"));
|
||||
cliOptions
|
||||
.add(new CliOption(CodegenConstants.PACKAGE_VERSION, "Eiffel package version.").defaultValue("1.0.0"));
|
||||
cliOptions.add(new CliOption(CodegenConstants.HIDE_GENERATION_TIMESTAMP,
|
||||
"hides the timestamp when files were generated").defaultValue(Boolean.TRUE.toString()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String escapeReservedWord(String name) {
|
||||
// Can't start with an underscore, as our fields need to start with an
|
||||
// UppercaseLetter so that Go treats them as public/visible.
|
||||
|
||||
// Options?
|
||||
// - MyName
|
||||
// - AName
|
||||
// - TheName
|
||||
// - XName
|
||||
// - X_Name
|
||||
// ... or maybe a suffix?
|
||||
// - Name_ ... think this will work.
|
||||
if (this.reservedWordsMappings().containsKey(name)) {
|
||||
return this.reservedWordsMappings().get(name);
|
||||
}
|
||||
if (name.matches("^\\d.*")) {// prepend var_
|
||||
return "var_" + name;
|
||||
}
|
||||
return "var_" + name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toVarName(String name) {
|
||||
// replace - with _ e.g. created-at => created_at
|
||||
name = sanitizeName(name.replaceAll("-", "_"));
|
||||
|
||||
// if it's all uppper case, do nothing
|
||||
if (name.matches("^[A-Z_]*$")) {
|
||||
return name;
|
||||
}
|
||||
|
||||
// pet_id
|
||||
// petId => pet_id
|
||||
name = unCamelize(name);
|
||||
|
||||
if (name.startsWith("_")){
|
||||
name = "var" + name;
|
||||
}
|
||||
|
||||
// for reserved word
|
||||
if (isReservedWord(name)) {
|
||||
name = escapeReservedWord(name);
|
||||
}
|
||||
|
||||
// for reserved word or word starting with number, append
|
||||
if (name.matches("^\\d.*")) {
|
||||
name = escapeReservedWord(name);
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toParamName(String name) {
|
||||
// params should be lowercase. E.g. "person: PERSON"
|
||||
return toVarName(name).toLowerCase();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toModelName(String name) {
|
||||
// phone_number => PHONE_NUMBER
|
||||
return toModelFilename(name).toUpperCase();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toModelFilename(String name) {
|
||||
if (!StringUtils.isEmpty(modelNamePrefix)) {
|
||||
name = modelNamePrefix + "_" + name;
|
||||
}
|
||||
|
||||
if (!StringUtils.isEmpty(modelNameSuffix)) {
|
||||
name = name + "_" + modelNameSuffix;
|
||||
}
|
||||
|
||||
name = sanitizeName(name);
|
||||
|
||||
// model name cannot use reserved keyword, e.g. return
|
||||
if (isReservedWord(name)) {
|
||||
LOGGER.warn(name + " (reserved word) cannot be used as model name. Renamed to " + ("model_" + name));
|
||||
name = "model_" + name; // e.g. return => ModelReturn (after
|
||||
// camelize)
|
||||
}
|
||||
|
||||
// model name starts with number
|
||||
if (name.matches("^\\d.*")) {
|
||||
LOGGER.warn(name + " (model name starts with number) cannot be used as model name. Renamed to "
|
||||
+ ("model_" + name));
|
||||
name = "model_" + name; // e.g. 200Response => Model200Response
|
||||
// (after camelize)
|
||||
}
|
||||
|
||||
return underscore(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toApiFilename(String name) {
|
||||
// replace - with _ e.g. created-at => created_at
|
||||
name = name.replaceAll("-", "_"); // FIXME: a parameter should not be
|
||||
// assigned. Also declare the
|
||||
// methods parameters as 'final'.
|
||||
|
||||
// e.g. PetApi.go => pet_api.go
|
||||
return underscore(name) + "_api";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toApiTestFilename(String name) {
|
||||
return toApiName(name).toLowerCase() + "_test";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toApiName(String name) {
|
||||
if (name.length() == 0) {
|
||||
return "DEFAULT_API";
|
||||
}
|
||||
return name.toUpperCase() + "_API";
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides postProcessParameter to add a vendor extension
|
||||
* "x-exportParamName". This is useful when paramName starts with a
|
||||
* lowercase letter, but we need that param to be exportable (starts with an
|
||||
* Uppercase letter).
|
||||
*
|
||||
* @param parameter
|
||||
* CodegenParameter object to be processed.
|
||||
*/
|
||||
@Override
|
||||
public void postProcessParameter(CodegenParameter parameter) {
|
||||
|
||||
// Give the base class a chance to process
|
||||
super.postProcessParameter(parameter);
|
||||
|
||||
char firstChar = parameter.paramName.charAt(0);
|
||||
|
||||
if (Character.isUpperCase(firstChar)) {
|
||||
// First char is already uppercase, just use paramName.
|
||||
parameter.vendorExtensions.put("x-exportParamName", parameter.paramName);
|
||||
|
||||
}
|
||||
|
||||
// It's a lowercase first char, let's convert it to uppercase
|
||||
StringBuilder sb = new StringBuilder(parameter.paramName);
|
||||
sb.setCharAt(0, Character.toUpperCase(firstChar));
|
||||
parameter.vendorExtensions.put("x-exportParamName", sb.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcessModelProperty(CodegenModel model, CodegenProperty property) {
|
||||
if (!isNullOrEmpty(model.parent)) {
|
||||
parentModels.add(model.parent);
|
||||
if (!childrenByParent.containsEntry(model.parent, model)) {
|
||||
childrenByParent.put(model.parent, model);
|
||||
}
|
||||
}
|
||||
if (!isNullOrEmpty(model.parentSchema)) {
|
||||
model.parentSchema = model.parentSchema.toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toModelDocFilename(String name) {
|
||||
return toModelName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toApiDocFilename(String name) {
|
||||
return toApiName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeDeclaration(Property p) {
|
||||
if (p instanceof ArrayProperty) {
|
||||
ArrayProperty ap = (ArrayProperty) p;
|
||||
Property inner = ap.getItems();
|
||||
return "LIST [" + getTypeDeclaration(inner) + "]";
|
||||
} else if (p instanceof MapProperty) {
|
||||
MapProperty mp = (MapProperty) p;
|
||||
Property inner = mp.getAdditionalProperties();
|
||||
|
||||
return getSwaggerType(p) + "[" + getTypeDeclaration(inner) + "]";
|
||||
}
|
||||
// return super.getTypeDeclaration(p);
|
||||
|
||||
// Not using the supertype invocation, because we want to UpperCamelize
|
||||
// the type.
|
||||
String swaggerType = getSwaggerType(p);
|
||||
if (typeMapping.containsKey(swaggerType)) {
|
||||
return typeMapping.get(swaggerType);
|
||||
}
|
||||
|
||||
if (typeMapping.containsValue(swaggerType)) {
|
||||
return swaggerType;
|
||||
}
|
||||
|
||||
if (languageSpecificPrimitives.contains(swaggerType)) {
|
||||
return swaggerType;
|
||||
}
|
||||
|
||||
return toModelName(swaggerType);
|
||||
}
|
||||
|
||||
@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) {
|
||||
String sanitizedOperationId = sanitizeName(operationId);
|
||||
|
||||
// method name cannot use reserved keyword, e.g. return
|
||||
if (isReservedWord(sanitizedOperationId)) {
|
||||
LOGGER.warn(operationId + " (reserved word) cannot be used as method name. Renamed to "
|
||||
+ camelize("call_" + operationId));
|
||||
sanitizedOperationId = "call_" + sanitizedOperationId;
|
||||
}
|
||||
// method name from updateSomething to update_Something.
|
||||
sanitizedOperationId = unCamelize(sanitizedOperationId);
|
||||
|
||||
return toEiffelFeatureStyle(sanitizedOperationId);
|
||||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
// if the return type is not primitive, import encoding/json
|
||||
for (CodegenOperation operation : operations) {
|
||||
if (operation.returnBaseType != null && needToImport(operation.returnBaseType)) {
|
||||
imports.add(createMapping("import", "encoding/json"));
|
||||
break; // just need to import once
|
||||
}
|
||||
}
|
||||
|
||||
// this will only import "fmt" if there are items in pathParams
|
||||
for (CodegenOperation operation : operations) {
|
||||
if (operation.pathParams != null && operation.pathParams.size() > 0) {
|
||||
imports.add(createMapping("import", "fmt"));
|
||||
break; // just need to import once
|
||||
}
|
||||
}
|
||||
|
||||
// recursively add import for mapping one type to multiple imports
|
||||
List<Map<String, String>> recursiveImports = (List<Map<String, String>>) objs.get("imports");
|
||||
if (recursiveImports == null)
|
||||
return objs;
|
||||
|
||||
ListIterator<Map<String, String>> listIterator = imports.listIterator();
|
||||
while (listIterator.hasNext()) {
|
||||
String _import = listIterator.next().get("import");
|
||||
// if the import package happens to be found in the importMapping
|
||||
// (key)
|
||||
// add the corresponding import package to the list
|
||||
if (importMapping.containsKey(_import)) {
|
||||
listIterator.add(createMapping("import", importMapping.get(_import)));
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
// recursively add import for mapping one type to multiple imports
|
||||
List<Map<String, String>> recursiveImports = (List<Map<String, String>>) objs.get("imports");
|
||||
if (recursiveImports == null)
|
||||
return objs;
|
||||
|
||||
ListIterator<Map<String, String>> listIterator = imports.listIterator();
|
||||
while (listIterator.hasNext()) {
|
||||
String _import = listIterator.next().get("import");
|
||||
// if the import package happens to be found in the importMapping
|
||||
// (key)
|
||||
// add the corresponding import package to the list
|
||||
if (importMapping.containsKey(_import)) {
|
||||
listIterator.add(createMapping("import", importMapping.get(_import)));
|
||||
}
|
||||
}
|
||||
|
||||
return objs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> postProcessAllModels(final Map<String, Object> models) {
|
||||
|
||||
final Map<String, Object> processed = super.postProcessAllModels(models);
|
||||
postProcessParentModels(models);
|
||||
return processed;
|
||||
}
|
||||
|
||||
private void postProcessParentModels(final Map<String, Object> models) {
|
||||
for (final String parent : parentModels) {
|
||||
final CodegenModel parentModel = ModelUtils.getModelByName(parent, models);
|
||||
final Collection<CodegenModel> childrenModels = childrenByParent.get(parent);
|
||||
for (final CodegenModel child : childrenModels) {
|
||||
processParentPropertiesInChildModel(parentModel, child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the child property's isInherited flag to true if it is an inherited
|
||||
* property
|
||||
*/
|
||||
private void processParentPropertiesInChildModel(final CodegenModel parent, final CodegenModel child) {
|
||||
final Map<String, CodegenProperty> childPropertiesByName = new HashMap<>(child.vars.size());
|
||||
for (final CodegenProperty childProperty : child.vars) {
|
||||
childPropertiesByName.put(childProperty.name, childProperty);
|
||||
}
|
||||
for (final CodegenProperty parentProperty : parent.vars) {
|
||||
final CodegenProperty duplicatedByParent = childPropertiesByName.get(parentProperty.name);
|
||||
if (duplicatedByParent != null) {
|
||||
duplicatedByParent.isInherited = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean needToImport(String type) {
|
||||
return !defaultIncludes.contains(type) && !languageSpecificPrimitives.contains(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String escapeQuotationMark(String input) {
|
||||
// remove " to avoid code injection
|
||||
return input.replace("\"", "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String escapeUnsafeCharacters(String input) {
|
||||
return input.replace("*/", "*_/").replace("/*", "/_*");
|
||||
}
|
||||
|
||||
public Map<String, String> createMapping(String key, String value) {
|
||||
Map<String, String> customImport = new HashMap<String, String>();
|
||||
customImport.put(key, value);
|
||||
|
||||
return customImport;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toInstantiationType(Property p) {
|
||||
if (p instanceof MapProperty) {
|
||||
MapProperty ap = (MapProperty) p;
|
||||
Property additionalProperties2 = ap.getAdditionalProperties();
|
||||
String type = additionalProperties2.getType();
|
||||
if (null == type) {
|
||||
LOGGER.error("No Type defined for Additional Property " + additionalProperties2 + "\n" //
|
||||
+ "\tIn Property: " + p);
|
||||
}
|
||||
String inner = toModelName(getSwaggerType(additionalProperties2));
|
||||
return instantiationTypes.get("map") + " [" + inner + "]";
|
||||
} else if (p instanceof ArrayProperty) {
|
||||
ArrayProperty ap = (ArrayProperty) p;
|
||||
String inner = toModelName(getSwaggerType(ap.getItems()));
|
||||
return instantiationTypes.get("array") + " [" + inner + "]";
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String unCamelize(String name) {
|
||||
return name.replaceAll("(.)(\\p{Upper})", "$1_$2").toLowerCase();
|
||||
}
|
||||
|
||||
public String toEiffelFeatureStyle(String operationId) {
|
||||
if (operationId.startsWith("get_")) {
|
||||
return operationId.substring(4, operationId.length());
|
||||
} else {
|
||||
return operationId;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,42 +1,16 @@
|
||||
package io.swagger.codegen.languages;
|
||||
|
||||
import static com.google.common.base.Strings.isNullOrEmpty;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
import io.swagger.codegen.CliOption;
|
||||
import io.swagger.codegen.CodegenConfig;
|
||||
import io.swagger.codegen.CodegenConstants;
|
||||
import io.swagger.codegen.CodegenModel;
|
||||
import io.swagger.codegen.CodegenOperation;
|
||||
import io.swagger.codegen.CodegenParameter;
|
||||
import io.swagger.codegen.CodegenProperty;
|
||||
import io.swagger.codegen.CodegenType;
|
||||
import io.swagger.codegen.DefaultCodegen;
|
||||
import io.swagger.codegen.SupportingFile;
|
||||
import io.swagger.codegen.utils.ModelUtils;
|
||||
import io.swagger.models.properties.ArrayProperty;
|
||||
import io.swagger.models.properties.MapProperty;
|
||||
import io.swagger.models.properties.Property;
|
||||
|
||||
public class EiffelClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
public class EiffelClientCodegen extends AbstractEiffelCogegen {
|
||||
static Logger LOGGER = LoggerFactory.getLogger(EiffelClientCodegen.class);
|
||||
|
||||
protected String libraryTarget = "swagger_eiffel_client";
|
||||
@ -49,9 +23,6 @@ public class EiffelClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
protected UUID uuid;
|
||||
protected UUID uuidTest;
|
||||
|
||||
private final Set<String> parentModels = new HashSet<>();
|
||||
private final Multimap<String, CodegenModel> childrenByParent = ArrayListMultimap.create();
|
||||
|
||||
@Override
|
||||
public CodegenType getTag() {
|
||||
return CodegenType.CLIENT;
|
||||
@ -79,59 +50,6 @@ public class EiffelClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
apiTestTemplateFiles.put("test/api_test.mustache", ".e");
|
||||
apiDocTemplateFiles.put("api_doc.mustache", ".md");
|
||||
embeddedTemplateDir = templateDir = "Eiffel";
|
||||
|
||||
setReservedWordsLowerCase(Arrays.asList(
|
||||
// language reserved words
|
||||
"across", "agent", "alias", "all", "and", "as", "assign", "attribute", "check", "class", "convert",
|
||||
"create", "Current", "debug", "deferred", "do", "else", "elseif", "end", "ensure", "expanded", "export",
|
||||
"external", "False", "feature", "from", "frozen", "if", "implies", "inherit", "inspect", "invariant",
|
||||
"like", "local", "loop", "not", "note", "obsolete", "old", "once", "only", "or", "Precursor",
|
||||
"redefine", "rename", "require", "rescue", "Result", "retry", "select", "separate", "then", "True",
|
||||
"TUPLE", "undefine", "until", "variant", "Void", "when", "xor"));
|
||||
|
||||
defaultIncludes = new HashSet<String>(Arrays.asList("map", "array"));
|
||||
|
||||
languageSpecificPrimitives = new HashSet<String>(
|
||||
Arrays.asList("BOOLEAN", "INTEGER_8", "INTEGER_16", "INTEGER_32", "INTEGER_64", "NATURAL_8",
|
||||
"NATURAL_16", "NATURAL_32", "NATURAL_64", "REAL_32", "REAL_64"));
|
||||
|
||||
instantiationTypes.clear();
|
||||
|
||||
typeMapping.clear();
|
||||
typeMapping.put("integer", "INTEGER_32");
|
||||
typeMapping.put("long", "INTEGER_64");
|
||||
typeMapping.put("number", "REAL_32");
|
||||
typeMapping.put("float", "REAL_32");
|
||||
typeMapping.put("double", "REAL_64");
|
||||
typeMapping.put("boolean", "BOOLEAN");
|
||||
typeMapping.put("string", "STRING_32");
|
||||
typeMapping.put("UUID", "UUID"); //
|
||||
typeMapping.put("date", "DATE");
|
||||
typeMapping.put("DateTime", "DATE_TIME");
|
||||
typeMapping.put("date-time", "DATE_TIME");
|
||||
typeMapping.put("password", "STRING");
|
||||
typeMapping.put("File", "FILE");
|
||||
typeMapping.put("file", "FILE");
|
||||
typeMapping.put("binary", "STRING_32");
|
||||
typeMapping.put("ByteArray", "ARRAY [NATURAL_8]");
|
||||
typeMapping.put("object", "ANY");
|
||||
typeMapping.put("map", "STRING_TABLE");
|
||||
typeMapping.put("array", "LIST");
|
||||
typeMapping.put("list", "LIST");
|
||||
|
||||
//instantiationTypes.put("array", "ARRAY");
|
||||
//instantiationTypes.put("list", "ARRAYED_LIST");
|
||||
//instantiationTypes.put("map", "STRING_TABLE");
|
||||
|
||||
|
||||
cliOptions.clear();
|
||||
cliOptions.add(new CliOption(CodegenConstants.PACKAGE_NAME, "Eiffel Cluster name (convention: lowercase).")
|
||||
.defaultValue("swagger"));
|
||||
cliOptions
|
||||
.add(new CliOption(CodegenConstants.PACKAGE_VERSION, "Eiffel package version.").defaultValue("1.0.0"));
|
||||
cliOptions.add(new CliOption(CodegenConstants.HIDE_GENERATION_TIMESTAMP,
|
||||
"hides the timestamp when files were generated").defaultValue(Boolean.TRUE.toString()));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -173,6 +91,7 @@ public class EiffelClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
final String authFolder = ("src/framework/auth");
|
||||
final String serializerFolder = ("src/framework/serialization");
|
||||
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
|
||||
supportingFiles.add(new SupportingFile("travis.mustache", "", ".travis.yml"));
|
||||
supportingFiles.add(new SupportingFile("ecf.mustache", "", "api_client.ecf"));
|
||||
supportingFiles.add(new SupportingFile("test/ecf_test.mustache", "test", "api_test.ecf"));
|
||||
supportingFiles.add(new SupportingFile("test/application.mustache", "test", "application.e"));
|
||||
@ -205,24 +124,6 @@ public class EiffelClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String escapeReservedWord(String name) {
|
||||
// Can't start with an underscore, as our fields need to start with an
|
||||
// UppercaseLetter so that Go treats them as public/visible.
|
||||
|
||||
// Options?
|
||||
// - MyName
|
||||
// - AName
|
||||
// - TheName
|
||||
// - XName
|
||||
// - X_Name
|
||||
// ... or maybe a suffix?
|
||||
// - Name_ ... think this will work.
|
||||
if (this.reservedWordsMappings().containsKey(name)) {
|
||||
return this.reservedWordsMappings().get(name);
|
||||
}
|
||||
return camelize(name) + '_';
|
||||
}
|
||||
|
||||
@Override
|
||||
public String apiFileFolder() {
|
||||
@ -237,141 +138,6 @@ public class EiffelClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
return outputFolder + File.separator + "test" + File.separator + "apis";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toVarName(String name) {
|
||||
// replace - with _ e.g. created-at => created_at
|
||||
name = sanitizeName(name.replaceAll("-", "_"));
|
||||
|
||||
// if it's all uppper case, do nothing
|
||||
if (name.matches("^[A-Z_]*$")) {
|
||||
return name;
|
||||
}
|
||||
|
||||
// pet_id
|
||||
// petId => pet_id
|
||||
name = unCamelize(name);
|
||||
|
||||
// for reserved word or word starting with number, append _
|
||||
if (isReservedWord(name)) {
|
||||
name = escapeReservedWord(name);
|
||||
}
|
||||
|
||||
// for reserved word or word starting with number, append _
|
||||
if (isReservedWord(name) || name.matches("^\\d.*")) {
|
||||
name = escapeReservedWord(name);
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toParamName(String name) {
|
||||
// params should be lowercase. E.g. "person: PERSON"
|
||||
return toVarName(name).toLowerCase();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toModelName(String name) {
|
||||
// phone_number => PHONE_NUMBER
|
||||
return toModelFilename(name).toUpperCase();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toModelFilename(String name) {
|
||||
if (!StringUtils.isEmpty(modelNamePrefix)) {
|
||||
name = modelNamePrefix + "_" + name;
|
||||
}
|
||||
|
||||
if (!StringUtils.isEmpty(modelNameSuffix)) {
|
||||
name = name + "_" + modelNameSuffix;
|
||||
}
|
||||
|
||||
name = sanitizeName(name);
|
||||
|
||||
// model name cannot use reserved keyword, e.g. return
|
||||
if (isReservedWord(name)) {
|
||||
LOGGER.warn(name + " (reserved word) cannot be used as model name. Renamed to " + ("model_" + name));
|
||||
name = "model_" + name; // e.g. return => ModelReturn (after
|
||||
// camelize)
|
||||
}
|
||||
|
||||
// model name starts with number
|
||||
if (name.matches("^\\d.*")) {
|
||||
LOGGER.warn(name + " (model name starts with number) cannot be used as model name. Renamed to "
|
||||
+ ("model_" + name));
|
||||
name = "model_" + name; // e.g. 200Response => Model200Response
|
||||
// (after camelize)
|
||||
}
|
||||
|
||||
return underscore(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toApiFilename(String name) {
|
||||
// replace - with _ e.g. created-at => created_at
|
||||
name = name.replaceAll("-", "_"); // FIXME: a parameter should not be
|
||||
// assigned. Also declare the
|
||||
// methods parameters as 'final'.
|
||||
|
||||
// e.g. PetApi.go => pet_api.go
|
||||
return underscore(name) + "_api";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toApiTestFilename(String name) {
|
||||
return toApiName(name).toLowerCase() + "_test";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toApiName(String name) {
|
||||
if (name.length() == 0) {
|
||||
return "DEFAULT_API";
|
||||
}
|
||||
return name.toUpperCase() + "_API";
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides postProcessParameter to add a vendor extension
|
||||
* "x-exportParamName". This is useful when paramName starts with a
|
||||
* lowercase letter, but we need that param to be exportable (starts with an
|
||||
* Uppercase letter).
|
||||
*
|
||||
* @param parameter
|
||||
* CodegenParameter object to be processed.
|
||||
*/
|
||||
@Override
|
||||
public void postProcessParameter(CodegenParameter parameter) {
|
||||
|
||||
// Give the base class a chance to process
|
||||
super.postProcessParameter(parameter);
|
||||
|
||||
char firstChar = parameter.paramName.charAt(0);
|
||||
|
||||
if (Character.isUpperCase(firstChar)) {
|
||||
// First char is already uppercase, just use paramName.
|
||||
parameter.vendorExtensions.put("x-exportParamName", parameter.paramName);
|
||||
|
||||
}
|
||||
|
||||
// It's a lowercase first char, let's convert it to uppercase
|
||||
StringBuilder sb = new StringBuilder(parameter.paramName);
|
||||
sb.setCharAt(0, Character.toUpperCase(firstChar));
|
||||
parameter.vendorExtensions.put("x-exportParamName", sb.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcessModelProperty(CodegenModel model, CodegenProperty property) {
|
||||
if (!isNullOrEmpty(model.parent)) {
|
||||
parentModels.add(model.parent);
|
||||
if (!childrenByParent.containsEntry(model.parent, model)) {
|
||||
childrenByParent.put(model.parent, model);
|
||||
}
|
||||
}
|
||||
if (!isNullOrEmpty(model.parentSchema)) {
|
||||
model.parentSchema = model.parentSchema.toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String apiDocFileFolder() {
|
||||
return (outputFolder + "/" + apiDocPath).replace('/', File.separatorChar);
|
||||
@ -382,206 +148,6 @@ public class EiffelClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
return (outputFolder + "/" + modelDocPath).replace('/', File.separatorChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toModelDocFilename(String name) {
|
||||
return toModelName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toApiDocFilename(String name) {
|
||||
return toApiName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeDeclaration(Property p) {
|
||||
if (p instanceof ArrayProperty) {
|
||||
ArrayProperty ap = (ArrayProperty) p;
|
||||
Property inner = ap.getItems();
|
||||
return "LIST [" + getTypeDeclaration(inner) + "]";
|
||||
} else if (p instanceof MapProperty) {
|
||||
MapProperty mp = (MapProperty) p;
|
||||
Property inner = mp.getAdditionalProperties();
|
||||
|
||||
return getSwaggerType(p) + "[" + getTypeDeclaration(inner) + "]";
|
||||
}
|
||||
// return super.getTypeDeclaration(p);
|
||||
|
||||
// Not using the supertype invocation, because we want to UpperCamelize
|
||||
// the type.
|
||||
String swaggerType = getSwaggerType(p);
|
||||
if (typeMapping.containsKey(swaggerType)) {
|
||||
return typeMapping.get(swaggerType);
|
||||
}
|
||||
|
||||
if (typeMapping.containsValue(swaggerType)) {
|
||||
return swaggerType;
|
||||
}
|
||||
|
||||
if (languageSpecificPrimitives.contains(swaggerType)) {
|
||||
return swaggerType;
|
||||
}
|
||||
|
||||
return toModelName(swaggerType);
|
||||
}
|
||||
|
||||
@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) {
|
||||
String sanitizedOperationId = sanitizeName(operationId);
|
||||
|
||||
// method name cannot use reserved keyword, e.g. return
|
||||
if (isReservedWord(sanitizedOperationId)) {
|
||||
LOGGER.warn(operationId + " (reserved word) cannot be used as method name. Renamed to "
|
||||
+ camelize("call_" + operationId));
|
||||
sanitizedOperationId = "call_" + sanitizedOperationId;
|
||||
}
|
||||
// method name from updateSomething to update_Something.
|
||||
sanitizedOperationId = unCamelize(sanitizedOperationId);
|
||||
|
||||
return toEiffelFeatureStyle(sanitizedOperationId);
|
||||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
// if the return type is not primitive, import encoding/json
|
||||
for (CodegenOperation operation : operations) {
|
||||
if (operation.returnBaseType != null && needToImport(operation.returnBaseType)) {
|
||||
imports.add(createMapping("import", "encoding/json"));
|
||||
break; // just need to import once
|
||||
}
|
||||
}
|
||||
|
||||
// this will only import "fmt" if there are items in pathParams
|
||||
for (CodegenOperation operation : operations) {
|
||||
if (operation.pathParams != null && operation.pathParams.size() > 0) {
|
||||
imports.add(createMapping("import", "fmt"));
|
||||
break; // just need to import once
|
||||
}
|
||||
}
|
||||
|
||||
// recursively add import for mapping one type to multiple imports
|
||||
List<Map<String, String>> recursiveImports = (List<Map<String, String>>) objs.get("imports");
|
||||
if (recursiveImports == null)
|
||||
return objs;
|
||||
|
||||
ListIterator<Map<String, String>> listIterator = imports.listIterator();
|
||||
while (listIterator.hasNext()) {
|
||||
String _import = listIterator.next().get("import");
|
||||
// if the import package happens to be found in the importMapping
|
||||
// (key)
|
||||
// add the corresponding import package to the list
|
||||
if (importMapping.containsKey(_import)) {
|
||||
listIterator.add(createMapping("import", importMapping.get(_import)));
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
// recursively add import for mapping one type to multiple imports
|
||||
List<Map<String, String>> recursiveImports = (List<Map<String, String>>) objs.get("imports");
|
||||
if (recursiveImports == null)
|
||||
return objs;
|
||||
|
||||
ListIterator<Map<String, String>> listIterator = imports.listIterator();
|
||||
while (listIterator.hasNext()) {
|
||||
String _import = listIterator.next().get("import");
|
||||
// if the import package happens to be found in the importMapping
|
||||
// (key)
|
||||
// add the corresponding import package to the list
|
||||
if (importMapping.containsKey(_import)) {
|
||||
listIterator.add(createMapping("import", importMapping.get(_import)));
|
||||
}
|
||||
}
|
||||
|
||||
return objs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> postProcessAllModels(final Map<String, Object> models) {
|
||||
|
||||
final Map<String, Object> processed = super.postProcessAllModels(models);
|
||||
postProcessParentModels(models);
|
||||
return processed;
|
||||
}
|
||||
|
||||
private void postProcessParentModels(final Map<String, Object> models) {
|
||||
for (final String parent : parentModels) {
|
||||
final CodegenModel parentModel = ModelUtils.getModelByName(parent, models);
|
||||
final Collection<CodegenModel> childrenModels = childrenByParent.get(parent);
|
||||
for (final CodegenModel child : childrenModels) {
|
||||
processParentPropertiesInChildModel(parentModel, child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the child property's isInherited flag to true if it is an inherited
|
||||
* property
|
||||
*/
|
||||
private void processParentPropertiesInChildModel(final CodegenModel parent, final CodegenModel child) {
|
||||
final Map<String, CodegenProperty> childPropertiesByName = new HashMap<>(child.vars.size());
|
||||
for (final CodegenProperty childProperty : child.vars) {
|
||||
childPropertiesByName.put(childProperty.name, childProperty);
|
||||
}
|
||||
for (final CodegenProperty parentProperty : parent.vars) {
|
||||
final CodegenProperty duplicatedByParent = childPropertiesByName.get(parentProperty.name);
|
||||
if (duplicatedByParent != null) {
|
||||
duplicatedByParent.isInherited = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean needToImport(String type) {
|
||||
return !defaultIncludes.contains(type) && !languageSpecificPrimitives.contains(type);
|
||||
}
|
||||
|
||||
public void setPackageName(String packageName) {
|
||||
this.packageName = packageName;
|
||||
}
|
||||
@ -590,34 +156,5 @@ public class EiffelClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
this.packageVersion = packageVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String escapeQuotationMark(String input) {
|
||||
// remove " to avoid code injection
|
||||
return input.replace("\"", "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String escapeUnsafeCharacters(String input) {
|
||||
return input.replace("*/", "*_/").replace("/*", "/_*");
|
||||
}
|
||||
|
||||
public Map<String, String> createMapping(String key, String value) {
|
||||
Map<String, String> customImport = new HashMap<String, String>();
|
||||
customImport.put(key, value);
|
||||
|
||||
return customImport;
|
||||
}
|
||||
|
||||
public String unCamelize(String name) {
|
||||
return name.replaceAll("(.)(\\p{Upper})", "$1_$2").toLowerCase();
|
||||
}
|
||||
|
||||
public String toEiffelFeatureStyle(String operationId) {
|
||||
if (operationId.startsWith("get_")) {
|
||||
return operationId.substring(4, operationId.length());
|
||||
} else {
|
||||
return operationId;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -29,12 +29,12 @@ All URIs are relative to *{{basePath}}*
|
||||
|
||||
Class | Method | HTTP request | Description
|
||||
------------ | ------------- | ------------- | -------------
|
||||
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}*{{classname}}* | [**{{operationId}}**]({{apiDocPath}}{{classname}}.md#{{operationIdLowerCase}}) | **{{httpMethod}}** {{path}} | {{#summary}}{{summary}}{{/summary}}
|
||||
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}*{{classname}}* | [**{{operationId}}**]({{apiDocPath}}/{{classname}}.md#{{operationIdLowerCase}}) | **{{httpMethod}}** {{path}} | {{#summary}}{{summary}}{{/summary}}
|
||||
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
|
||||
## Documentation For Models
|
||||
|
||||
{{#models}}{{#model}} - [{{{classname}}}]({{modelDocPath}}{{{classname}}}.md)
|
||||
{{#models}}{{#model}} - [{{{classname}}}]({{modelDocPath}}/{{{classname}}}.md)
|
||||
{{/model}}{{/models}}
|
||||
|
||||
## Documentation For Authorization
|
||||
|
@ -1,4 +1,4 @@
|
||||
{{>noteInfo}}
|
||||
{{>noteinfo}}
|
||||
|
||||
class
|
||||
API_CLIENT
|
||||
|
@ -1,4 +1,4 @@
|
||||
{{>noteInfo}}
|
||||
{{>noteinfo}}
|
||||
|
||||
deferred class
|
||||
AUTHENTICATION
|
||||
|
@ -0,0 +1,20 @@
|
||||
language: eiffel
|
||||
before_script:
|
||||
- export current_dir=$(pwd)
|
||||
- echo current_dir
|
||||
- cd ..
|
||||
- wget https://ftp.eiffel.com/pub/beta/nightly/Eiffel_17.11_gpl_100608-linux-x86-64.tar.bz2
|
||||
- tar -xvf Eiffel_17.11_gpl_100608-linux-x86-64.tar.bz2
|
||||
- export ISE_EIFFEL=$PWD/Eiffel_17.11
|
||||
- export ISE_PLATFORM=linux-x86-64
|
||||
- export PATH=$PATH:$ISE_EIFFEL/studio/spec/$ISE_PLATFORM/bin
|
||||
- export PATH=$PATH:$ISE_EIFFEL/tools/spec/$ISE_PLATFORM/bin
|
||||
- cd $current_dir
|
||||
|
||||
# safelist
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
|
||||
script: compile_all -ecb -melt -list_failures -clean -options dotnet=false
|
||||
|
Loading…
x
Reference in New Issue
Block a user