├── settings.gradle ├── src ├── test │ ├── resources │ │ ├── mockito-extensions │ │ │ └── org.mockito.plugins.MockMaker │ │ └── log4j2.xml │ └── kotlin │ │ └── com │ │ └── gatehill │ │ └── vertxoas │ │ ├── OpenApiServiceSpec.kt │ │ └── RouterSpecGeneratorSpec.kt └── main │ └── kotlin │ └── com │ └── gatehill │ └── vertxoas │ ├── service │ ├── OpenApiService.kt │ └── OpenApiServiceImpl.kt │ └── RouterSpecGenerator.kt ├── examples └── maven │ ├── pom.xml │ ├── README.md │ └── src │ └── main │ ├── resources │ └── log4j2.xml │ └── java │ └── com │ └── gatehill │ └── vertxoas │ └── example │ └── Example.java ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitignore ├── .circleci └── config.yml ├── script └── publish-local.sh ├── gradlew.bat ├── README.md └── gradlew /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'vertx-oas' 2 | -------------------------------------------------------------------------------- /src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker: -------------------------------------------------------------------------------- 1 | mock-maker-inline 2 | -------------------------------------------------------------------------------- /examples/maven/pom.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outofcoffee/vertx-oas/HEAD/examples/maven/pom.xml -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outofcoffee/vertx-oas/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | build/ 3 | *.iml 4 | .gradle/ 5 | classes 6 | .gradletasknamecache 7 | /gradle.properties 8 | out/ 9 | -------------------------------------------------------------------------------- /examples/maven/README.md: -------------------------------------------------------------------------------- 1 | vertx-oas Maven Example 2 | ======================= 3 | 4 | An example of using vertx-oas with a Maven project. 5 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sat Aug 26 22:41:40 BST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip 7 | -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: 2 3 | jobs: 4 | build: 5 | docker: 6 | - image: openjdk:8 7 | 8 | steps: 9 | - checkout 10 | - run: 11 | name: Build and deploy 12 | command: ./gradlew clean build publish -Pversion=${CIRCLE_SHA1:0:7} --stacktrace 13 | -------------------------------------------------------------------------------- /script/publish-local.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | ROOT_PROJECT_DIR="$( cd .. && pwd )" 5 | GIT_HASH="$( git rev-parse HEAD )" 6 | GIT_HASH="${GIT_HASH:0:7}" 7 | 8 | echo -e "Publishing with version: ${GIT_HASH}" 9 | 10 | ./gradlew clean publishToMavenLocal -Pversion=${GIT_HASH} --stacktrace 11 | 12 | echo -e "Published with version: ${GIT_HASH}" 13 | -------------------------------------------------------------------------------- /src/main/kotlin/com/gatehill/vertxoas/service/OpenApiService.kt: -------------------------------------------------------------------------------- 1 | package com.gatehill.vertxoas.service 2 | 3 | import io.swagger.v3.oas.models.OpenAPI 4 | import io.vertx.ext.web.Router 5 | 6 | /** 7 | * @author Pete Cornish <outofcoffee@gmail.com> 8 | */ 9 | interface OpenApiService { 10 | fun buildSpecification(router: Router, basePath: String, title: String? = null): OpenAPI 11 | } 12 | -------------------------------------------------------------------------------- /examples/maven/src/main/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/test/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/maven/src/main/java/com/gatehill/vertxoas/example/Example.java: -------------------------------------------------------------------------------- 1 | package com.gatehill.vertxoas.example; 2 | 3 | import com.gatehill.vertxoas.RouterSpecGenerator; 4 | import io.vertx.core.Vertx; 5 | import io.vertx.ext.web.Router; 6 | 7 | /** 8 | * @author Pete Cornish {@literal } 9 | */ 10 | public class Example { 11 | public static void main(String[] args) { 12 | final Vertx vertx = Vertx.factory.vertx(); 13 | 14 | // your normal Vert.x Web Router with paths etc. 15 | final Router router = Router.router(vertx); 16 | router.post("/users").handler(routingContext -> { /* etc... */ }); 17 | router.get("/users/:userId").handler(routingContext -> { /* etc... */ }); 18 | 19 | // publish the Swagger/OpenAPI specification to a URL 20 | RouterSpecGenerator.publishApiDocs(router, "/api/spec"); 21 | 22 | vertx.createHttpServer() 23 | .requestHandler(router::accept) 24 | .listen(8080, result -> { 25 | if (result.succeeded()) { 26 | System.out.println("API specification served at: http://localhost:8080/api/spec"); 27 | } else { 28 | result.cause().printStackTrace(); 29 | } 30 | }); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/kotlin/com/gatehill/vertxoas/RouterSpecGenerator.kt: -------------------------------------------------------------------------------- 1 | package com.gatehill.vertxoas 2 | 3 | import com.gatehill.vertxoas.service.OpenApiServiceImpl 4 | import io.swagger.util.Json 5 | import io.swagger.util.Yaml 6 | import io.vertx.ext.web.Router 7 | 8 | object RouterSpecGenerator { 9 | private const val contentTypeHeader = "Content-Type" 10 | private val openApiService by lazy { OpenApiServiceImpl() } 11 | 12 | @JvmStatic 13 | fun publishApiDocs(router: Router, path: String) { 14 | val spec = openApiService.buildSpecification(router, "/") 15 | val jsonSpec by lazy { Json.pretty(spec) } 16 | val yamlSpec by lazy { Yaml.pretty().writeValueAsString(spec) } 17 | 18 | router.get(path + ".json").handler { routingContext -> 19 | routingContext.response() 20 | .putHeader(contentTypeHeader, "application/json") 21 | .end(jsonSpec) 22 | } 23 | router.get(path + ".yaml").handler { routingContext -> 24 | routingContext.response() 25 | .putHeader(contentTypeHeader, "application/x-yaml") 26 | .end(yamlSpec) 27 | } 28 | 29 | // default redirect 30 | router.get(path).handler { routingContext -> 31 | routingContext.response() 32 | .putHeader("Location", "$path.yaml") 33 | .setStatusCode(302) 34 | .end() 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /src/test/kotlin/com/gatehill/vertxoas/OpenApiServiceSpec.kt: -------------------------------------------------------------------------------- 1 | package com.gatehill.vertxoas 2 | 3 | import com.gatehill.vertxoas.service.OpenApiServiceImpl 4 | import io.vertx.core.Vertx 5 | import io.vertx.ext.web.Router 6 | import org.amshove.kluent.`should be empty` 7 | import org.amshove.kluent.`should be false` 8 | import org.amshove.kluent.`should be true` 9 | import org.amshove.kluent.`should equal` 10 | import org.amshove.kluent.`should not be null` 11 | import org.jetbrains.spek.api.Spek 12 | import org.jetbrains.spek.api.dsl.describe 13 | import org.jetbrains.spek.api.dsl.it 14 | import org.jetbrains.spek.api.dsl.on 15 | 16 | /** 17 | * Specification for `OpenApiService`. 18 | * 19 | * @author pete 20 | */ 21 | object OpenApiServiceSpec : Spek({ 22 | describe("an Open API service") { 23 | val service = OpenApiServiceImpl() 24 | 25 | on("processing non-empty routes") { 26 | val router = Router.router(Vertx.vertx()).apply { 27 | post("/users").handler({}) 28 | get("/users/:userId").handler({}) 29 | } 30 | 31 | val spec = service.buildSpecification(router, "/") 32 | 33 | it("converts routes to paths") { 34 | spec.paths.`should not be null`() 35 | spec.paths.size `should equal` 2 36 | } 37 | 38 | it("maps POST operation") { 39 | val postPaths = spec.paths.filterValues { it.post != null } 40 | postPaths.size `should equal` 1 41 | 42 | val params = postPaths.values.first().post.parameters 43 | params.`should not be null`() 44 | params.`should be empty`() 45 | } 46 | 47 | it("maps GET operation") { 48 | val getPaths = spec.paths.filterValues { it.get != null } 49 | getPaths.size `should equal` 1 50 | 51 | val params = getPaths.values.first().get.parameters 52 | params.`should not be null`() 53 | params.size `should equal` 1 54 | 55 | params.first().name `should equal` "userId" 56 | params.first().required.`should be true`() 57 | params.first().allowEmptyValue.`should be false`() 58 | } 59 | } 60 | 61 | on("processing empty route") { 62 | val router = Router.router(Vertx.vertx()).apply { 63 | post().handler({}) 64 | } 65 | 66 | val spec = service.buildSpecification(router, "/") 67 | 68 | it("ignores empty route") { 69 | spec.paths.`should not be null`() 70 | spec.paths.`should be empty`() 71 | } 72 | } 73 | } 74 | }) 75 | -------------------------------------------------------------------------------- /src/test/kotlin/com/gatehill/vertxoas/RouterSpecGeneratorSpec.kt: -------------------------------------------------------------------------------- 1 | package com.gatehill.vertxoas 2 | 3 | import com.jayway.restassured.RestAssured 4 | import com.jayway.restassured.RestAssured.given 5 | import io.vertx.core.Vertx 6 | import io.vertx.ext.web.Router 7 | import org.hamcrest.Matchers.endsWith 8 | import org.hamcrest.Matchers.equalTo 9 | import org.hamcrest.Matchers.startsWith 10 | import org.jetbrains.spek.api.Spek 11 | import org.jetbrains.spek.api.dsl.describe 12 | import org.jetbrains.spek.api.dsl.it 13 | import org.jetbrains.spek.api.dsl.on 14 | import java.net.ServerSocket 15 | import java.util.concurrent.CountDownLatch 16 | 17 | /** 18 | * Specification for `OpenApiService`. 19 | * 20 | * @author pete 21 | */ 22 | object RouterSpecGeneratorSpec : Spek({ 23 | val port = ServerSocket(0).use { it.localPort } 24 | RestAssured.baseURI = "http://localhost:$port" 25 | 26 | val vertx = Vertx.vertx() 27 | val router = Router.router(vertx).apply { 28 | post("/users").handler({}) 29 | get("/users/:userId").handler({}) 30 | } 31 | 32 | val listenLatch = CountDownLatch(1) 33 | vertx.createHttpServer() 34 | .requestHandler(router::accept) 35 | .listen(port, { listenLatch.countDown() }) 36 | listenLatch.await() 37 | 38 | describe("a Router specification generator") { 39 | on("processing the router") { 40 | RouterSpecGenerator.publishApiDocs(router, "/spec") 41 | 42 | it("redirects to the default specification") { 43 | given().redirects().follow(false) 44 | .get("/spec") 45 | .then() 46 | .statusCode(equalTo(302)) 47 | .and() 48 | .header("Location", endsWith(".yaml")) 49 | .log().all() 50 | } 51 | 52 | it("exposes a JSON specification") { 53 | given().get("/spec.json") 54 | .then() 55 | .statusCode(equalTo(200)) 56 | .and() 57 | .contentType(equalTo("application/json")) 58 | .and() 59 | .body("openapi", startsWith("3")) 60 | .log().all() 61 | } 62 | 63 | it("exposes a YAML specification") { 64 | given().get("/spec.yaml") 65 | .then() 66 | .statusCode(equalTo(200)) 67 | .and() 68 | .contentType(equalTo("application/x-yaml")) 69 | .log().all() 70 | } 71 | } 72 | } 73 | 74 | afterGroup { 75 | vertx.close() 76 | } 77 | }) 78 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vertx-oas 2 | 3 | Generates a Swagger/OpenAPI specification from a Vert.x Web Router. 4 | 5 | ## Usage 6 | 7 | Assuming you're using Vert.x Web, use it with your `Router` as follows: 8 | 9 | ```java 10 | // your normal Vert.x Web Router with paths etc. 11 | Router router = Router.router(vertx); 12 | router.post("/users").handler( routingContext -> { /* etc... */ }); 13 | router.get("/users/:userId").handler( routingContext -> { /* etc... */ }); 14 | 15 | // publish the Swagger/OpenAPI specification to a URL 16 | RouterSpecGenerator.publishApiDocs(router, "/api/spec"); 17 | ``` 18 | 19 | In this example, the specification is published to `/api/spec`. 20 | 21 | You can obtain YAML or JSON versions of the specification by adding the appropriate file extension. 22 | 23 | --- 24 | 25 | For example, fetching `/api/spec.yaml` would produce: 26 | 27 | ```yaml 28 | openapi: "3.0.1" 29 | info: 30 | title: "Vert.x APIs" 31 | description: "This specification was generated from a Vert.x Web Router." 32 | paths: 33 | /users: 34 | post: 35 | parameters: [] 36 | /users/{userId}: 37 | get: 38 | parameters: 39 | - name: "userId" 40 | required: true 41 | allowEmptyValue: false 42 | ``` 43 | 44 | ## Limitations 45 | 46 | - Doesn't understand regex paths 47 | - Doesn't know the type of path parameters 48 | - Doesn't know about request or response body models 49 | 50 | ## Use in your project 51 | 52 | ### Maven 53 | 54 | Add repository: 55 | 56 | ```xml 57 | 58 | ... 59 | 60 | 61 | gatehillsoftware-snapshots 62 | Gatehill Software Snapshots 63 | https://s3-eu-west-1.amazonaws.com/gatehillsoftware-maven/snapshots 64 | 65 | 66 | sonatype-snapshots 67 | Sonatype OSS Snapshots 68 | https://oss.sonatype.org/content/repositories/snapshots 69 | 70 | 71 | ... 72 | 73 | ``` 74 | 75 | Add dependency: 76 | 77 | ```xml 78 | 79 | ... 80 | 81 | com.gatehill.vertx-oas 82 | vertx-oas 83 | 1.0.1 84 | 85 | ... 86 | 87 | ``` 88 | 89 | ### Gradle 90 | 91 | Add repository: 92 | 93 | repositories { 94 | maven { 95 | url 'https://s3-eu-west-1.amazonaws.com/gatehillsoftware-maven/snapshots' 96 | } 97 | maven { 98 | url 'https://oss.sonatype.org/content/repositories/snapshots' 99 | } 100 | } 101 | 102 | Add dependency: 103 | 104 | compile 'com.gatehill.vertx-oas:vertx-oas:1.0.1' 105 | 106 | ## Build 107 | 108 | If you'd like to build the code locally, follow these instructions. 109 | 110 | ### Prerequisites 111 | 112 | - JDK8 113 | 114 | ### Compile and test 115 | 116 | ./gradlew clean build 117 | 118 | ### Publish 119 | 120 | Publish to local Maven repository: 121 | 122 | ./gradlew publishToMavenLocal 123 | 124 | Publish to remote Maven repository: 125 | 126 | ./gradlew publish 127 | 128 | ## Contributing 129 | 130 | * Pull requests are welcome. 131 | * Please run `ktlint` on your branch. 132 | 133 | ## Author 134 | 135 | Pete Cornish (outofcoffee@gmail.com) 136 | -------------------------------------------------------------------------------- /src/main/kotlin/com/gatehill/vertxoas/service/OpenApiServiceImpl.kt: -------------------------------------------------------------------------------- 1 | package com.gatehill.vertxoas.service 2 | 3 | import io.swagger.v3.oas.models.OpenAPI 4 | import io.swagger.v3.oas.models.Operation 5 | import io.swagger.v3.oas.models.PathItem 6 | import io.swagger.v3.oas.models.Paths 7 | import io.swagger.v3.oas.models.info.Info 8 | import io.swagger.v3.oas.models.parameters.Parameter 9 | import io.swagger.v3.oas.models.servers.Server 10 | import io.swagger.v3.oas.models.tags.Tag 11 | import io.vertx.core.http.HttpMethod 12 | import io.vertx.ext.web.Router 13 | import io.vertx.ext.web.impl.RouteImpl 14 | import org.apache.logging.log4j.LogManager 15 | import java.util.Objects.nonNull 16 | 17 | /** 18 | * @author Pete Cornish <outofcoffee@gmail.com> 19 | */ 20 | class OpenApiServiceImpl : OpenApiService { 21 | override fun buildSpecification(router: Router, basePath: String, title: String?): OpenAPI { 22 | LOGGER.debug("Generating specification for ${router.routes.size} route(s)") 23 | 24 | val spec = OpenAPI() 25 | 26 | val info = Info() 27 | spec.info = info 28 | 29 | val servers = mutableListOf() 30 | spec.servers = servers 31 | 32 | val paths = Paths() 33 | spec.paths = paths 34 | 35 | val tags = mutableListOf() 36 | spec.tags = tags 37 | 38 | val description = StringBuilder() 39 | .append("This specification was generated from a Vert.x Web Router.") 40 | 41 | router.routes.filter { nonNull(it.path) }.forEach { route -> 42 | val splitPath = route.path.split("/") 43 | 44 | val convertedPath = splitPath.joinToString("/") { 45 | if (it.startsWith(":")) { 46 | "{${it.substring(1)}}" 47 | } else { 48 | it 49 | } 50 | } 51 | 52 | val pathItem = PathItem().apply { 53 | val operation = Operation().apply { 54 | parameters = splitPath 55 | .filter { it.startsWith(":") } 56 | .map { it.substring(1) } 57 | .map { param -> 58 | Parameter().apply { 59 | name = param 60 | required = true 61 | allowEmptyValue = false 62 | } 63 | } 64 | } 65 | 66 | (route as RouteImpl).javaClass.getDeclaredField("methods").apply { 67 | isAccessible = true 68 | 69 | @Suppress("UNCHECKED_CAST") 70 | val methods = get(route) as Collection 71 | 72 | for (method in methods) { 73 | when (method) { 74 | HttpMethod.OPTIONS -> options = operation 75 | HttpMethod.GET -> get = operation 76 | HttpMethod.HEAD -> head = operation 77 | HttpMethod.POST -> post = operation 78 | HttpMethod.PUT -> put = operation 79 | HttpMethod.DELETE -> delete = operation 80 | HttpMethod.TRACE -> trace = operation 81 | HttpMethod.PATCH -> patch = operation 82 | HttpMethod.CONNECT -> TODO() 83 | HttpMethod.OTHER -> TODO() 84 | } 85 | } 86 | } 87 | } 88 | 89 | paths.put(convertedPath, pathItem) 90 | } 91 | 92 | // info 93 | info.title = title ?: DEFAULT_TITLE 94 | info.description = description.toString() 95 | 96 | return spec 97 | } 98 | 99 | companion object { 100 | private val LOGGER = LogManager.getLogger(OpenApiServiceImpl::class.java) 101 | private val DEFAULT_TITLE = "Vert.x APIs" 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn ( ) { 37 | echo "$*" 38 | } 39 | 40 | die ( ) { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | --------------------------------------------------------------------------------