forked from loafle/openapi-generator-original
[Bash] Bash client script generator (#4541)
* Initial commit * Remormatted petstore tests * Added Bash codegen to main README.md * Added bash to integration tests * Fixed stdin detection in generated script * Added back ruby module
This commit is contained in:
parent
2e4de0ca1e
commit
0fb154e9a2
@ -24,6 +24,12 @@ before_install:
|
||||
- docker pull swaggerapi/petstore
|
||||
- docker run -d -e SWAGGER_HOST=http://petstore.swagger.io -e SWAGGER_BASE_PATH=/v2 -p 80:8080 swaggerapi/petstore
|
||||
- docker ps -a
|
||||
# Add bats test framework and cURL for Bash script integration tests
|
||||
- sudo add-apt-repository ppa:duggan/bats --yes
|
||||
- sudo apt-get update -qq
|
||||
- sudo apt-get install -qq bats
|
||||
- sudo apt-get install -qq curl
|
||||
|
||||
# show host table to confirm petstore.swagger.io is mapped to localhost
|
||||
- cat /etc/hosts
|
||||
|
||||
|
@ -30,6 +30,7 @@ For a list of variables available in the template, please refer to this [page](h
|
||||
### Style guide
|
||||
Code change should conform to the programming style guide of the respective languages:
|
||||
- Android: https://source.android.com/source/code-style.html
|
||||
- Bash: https://github.com/bahamas10/bash-style-guide
|
||||
- C#: https://msdn.microsoft.com/en-us/library/vstudio/ff926074.aspx
|
||||
- C++: https://google.github.io/styleguide/cppguide.html
|
||||
- Clojure: https://github.com/bbatsov/clojure-style-guide
|
||||
|
@ -15,7 +15,7 @@
|
||||
## Overview
|
||||
This is the swagger codegen project, which allows generation of API client libraries (SDK generation), server stubs and documentation automatically given an [OpenAPI Spec](https://github.com/OAI/OpenAPI-Specification). Currently, the following languages/frameworks are supported:
|
||||
|
||||
- **API clients**: **ActionScript**, **C#** (.net 2.0, 4.0 or later), **C++** (cpprest, Qt5, Tizen), **Clojure**, **Dart**, **Go**, **Groovy**, **Haskell**, **Java** (Jersey1.x, Jersey2.x, OkHttp, Retrofit1.x, Retrofit2.x, Feign), **Node.js** (ES5, ES6, AngularJS with Google Closure Compiler annotations) **Objective-C**, **Perl**, **PHP**, **Python**, **Ruby**, **Scala**, **Swift** (2.x, 3.x), **Typescript** (Angular1.x, Angular2.x, Fetch, Node)
|
||||
- **API clients**: **ActionScript**, **Bash**,**C#** (.net 2.0, 4.0 or later), **C++** (cpprest, Qt5, Tizen), **Clojure**, **Dart**, **Go**, **Groovy**, **Haskell**, **Java** (Jersey1.x, Jersey2.x, OkHttp, Retrofit1.x, Retrofit2.x, Feign), **Node.js** (ES5, ES6, AngularJS with Google Closure Compiler annotations) **Objective-C**, **Perl**, **PHP**, **Python**, **Ruby**, **Scala**, **Swift** (2.x, 3.x), **Typescript** (Angular1.x, Angular2.x, Fetch, Node)
|
||||
- **Server stubs**: **C#** (ASP.NET Core, NancyFx), **Erlang**, **Go**, **Haskell**, **Java** (MSF4J, Spring, Undertow, JAX-RS: CDI, CXF, Inflector, RestEasy), **PHP** (Lumen, Slim, Silex), **Python** (Flask), **NodeJS**, **Ruby** (Sinatra, Rails5), **Scala** (Scalatra)
|
||||
- **API documentation generators**: **HTML**, **Confluence Wiki**
|
||||
- **Others**: **JMeter**
|
||||
@ -463,6 +463,7 @@ AndroidClientCodegen.java
|
||||
AspNet5ServerCodegen.java
|
||||
AspNetCoreServerCodegen.java
|
||||
AsyncScalaClientCodegen.java
|
||||
BashClientCodegen.java
|
||||
CSharpClientCodegen.java
|
||||
ClojureClientCodegen.java
|
||||
CsharpDotNet2ClientCodegen.java
|
||||
@ -891,6 +892,7 @@ Swagger Codegen core team members are contributors who have been making signific
|
||||
Here is a list of template creators:
|
||||
* API Clients:
|
||||
* Akka-Scala: @cchafer
|
||||
* Bash: @bkryza
|
||||
* C++ REST: @Danielku15
|
||||
* C# (.NET 2.0): @who
|
||||
* Clojure: @xhh
|
||||
|
31
bin/bash-petstore.sh
Executable file
31
bin/bash-petstore.sh
Executable 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"
|
||||
args="$@ generate -t modules/swagger-codegen/src/main/resources/bash -i modules/swagger-codegen/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -l bash -o samples/client/petstore/bash -c modules/swagger-codegen/src/test/resources/2_0/bash-config.json"
|
||||
|
||||
java $JAVA_OPTS -jar $executable $args
|
@ -0,0 +1,655 @@
|
||||
package io.swagger.codegen.languages;
|
||||
|
||||
import io.swagger.codegen.*;
|
||||
import io.swagger.models.properties.*;
|
||||
import io.swagger.models.parameters.*;
|
||||
import io.swagger.models.Model;
|
||||
import io.swagger.models.Operation;
|
||||
import io.swagger.models.Swagger;
|
||||
import io.swagger.models.properties.ArrayProperty;
|
||||
import io.swagger.models.properties.MapProperty;
|
||||
import io.swagger.models.properties.Property;
|
||||
|
||||
import org.apache.commons.lang3.StringEscapeUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.io.File;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.core.JsonGenerationException;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
|
||||
public class BashClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
|
||||
protected String apiVersion = "1.0.0";
|
||||
|
||||
protected String curlOptions;
|
||||
protected boolean processMarkdown = false;
|
||||
protected String scriptName = "client.sh";
|
||||
protected boolean generateBashCompletion = false;
|
||||
protected boolean generateZshCompletion = false;
|
||||
protected String hostEnvironmentVariable;
|
||||
protected String basicAuthEnvironmentVariable;
|
||||
protected String apiKeyAuthEnvironmentVariable;
|
||||
|
||||
|
||||
public static final String CURL_OPTIONS = "curlOptions";
|
||||
public static final String PROCESS_MARKDOWN = "processMarkdown";
|
||||
public static final String SCRIPT_NAME = "scriptName";
|
||||
public static final String
|
||||
GENERATE_BASH_COMPLETION = "generateBashCompletion";
|
||||
public static final String
|
||||
GENERATE_ZSH_COMPLETION = "generateZshCompletion";
|
||||
public static final String
|
||||
HOST_ENVIRONMENT_VARIABLE_NAME = "hostEnvironmentVariable";
|
||||
public static final String
|
||||
BASIC_AUTH_ENVIRONMENT_VARIABLE_NAME = "basicAuthEnvironmentVariable";
|
||||
public static final String
|
||||
APIKEY_AUTH_ENVIRONMENT_VARIABLE_NAME = "apiKeyAuthEnvironmentVariable";
|
||||
|
||||
/**
|
||||
* Configures the type of generator.
|
||||
*
|
||||
* @return the CodegenType for this generator
|
||||
* @see io.swagger.codegen.CodegenType
|
||||
*/
|
||||
public CodegenType getTag() {
|
||||
return CodegenType.CLIENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures a friendly name for the generator. This will be used by
|
||||
* the generator to select the library with the -l flag.
|
||||
*
|
||||
* @return the friendly name for the generator
|
||||
*/
|
||||
public String getName() {
|
||||
return "bash";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns human-friendly help for the generator. Provide the consumer with
|
||||
* help tips, parameters here
|
||||
*
|
||||
* @return A string value for the help message
|
||||
*/
|
||||
public String getHelp() {
|
||||
return "Generates a Bash client script based on cURL.";
|
||||
}
|
||||
|
||||
public BashClientCodegen() {
|
||||
super();
|
||||
|
||||
/**
|
||||
* Set the output folder here
|
||||
*/
|
||||
outputFolder = "generated-code/bash";
|
||||
|
||||
/**
|
||||
* No model files.
|
||||
*/
|
||||
modelTemplateFiles.clear();
|
||||
|
||||
|
||||
/**
|
||||
* No API files.
|
||||
*/
|
||||
apiTemplateFiles.clear();
|
||||
|
||||
|
||||
/**
|
||||
* Templates location for client script and bash completion template.
|
||||
*/
|
||||
templateDir = "bash";
|
||||
|
||||
|
||||
/**
|
||||
* Allow the user to force the script to always include certain cURL
|
||||
* comamnds
|
||||
*/
|
||||
cliOptions.add(CliOption.newString(CURL_OPTIONS, "Default cURL options"));
|
||||
cliOptions.add(CliOption.newBoolean(PROCESS_MARKDOWN,
|
||||
"Convert all Markdown Markup into terminal formatting"));
|
||||
cliOptions.add(CliOption.newString(SCRIPT_NAME,
|
||||
"The name of the script that will be generated "+
|
||||
"(e.g. petstore-cli)"));
|
||||
cliOptions.add(CliOption.newBoolean(GENERATE_BASH_COMPLETION,
|
||||
"Whether to generate the Bash completion script"));
|
||||
cliOptions.add(CliOption.newBoolean(GENERATE_ZSH_COMPLETION,
|
||||
"Whether to generate the Zsh completion script"));
|
||||
cliOptions.add(CliOption.newString(HOST_ENVIRONMENT_VARIABLE_NAME,
|
||||
"Name of environment variable where host can be defined "+
|
||||
"(e.g. PETSTORE_HOST='http://petstore.swagger.io:8080')"));
|
||||
cliOptions.add(CliOption.newString(BASIC_AUTH_ENVIRONMENT_VARIABLE_NAME,
|
||||
"Name of environment variable where username and password "
|
||||
+
|
||||
"can be defined (e.g. PETSTORE_CREDS='username:password')"));
|
||||
cliOptions.add(CliOption.newBoolean(APIKEY_AUTH_ENVIRONMENT_VARIABLE_NAME,
|
||||
"Name of environment variable where API key "
|
||||
+
|
||||
"can be defined (e.g. PETSTORE_APIKEY='kjhasdGASDa5asdASD')"));
|
||||
|
||||
/**
|
||||
* Bash reserved words.
|
||||
*/
|
||||
reservedWords = new HashSet<String> (
|
||||
Arrays.asList(
|
||||
"case",
|
||||
"do",
|
||||
"done",
|
||||
"elif",
|
||||
"else",
|
||||
"esac",
|
||||
"fi",
|
||||
"for",
|
||||
"function",
|
||||
"if",
|
||||
"in",
|
||||
"select",
|
||||
"then",
|
||||
"time",
|
||||
"until",
|
||||
"while")
|
||||
);
|
||||
|
||||
typeMapping.clear();
|
||||
typeMapping.put("array", "array");
|
||||
typeMapping.put("map", "map");
|
||||
typeMapping.put("List", "array");
|
||||
typeMapping.put("boolean", "boolean");
|
||||
typeMapping.put("string", "string");
|
||||
typeMapping.put("int", "integer");
|
||||
typeMapping.put("float", "float");
|
||||
typeMapping.put("number", "integer");
|
||||
typeMapping.put("DateTime", "string");
|
||||
typeMapping.put("long", "integer");
|
||||
typeMapping.put("short", "integer");
|
||||
typeMapping.put("char", "string");
|
||||
typeMapping.put("double", "float");
|
||||
typeMapping.put("object", "map");
|
||||
typeMapping.put("integer", "integer");
|
||||
typeMapping.put("ByteArray", "string");
|
||||
typeMapping.put("binary", "binary");
|
||||
|
||||
/**
|
||||
* Additional Properties. These values can be passed to the templates and
|
||||
* are available in models, apis, and supporting files.
|
||||
*/
|
||||
additionalProperties.put("apiVersion", apiVersion);
|
||||
|
||||
/**
|
||||
* Language Specific Primitives. These types will not trigger imports by
|
||||
* the client generator
|
||||
*/
|
||||
languageSpecificPrimitives = new HashSet<String>();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void processOpts() {
|
||||
super.processOpts();
|
||||
String curlopts = "";
|
||||
|
||||
if (additionalProperties.containsKey(CURL_OPTIONS)) {
|
||||
setCurlOptions(additionalProperties.get(CURL_OPTIONS).toString());
|
||||
additionalProperties.put("x-codegen-curl-options", curlopts);
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey(PROCESS_MARKDOWN)) {
|
||||
setProcessMarkdown(
|
||||
Boolean.parseBoolean(
|
||||
additionalProperties.get(PROCESS_MARKDOWN).toString()));
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey(GENERATE_BASH_COMPLETION)) {
|
||||
setGenerateBashCompletion(
|
||||
Boolean.parseBoolean(
|
||||
additionalProperties.get(GENERATE_BASH_COMPLETION).toString()));
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey(GENERATE_ZSH_COMPLETION)) {
|
||||
setGenerateZshCompletion(
|
||||
Boolean.parseBoolean(
|
||||
additionalProperties.get(GENERATE_ZSH_COMPLETION).toString()));
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey(SCRIPT_NAME)) {
|
||||
setScriptName(additionalProperties.get(SCRIPT_NAME).toString());
|
||||
}
|
||||
additionalProperties.put("x-codegen-script-name", scriptName);
|
||||
|
||||
if (additionalProperties.containsKey(HOST_ENVIRONMENT_VARIABLE_NAME)) {
|
||||
setHostEnvironmentVariable(
|
||||
additionalProperties.get(HOST_ENVIRONMENT_VARIABLE_NAME).toString());
|
||||
additionalProperties.put("x-codegen-host-env", hostEnvironmentVariable);
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey(BASIC_AUTH_ENVIRONMENT_VARIABLE_NAME)) {
|
||||
setBasicAuthEnvironmentVariable(
|
||||
additionalProperties.get(BASIC_AUTH_ENVIRONMENT_VARIABLE_NAME).toString());
|
||||
additionalProperties.put("x-codegen-basicauth-env", basicAuthEnvironmentVariable);
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey(APIKEY_AUTH_ENVIRONMENT_VARIABLE_NAME)) {
|
||||
setApiKeyAuthEnvironmentVariable(
|
||||
additionalProperties.get(APIKEY_AUTH_ENVIRONMENT_VARIABLE_NAME).toString());
|
||||
additionalProperties.put("x-codegen-apikey-env", apiKeyAuthEnvironmentVariable);
|
||||
}
|
||||
|
||||
supportingFiles.add(new SupportingFile(
|
||||
"client.mustache", "", scriptName));
|
||||
supportingFiles.add(new SupportingFile(
|
||||
"bash-completion.mustache", "", scriptName+".bash-completion"));
|
||||
supportingFiles.add(new SupportingFile(
|
||||
"zsh-completion.mustache", "", "_"+scriptName));
|
||||
supportingFiles.add(new SupportingFile(
|
||||
"README.mustache", "", "README.md"));
|
||||
}
|
||||
|
||||
public void setCurlOptions(String curlOptions) {
|
||||
this.curlOptions = curlOptions;
|
||||
}
|
||||
|
||||
public void setProcessMarkdown(boolean processMarkdown) {
|
||||
this.processMarkdown = processMarkdown;
|
||||
}
|
||||
|
||||
public void setScriptName(String scriptName) {
|
||||
this.scriptName = scriptName;
|
||||
}
|
||||
|
||||
public void setGenerateBashCompletion(boolean generateBashCompletion) {
|
||||
this.generateBashCompletion = generateBashCompletion;
|
||||
}
|
||||
|
||||
public void setGenerateZshCompletion(boolean generateZshCompletion) {
|
||||
this.generateZshCompletion = generateZshCompletion;
|
||||
}
|
||||
|
||||
public void setHostEnvironmentVariable(String hostEnvironmentVariable) {
|
||||
this.hostEnvironmentVariable = hostEnvironmentVariable;
|
||||
}
|
||||
|
||||
public void setBasicAuthEnvironmentVariable(String
|
||||
basicAuthEnvironmentVariable) {
|
||||
this.basicAuthEnvironmentVariable = basicAuthEnvironmentVariable;
|
||||
}
|
||||
|
||||
public void setApiKeyAuthEnvironmentVariable(String
|
||||
apiKeyAuthEnvironmentVariable) {
|
||||
this.apiKeyAuthEnvironmentVariable = apiKeyAuthEnvironmentVariable;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Escapes a reserved word as defined in the `reservedWords` array. Handle
|
||||
* escaping those terms here. This logic is only called if a variable
|
||||
* matches the reseved words.
|
||||
*
|
||||
* @return the escaped term
|
||||
*/
|
||||
@Override
|
||||
public String escapeReservedWord(String name) {
|
||||
return "_" + name; // add an underscore to the name
|
||||
}
|
||||
|
||||
/**
|
||||
* Location to write model files. You can use the modelPackage() as defined
|
||||
* when the class is instantiated.
|
||||
*/
|
||||
public String modelFileFolder() {
|
||||
return outputFolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Location to write api files. You can use the apiPackage() as defined when
|
||||
* the class is instantiated.
|
||||
*/
|
||||
@Override
|
||||
public String apiFileFolder() {
|
||||
return outputFolder;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Optional - type declaration. This is a String which is used by the
|
||||
* templates to instantiate your types. There is typically special handling
|
||||
* for different property types
|
||||
*
|
||||
* @return a string value used as the `dataType` field for model templates,
|
||||
* `returnType` for api templates
|
||||
*/
|
||||
@Override
|
||||
public String getTypeDeclaration(Property p) {
|
||||
if(p instanceof ArrayProperty) {
|
||||
ArrayProperty ap = (ArrayProperty) p;
|
||||
Property inner = ap.getItems();
|
||||
return getSwaggerType(p) + "[" + 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional - swagger type conversion. This is used to map swagger types in
|
||||
* a `Property` into either language specific types via `typeMapping` or into
|
||||
* complex models if there is not a mapping.
|
||||
*
|
||||
* @return a string value of the type or complex model for this property
|
||||
* @see io.swagger.models.properties.Property
|
||||
*/
|
||||
@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 toModelName(type);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert Swagger Parameter object to Codegen Parameter object
|
||||
*
|
||||
* @param param Swagger parameter object
|
||||
* @param imports set of imports for library/package/module
|
||||
* @return Codegen Parameter object
|
||||
*/
|
||||
@Override
|
||||
public CodegenParameter fromParameter(Parameter param, Set<String> imports) {
|
||||
|
||||
CodegenParameter p = super.fromParameter(param, imports);
|
||||
|
||||
if(param instanceof BodyParameter) {
|
||||
|
||||
Model model = ((BodyParameter)param).getSchema();
|
||||
|
||||
}
|
||||
else if(param instanceof SerializableParameter) {
|
||||
|
||||
/**
|
||||
* Currently it's not possible to specify in the codegen other collection
|
||||
* formats than 'multi'
|
||||
*/
|
||||
SerializableParameter sparam = (SerializableParameter)param;
|
||||
|
||||
if( sparam.getCollectionFormat() != null
|
||||
&& !sparam.getCollectionFormat().isEmpty()) {
|
||||
|
||||
String collectionFormat = sparam.getCollectionFormat();
|
||||
|
||||
if(sparam.isExclusiveMaximum()!=null && sparam.isExclusiveMaximum()) {
|
||||
p.vendorExtensions.put("x-codegen-collection-max-items",
|
||||
sparam.getMaxItems());
|
||||
}
|
||||
|
||||
if(sparam.isExclusiveMinimum()!=null && sparam.isExclusiveMinimum()) {
|
||||
p.vendorExtensions.put("x-codegen-collection-min-items",
|
||||
sparam.getMinItems());
|
||||
}
|
||||
|
||||
if( (collectionFormat.equals("multi"))
|
||||
&& (param.getIn().equals("query")) ) {
|
||||
|
||||
/**
|
||||
* 'multi' is only supported for query parameters
|
||||
*/
|
||||
p.vendorExtensions.put("x-codegen-collection-multi", true);
|
||||
|
||||
}
|
||||
else if(collectionFormat.equals("csv")) {
|
||||
p.vendorExtensions.put("x-codegen-collection-csv", true);
|
||||
}
|
||||
else if(collectionFormat.equals("ssv")) {
|
||||
p.vendorExtensions.put("x-codegen-collection-ssv", true);
|
||||
}
|
||||
else if(collectionFormat.equals("tsv")) {
|
||||
p.vendorExtensions.put("x-codegen-collection-tsv", true);
|
||||
}
|
||||
else if(collectionFormat.equals("pipes")) {
|
||||
p.vendorExtensions.put("x-codegen-collection-pipes", true);
|
||||
}
|
||||
else {
|
||||
/** Unsupported collection format */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return p;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Override with any special text escaping logic
|
||||
*/
|
||||
@SuppressWarnings("static-method")
|
||||
public String escapeText(String input) {
|
||||
if (input == null) {
|
||||
return input;
|
||||
}
|
||||
|
||||
/**
|
||||
* remove standalone '\'
|
||||
*
|
||||
* replace " with \"
|
||||
* outter unescape to retain the original multi-byte characters
|
||||
*/
|
||||
String result = escapeUnsafeCharacters(
|
||||
StringEscapeUtils.unescapeJava(
|
||||
StringEscapeUtils.escapeJava(input).replace("\\/", "/"))
|
||||
.replace("\\", "\\\\")
|
||||
.replace("\"", "\\\""));
|
||||
|
||||
if(this.processMarkdown) {
|
||||
|
||||
/**
|
||||
* Convert markdown strong **Bold text** and __Bold text__
|
||||
* to bash bold control sequences (tput bold)
|
||||
*/
|
||||
result = result.replaceAll("(?m)(^|\\s)\\*{2}([\\w\\d ]+)\\*{2}($|\\s)",
|
||||
"\\$\\(tput bold\\) $2 \\$\\(tput sgr0\\)");
|
||||
|
||||
result = result.replaceAll("(?m)(^|\\s)_{2}([\\w\\d ]+)_{2}($|\\s)",
|
||||
"\\$\\(tput bold\\) $2 \\$\\(tput sgr0\\)");
|
||||
/**
|
||||
* Convert markdown *Italics text* and _Italics text_ to bash dim
|
||||
* control sequences (tput dim)
|
||||
*/
|
||||
result = result.replaceAll("(?m)(^|\\s)\\*{1}([\\w\\d ]+)\\*{1}($|\\s)",
|
||||
"\\$\\(tput dim\\) $2 \\$\\(tput sgr0\\)");
|
||||
|
||||
result = result.replaceAll("(?m)(^|\\s)_{1}([\\w\\d ]+)_{1}($|\\s)",
|
||||
"\\$\\(tput dim\\) $2 \\$\\(tput sgr0\\)");
|
||||
|
||||
|
||||
/**
|
||||
* Convert all markdown section 1 level headers with bold
|
||||
*/
|
||||
result = result.replaceAll("(?m)^\\#\\s+(.+)$",
|
||||
"\n\\$\\(tput bold\\)\\$\\(tput setaf 7\\)"
|
||||
+"$1\\$\\(tput sgr0\\)");
|
||||
|
||||
/**
|
||||
* Convert all markdown section 2 level headers with bold
|
||||
*/
|
||||
result = result.replaceAll("(?m)^\\#\\#\\s+(.+)$",
|
||||
"\n\\$\\(tput bold\\)\\$\\(tput setaf 7\\)"
|
||||
+"$1\\$\\(tput sgr0\\)");
|
||||
|
||||
/**
|
||||
* Convert all markdown section 3 level headers with bold
|
||||
*/
|
||||
result = result.replaceAll("(?m)^\\#\\#\\#\\s+(.+)$",
|
||||
"\n\\$\\(tput bold\\)\\$\\(tput setaf 7\\)"
|
||||
+"$1\\$\\(tput sgr0\\)");
|
||||
|
||||
/**
|
||||
* Convert all markdown code blocks into --- delimited sections
|
||||
*/
|
||||
result = result.replaceAll("(?m)\\s*```.*$",
|
||||
"\n---");
|
||||
|
||||
result = result.replaceAll("(?m)\\s*\\'\\'\\'.*$",
|
||||
"\n---");
|
||||
|
||||
/**
|
||||
* Remove any trailing new line at the end of the string
|
||||
*/
|
||||
result = result.replaceAll("\\s+$", "");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String escapeQuotationMark(String input) {
|
||||
return input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override with any special text escaping logic to handle unsafe
|
||||
* characters so as to avoid code injection.
|
||||
*
|
||||
* @param input String to be cleaned up
|
||||
* @return string with unsafe characters removed or escaped
|
||||
*/
|
||||
public String escapeUnsafeCharacters(String input) {
|
||||
|
||||
/**
|
||||
* Replace backticks with normal single quotes.
|
||||
*/
|
||||
String result = input.replaceAll("`", "'");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public CodegenOperation fromOperation(String path, String httpMethod,
|
||||
Operation operation,
|
||||
Map<String, Model> definitions,
|
||||
Swagger swagger) {
|
||||
|
||||
CodegenOperation op = super.fromOperation(path, httpMethod, operation,
|
||||
definitions, swagger);
|
||||
|
||||
/**
|
||||
* Check if the operation has a Bash codegen specific description
|
||||
* for help
|
||||
*/
|
||||
if(op.vendorExtensions.containsKey("x-bash-codegen-description")) {
|
||||
String bash_description
|
||||
= (String)op.vendorExtensions.get("x-bash-codegen-description");
|
||||
|
||||
op.vendorExtensions.put("x-bash-codegen-description",
|
||||
escapeText(bash_description));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if operation has an 'x-code-samples' vendor extension with
|
||||
* Shell example
|
||||
*/
|
||||
if(op.vendorExtensions.containsKey("x-code-samples")) {
|
||||
|
||||
List codesamples = (List)op.vendorExtensions.get("x-code-samples");
|
||||
|
||||
for (Object codesample : codesamples) {
|
||||
ObjectNode codesample_object = (ObjectNode)codesample;
|
||||
|
||||
if((codesample_object.get("lang").asText()).equals("Shell")) {
|
||||
|
||||
op.vendorExtensions.put("x-bash-codegen-sample",
|
||||
escapeUnsafeCharacters(
|
||||
codesample_object.get("source").asText()));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
for (CodegenParameter p : op.bodyParams) {
|
||||
if(p.dataType != null && definitions.get(p.dataType) != null) {
|
||||
/**
|
||||
* If the operation produces Json and has nonempty example
|
||||
* try to reformat it.
|
||||
*/
|
||||
if(operation.getConsumes() != null
|
||||
&& operation.getConsumes().contains("application/json")
|
||||
&& definitions.get(p.dataType).getExample() != null) {
|
||||
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
try {
|
||||
p.vendorExtensions.put(
|
||||
"x-codegen-body-example",
|
||||
mapper.writerWithDefaultPrettyPrinter().writeValueAsString(
|
||||
definitions.get(p.dataType).getExample()));
|
||||
}
|
||||
catch(JsonProcessingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
else {
|
||||
/**
|
||||
* Otherwise present whatever is provided as example
|
||||
*/
|
||||
p.vendorExtensions.put(
|
||||
"x-codegen-body-example",
|
||||
definitions.get(p.dataType).getExample());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return op;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Preprocess original properties from the Swagger definition where necessary.
|
||||
*
|
||||
* @param swagger [description]
|
||||
*/
|
||||
@Override
|
||||
public void preprocessSwagger(Swagger swagger) {
|
||||
super.preprocessSwagger(swagger);
|
||||
|
||||
if ("/".equals(swagger.getBasePath())) {
|
||||
swagger.setBasePath("");
|
||||
}
|
||||
|
||||
if(swagger.getInfo() != null
|
||||
&& swagger.getInfo().getVendorExtensions()!=null) {
|
||||
String bash_codegen_app_description
|
||||
= (String)swagger.getInfo().getVendorExtensions()
|
||||
.get("x-bash-codegen-description");
|
||||
|
||||
if(bash_codegen_app_description != null) {
|
||||
|
||||
bash_codegen_app_description
|
||||
= escapeText(bash_codegen_app_description);
|
||||
|
||||
additionalProperties.put("x-bash-codegen-app-description",
|
||||
bash_codegen_app_description);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -2,6 +2,7 @@ io.swagger.codegen.languages.AndroidClientCodegen
|
||||
io.swagger.codegen.languages.AspNet5ServerCodegen
|
||||
io.swagger.codegen.languages.AspNetCoreServerCodegen
|
||||
io.swagger.codegen.languages.AsyncScalaClientCodegen
|
||||
io.swagger.codegen.languages.BashClientCodegen
|
||||
io.swagger.codegen.languages.ConfluenceWikiGenerator
|
||||
io.swagger.codegen.languages.CSharpClientCodegen
|
||||
io.swagger.codegen.languages.CppRestClientCodegen
|
||||
|
220
modules/swagger-codegen/src/main/resources/bash/README.md
Normal file
220
modules/swagger-codegen/src/main/resources/bash/README.md
Normal file
@ -0,0 +1,220 @@
|
||||
# Bash script generator for Swagger Codegen
|
||||
|
||||
## Overview
|
||||
This is a Bash client script codegen.
|
||||
|
||||
The codegen creates a standalone, single-file Bash script client to quickly test and access Swagger annotated REST services. The generated script uses underneath [cURL](https://curl.haxx.se) to make actual REST calls.
|
||||
|
||||
The generated Bash script has only 2 dependencies:
|
||||
- Bash (>= 4.3)
|
||||
- cURL
|
||||
|
||||
## Features
|
||||
- Fully automatic generation of a client Bash script to access any Swagger-defined REST service
|
||||
- Generation of Bash and Zsh completion scripts
|
||||
- All valid cURL options can be passed directly
|
||||
- Preview of cURL commands to execute each operation using `--dry-run` option
|
||||
- Complete help for entire service as well as for each operation
|
||||
- No external dependencies besides Bash and cURL
|
||||
|
||||
## Usage
|
||||
|
||||
### Generating Bash client for REST service
|
||||
|
||||
Get the sources:
|
||||
```shell
|
||||
$ git clone https://github.com/swagger-api/swagger-codegen
|
||||
```
|
||||
|
||||
Build the codegen:
|
||||
```shell
|
||||
$ mvn assembly:assembly -DdescriptorId=jar-with-dependencies
|
||||
```
|
||||
|
||||
Define custom codegen properties in a Json file, e.g.:
|
||||
```shell
|
||||
{
|
||||
"processMarkdown": true,
|
||||
"curlOptions": "-sS --tlsv1.2",
|
||||
"scriptName": "petstore-cli",
|
||||
"generateBashCompletion": true,
|
||||
"generateZshCompletion": true,
|
||||
"hostEnvironmentVariable": "PETSTORE_HOST",
|
||||
"basicAuthEnvironmentVariable": "PETSTORE_BASIC_AUTH",
|
||||
"apiKeyAuthEnvironmentVariable": "PETSTORE_API_KEY"
|
||||
}
|
||||
```
|
||||
|
||||
Generate the client:
|
||||
```shell
|
||||
$ java -cp target/bash-swagger-codegen-1.0.0.jar io.swagger.codegen.SwaggerCodegen generate -l bash -i http://petstore.swagger.io/v2/swagger.json -o output -c resources/example-config.json
|
||||
|
||||
$ chmod +x output/petstore-cli
|
||||
```
|
||||
|
||||
Enjoy:
|
||||
```shell
|
||||
$ output/petstore-cli -h
|
||||
|
||||
Swagger Petstore command line client (API version 1.0.0)
|
||||
|
||||
Usage
|
||||
|
||||
petstore-cli [-h|--help] [-V|--version] [--about] [<curl-options>]
|
||||
[-ac|--accept <mime-type>] [-ct,--content-type <mime-type>]
|
||||
[--host <url>] [--dry-run] <operation> [-h|--help] [<headers>]
|
||||
[<parameters>] [<body-parameters>]
|
||||
|
||||
- <url> - endpoint of the REST service without basepath
|
||||
Can also be specified in PETSTORE_HOST environment variable.
|
||||
- <curl-options> - any valid cURL options can be passed before <operation>
|
||||
- <mime-type> - either full mime-type or one of supported abbreviations:
|
||||
(text, html, md, csv, css, rtf, json, xml, yaml, js, bin,
|
||||
rdf, jpg, png, gif, bmp, tiff)
|
||||
- <headers> - HTTP headers can be passed in the form HEADER:VALUE
|
||||
- <parameters> - REST operation parameters can be passed in the following
|
||||
forms:
|
||||
* KEY=VALUE - path or query parameters
|
||||
- <body-parameters> - simple JSON body content (first level only) can be build
|
||||
using the following arguments:
|
||||
* KEY==VALUE - body parameters which will be added to body
|
||||
JSON as '{ ..., "KEY": "VALUE", ... }'
|
||||
* KEY:=VALUE - body parameters which will be added to body
|
||||
JSON as '{ ..., "KEY": VALUE, ... }'
|
||||
|
||||
Authentication methods
|
||||
|
||||
- Api-key - add 'api_key:<api-key>' after <operation>
|
||||
or export PETSTORE_API_KEY='<api-key>'
|
||||
- OAuth2 (flow: implicit)
|
||||
Authorization URL:
|
||||
* http://petstore.swagger.io/oauth/dialog
|
||||
Scopes:
|
||||
* write:pets - modify pets in your account
|
||||
* read:pets - read your pets
|
||||
|
||||
Operations (grouped by tags)
|
||||
|
||||
[pet]
|
||||
addPet Add a new pet to the store
|
||||
deletePet Deletes a pet
|
||||
findPetsByStatus Finds Pets by status
|
||||
findPetsByTags Finds Pets by tags
|
||||
getPetById Find pet by ID
|
||||
updatePet Update an existing pet
|
||||
updatePetWithForm Updates a pet in the store with form data
|
||||
uploadFile uploads an image
|
||||
|
||||
[store]
|
||||
deleteOrder Delete purchase order by ID
|
||||
getInventory Returns pet inventories by status
|
||||
getOrderById Find purchase order by ID
|
||||
placeOrder Place an order for a pet
|
||||
|
||||
[user]
|
||||
createUser Create user
|
||||
createUsersWithArrayInput Creates list of users with given input array
|
||||
createUsersWithListInput Creates list of users with given input array
|
||||
deleteUser Delete user
|
||||
getUserByName Get user by user name
|
||||
loginUser Logs user into the system
|
||||
logoutUser Logs out current logged in user session
|
||||
updateUser Updated user
|
||||
|
||||
Options
|
||||
-h,--help Print this help
|
||||
-V,--version Print API version
|
||||
--about Print the information about service
|
||||
--host <url> Specify the host URL
|
||||
(e.g. 'https://petstore.swagger.io')
|
||||
--force Force command invocation in spite of missing
|
||||
required parameters or wrong content type
|
||||
--dry-run Print out the cURL command without
|
||||
executing it
|
||||
-ac,--accept <mime-type> Set the 'Accept' header in the request
|
||||
-ct,--content-type <mime-type> Set the 'Content-type' header in
|
||||
the request
|
||||
```
|
||||
|
||||
Client generator takes several specific configuration options:
|
||||
* *processMarkdown* - [boolean] if set to `true`, all text (descriptions) in the Swagger specification will be treated as Markdown and converted to terminal formatting commands,
|
||||
* *curlOptions* - [string] a list of default cURL options that will be added to each command
|
||||
* *scriptName* - [string] the name of the target script, necessary when building Bash completion script
|
||||
* *generateBashCompletion* - [boolean] if set to `true` the Bash completion script will be generated
|
||||
* *generateZshCompletion* - [boolean] if set to `true` the Bash completion script will be generated
|
||||
* *hostEnvironmentVariable* - [string] the name of environment variable to search for default host
|
||||
* *basicAuthEnvironmentVariable* - [string] the name of environment variable to search for default basic auth credentials
|
||||
* *apiKeyAuthEnvironmentVariable* - [string] the name of environment variable to search for default api key
|
||||
|
||||
These options can be specified in a Json file used when running the codegen using option `-c` (see [example](resources/example-config.json)).
|
||||
|
||||
### Using the generated Bash script
|
||||
|
||||
```shell
|
||||
# Print the list of operations available on the service
|
||||
$ petstore-cli --help
|
||||
|
||||
# Print the service description
|
||||
$ petstore-cli --about
|
||||
|
||||
# Print detailed information about specific operation
|
||||
$ petstore-cli addPet --help
|
||||
|
||||
# Call REST API operation
|
||||
$ echo '{"id":891,"name":"lucky","status":"available"}' | petstore-cli --host http://petstore.swagger.io --content-type json addPet -
|
||||
|
||||
{"id":891,"name":"lucky","photoUrls":[],"tags":[],"status":"available"}
|
||||
|
||||
# The above is equivalent to
|
||||
$ petstore-cli --host http://petstore.swagger.io --content-type json --accept xml addPet id:=891 name==lucky status==available
|
||||
|
||||
<xml version="1.0" encoding="UTF-8" standalone="yes"?><Pet><id>891</id><name>lucky</name><photoUrls/><status>available</status><tags/></Pet>
|
||||
|
||||
|
||||
# Preview the cURL command without actually executing it
|
||||
# The above is equivalent to
|
||||
$ petstore-cli --host http://petstore.swagger.io --content-type json --dry-run addPet id:=891 name==lucky status==available
|
||||
|
||||
curl -sS --tlsv1.2 -H 'Content-type: application/json' -X POST -d '{"name": "lucky", "status": "available", "id": 891}' "http://petstore.swagger.io/v2/pet"
|
||||
```
|
||||
|
||||
## Shell completion
|
||||
|
||||
### Bash
|
||||
The generated bash-completion script can be either directly loaded to the current Bash session using:
|
||||
|
||||
```shell
|
||||
source output/petstore-cli.bash-completion
|
||||
```
|
||||
|
||||
Alternatively, the script can be copied to the `/etc/bash-completion.d` (or on OSX with Homebrew to `/usr/local/etc/bash-completion.d`):
|
||||
|
||||
```shell
|
||||
sudo cp output/petstore-cli.bash-completion /etc/bash-completion.d/petstore-cli
|
||||
```
|
||||
|
||||
#### OS X
|
||||
On OSX you might need to install bash-completion using Homebrew:
|
||||
```shell
|
||||
brew install bash-completion
|
||||
```
|
||||
and add the following to the `~/.bashrc`:
|
||||
|
||||
```shell
|
||||
if [ -f $(brew --prefix)/etc/bash_completion ]; then
|
||||
. $(brew --prefix)/etc/bash_completion
|
||||
fi
|
||||
```
|
||||
|
||||
### Zsh
|
||||
In Zsh, the generated `_{{scriptName}}` file (e.g. _petstore-cli) must be copied to one of the folders under `$fpath` variable.
|
||||
|
||||
|
||||
## TODO
|
||||
- [ ] Add enum values for parameters shell completion
|
||||
- [ ] Wrap handling of errors returned by the service, using comments defined in the Swagger specification
|
||||
- [ ] Improve `--help` and `--about` formatting
|
||||
- [ ] Add support to bash 4.0-4.2 (currently must be >= 4.3)
|
||||
- [ ] Add manpage generation
|
||||
- [ ] Add support for form data
|
||||
- [ ] Move todos to Github issues
|
@ -0,0 +1,75 @@
|
||||
# {{appName}} Bash client
|
||||
|
||||
## Overview
|
||||
This is a Bash client script for accessing {{appName}} service.
|
||||
|
||||
The script uses cURL underneath for making all REST calls.
|
||||
|
||||
## Usage
|
||||
|
||||
```shell
|
||||
# Make sure the script has executable rights
|
||||
$ chmod u+x {{scriptName}}
|
||||
|
||||
# Print the list of operations available on the service
|
||||
$ ./{{scriptName}} -h
|
||||
|
||||
# Print the service description
|
||||
$ ./{{scriptName}} --about
|
||||
|
||||
# Print detailed information about specific operation
|
||||
$ ./{{scriptName}} <operationId> -h
|
||||
|
||||
# Make GET request
|
||||
./{{scriptName}} --host http://<hostname>:<port> --accept xml <operationId> <queryParam1>=<value1> <header_key1>:<header_value2>
|
||||
|
||||
# Make GET request using arbitrary curl options (must be passed before <operationId>) to an SSL service using username:password
|
||||
{{scriptName}} -k -sS --tlsv1.2 --host https://<hostname> -u <user>:<password> --accept xml <operationId> <queryParam1>=<value1> <header_key1>:<header_value2>
|
||||
|
||||
# Make POST request
|
||||
$ echo '<body_content>' | {{scriptName}} --host <hostname> --content-type json <operationId> -
|
||||
|
||||
# Make POST request with simple JSON content, e.g.:
|
||||
# {
|
||||
# "key1": "value1",
|
||||
# "key2": "value2",
|
||||
# "key3": 23
|
||||
# }
|
||||
$ echo '<body_content>' | {{scriptName}} --host <hostname> --content-type json <operationId> key1==value1 key2=value2 key3:=23 -
|
||||
|
||||
# Preview the cURL command without actually executing it
|
||||
$ {{scriptName}} --host http://<hostname>:<port> --dry-run <operationid>
|
||||
|
||||
```
|
||||
|
||||
## Shell completion
|
||||
|
||||
### Bash
|
||||
The generated bash-completion script can be either directly loaded to the current Bash session using:
|
||||
|
||||
```shell
|
||||
source {{scriptName}}.bash-completion
|
||||
```
|
||||
|
||||
Alternatively, the script can be copied to the `/etc/bash-completion.d` (or on OSX with Homebrew to `/usr/local/etc/bash-completion.d`):
|
||||
|
||||
```shell
|
||||
sudo cp {{scriptName}}.bash-completion /etc/bash-completion.d/{{scriptName}}
|
||||
```
|
||||
|
||||
#### OS X
|
||||
On OSX you might need to install bash-completion using Homebrew:
|
||||
```shell
|
||||
brew install bash-completion
|
||||
```
|
||||
and add the following to the `~/.bashrc`:
|
||||
|
||||
```shell
|
||||
if [ -f $(brew --prefix)/etc/bash_completion ]; then
|
||||
. $(brew --prefix)/etc/bash_completion
|
||||
fi
|
||||
```
|
||||
|
||||
### Zsh
|
||||
In Zsh, the generated `_{{scriptName}}` Zsh completion file must be copied to one of the folders under `$FPATH` variable.
|
||||
|
@ -0,0 +1,286 @@
|
||||
# {{scriptName}} completion -*- shell-script -*-
|
||||
|
||||
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
# !
|
||||
# ! Note:
|
||||
# !
|
||||
# ! THIS SCRIPT HAS BEEN AUTOMATICALLY GENERATED USING
|
||||
# ! swagger-codegen (https://github.com/swagger-api/swagger-codegen)
|
||||
# ! FROM SWAGGER SPECIFICATION IN JSON.
|
||||
# !
|
||||
# ! Generated on: {{generatedDate}}
|
||||
# !
|
||||
# !
|
||||
# ! System wide installation:
|
||||
# !
|
||||
# ! $ sudo cp {{scriptName}}.bash-completion /etc/bash-completion.d/{{scriptName}}
|
||||
# !
|
||||
# !
|
||||
# ! User home installation (add this line to .bash_profile):
|
||||
# !
|
||||
# ! [ -r ~/{{scriptName}}.bash-completion ] && source ~/{{scriptName}}.bash-completion
|
||||
# !
|
||||
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
declare -A mime_type_abbreviations
|
||||
# text/*
|
||||
mime_type_abbreviations["text"]="text/plain"
|
||||
mime_type_abbreviations["html"]="text/html"
|
||||
mime_type_abbreviations["md"]="text/x-markdown"
|
||||
mime_type_abbreviations["csv"]="text/csv"
|
||||
mime_type_abbreviations["css"]="text/css"
|
||||
mime_type_abbreviations["rtf"]="text/rtf"
|
||||
# application/*
|
||||
mime_type_abbreviations["json"]="application/json"
|
||||
mime_type_abbreviations["xml"]="application/xml"
|
||||
mime_type_abbreviations["yaml"]="application/yaml"
|
||||
mime_type_abbreviations["js"]="application/javascript"
|
||||
mime_type_abbreviations["bin"]="application/octet-stream"
|
||||
mime_type_abbreviations["rdf"]="application/rdf+xml"
|
||||
# image/*
|
||||
mime_type_abbreviations["jpg"]="image/jpeg"
|
||||
mime_type_abbreviations["png"]="image/png"
|
||||
mime_type_abbreviations["gif"]="image/gif"
|
||||
mime_type_abbreviations["bmp"]="image/bmp"
|
||||
mime_type_abbreviations["tiff"]="image/tiff"
|
||||
|
||||
|
||||
|
||||
__osx_init_completion()
|
||||
{
|
||||
COMPREPLY=()
|
||||
_get_comp_words_by_ref cur prev words cword
|
||||
}
|
||||
|
||||
|
||||
_{{scriptName}}()
|
||||
{
|
||||
local cur
|
||||
local prev
|
||||
local words
|
||||
local cword
|
||||
|
||||
#words="${COMP_WORDS}"
|
||||
#cword="${COMP_CWORD}"
|
||||
#prev="${COMP_WORDS[COMP_CWORD-1]}"
|
||||
#cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
|
||||
# The reference of currently selected REST operation
|
||||
local operation=""
|
||||
|
||||
# The list of available operation in the REST service
|
||||
# It's modelled as an associative array for efficient key lookup
|
||||
declare -A operations
|
||||
{{#apiInfo}}
|
||||
{{#apis}}
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
operations["{{operationId}}"]=1
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
{{/apis}}
|
||||
{{/apiInfo}}
|
||||
|
||||
# An associative array of operations to their parameters
|
||||
# Only include path, query and header parameters
|
||||
declare -A operation_parameters
|
||||
{{#apiInfo}}
|
||||
{{#apis}}
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
operation_parameters["{{operationId}}"]="{{#pathParams}}{{baseName}}= {{/pathParams}}{{#queryParams}}{{baseName}}= {{/queryParams}}{{#headerParams}}{{baseName}}: {{/headerParams}}"
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
{{/apis}}
|
||||
{{/apiInfo}}
|
||||
|
||||
# An associative array of possible values for enum parameters
|
||||
declare -A operation_parameters_enum_values
|
||||
{{#apiInfo}}
|
||||
{{#apis}}
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
{{#allParams}}
|
||||
{{#pathParams}}
|
||||
{{#isBoolean}}
|
||||
operation_parameters_enum_values["{{operationId}}::{{baseName}}"]="true false"
|
||||
{{/isBoolean}}
|
||||
{{#isEnum}}
|
||||
operation_parameters_enum_values["{{operationId}}::{{baseName}}"]=""
|
||||
{{/isEnum}}
|
||||
{{/pathParams}}
|
||||
{{#queryParams}}
|
||||
{{#isBoolean}}
|
||||
operation_parameters_enum_values["{{operationId}}::{{baseName}}"]="true false"
|
||||
{{/isBoolean}}
|
||||
{{/queryParams}}
|
||||
{{#headerParams}}
|
||||
{{#isBoolean}}
|
||||
operation_parameters_enum_values["{{operationId}}::{{baseName}}"]="true false"
|
||||
{{/isBoolean}}
|
||||
{{/headerParams}}
|
||||
{{/allParams}}
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
{{/apis}}
|
||||
{{/apiInfo}}
|
||||
|
||||
#
|
||||
# Check if the _init_completion function is available, which is
|
||||
# available since bash-completion 1.4
|
||||
#
|
||||
if declare -F _init_completions >/dev/null 2>&1; then
|
||||
_init_completion -s || return
|
||||
else
|
||||
__osx_init_completion || return
|
||||
fi
|
||||
|
||||
|
||||
# Check if operation is already in the command line provided
|
||||
for word in "${words[@]}"; do
|
||||
if [[ -n $word && ${operations[$word]} ]]; then
|
||||
operation="${word}"
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ -z $operation ]]; then
|
||||
case $prev in
|
||||
--ciphers|--connect-timeout|-C|--continue-at|-F|--form|--form-string|\
|
||||
--ftp-account|--ftp-alternative-to-user|-P|--ftp-port|-H|--header|-h|\
|
||||
--help|--hostpubmd5|--keepalive-time|--krb|--limit-rate|--local-port|\
|
||||
--mail-from|--mail-rcpt|--max-filesize|--max-redirs|-m|--max-time|\
|
||||
--pass|--proto|--proto-redir|--proxy-user|--proxy1.0|-Q|--quote|-r|\
|
||||
--range|-X|--request|--retry|--retry-delay|--retry-max-time|\
|
||||
--socks5-gssapi-service|-t|--telnet-option|--tftp-blksize|-z|\
|
||||
--time-cond|--url|-u|--user|-A|--user-agent|-V|--version|-w|\
|
||||
--write-out|--resolve|--tlsuser|--tlspassword|--about)
|
||||
return
|
||||
;;
|
||||
-K|--config|-b|--cookie|-c|--cookie-jar|-D|--dump-header|--egd-file|\
|
||||
--key|--libcurl|-o|--output|--random-file|-T|--upload-file|--trace|\
|
||||
--trace-ascii|--netrc-file)
|
||||
_filedir
|
||||
return
|
||||
;;
|
||||
--cacert|-E|--cert)
|
||||
_filedir '@(c?(e)rt|cer|pem|der)'
|
||||
return
|
||||
;;
|
||||
--capath)
|
||||
_filedir -d
|
||||
return
|
||||
;;
|
||||
--cert-type|--key-type)
|
||||
COMPREPLY=( $( compgen -W 'DER PEM ENG' -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
--crlfile)
|
||||
_filedir crl
|
||||
return
|
||||
;;
|
||||
-d|--data|--data-ascii|--data-binary|--data-urlencode)
|
||||
if [[ $cur == \@* ]]; then
|
||||
cur=${cur:1}
|
||||
_filedir
|
||||
COMPREPLY=( "${COMPREPLY[@]/#/@}" )
|
||||
fi
|
||||
return
|
||||
;;
|
||||
--delegation)
|
||||
COMPREPLY=( $( compgen -W 'none policy always' -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
--engine)
|
||||
COMPREPLY=( $( compgen -W 'list' -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
--ftp-method)
|
||||
COMPREPLY=( $( compgen -W 'multicwd nocwd singlecwd' -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
--ftp-ssl-ccc-mode)
|
||||
COMPREPLY=( $( compgen -W 'active passive' -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
--interface)
|
||||
_available_interfaces -a
|
||||
return
|
||||
;;
|
||||
-x|--proxy|--socks4|--socks4a|--socks5|--socks5-hostname)
|
||||
_known_hosts_real
|
||||
return
|
||||
;;
|
||||
--pubkey)
|
||||
_filedir pub
|
||||
return
|
||||
;;
|
||||
--stderr)
|
||||
COMPREPLY=( $( compgen -W '-' -- "$cur" ) )
|
||||
_filedir
|
||||
return
|
||||
;;
|
||||
--tlsauthtype)
|
||||
COMPREPLY=( $( compgen -W 'SRP' -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
--host)
|
||||
COMPREPLY=( $( compgen -W 'http:// https://' -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
-ct|--content-type|-ac|--accept)
|
||||
COMPREPLY=( $( compgen -W '${!mime_type_abbreviations[*]}' -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
#
|
||||
# Complete the server address based on ~/.ssh/known_hosts
|
||||
# and ~/.ssh/config
|
||||
#
|
||||
# \todo Fix - cur matches only '//' when $prev is ':'
|
||||
#
|
||||
if [[ "$cur" == "http://" || "$cur" == "https://" ]]; then
|
||||
COMPREPLY=()
|
||||
local comp_ssh_hosts=`cat ~/.ssh/known_hosts | \
|
||||
cut -f 1 -d ' ' | \
|
||||
sed -e s/,.*//g | \
|
||||
grep -v ^# | \
|
||||
uniq | \
|
||||
grep -v "\[" ;
|
||||
cat ~/.ssh/config | \
|
||||
grep "^Host " | \
|
||||
awk '{print $2}'`
|
||||
COMPREPLY=( $(compgen -W "${comp_ssh_hosts}" -- $cur))
|
||||
return
|
||||
fi
|
||||
|
||||
#
|
||||
# Complete the {{scriptName}} and cURL's arguments
|
||||
#
|
||||
if [[ $cur == -* ]]; then
|
||||
COMPREPLY=( $( compgen -W '$(_parse_help curl) $(_parse_help $1)' -- "$cur" ) )
|
||||
return
|
||||
fi
|
||||
|
||||
#
|
||||
# If the argument starts with a letter this could be either an operation
|
||||
# or an operation parameter
|
||||
# When $cur is empty, suggest the list of operations by default
|
||||
#
|
||||
if [[ $cur =~ ^[A-Za-z_0-9]* ]]; then
|
||||
# If operation has not been yet selected, suggest the list of operations
|
||||
# otherwise suggest arguments of this operation as declared in the
|
||||
# Swagger specification
|
||||
if [[ -z $operation ]]; then
|
||||
COMPREPLY=( $(compgen -W '${!operations[*]}' -- ${cur}) )
|
||||
else
|
||||
COMPREPLY=( $(compgen -W '${operation_parameters[$operation]}' -- ${cur}) )
|
||||
fi
|
||||
return
|
||||
fi
|
||||
|
||||
} &&
|
||||
complete -F _{{scriptName}} {{scriptName}}
|
||||
|
||||
# ex: ts=4 sw=4 et filetype=sh
|
1106
modules/swagger-codegen/src/main/resources/bash/client.mustache
Normal file
1106
modules/swagger-codegen/src/main/resources/bash/client.mustache
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,301 @@
|
||||
#compdef {{scriptName}}
|
||||
|
||||
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
# !
|
||||
# ! Note:
|
||||
# !
|
||||
# ! THIS SCRIPT HAS BEEN AUTOMATICALLY GENERATED USING
|
||||
# ! swagger-codegen (https://github.com/swagger-api/swagger-codegen)
|
||||
# ! FROM SWAGGER SPECIFICATION IN JSON.
|
||||
# !
|
||||
# ! Based on: https://github.com/Valodim/zsh-curl-completion/blob/master/_curl
|
||||
# !
|
||||
# ! Generated on: {{generatedDate}}
|
||||
# !
|
||||
# !
|
||||
# ! Installation:
|
||||
# !
|
||||
# ! Copy the _{{scriptName}} file to any directory under FPATH
|
||||
# ! environment variable (echo $FPATH)
|
||||
# !
|
||||
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
|
||||
local curcontext="$curcontext" state line ret=1
|
||||
typeset -A opt_args
|
||||
|
||||
#
|
||||
# cURL crypto engines completion function
|
||||
#
|
||||
_curl_crypto_engine() {
|
||||
local vals
|
||||
vals=( ${${(f)"$(curl --engine list)":gs/ /}[2,$]} )
|
||||
_describe -t outputs 'engines' vals && return 0
|
||||
}
|
||||
|
||||
#
|
||||
# cURL post data completion functions=
|
||||
#
|
||||
_curl_post_data() {
|
||||
|
||||
# don't do anything further if this is raw content
|
||||
compset -P '=' && _message 'raw content' && return 0
|
||||
|
||||
# complete filename or stdin for @ syntax
|
||||
compset -P '*@' && {
|
||||
local expl
|
||||
_description files expl stdin
|
||||
compadd "$expl[@]" - "-"
|
||||
_files
|
||||
return 0
|
||||
}
|
||||
|
||||
# got a name already? expecting data.
|
||||
compset -P '*=' && _message 'data value' && return 0
|
||||
|
||||
# otherwise, name (or @ or =) should be specified
|
||||
_message 'data name' && return 0
|
||||
|
||||
}
|
||||
|
||||
|
||||
local arg_http arg_ftp arg_other arg_proxy arg_crypto arg_connection arg_auth arg_input arg_output
|
||||
|
||||
# HTTP Arguments
|
||||
arg_http=(''\
|
||||
{-0,--http1.0}'[force use of use http 1.0 instead of 1.1]' \
|
||||
{-b,--cookie}'[pass data to http server as cookie]:data or file' \
|
||||
{-c,--cookie-jar}'[specify cookie file]:file name:_files' \
|
||||
{-d,--data}'[send specified data as HTTP POST data]:data:{_curl_post_data}' \
|
||||
'--data-binary[post HTTP POST data without any processing]:data:{_curl_post_data}' \
|
||||
'--data-urlencode[post HTTP POST data, with url encoding]:data:{_curl_post_data}' \
|
||||
{-f,--fail}'[enable failfast behavior for server errors]' \
|
||||
'*'{-F,--form}'[add POST form data]:name=content' \
|
||||
{-G,--get}'[use HTTP GET even with data (-d, --data, --data-binary)]' \
|
||||
'*'{-H,--header}'[specify an extra header]:header' \
|
||||
'--ignore-content-length[ignore Content-Length header]' \
|
||||
{-i,--include}'[include HTTP header in the output]' \
|
||||
{-j,--junk-session-cookies}'[discard all session cookies]' \
|
||||
{-e,--referer}'[send url as referer]:referer url:_urls' \
|
||||
{-L,--location}'[follow Location headers on http 3XX response]' \
|
||||
'--location-trusted[like --location, but allows sending of auth data to redirected hosts]' \
|
||||
'--max-redirs[set maximum number of redirection followings allowed]:number' \
|
||||
{-J,--remote-header-name}'[use Content-Disposition for output file name]' \
|
||||
{-O,--remote-name}'[write to filename parsed from url instead of stdout]' \
|
||||
'--post301[do not convert POST to GET after following 301 Location response (follow RFC 2616/10.3.2)]' \
|
||||
'--post302[do not convert POST to GET after following 302 Location response (follow RFC 2616/10.3.2)]' \
|
||||
)
|
||||
|
||||
# FTP arguments
|
||||
arg_ftp=(\
|
||||
{-a,--append}'[append to target file instead of overwriting (FTP/SFTP)]' \
|
||||
'--crlf[convert LF to CRLF in upload]' \
|
||||
'--disable-eprt[disable use of EPRT and LPRT for active FTP transfers]' \
|
||||
'--disable-epsv[disable use of EPSV for passive FTP transfers]' \
|
||||
'--ftp-account[account data (FTP)]:data' \
|
||||
'--ftp-alternative-to-user[command to send when USER and PASS commands fail (FTP)]:command' \
|
||||
'--ftp-create-dirs[create paths remotely if it does not exist]' \
|
||||
'--ftp-method[ftp method to use to reach a file (FTP)]:method:(multicwd ocwd singlecwd)' \
|
||||
'--ftp-pasv[use passive mode for the data connection (FTP)]' \
|
||||
'--ftp-skip-pasv-ip[do not use the ip the server suggests for PASV]' \
|
||||
'--form-string[like --form, but do not parse content]:name=string' \
|
||||
'--ftp-pret[send PRET before PASV]' \
|
||||
'--ftp-ssl-ccc[use clear command channel (CCC) after authentication (FTP)]' \
|
||||
'--ftp-ssl-ccc-mode[sets the CCC mode (FTP)]:mode:(active passive)' \
|
||||
'--ftp-ssl-control[require SSL/TLS for FTP login, clear for transfer]' \
|
||||
{-l,--list-only}'[list names only when listing directories (FTP)]' \
|
||||
{-P,--ftp-port}'[use active mode, tell server to connect to specified address or interface (FTP]:address' \
|
||||
'*'{-Q,--quote}'[send arbitrary command to the remote server before transfer (FTP/SFTP)]:command' \
|
||||
)
|
||||
|
||||
# Other Protocol arguments
|
||||
arg_other=(\
|
||||
'--mail-from[specify From: address]:address' \
|
||||
'--mail-rcpt[specify email recipient for SMTP, may be given multiple times]:address' \
|
||||
{-t,--telnet-option}'[pass options to telnet protocol]:opt=val' \
|
||||
'--tftp-blksize[set tftp BLKSIZE option]:value' \
|
||||
)
|
||||
|
||||
# Proxy arguments
|
||||
arg_proxy=(\
|
||||
'--noproxy[list of hosts to connect directly to instead of through proxy]:no-proxy-list' \
|
||||
{-p,--proxytunnel}'[tunnel non-http protocols through http proxy]' \
|
||||
{-U,--proxy-user}'[specify the user name and password to use for proxy authentication]:user:password' \
|
||||
'--proxy-anyauth[use any authentication method for proxy, default to most secure]' \
|
||||
'--proxy-basic[use HTTP Basic authentication for proxy]' \
|
||||
'--proxy-digest[use http digest authentication for proxy]' \
|
||||
'--proxy-negotiate[enable GSS-Negotiate authentication for proxy]' \
|
||||
'--proxy-ntlm[enable ntlm authentication for proxy]' \
|
||||
'--proxy1.0[use http 1.0 proxy]:proxy url' \
|
||||
{-x,--proxy}'[use specified proxy]:proxy url' \
|
||||
'--socks5-gssapi-service[change service name for socks server]:servicename' \
|
||||
'--socks5-gssapi-nec[allow unprotected exchange of protection mode negotiation]' \
|
||||
)
|
||||
|
||||
# Crypto arguments
|
||||
arg_crypto=(\
|
||||
{-1,--tlsv1}'[Forces curl to use TLS version 1 when negotiating with a remote TLS server.]' \
|
||||
{-2,--sslv2}'[Forces curl to use SSL version 2 when negotiating with a remote SSL server.]' \
|
||||
{-3,--sslv3}'[Forces curl to use SSL version 3 when negotiating with a remote SSL server.]' \
|
||||
'--ciphers[specifies which cipher to use for the ssl connection]:list of ciphers' \
|
||||
'--crlfile[specify file with revoked certificates]:file' \
|
||||
'--delegation[set delegation policy to use with GSS/kerberos]:delegation policy:(none policy always)' \
|
||||
{-E,--cert}'[use specified client certificate]:certificate file:_files' \
|
||||
'--engine[use selected OpenSSL crypto engine]:ssl crypto engine:{_curl_crypto_engine}' \
|
||||
'--egd-file[set ssl entropy gathering daemon socket]:entropy socket:_files' \
|
||||
'--cert-type[specify certificate type (PEM, DER, ENG)]:certificate type:(PEM DER ENG)' \
|
||||
'--cacert[specify certificate file to verify the peer with]:CA certificate:_files' \
|
||||
'--capath[specify a search path for certificate files]:CA certificate directory:_directories' \
|
||||
'--hostpubmd5[check remote hosts public key]:md5 hash' \
|
||||
{-k,--insecure}'[allow ssl to perform insecure ssl connections (ie, ignore certificate)]' \
|
||||
'--key[ssl/ssh private key file name]:key file:_files' \
|
||||
'--key-type[ssl/ssh private key file type]:file type:(PEM DER ENG)' \
|
||||
'--pubkey[ssh public key file]:pubkey file:_files' \
|
||||
'--random-file[set source of random data for ssl]:random source:_files' \
|
||||
'--no-sessionid[disable caching of ssl session ids]' \
|
||||
'--pass:phrase[passphrase for ssl/ssh private key]' \
|
||||
'--ssl[try to use ssl/tls for connection, if available]' \
|
||||
'--ssl-reqd[try to use ssl/tls for connection, fail if unavailable]' \
|
||||
'--tlsauthtype[set TLS authentication type (only SRP supported!)]:authtype' \
|
||||
'--tlsuser[set username for TLS authentication]:user' \
|
||||
'--tlspassword[set password for TLS authentication]:password' \
|
||||
)
|
||||
|
||||
# Connection arguments
|
||||
arg_connection=(\
|
||||
{-4,--ipv4}'[prefer ipv4]' \
|
||||
{-6,--ipv6}'[prefer ipv6, if available]' \
|
||||
{-B,--use-ascii}'[use ascii mode]' \
|
||||
'--compressed[request a compressed transfer]' \
|
||||
'--connect-timeout[timeout for connection phase]:seconds' \
|
||||
{-I,--head}'[fetch http HEAD only (HTTP/FTP/FILE]' \
|
||||
'--interface[work on a specific interface]:name' \
|
||||
'--keepalive-time[set time to wait before sending keepalive probes]:seconds' \
|
||||
'--limit-rate[specify maximum transfer rate]:speed' \
|
||||
'--local-port[set preferred number or range of local ports to use]:num' \
|
||||
{-N,--no-buffer}'[disable buffering of the output stream]' \
|
||||
'--no-keepalive[disable use of keepalive messages in TCP connections]' \
|
||||
'--raw[disable all http decoding and pass raw data]' \
|
||||
'--resolve[provide a custom address for a specific host and port pair]:host\:port\:address' \
|
||||
'--retry[specify maximum number of retries for transient errors]:num' \
|
||||
'--retry-delay[specify delay between retries]:seconds' \
|
||||
'--retry-max-time[maximum time to spend on retries]:seconds' \
|
||||
'--tcp-nodelay[turn on TCP_NODELAY option]' \
|
||||
{-y,--speed-time}'[specify time to abort after if download is slower than speed-limit]:time' \
|
||||
{-Y,--speed-limit}'[specify minimum speed for --speed-time]:speed' \
|
||||
)
|
||||
|
||||
# Authentication arguments
|
||||
arg_auth=(\
|
||||
'--anyauth[use any authentication method, default to most secure]' \
|
||||
'--basic[use HTTP Basic authentication]' \
|
||||
'--ntlm[enable ntlm authentication]' \
|
||||
'--digest[use http digest authentication]' \
|
||||
'--krb[use kerberos authentication]:auth:(clear safe confidential private)' \
|
||||
'--negotiate[enable GSS-Negotiate authentication]' \
|
||||
{-n,--netrc}'[scan ~/.netrc for login data]' \
|
||||
'--netrc-optional[like --netrc, but does not make .netrc usage mandatory]' \
|
||||
'--netrc-file[like --netrc, but specify file to use]:netrc file:_files' \
|
||||
'--tr-encoding[request compressed transfer-encoding]' \
|
||||
{-u,--user}'[specify user name and password for server authentication]:user\:password' \
|
||||
)
|
||||
|
||||
# Input arguments
|
||||
arg_input=(\
|
||||
{-C,--continue-at}'[resume at offset ]:offset' \
|
||||
{-g,--globoff}'[do not glob {}\[\] letters]' \
|
||||
'--max-filesize[maximum filesize to download, fail for bigger files]:bytes' \
|
||||
'--proto[specify allowed protocols for transfer]:protocols' \
|
||||
'--proto-redir[specify allowed protocols for transfer after a redirect]:protocols' \
|
||||
{-r,--range}'[set range of bytes to request (HTTP/FTP/SFTP/FILE)]:range' \
|
||||
{-R,--remote-time}'[use timestamp of remote file for local file]' \
|
||||
{-T,--upload-file}'[transfer file to remote url (using PUT for HTTP)]:file to upload:_files' \
|
||||
'--url[specify a URL to fetch (multi)]:url:_urls' \
|
||||
{-z,--time-cond}'[request downloaded file to be newer than date or given reference file]:date expression' \
|
||||
)
|
||||
|
||||
# Output arguments
|
||||
arg_output=(\
|
||||
'--create-dirs[create local directory hierarchy as needed]' \
|
||||
{-D,--dump-header}'[write protocol headers to file]:dump file:_files' \
|
||||
{-o,--output}'[write to specified file instead of stdout]:output file:_files' \
|
||||
{--progress-bar,-\#}'[display progress as a simple progress bar]' \
|
||||
{-\#,--progress-bar}'[Make curl display progress as a simple progress bar instead of the standard, more informational, meter.]' \
|
||||
{-R,--remote-time}'[use timestamp of remote file for local file]' \
|
||||
'--raw[disable all http decoding and pass raw data]' \
|
||||
{-s,--silent}'[silent mode, do not show progress meter or error messages]' \
|
||||
{-S,--show-error}'[show errors in silent mode]' \
|
||||
'--stderr[redirect stderr to specified file]:output file:_files' \
|
||||
'--trace[enable full trace dump of all incoming and outgoing data]:trace file:_files' \
|
||||
'--trace-ascii[enable full trace dump of all incoming and outgoing data, without hex data]:trace file:_files' \
|
||||
'--trace-time[prepends a time stamp to each trace or verbose line that curl displays]' \
|
||||
{-v,--verbose}'[output debug info]' \
|
||||
{-w,--write-out}'[specify message to output on successful operation]:format string' \
|
||||
'--xattr[store some file metadata in extended file attributes]' \
|
||||
{-X,--request}'[specifies request method for HTTP server]:method:(GET POST PUT DELETE HEAD OPTIONS TRACE CONNECT PATCH LINK UNLINK)' \
|
||||
)
|
||||
|
||||
_arguments -C -s $arg_http $arg_ftp $arg_other $arg_crypto $arg_connection $arg_auth $arg_input $arg_output \
|
||||
{-M,--manual}'[print manual]' \
|
||||
'*'{-K,--config}'[use other config file to read arguments from]:config file:_files' \
|
||||
'--libcurl[output libcurl code for the operation to file]:output file:_files' \
|
||||
{-m,--max-time}'[limit total time of operation]:seconds' \
|
||||
{-s,--silent}'[silent mode, do not show progress meter or error messages]' \
|
||||
{-S,--show-error}'[show errors in silent mode]' \
|
||||
'--stderr[redirect stderr to specified file]:output file:_files' \
|
||||
'-q[do not read settings from .curlrc (must be first option)]' \
|
||||
{-h,--help}'[Print help and list of operations]' \
|
||||
{-V,--version}'[Print service API version]' \
|
||||
'--about[Print the information about service]' \
|
||||
'--host[Specify the host URL]':URL:_urls \
|
||||
'--dry-run[Print out the cURL command without executing it]' \
|
||||
{-ac,--accept}'[Set the 'Accept' header in the request]' \
|
||||
{-ct,--content-type}'[Set the 'Content-type' header in request]' \
|
||||
'1: :->ops' \
|
||||
'*:: :->args' \
|
||||
&& ret=0
|
||||
|
||||
|
||||
case $state in
|
||||
ops)
|
||||
# Operations
|
||||
_values "Operations" \
|
||||
{{#apiInfo}}
|
||||
{{#apis}}
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
"{{operationId}}[{{{summary}}}]" {{#hasMore}}\
|
||||
{{/hasMore}}{{/operation}}{{/operations}}{{/apis}}{{#hasMore}}\
|
||||
{{/hasMore}}
|
||||
{{/apiInfo}}
|
||||
|
||||
_arguments "(--help)--help[Print information about operation]"
|
||||
|
||||
ret=0
|
||||
;;
|
||||
args)
|
||||
case $line[1] in
|
||||
{{#apiInfo}}
|
||||
{{#apis}}
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
{{operationId}})
|
||||
local -a _op_arguments
|
||||
_op_arguments=(
|
||||
{{#pathParams}}"{{baseName}}=:{{{description}}}"
|
||||
{{/pathParams}} {{#queryParams}}{{#isBoolean}}"{{baseName}}=true:{{description}}"
|
||||
"{{baseName}}=false:{{description}}"{{/isBoolean}}{{^isBoolean}}"{{baseName}}=:{{description}}"{{/isBoolean}}
|
||||
{{/queryParams}} {{#headerParams}}"{{baseName}}\::{{{description}}}"
|
||||
{{/headerParams}})
|
||||
_describe -t actions 'operations' _op_arguments && ret=0
|
||||
;;
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
{{/apis}}
|
||||
{{/apiInfo}}
|
||||
esac
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
return ret
|
@ -0,0 +1,56 @@
|
||||
package io.swagger.codegen.bash;
|
||||
|
||||
import io.swagger.codegen.AbstractOptionsTest;
|
||||
import io.swagger.codegen.CodegenConfig;
|
||||
import io.swagger.codegen.languages.BashClientCodegen;
|
||||
import io.swagger.codegen.options.BashClientOptionsProvider;
|
||||
|
||||
import mockit.Expectations;
|
||||
import mockit.Tested;
|
||||
|
||||
public class BashClientOptionsTest extends AbstractOptionsTest {
|
||||
|
||||
@Tested
|
||||
private BashClientCodegen clientCodegen;
|
||||
|
||||
public BashClientOptionsTest() {
|
||||
super(new BashClientOptionsProvider());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CodegenConfig getCodegenConfig() {
|
||||
return clientCodegen;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Override
|
||||
protected void setExpectations() {
|
||||
new Expectations(clientCodegen) {{
|
||||
clientCodegen.setCurlOptions(
|
||||
BashClientOptionsProvider.CURL_OPTIONS);
|
||||
times = 1;
|
||||
clientCodegen.setProcessMarkdown(
|
||||
Boolean.parseBoolean(
|
||||
BashClientOptionsProvider.PROCESS_MARKDOWN));
|
||||
times = 1;
|
||||
clientCodegen.setScriptName(
|
||||
BashClientOptionsProvider.SCRIPT_NAME);
|
||||
times = 1;
|
||||
clientCodegen.setGenerateBashCompletion(
|
||||
Boolean.parseBoolean(
|
||||
BashClientOptionsProvider.GENERATE_BASH_COMPLETION));
|
||||
times = 1;
|
||||
clientCodegen.setGenerateZshCompletion(
|
||||
Boolean.parseBoolean(
|
||||
BashClientOptionsProvider.GENERATE_ZSH_COMPLETION));
|
||||
times = 1;
|
||||
clientCodegen.setHostEnvironmentVariable(
|
||||
BashClientOptionsProvider.HOST_ENVIRONMENT_VARIABLE_NAME);
|
||||
times = 1;
|
||||
clientCodegen.setApiKeyAuthEnvironmentVariable(
|
||||
BashClientOptionsProvider.APIKEY_AUTH_ENVIRONMENT_VARIABLE_NAME);
|
||||
times = 1;
|
||||
}};
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,158 @@
|
||||
package io.swagger.codegen.python;
|
||||
|
||||
import io.swagger.codegen.CodegenModel;
|
||||
import io.swagger.codegen.CodegenOperation;
|
||||
import io.swagger.codegen.CodegenProperty;
|
||||
import io.swagger.codegen.CodegenParameter;
|
||||
import io.swagger.codegen.DefaultCodegen;
|
||||
import io.swagger.codegen.languages.BashClientCodegen;
|
||||
import io.swagger.models.ArrayModel;
|
||||
import io.swagger.models.Model;
|
||||
import io.swagger.models.ModelImpl;
|
||||
import io.swagger.models.Operation;
|
||||
import io.swagger.models.Swagger;
|
||||
import io.swagger.models.properties.ArrayProperty;
|
||||
import io.swagger.models.properties.DateTimeProperty;
|
||||
import io.swagger.models.properties.LongProperty;
|
||||
import io.swagger.models.properties.MapProperty;
|
||||
import io.swagger.models.properties.RefProperty;
|
||||
import io.swagger.models.properties.StringProperty;
|
||||
import io.swagger.parser.SwaggerParser;
|
||||
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
import org.testng.annotations.ITestAnnotation;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings("static-method")
|
||||
public class BashTest {
|
||||
|
||||
@Test(description = "test basic petstore operation with Bash extensions")
|
||||
public void petstoreOperationTest() {
|
||||
|
||||
final Swagger swagger
|
||||
= new SwaggerParser()
|
||||
.read("src/test/resources/2_0/petstore-bash.json");
|
||||
final DefaultCodegen codegen = new BashClientCodegen();
|
||||
final Operation findPetsByStatusOperation
|
||||
= swagger.getPath("/pet/findByStatus").getGet();
|
||||
|
||||
final CodegenOperation op
|
||||
= codegen.fromOperation(
|
||||
"/pet/findByStatus",
|
||||
"GET",
|
||||
findPetsByStatusOperation,
|
||||
swagger.getDefinitions(),
|
||||
swagger);
|
||||
|
||||
Assert.assertTrue(
|
||||
op.vendorExtensions.containsKey("x-bash-codegen-sample"));
|
||||
|
||||
Assert.assertEquals(
|
||||
op.vendorExtensions.get("x-bash-codegen-description"),
|
||||
"Multiple status 'values' can be provided with comma separated strings");
|
||||
|
||||
}
|
||||
|
||||
@Test(description = "test basic petstore operation with example body")
|
||||
public void petstoreParameterExampleTest() {
|
||||
|
||||
final Swagger swagger
|
||||
= new SwaggerParser()
|
||||
.read("src/test/resources/2_0/petstore-bash.json");
|
||||
final DefaultCodegen codegen = new BashClientCodegen();
|
||||
final Operation addPetOperation
|
||||
= swagger.getPath("/pet").getPost();
|
||||
|
||||
final CodegenOperation op
|
||||
= codegen.fromOperation(
|
||||
"/pet",
|
||||
"POST",
|
||||
addPetOperation,
|
||||
swagger.getDefinitions(),
|
||||
swagger);
|
||||
|
||||
Assert.assertEquals(op.bodyParams.size(), 1);
|
||||
|
||||
CodegenParameter pet = op.bodyParams.get(0);
|
||||
|
||||
Assert.assertTrue(pet.vendorExtensions
|
||||
.containsKey("x-codegen-body-example"));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test(description = "test Bash client codegen escapeText method")
|
||||
public void escapeTextTest() {
|
||||
final DefaultCodegen codegen = new BashClientCodegen();
|
||||
|
||||
|
||||
Assert.assertEquals(codegen.escapeText("\\/"), "/");
|
||||
|
||||
Assert.assertEquals(codegen.escapeText("\\"), "\\\\");
|
||||
|
||||
|
||||
((BashClientCodegen)codegen).setProcessMarkdown(false);
|
||||
|
||||
Assert.assertEquals(codegen.escapeText("__Bold text__"),
|
||||
"__Bold text__");
|
||||
|
||||
Assert.assertEquals(codegen.escapeText("**Bold text**"),
|
||||
"**Bold text**");
|
||||
|
||||
Assert.assertEquals(codegen.escapeText("*Italic text*"),
|
||||
"*Italic text*");
|
||||
|
||||
Assert.assertEquals(codegen.escapeText("_Italic text_"),
|
||||
"_Italic text_");
|
||||
|
||||
|
||||
((BashClientCodegen)codegen).setProcessMarkdown(true);
|
||||
|
||||
Assert.assertEquals(codegen.escapeText("__Bold text__"),
|
||||
"$(tput bold) Bold text $(tput sgr0)");
|
||||
|
||||
Assert.assertEquals(codegen.escapeText("**Bold text**"),
|
||||
"$(tput bold) Bold text $(tput sgr0)");
|
||||
|
||||
Assert.assertEquals(codegen.escapeText("*Italic text*"),
|
||||
"$(tput dim) Italic text $(tput sgr0)");
|
||||
|
||||
Assert.assertEquals(codegen.escapeText("_Italic text_"),
|
||||
"$(tput dim) Italic text $(tput sgr0)");
|
||||
|
||||
Assert.assertEquals(codegen.escapeText("# SECTION NAME"),
|
||||
"\n$(tput bold)$(tput setaf 7)SECTION NAME$(tput sgr0)");
|
||||
|
||||
Assert.assertEquals(codegen.escapeText("## SECTION NAME"),
|
||||
"\n$(tput bold)$(tput setaf 7)SECTION NAME$(tput sgr0)");
|
||||
|
||||
Assert.assertEquals(codegen.escapeText("### SECTION NAME"),
|
||||
"\n$(tput bold)$(tput setaf 7)SECTION NAME$(tput sgr0)");
|
||||
|
||||
Assert.assertEquals(codegen.escapeText(
|
||||
"```\nnice -n 100 mvn test\n```"),
|
||||
"\n---\nnice -n 100 mvn test\n---");
|
||||
}
|
||||
|
||||
@Test(description = "test Bash client codegen escapeUnsafeCharacters method")
|
||||
public void escapeUnsafeCharactersTest() {
|
||||
final DefaultCodegen codegen = new BashClientCodegen();
|
||||
|
||||
Assert.assertEquals(codegen.escapeUnsafeCharacters("`no backticks`"),
|
||||
"'no backticks'");
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Test(description = "test Bash client codegen escapeReservedWord method")
|
||||
public void escapeReservedWordTest() {
|
||||
final DefaultCodegen codegen = new BashClientCodegen();
|
||||
|
||||
Assert.assertEquals(codegen.escapeReservedWord("case"), "_case");
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package io.swagger.codegen.options;
|
||||
|
||||
import io.swagger.codegen.CodegenConstants;
|
||||
import io.swagger.codegen.languages.BashClientCodegen;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class BashClientOptionsProvider implements OptionsProvider {
|
||||
|
||||
public static final String CURL_OPTIONS = "-k --tlsv1.2";
|
||||
public static final String PROCESS_MARKDOWN = "true";
|
||||
public static final String SCRIPT_NAME = "petstore-cli";
|
||||
public static final String GENERATE_BASH_COMPLETION = "true";
|
||||
public static final String GENERATE_ZSH_COMPLETION = "false";
|
||||
public static final String HOST_ENVIRONMENT_VARIABLE_NAME
|
||||
= "PETSTORE_HOSTNAME";
|
||||
public static final String BASIC_AUTH_ENVIRONMENT_VARIABLE_NAME
|
||||
= "PETSTORE_BASIC_AUTH";
|
||||
public static final String APIKEY_AUTH_ENVIRONMENT_VARIABLE_NAME
|
||||
= "PETSTORE_APIKEY";
|
||||
|
||||
@Override
|
||||
public String getLanguage() {
|
||||
return "bash";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> createOptions() {
|
||||
|
||||
ImmutableMap.Builder<String, String> builder
|
||||
= new ImmutableMap.Builder<String, String>();
|
||||
|
||||
return builder
|
||||
.put(BashClientCodegen.CURL_OPTIONS, CURL_OPTIONS)
|
||||
.put(BashClientCodegen.SCRIPT_NAME, SCRIPT_NAME)
|
||||
.put(BashClientCodegen.PROCESS_MARKDOWN, PROCESS_MARKDOWN)
|
||||
.put(BashClientCodegen.GENERATE_BASH_COMPLETION,
|
||||
GENERATE_BASH_COMPLETION)
|
||||
.put(BashClientCodegen.GENERATE_ZSH_COMPLETION,
|
||||
GENERATE_ZSH_COMPLETION)
|
||||
.put(BashClientCodegen.HOST_ENVIRONMENT_VARIABLE_NAME,
|
||||
HOST_ENVIRONMENT_VARIABLE_NAME)
|
||||
.put(BashClientCodegen.BASIC_AUTH_ENVIRONMENT_VARIABLE_NAME,
|
||||
BASIC_AUTH_ENVIRONMENT_VARIABLE_NAME)
|
||||
.put(BashClientCodegen.APIKEY_AUTH_ENVIRONMENT_VARIABLE_NAME,
|
||||
APIKEY_AUTH_ENVIRONMENT_VARIABLE_NAME)
|
||||
.put(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG, "false")
|
||||
.put(CodegenConstants.ENSURE_UNIQUE_PARAMS, "false")
|
||||
.build();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isServer() {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
{
|
||||
"processMarkdown": true,
|
||||
"curlOptions": "-sS --tlsv1.2",
|
||||
"scriptName": "petstore-cli",
|
||||
"generateBashCompletion": true,
|
||||
"generateZshCompletion": true,
|
||||
"hostEnvironmentVariable": "PETSTORE_HOST",
|
||||
"basicAuthEnvironmentVariable": "PETSTORE_BASIC_AUTH",
|
||||
"apiKeyAuthEnvironmentVariable": "PETSTORE_API_KEY"
|
||||
}
|
1056
modules/swagger-codegen/src/test/resources/2_0/petstore-bash.json
Normal file
1056
modules/swagger-codegen/src/test/resources/2_0/petstore-bash.json
Normal file
File diff suppressed because it is too large
Load Diff
13
pom.xml
13
pom.xml
@ -314,6 +314,18 @@
|
||||
<module>samples/client/petstore/android/volley</module>
|
||||
</modules>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>bash-client</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>env</name>
|
||||
<value>java</value>
|
||||
</property>
|
||||
</activation>
|
||||
<modules>
|
||||
<module>samples/client/petstore/bash</module>
|
||||
</modules>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>clojure-client</id>
|
||||
<activation>
|
||||
@ -748,6 +760,7 @@
|
||||
<!-- clients -->
|
||||
<module>samples/client/petstore/ruby</module>
|
||||
<module>samples/client/petstore/android/volley</module>
|
||||
<module>samples/client/petstore/bash</module>
|
||||
<module>samples/client/petstore/clojure</module>
|
||||
<module>samples/client/petstore/go</module>
|
||||
<module>samples/client/petstore/java/feign</module>
|
||||
|
23
samples/client/petstore/bash/.swagger-codegen-ignore
Normal file
23
samples/client/petstore/bash/.swagger-codegen-ignore
Normal file
@ -0,0 +1,23 @@
|
||||
# Swagger Codegen Ignore
|
||||
# Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen
|
||||
|
||||
# Use this file to prevent files from being overwritten by the generator.
|
||||
# The patterns follow closely to .gitignore or .dockerignore.
|
||||
|
||||
# As an example, the C# client generator defines ApiClient.cs.
|
||||
# You can make changes and tell Swagger Codgen to ignore just this file by uncommenting the following line:
|
||||
#ApiClient.cs
|
||||
|
||||
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
|
||||
#foo/*/qux
|
||||
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
|
||||
|
||||
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
|
||||
#foo/**/qux
|
||||
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
|
||||
|
||||
# You can also negate patterns with an exclamation (!).
|
||||
# For example, you can ignore all files in a docs folder with the file extension .md:
|
||||
#docs/*.md
|
||||
# Then explicitly reverse the ignore rule for a single file:
|
||||
#!docs/README.md
|
75
samples/client/petstore/bash/README.md
Normal file
75
samples/client/petstore/bash/README.md
Normal file
@ -0,0 +1,75 @@
|
||||
# Swagger Petstore Bash client
|
||||
|
||||
## Overview
|
||||
This is a Bash client script for accessing Swagger Petstore service.
|
||||
|
||||
The script uses cURL underneath for making all REST calls.
|
||||
|
||||
## Usage
|
||||
|
||||
```shell
|
||||
# Make sure the script has executable rights
|
||||
$ chmod u+x petstore-cli
|
||||
|
||||
# Print the list of operations available on the service
|
||||
$ ./petstore-cli -h
|
||||
|
||||
# Print the service description
|
||||
$ ./petstore-cli --about
|
||||
|
||||
# Print detailed information about specific operation
|
||||
$ ./petstore-cli <operationId> -h
|
||||
|
||||
# Make GET request
|
||||
./petstore-cli --host http://<hostname>:<port> --accept xml <operationId> <queryParam1>=<value1> <header_key1>:<header_value2>
|
||||
|
||||
# Make GET request using arbitrary curl options (must be passed before <operationId>) to an SSL service using username:password
|
||||
petstore-cli -k -sS --tlsv1.2 --host https://<hostname> -u <user>:<password> --accept xml <operationId> <queryParam1>=<value1> <header_key1>:<header_value2>
|
||||
|
||||
# Make POST request
|
||||
$ echo '<body_content>' | petstore-cli --host <hostname> --content-type json <operationId> -
|
||||
|
||||
# Make POST request with simple JSON content, e.g.:
|
||||
# {
|
||||
# "key1": "value1",
|
||||
# "key2": "value2",
|
||||
# "key3": 23
|
||||
# }
|
||||
$ echo '<body_content>' | petstore-cli --host <hostname> --content-type json <operationId> key1==value1 key2=value2 key3:=23 -
|
||||
|
||||
# Preview the cURL command without actually executing it
|
||||
$ petstore-cli --host http://<hostname>:<port> --dry-run <operationid>
|
||||
|
||||
```
|
||||
|
||||
## Shell completion
|
||||
|
||||
### Bash
|
||||
The generated bash-completion script can be either directly loaded to the current Bash session using:
|
||||
|
||||
```shell
|
||||
source petstore-cli.bash-completion
|
||||
```
|
||||
|
||||
Alternatively, the script can be copied to the `/etc/bash-completion.d` (or on OSX with Homebrew to `/usr/local/etc/bash-completion.d`):
|
||||
|
||||
```shell
|
||||
sudo cp petstore-cli.bash-completion /etc/bash-completion.d/petstore-cli
|
||||
```
|
||||
|
||||
#### OS X
|
||||
On OSX you might need to install bash-completion using Homebrew:
|
||||
```shell
|
||||
brew install bash-completion
|
||||
```
|
||||
and add the following to the `~/.bashrc`:
|
||||
|
||||
```shell
|
||||
if [ -f $(brew --prefix)/etc/bash_completion ]; then
|
||||
. $(brew --prefix)/etc/bash_completion
|
||||
fi
|
||||
```
|
||||
|
||||
### Zsh
|
||||
In Zsh, the generated `_petstore-cli` Zsh completion file must be copied to one of the folders under `$FPATH` variable.
|
||||
|
454
samples/client/petstore/bash/_petstore-cli
Normal file
454
samples/client/petstore/bash/_petstore-cli
Normal file
@ -0,0 +1,454 @@
|
||||
#compdef petstore-cli
|
||||
|
||||
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
# !
|
||||
# ! Note:
|
||||
# !
|
||||
# ! THIS SCRIPT HAS BEEN AUTOMATICALLY GENERATED USING
|
||||
# ! swagger-codegen (https://github.com/swagger-api/swagger-codegen)
|
||||
# ! FROM SWAGGER SPECIFICATION IN JSON.
|
||||
# !
|
||||
# ! Based on: https://github.com/Valodim/zsh-curl-completion/blob/master/_curl
|
||||
# !
|
||||
# ! Generated on: 2017-01-12T00:07:27.471+01:00
|
||||
# !
|
||||
# !
|
||||
# ! Installation:
|
||||
# !
|
||||
# ! Copy the _petstore-cli file to any directory under FPATH
|
||||
# ! environment variable (echo $FPATH)
|
||||
# !
|
||||
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
|
||||
local curcontext="$curcontext" state line ret=1
|
||||
typeset -A opt_args
|
||||
|
||||
#
|
||||
# cURL crypto engines completion function
|
||||
#
|
||||
_curl_crypto_engine() {
|
||||
local vals
|
||||
vals=( ${${(f)"$(curl --engine list)":gs/ /}[2,$]} )
|
||||
_describe -t outputs 'engines' vals && return 0
|
||||
}
|
||||
|
||||
#
|
||||
# cURL post data completion functions=
|
||||
#
|
||||
_curl_post_data() {
|
||||
|
||||
# don't do anything further if this is raw content
|
||||
compset -P '=' && _message 'raw content' && return 0
|
||||
|
||||
# complete filename or stdin for @ syntax
|
||||
compset -P '*@' && {
|
||||
local expl
|
||||
_description files expl stdin
|
||||
compadd "$expl[@]" - "-"
|
||||
_files
|
||||
return 0
|
||||
}
|
||||
|
||||
# got a name already? expecting data.
|
||||
compset -P '*=' && _message 'data value' && return 0
|
||||
|
||||
# otherwise, name (or @ or =) should be specified
|
||||
_message 'data name' && return 0
|
||||
|
||||
}
|
||||
|
||||
|
||||
local arg_http arg_ftp arg_other arg_proxy arg_crypto arg_connection arg_auth arg_input arg_output
|
||||
|
||||
# HTTP Arguments
|
||||
arg_http=(''\
|
||||
{-0,--http1.0}'[force use of use http 1.0 instead of 1.1]' \
|
||||
{-b,--cookie}'[pass data to http server as cookie]:data or file' \
|
||||
{-c,--cookie-jar}'[specify cookie file]:file name:_files' \
|
||||
{-d,--data}'[send specified data as HTTP POST data]:data:{_curl_post_data}' \
|
||||
'--data-binary[post HTTP POST data without any processing]:data:{_curl_post_data}' \
|
||||
'--data-urlencode[post HTTP POST data, with url encoding]:data:{_curl_post_data}' \
|
||||
{-f,--fail}'[enable failfast behavior for server errors]' \
|
||||
'*'{-F,--form}'[add POST form data]:name=content' \
|
||||
{-G,--get}'[use HTTP GET even with data (-d, --data, --data-binary)]' \
|
||||
'*'{-H,--header}'[specify an extra header]:header' \
|
||||
'--ignore-content-length[ignore Content-Length header]' \
|
||||
{-i,--include}'[include HTTP header in the output]' \
|
||||
{-j,--junk-session-cookies}'[discard all session cookies]' \
|
||||
{-e,--referer}'[send url as referer]:referer url:_urls' \
|
||||
{-L,--location}'[follow Location headers on http 3XX response]' \
|
||||
'--location-trusted[like --location, but allows sending of auth data to redirected hosts]' \
|
||||
'--max-redirs[set maximum number of redirection followings allowed]:number' \
|
||||
{-J,--remote-header-name}'[use Content-Disposition for output file name]' \
|
||||
{-O,--remote-name}'[write to filename parsed from url instead of stdout]' \
|
||||
'--post301[do not convert POST to GET after following 301 Location response (follow RFC 2616/10.3.2)]' \
|
||||
'--post302[do not convert POST to GET after following 302 Location response (follow RFC 2616/10.3.2)]' \
|
||||
)
|
||||
|
||||
# FTP arguments
|
||||
arg_ftp=(\
|
||||
{-a,--append}'[append to target file instead of overwriting (FTP/SFTP)]' \
|
||||
'--crlf[convert LF to CRLF in upload]' \
|
||||
'--disable-eprt[disable use of EPRT and LPRT for active FTP transfers]' \
|
||||
'--disable-epsv[disable use of EPSV for passive FTP transfers]' \
|
||||
'--ftp-account[account data (FTP)]:data' \
|
||||
'--ftp-alternative-to-user[command to send when USER and PASS commands fail (FTP)]:command' \
|
||||
'--ftp-create-dirs[create paths remotely if it does not exist]' \
|
||||
'--ftp-method[ftp method to use to reach a file (FTP)]:method:(multicwd ocwd singlecwd)' \
|
||||
'--ftp-pasv[use passive mode for the data connection (FTP)]' \
|
||||
'--ftp-skip-pasv-ip[do not use the ip the server suggests for PASV]' \
|
||||
'--form-string[like --form, but do not parse content]:name=string' \
|
||||
'--ftp-pret[send PRET before PASV]' \
|
||||
'--ftp-ssl-ccc[use clear command channel (CCC) after authentication (FTP)]' \
|
||||
'--ftp-ssl-ccc-mode[sets the CCC mode (FTP)]:mode:(active passive)' \
|
||||
'--ftp-ssl-control[require SSL/TLS for FTP login, clear for transfer]' \
|
||||
{-l,--list-only}'[list names only when listing directories (FTP)]' \
|
||||
{-P,--ftp-port}'[use active mode, tell server to connect to specified address or interface (FTP]:address' \
|
||||
'*'{-Q,--quote}'[send arbitrary command to the remote server before transfer (FTP/SFTP)]:command' \
|
||||
)
|
||||
|
||||
# Other Protocol arguments
|
||||
arg_other=(\
|
||||
'--mail-from[specify From: address]:address' \
|
||||
'--mail-rcpt[specify email recipient for SMTP, may be given multiple times]:address' \
|
||||
{-t,--telnet-option}'[pass options to telnet protocol]:opt=val' \
|
||||
'--tftp-blksize[set tftp BLKSIZE option]:value' \
|
||||
)
|
||||
|
||||
# Proxy arguments
|
||||
arg_proxy=(\
|
||||
'--noproxy[list of hosts to connect directly to instead of through proxy]:no-proxy-list' \
|
||||
{-p,--proxytunnel}'[tunnel non-http protocols through http proxy]' \
|
||||
{-U,--proxy-user}'[specify the user name and password to use for proxy authentication]:user:password' \
|
||||
'--proxy-anyauth[use any authentication method for proxy, default to most secure]' \
|
||||
'--proxy-basic[use HTTP Basic authentication for proxy]' \
|
||||
'--proxy-digest[use http digest authentication for proxy]' \
|
||||
'--proxy-negotiate[enable GSS-Negotiate authentication for proxy]' \
|
||||
'--proxy-ntlm[enable ntlm authentication for proxy]' \
|
||||
'--proxy1.0[use http 1.0 proxy]:proxy url' \
|
||||
{-x,--proxy}'[use specified proxy]:proxy url' \
|
||||
'--socks5-gssapi-service[change service name for socks server]:servicename' \
|
||||
'--socks5-gssapi-nec[allow unprotected exchange of protection mode negotiation]' \
|
||||
)
|
||||
|
||||
# Crypto arguments
|
||||
arg_crypto=(\
|
||||
{-1,--tlsv1}'[Forces curl to use TLS version 1 when negotiating with a remote TLS server.]' \
|
||||
{-2,--sslv2}'[Forces curl to use SSL version 2 when negotiating with a remote SSL server.]' \
|
||||
{-3,--sslv3}'[Forces curl to use SSL version 3 when negotiating with a remote SSL server.]' \
|
||||
'--ciphers[specifies which cipher to use for the ssl connection]:list of ciphers' \
|
||||
'--crlfile[specify file with revoked certificates]:file' \
|
||||
'--delegation[set delegation policy to use with GSS/kerberos]:delegation policy:(none policy always)' \
|
||||
{-E,--cert}'[use specified client certificate]:certificate file:_files' \
|
||||
'--engine[use selected OpenSSL crypto engine]:ssl crypto engine:{_curl_crypto_engine}' \
|
||||
'--egd-file[set ssl entropy gathering daemon socket]:entropy socket:_files' \
|
||||
'--cert-type[specify certificate type (PEM, DER, ENG)]:certificate type:(PEM DER ENG)' \
|
||||
'--cacert[specify certificate file to verify the peer with]:CA certificate:_files' \
|
||||
'--capath[specify a search path for certificate files]:CA certificate directory:_directories' \
|
||||
'--hostpubmd5[check remote hosts public key]:md5 hash' \
|
||||
{-k,--insecure}'[allow ssl to perform insecure ssl connections (ie, ignore certificate)]' \
|
||||
'--key[ssl/ssh private key file name]:key file:_files' \
|
||||
'--key-type[ssl/ssh private key file type]:file type:(PEM DER ENG)' \
|
||||
'--pubkey[ssh public key file]:pubkey file:_files' \
|
||||
'--random-file[set source of random data for ssl]:random source:_files' \
|
||||
'--no-sessionid[disable caching of ssl session ids]' \
|
||||
'--pass:phrase[passphrase for ssl/ssh private key]' \
|
||||
'--ssl[try to use ssl/tls for connection, if available]' \
|
||||
'--ssl-reqd[try to use ssl/tls for connection, fail if unavailable]' \
|
||||
'--tlsauthtype[set TLS authentication type (only SRP supported!)]:authtype' \
|
||||
'--tlsuser[set username for TLS authentication]:user' \
|
||||
'--tlspassword[set password for TLS authentication]:password' \
|
||||
)
|
||||
|
||||
# Connection arguments
|
||||
arg_connection=(\
|
||||
{-4,--ipv4}'[prefer ipv4]' \
|
||||
{-6,--ipv6}'[prefer ipv6, if available]' \
|
||||
{-B,--use-ascii}'[use ascii mode]' \
|
||||
'--compressed[request a compressed transfer]' \
|
||||
'--connect-timeout[timeout for connection phase]:seconds' \
|
||||
{-I,--head}'[fetch http HEAD only (HTTP/FTP/FILE]' \
|
||||
'--interface[work on a specific interface]:name' \
|
||||
'--keepalive-time[set time to wait before sending keepalive probes]:seconds' \
|
||||
'--limit-rate[specify maximum transfer rate]:speed' \
|
||||
'--local-port[set preferred number or range of local ports to use]:num' \
|
||||
{-N,--no-buffer}'[disable buffering of the output stream]' \
|
||||
'--no-keepalive[disable use of keepalive messages in TCP connections]' \
|
||||
'--raw[disable all http decoding and pass raw data]' \
|
||||
'--resolve[provide a custom address for a specific host and port pair]:host\:port\:address' \
|
||||
'--retry[specify maximum number of retries for transient errors]:num' \
|
||||
'--retry-delay[specify delay between retries]:seconds' \
|
||||
'--retry-max-time[maximum time to spend on retries]:seconds' \
|
||||
'--tcp-nodelay[turn on TCP_NODELAY option]' \
|
||||
{-y,--speed-time}'[specify time to abort after if download is slower than speed-limit]:time' \
|
||||
{-Y,--speed-limit}'[specify minimum speed for --speed-time]:speed' \
|
||||
)
|
||||
|
||||
# Authentication arguments
|
||||
arg_auth=(\
|
||||
'--anyauth[use any authentication method, default to most secure]' \
|
||||
'--basic[use HTTP Basic authentication]' \
|
||||
'--ntlm[enable ntlm authentication]' \
|
||||
'--digest[use http digest authentication]' \
|
||||
'--krb[use kerberos authentication]:auth:(clear safe confidential private)' \
|
||||
'--negotiate[enable GSS-Negotiate authentication]' \
|
||||
{-n,--netrc}'[scan ~/.netrc for login data]' \
|
||||
'--netrc-optional[like --netrc, but does not make .netrc usage mandatory]' \
|
||||
'--netrc-file[like --netrc, but specify file to use]:netrc file:_files' \
|
||||
'--tr-encoding[request compressed transfer-encoding]' \
|
||||
{-u,--user}'[specify user name and password for server authentication]:user\:password' \
|
||||
)
|
||||
|
||||
# Input arguments
|
||||
arg_input=(\
|
||||
{-C,--continue-at}'[resume at offset ]:offset' \
|
||||
{-g,--globoff}'[do not glob {}\[\] letters]' \
|
||||
'--max-filesize[maximum filesize to download, fail for bigger files]:bytes' \
|
||||
'--proto[specify allowed protocols for transfer]:protocols' \
|
||||
'--proto-redir[specify allowed protocols for transfer after a redirect]:protocols' \
|
||||
{-r,--range}'[set range of bytes to request (HTTP/FTP/SFTP/FILE)]:range' \
|
||||
{-R,--remote-time}'[use timestamp of remote file for local file]' \
|
||||
{-T,--upload-file}'[transfer file to remote url (using PUT for HTTP)]:file to upload:_files' \
|
||||
'--url[specify a URL to fetch (multi)]:url:_urls' \
|
||||
{-z,--time-cond}'[request downloaded file to be newer than date or given reference file]:date expression' \
|
||||
)
|
||||
|
||||
# Output arguments
|
||||
arg_output=(\
|
||||
'--create-dirs[create local directory hierarchy as needed]' \
|
||||
{-D,--dump-header}'[write protocol headers to file]:dump file:_files' \
|
||||
{-o,--output}'[write to specified file instead of stdout]:output file:_files' \
|
||||
{--progress-bar,-\#}'[display progress as a simple progress bar]' \
|
||||
{-\#,--progress-bar}'[Make curl display progress as a simple progress bar instead of the standard, more informational, meter.]' \
|
||||
{-R,--remote-time}'[use timestamp of remote file for local file]' \
|
||||
'--raw[disable all http decoding and pass raw data]' \
|
||||
{-s,--silent}'[silent mode, do not show progress meter or error messages]' \
|
||||
{-S,--show-error}'[show errors in silent mode]' \
|
||||
'--stderr[redirect stderr to specified file]:output file:_files' \
|
||||
'--trace[enable full trace dump of all incoming and outgoing data]:trace file:_files' \
|
||||
'--trace-ascii[enable full trace dump of all incoming and outgoing data, without hex data]:trace file:_files' \
|
||||
'--trace-time[prepends a time stamp to each trace or verbose line that curl displays]' \
|
||||
{-v,--verbose}'[output debug info]' \
|
||||
{-w,--write-out}'[specify message to output on successful operation]:format string' \
|
||||
'--xattr[store some file metadata in extended file attributes]' \
|
||||
{-X,--request}'[specifies request method for HTTP server]:method:(GET POST PUT DELETE HEAD OPTIONS TRACE CONNECT PATCH LINK UNLINK)' \
|
||||
)
|
||||
|
||||
_arguments -C -s $arg_http $arg_ftp $arg_other $arg_crypto $arg_connection $arg_auth $arg_input $arg_output \
|
||||
{-M,--manual}'[print manual]' \
|
||||
'*'{-K,--config}'[use other config file to read arguments from]:config file:_files' \
|
||||
'--libcurl[output libcurl code for the operation to file]:output file:_files' \
|
||||
{-m,--max-time}'[limit total time of operation]:seconds' \
|
||||
{-s,--silent}'[silent mode, do not show progress meter or error messages]' \
|
||||
{-S,--show-error}'[show errors in silent mode]' \
|
||||
'--stderr[redirect stderr to specified file]:output file:_files' \
|
||||
'-q[do not read settings from .curlrc (must be first option)]' \
|
||||
{-h,--help}'[Print help and list of operations]' \
|
||||
{-V,--version}'[Print service API version]' \
|
||||
'--about[Print the information about service]' \
|
||||
'--host[Specify the host URL]':URL:_urls \
|
||||
'--dry-run[Print out the cURL command without executing it]' \
|
||||
{-ac,--accept}'[Set the 'Accept' header in the request]' \
|
||||
{-ct,--content-type}'[Set the 'Content-type' header in request]' \
|
||||
'1: :->ops' \
|
||||
'*:: :->args' \
|
||||
&& ret=0
|
||||
|
||||
|
||||
case $state in
|
||||
ops)
|
||||
# Operations
|
||||
_values "Operations" \
|
||||
"testClientModel[To test \"client\" model]" \
|
||||
"testEndpointParameters[Fake endpoint for testing various parameters
|
||||
假端點
|
||||
偽のエンドポイント
|
||||
가짜 엔드 포인트]" \
|
||||
"testEnumParameters[To test enum parameters]" "addPet[Add a new pet to the store]" \
|
||||
"deletePet[Deletes a pet]" \
|
||||
"findPetsByStatus[Finds Pets by status]" \
|
||||
"findPetsByTags[Finds Pets by tags]" \
|
||||
"getPetById[Find pet by ID]" \
|
||||
"updatePet[Update an existing pet]" \
|
||||
"updatePetWithForm[Updates a pet in the store with form data]" \
|
||||
"uploadFile[uploads an image]" "deleteOrder[Delete purchase order by ID]" \
|
||||
"getInventory[Returns pet inventories by status]" \
|
||||
"getOrderById[Find purchase order by ID]" \
|
||||
"placeOrder[Place an order for a pet]" "createUser[Create user]" \
|
||||
"createUsersWithArrayInput[Creates list of users with given input array]" \
|
||||
"createUsersWithListInput[Creates list of users with given input array]" \
|
||||
"deleteUser[Delete user]" \
|
||||
"getUserByName[Get user by user name]" \
|
||||
"loginUser[Logs user into the system]" \
|
||||
"logoutUser[Logs out current logged in user session]" \
|
||||
"updateUser[Updated user]"
|
||||
_arguments "(--help)--help[Print information about operation]"
|
||||
|
||||
ret=0
|
||||
;;
|
||||
args)
|
||||
case $line[1] in
|
||||
testClientModel)
|
||||
local -a _op_arguments
|
||||
_op_arguments=(
|
||||
)
|
||||
_describe -t actions 'operations' _op_arguments && ret=0
|
||||
;;
|
||||
testEndpointParameters)
|
||||
local -a _op_arguments
|
||||
_op_arguments=(
|
||||
)
|
||||
_describe -t actions 'operations' _op_arguments && ret=0
|
||||
;;
|
||||
testEnumParameters)
|
||||
local -a _op_arguments
|
||||
_op_arguments=(
|
||||
"enum_query_string_array=:Query parameter enum test (string array)"
|
||||
"enum_query_string=:Query parameter enum test (string)"
|
||||
"enum_query_integer=:Query parameter enum test (double)"
|
||||
"enum_header_string_array\::Header parameter enum test (string array)"
|
||||
"enum_header_string\::Header parameter enum test (string)"
|
||||
)
|
||||
_describe -t actions 'operations' _op_arguments && ret=0
|
||||
;;
|
||||
addPet)
|
||||
local -a _op_arguments
|
||||
_op_arguments=(
|
||||
)
|
||||
_describe -t actions 'operations' _op_arguments && ret=0
|
||||
;;
|
||||
deletePet)
|
||||
local -a _op_arguments
|
||||
_op_arguments=(
|
||||
"petId=:Pet id to delete"
|
||||
"api_key\::"
|
||||
)
|
||||
_describe -t actions 'operations' _op_arguments && ret=0
|
||||
;;
|
||||
findPetsByStatus)
|
||||
local -a _op_arguments
|
||||
_op_arguments=(
|
||||
"status=:Status values that need to be considered for filter"
|
||||
)
|
||||
_describe -t actions 'operations' _op_arguments && ret=0
|
||||
;;
|
||||
findPetsByTags)
|
||||
local -a _op_arguments
|
||||
_op_arguments=(
|
||||
"tags=:Tags to filter by"
|
||||
)
|
||||
_describe -t actions 'operations' _op_arguments && ret=0
|
||||
;;
|
||||
getPetById)
|
||||
local -a _op_arguments
|
||||
_op_arguments=(
|
||||
"petId=:ID of pet to return"
|
||||
)
|
||||
_describe -t actions 'operations' _op_arguments && ret=0
|
||||
;;
|
||||
updatePet)
|
||||
local -a _op_arguments
|
||||
_op_arguments=(
|
||||
)
|
||||
_describe -t actions 'operations' _op_arguments && ret=0
|
||||
;;
|
||||
updatePetWithForm)
|
||||
local -a _op_arguments
|
||||
_op_arguments=(
|
||||
"petId=:ID of pet that needs to be updated"
|
||||
)
|
||||
_describe -t actions 'operations' _op_arguments && ret=0
|
||||
;;
|
||||
uploadFile)
|
||||
local -a _op_arguments
|
||||
_op_arguments=(
|
||||
"petId=:ID of pet to update"
|
||||
)
|
||||
_describe -t actions 'operations' _op_arguments && ret=0
|
||||
;;
|
||||
deleteOrder)
|
||||
local -a _op_arguments
|
||||
_op_arguments=(
|
||||
"orderId=:ID of the order that needs to be deleted"
|
||||
)
|
||||
_describe -t actions 'operations' _op_arguments && ret=0
|
||||
;;
|
||||
getInventory)
|
||||
local -a _op_arguments
|
||||
_op_arguments=(
|
||||
)
|
||||
_describe -t actions 'operations' _op_arguments && ret=0
|
||||
;;
|
||||
getOrderById)
|
||||
local -a _op_arguments
|
||||
_op_arguments=(
|
||||
"orderId=:ID of pet that needs to be fetched"
|
||||
)
|
||||
_describe -t actions 'operations' _op_arguments && ret=0
|
||||
;;
|
||||
placeOrder)
|
||||
local -a _op_arguments
|
||||
_op_arguments=(
|
||||
)
|
||||
_describe -t actions 'operations' _op_arguments && ret=0
|
||||
;;
|
||||
createUser)
|
||||
local -a _op_arguments
|
||||
_op_arguments=(
|
||||
)
|
||||
_describe -t actions 'operations' _op_arguments && ret=0
|
||||
;;
|
||||
createUsersWithArrayInput)
|
||||
local -a _op_arguments
|
||||
_op_arguments=(
|
||||
)
|
||||
_describe -t actions 'operations' _op_arguments && ret=0
|
||||
;;
|
||||
createUsersWithListInput)
|
||||
local -a _op_arguments
|
||||
_op_arguments=(
|
||||
)
|
||||
_describe -t actions 'operations' _op_arguments && ret=0
|
||||
;;
|
||||
deleteUser)
|
||||
local -a _op_arguments
|
||||
_op_arguments=(
|
||||
"username=:The name that needs to be deleted"
|
||||
)
|
||||
_describe -t actions 'operations' _op_arguments && ret=0
|
||||
;;
|
||||
getUserByName)
|
||||
local -a _op_arguments
|
||||
_op_arguments=(
|
||||
"username=:The name that needs to be fetched. Use user1 for testing."
|
||||
)
|
||||
_describe -t actions 'operations' _op_arguments && ret=0
|
||||
;;
|
||||
loginUser)
|
||||
local -a _op_arguments
|
||||
_op_arguments=(
|
||||
"username=:The user name for login"
|
||||
"password=:The password for login in clear text"
|
||||
)
|
||||
_describe -t actions 'operations' _op_arguments && ret=0
|
||||
;;
|
||||
logoutUser)
|
||||
local -a _op_arguments
|
||||
_op_arguments=(
|
||||
)
|
||||
_describe -t actions 'operations' _op_arguments && ret=0
|
||||
;;
|
||||
updateUser)
|
||||
local -a _op_arguments
|
||||
_op_arguments=(
|
||||
"username=:name that need to be deleted"
|
||||
)
|
||||
_describe -t actions 'operations' _op_arguments && ret=0
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
return ret
|
3312
samples/client/petstore/bash/petstore-cli
Executable file
3312
samples/client/petstore/bash/petstore-cli
Executable file
File diff suppressed because it is too large
Load Diff
286
samples/client/petstore/bash/petstore-cli.bash-completion
Normal file
286
samples/client/petstore/bash/petstore-cli.bash-completion
Normal file
@ -0,0 +1,286 @@
|
||||
# petstore-cli completion -*- shell-script -*-
|
||||
|
||||
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
# !
|
||||
# ! Note:
|
||||
# !
|
||||
# ! THIS SCRIPT HAS BEEN AUTOMATICALLY GENERATED USING
|
||||
# ! swagger-codegen (https://github.com/swagger-api/swagger-codegen)
|
||||
# ! FROM SWAGGER SPECIFICATION IN JSON.
|
||||
# !
|
||||
# ! Generated on: 2017-01-12T00:07:27.471+01:00
|
||||
# !
|
||||
# !
|
||||
# ! System wide installation:
|
||||
# !
|
||||
# ! $ sudo cp petstore-cli.bash-completion /etc/bash-completion.d/petstore-cli
|
||||
# !
|
||||
# !
|
||||
# ! User home installation (add this line to .bash_profile):
|
||||
# !
|
||||
# ! [ -r ~/petstore-cli.bash-completion ] && source ~/petstore-cli.bash-completion
|
||||
# !
|
||||
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
declare -A mime_type_abbreviations
|
||||
# text/*
|
||||
mime_type_abbreviations["text"]="text/plain"
|
||||
mime_type_abbreviations["html"]="text/html"
|
||||
mime_type_abbreviations["md"]="text/x-markdown"
|
||||
mime_type_abbreviations["csv"]="text/csv"
|
||||
mime_type_abbreviations["css"]="text/css"
|
||||
mime_type_abbreviations["rtf"]="text/rtf"
|
||||
# application/*
|
||||
mime_type_abbreviations["json"]="application/json"
|
||||
mime_type_abbreviations["xml"]="application/xml"
|
||||
mime_type_abbreviations["yaml"]="application/yaml"
|
||||
mime_type_abbreviations["js"]="application/javascript"
|
||||
mime_type_abbreviations["bin"]="application/octet-stream"
|
||||
mime_type_abbreviations["rdf"]="application/rdf+xml"
|
||||
# image/*
|
||||
mime_type_abbreviations["jpg"]="image/jpeg"
|
||||
mime_type_abbreviations["png"]="image/png"
|
||||
mime_type_abbreviations["gif"]="image/gif"
|
||||
mime_type_abbreviations["bmp"]="image/bmp"
|
||||
mime_type_abbreviations["tiff"]="image/tiff"
|
||||
|
||||
|
||||
|
||||
__osx_init_completion()
|
||||
{
|
||||
COMPREPLY=()
|
||||
_get_comp_words_by_ref cur prev words cword
|
||||
}
|
||||
|
||||
|
||||
_petstore-cli()
|
||||
{
|
||||
local cur
|
||||
local prev
|
||||
local words
|
||||
local cword
|
||||
|
||||
#words="${COMP_WORDS}"
|
||||
#cword="${COMP_CWORD}"
|
||||
#prev="${COMP_WORDS[COMP_CWORD-1]}"
|
||||
#cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
|
||||
# The reference of currently selected REST operation
|
||||
local operation=""
|
||||
|
||||
# The list of available operation in the REST service
|
||||
# It's modelled as an associative array for efficient key lookup
|
||||
declare -A operations
|
||||
operations["testClientModel"]=1
|
||||
operations["testEndpointParameters"]=1
|
||||
operations["testEnumParameters"]=1
|
||||
operations["addPet"]=1
|
||||
operations["deletePet"]=1
|
||||
operations["findPetsByStatus"]=1
|
||||
operations["findPetsByTags"]=1
|
||||
operations["getPetById"]=1
|
||||
operations["updatePet"]=1
|
||||
operations["updatePetWithForm"]=1
|
||||
operations["uploadFile"]=1
|
||||
operations["deleteOrder"]=1
|
||||
operations["getInventory"]=1
|
||||
operations["getOrderById"]=1
|
||||
operations["placeOrder"]=1
|
||||
operations["createUser"]=1
|
||||
operations["createUsersWithArrayInput"]=1
|
||||
operations["createUsersWithListInput"]=1
|
||||
operations["deleteUser"]=1
|
||||
operations["getUserByName"]=1
|
||||
operations["loginUser"]=1
|
||||
operations["logoutUser"]=1
|
||||
operations["updateUser"]=1
|
||||
|
||||
# An associative array of operations to their parameters
|
||||
# Only include path, query and header parameters
|
||||
declare -A operation_parameters
|
||||
operation_parameters["testClientModel"]=""
|
||||
operation_parameters["testEndpointParameters"]=""
|
||||
operation_parameters["testEnumParameters"]="enum_query_string_array= enum_query_string= enum_query_integer= enum_header_string_array: enum_header_string: "
|
||||
operation_parameters["addPet"]=""
|
||||
operation_parameters["deletePet"]="petId= api_key: "
|
||||
operation_parameters["findPetsByStatus"]="status= "
|
||||
operation_parameters["findPetsByTags"]="tags= "
|
||||
operation_parameters["getPetById"]="petId= "
|
||||
operation_parameters["updatePet"]=""
|
||||
operation_parameters["updatePetWithForm"]="petId= "
|
||||
operation_parameters["uploadFile"]="petId= "
|
||||
operation_parameters["deleteOrder"]="orderId= "
|
||||
operation_parameters["getInventory"]=""
|
||||
operation_parameters["getOrderById"]="orderId= "
|
||||
operation_parameters["placeOrder"]=""
|
||||
operation_parameters["createUser"]=""
|
||||
operation_parameters["createUsersWithArrayInput"]=""
|
||||
operation_parameters["createUsersWithListInput"]=""
|
||||
operation_parameters["deleteUser"]="username= "
|
||||
operation_parameters["getUserByName"]="username= "
|
||||
operation_parameters["loginUser"]="username= password= "
|
||||
operation_parameters["logoutUser"]=""
|
||||
operation_parameters["updateUser"]="username= "
|
||||
|
||||
# An associative array of possible values for enum parameters
|
||||
declare -A operation_parameters_enum_values
|
||||
|
||||
#
|
||||
# Check if the _init_completion function is available, which is
|
||||
# available since bash-completion 1.4
|
||||
#
|
||||
if declare -F _init_completions >/dev/null 2>&1; then
|
||||
_init_completion -s || return
|
||||
else
|
||||
__osx_init_completion || return
|
||||
fi
|
||||
|
||||
|
||||
# Check if operation is already in the command line provided
|
||||
for word in "${words[@]}"; do
|
||||
if [[ -n $word && ${operations[$word]} ]]; then
|
||||
operation="${word}"
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ -z $operation ]]; then
|
||||
case $prev in
|
||||
--ciphers|--connect-timeout|-C|--continue-at|-F|--form|--form-string|\
|
||||
--ftp-account|--ftp-alternative-to-user|-P|--ftp-port|-H|--header|-h|\
|
||||
--help|--hostpubmd5|--keepalive-time|--krb|--limit-rate|--local-port|\
|
||||
--mail-from|--mail-rcpt|--max-filesize|--max-redirs|-m|--max-time|\
|
||||
--pass|--proto|--proto-redir|--proxy-user|--proxy1.0|-Q|--quote|-r|\
|
||||
--range|-X|--request|--retry|--retry-delay|--retry-max-time|\
|
||||
--socks5-gssapi-service|-t|--telnet-option|--tftp-blksize|-z|\
|
||||
--time-cond|--url|-u|--user|-A|--user-agent|-V|--version|-w|\
|
||||
--write-out|--resolve|--tlsuser|--tlspassword|--about)
|
||||
return
|
||||
;;
|
||||
-K|--config|-b|--cookie|-c|--cookie-jar|-D|--dump-header|--egd-file|\
|
||||
--key|--libcurl|-o|--output|--random-file|-T|--upload-file|--trace|\
|
||||
--trace-ascii|--netrc-file)
|
||||
_filedir
|
||||
return
|
||||
;;
|
||||
--cacert|-E|--cert)
|
||||
_filedir '@(c?(e)rt|cer|pem|der)'
|
||||
return
|
||||
;;
|
||||
--capath)
|
||||
_filedir -d
|
||||
return
|
||||
;;
|
||||
--cert-type|--key-type)
|
||||
COMPREPLY=( $( compgen -W 'DER PEM ENG' -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
--crlfile)
|
||||
_filedir crl
|
||||
return
|
||||
;;
|
||||
-d|--data|--data-ascii|--data-binary|--data-urlencode)
|
||||
if [[ $cur == \@* ]]; then
|
||||
cur=${cur:1}
|
||||
_filedir
|
||||
COMPREPLY=( "${COMPREPLY[@]/#/@}" )
|
||||
fi
|
||||
return
|
||||
;;
|
||||
--delegation)
|
||||
COMPREPLY=( $( compgen -W 'none policy always' -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
--engine)
|
||||
COMPREPLY=( $( compgen -W 'list' -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
--ftp-method)
|
||||
COMPREPLY=( $( compgen -W 'multicwd nocwd singlecwd' -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
--ftp-ssl-ccc-mode)
|
||||
COMPREPLY=( $( compgen -W 'active passive' -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
--interface)
|
||||
_available_interfaces -a
|
||||
return
|
||||
;;
|
||||
-x|--proxy|--socks4|--socks4a|--socks5|--socks5-hostname)
|
||||
_known_hosts_real
|
||||
return
|
||||
;;
|
||||
--pubkey)
|
||||
_filedir pub
|
||||
return
|
||||
;;
|
||||
--stderr)
|
||||
COMPREPLY=( $( compgen -W '-' -- "$cur" ) )
|
||||
_filedir
|
||||
return
|
||||
;;
|
||||
--tlsauthtype)
|
||||
COMPREPLY=( $( compgen -W 'SRP' -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
--host)
|
||||
COMPREPLY=( $( compgen -W 'http:// https://' -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
-ct|--content-type|-ac|--accept)
|
||||
COMPREPLY=( $( compgen -W '${!mime_type_abbreviations[*]}' -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
#
|
||||
# Complete the server address based on ~/.ssh/known_hosts
|
||||
# and ~/.ssh/config
|
||||
#
|
||||
# \todo Fix - cur matches only '//' when $prev is ':'
|
||||
#
|
||||
if [[ "$cur" == "http://" || "$cur" == "https://" ]]; then
|
||||
COMPREPLY=()
|
||||
local comp_ssh_hosts=`cat ~/.ssh/known_hosts | \
|
||||
cut -f 1 -d ' ' | \
|
||||
sed -e s/,.*//g | \
|
||||
grep -v ^# | \
|
||||
uniq | \
|
||||
grep -v "\[" ;
|
||||
cat ~/.ssh/config | \
|
||||
grep "^Host " | \
|
||||
awk '{print $2}'`
|
||||
COMPREPLY=( $(compgen -W "${comp_ssh_hosts}" -- $cur))
|
||||
return
|
||||
fi
|
||||
|
||||
#
|
||||
# Complete the petstore-cli and cURL's arguments
|
||||
#
|
||||
if [[ $cur == -* ]]; then
|
||||
COMPREPLY=( $( compgen -W '$(_parse_help curl) $(_parse_help $1)' -- "$cur" ) )
|
||||
return
|
||||
fi
|
||||
|
||||
#
|
||||
# If the argument starts with a letter this could be either an operation
|
||||
# or an operation parameter
|
||||
# When $cur is empty, suggest the list of operations by default
|
||||
#
|
||||
if [[ $cur =~ ^[A-Za-z_0-9]* ]]; then
|
||||
# If operation has not been yet selected, suggest the list of operations
|
||||
# otherwise suggest arguments of this operation as declared in the
|
||||
# Swagger specification
|
||||
if [[ -z $operation ]]; then
|
||||
COMPREPLY=( $(compgen -W '${!operations[*]}' -- ${cur}) )
|
||||
else
|
||||
COMPREPLY=( $(compgen -W '${operation_parameters[$operation]}' -- ${cur}) )
|
||||
fi
|
||||
return
|
||||
fi
|
||||
|
||||
} &&
|
||||
complete -F _petstore-cli petstore-cli
|
||||
|
||||
# ex: ts=4 sw=4 et filetype=sh
|
47
samples/client/petstore/bash/pom.xml
Normal file
47
samples/client/petstore/bash/pom.xml
Normal file
@ -0,0 +1,47 @@
|
||||
<project>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>io.swagger</groupId>
|
||||
<artifactId>BashPetstoreClientTests</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<name>Bash Swagger Petstore Client</name>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>copy-dependencies</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>${project.build.directory}</outputDirectory>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>1.2.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>bats-test</id>
|
||||
<phase>integration-test</phase>
|
||||
<goals>
|
||||
<goal>exec</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<executable>bats</executable>
|
||||
<arguments>
|
||||
<argument>--tap</argument>
|
||||
<argument>tests/petstore_test.sh</argument>
|
||||
</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
102
samples/client/petstore/bash/tests/petstore_test.sh
Normal file
102
samples/client/petstore/bash/tests/petstore_test.sh
Normal file
@ -0,0 +1,102 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
|
||||
export PETSTORE_CLI="petstore-cli"
|
||||
|
||||
export PETSTORE_HOST="http://petstore.swagger.io"
|
||||
|
||||
|
||||
#
|
||||
# Tests for parameter handling and validation
|
||||
#
|
||||
@test "addPet without host" {
|
||||
unset PETSTORE_HOST
|
||||
run bash $PETSTORE_CLI -ac xml -ct json \
|
||||
addPet id:=123321 name==lucky status==available
|
||||
[[ "$output" =~ "Error: No hostname provided!!!" ]]
|
||||
}
|
||||
|
||||
@test "addPet without content type" {
|
||||
run bash $PETSTORE_CLI -ac xml --host $PETSTORE_HOST \
|
||||
addPet id:=123321 name==lucky status==available
|
||||
[[ "$output" =~ "Error: Request's content-type not specified!" ]]
|
||||
}
|
||||
|
||||
@test "fakeOperation invalid operation name" {
|
||||
run bash \
|
||||
-c "bash $PETSTORE_CLI --host http://petstore.swagger.io fakeOperation"
|
||||
[[ "$output" =~ "Error: No operation specified!" ]]
|
||||
}
|
||||
|
||||
@test "findPetsByStatus basic auth" {
|
||||
run bash \
|
||||
-c "bash $PETSTORE_CLI -u alice:secret --host http://petstore.swagger.io findPetsByStatus status=s1 --dry-run"
|
||||
[[ "$output" =~ "-u alice:secret" ]]
|
||||
}
|
||||
|
||||
@test "findPetsByStatus api key" {
|
||||
run bash \
|
||||
-c "bash $PETSTORE_CLI --host http://petstore.swagger.io findPetsByStatus status=s1 api_key:1234 --dry-run"
|
||||
[[ "$output" =~ "-H \"api_key: 1234\"" ]]
|
||||
}
|
||||
|
||||
@test "findPetsByStatus empty api key" {
|
||||
run bash \
|
||||
-c "bash $PETSTORE_CLI --host http://petstore.swagger.io findPetsByStatus status=s1 --dry-run"
|
||||
[[ ! "$output" =~ "-H \"api_key:" ]]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@test "findPetsByStatus too few values" {
|
||||
run bash \
|
||||
-c "bash $PETSTORE_CLI --host http://petstore.swagger.io findPetsByStatus"
|
||||
[[ "$output" =~ "Error: Too few values" ]]
|
||||
}
|
||||
|
||||
@test "findPetsByTags too few values" {
|
||||
run bash \
|
||||
-c "bash $PETSTORE_CLI --host http://petstore.swagger.io findPetsByTags"
|
||||
[[ "$output" =~ "Error: Too few values" ]]
|
||||
}
|
||||
|
||||
@test "findPetsByStatus status with space" {
|
||||
run bash \
|
||||
-c "bash $PETSTORE_CLI --host http://petstore.swagger.io findPetsByStatus \
|
||||
status=available status=\"gone test\" --dry-run"
|
||||
[[ "$output" =~ "status=available,gone%20test" ]]
|
||||
}
|
||||
|
||||
@test "findPetsByStatus collection csv" {
|
||||
run bash \
|
||||
-c "bash $PETSTORE_CLI --host http://petstore.swagger.io findPetsByTags \
|
||||
tags=TAG1 tags=TAG2 --dry-run"
|
||||
[[ "$output" =~ "tags=TAG1,TAG2" ]]
|
||||
}
|
||||
|
||||
@test "findPetsByStatus collection csv with space and question mark" {
|
||||
run bash \
|
||||
-c "bash $PETSTORE_CLI --host http://petstore.swagger.io findPetsByTags \
|
||||
tags=TAG1 tags=\"TAG2 TEST\" tags=TAG3?TEST --dry-run"
|
||||
[[ "$output" =~ "tags=TAG1,TAG2%20TEST,TAG3%3FTEST" ]]
|
||||
}
|
||||
|
||||
#
|
||||
# Operations calling the service and checking result
|
||||
#
|
||||
@test "addPet from parameters" {
|
||||
run bash $PETSTORE_CLI -ct json -ac xml \
|
||||
addPet id:=123321 name==lucky status==available
|
||||
[[ "$output" =~ "<id>123321</id>" ]]
|
||||
}
|
||||
|
||||
@test "addPet from pipe" {
|
||||
run bash \
|
||||
-c "echo '{\"id\": 37567, \"name\": \"lucky\", \"status\": \"available\"}' | \
|
||||
bash $PETSTORE_CLI -ct json -ac xml addPet -"
|
||||
[[ "$output" =~ "<id>37567</id>" ]]
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user