diff --git a/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/utils/ShellCommandExecutor.java b/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/utils/ShellCommandExecutor.java index 345bbb3939b..0cb2855da8e 100644 --- a/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/utils/ShellCommandExecutor.java +++ b/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/utils/ShellCommandExecutor.java @@ -11,6 +11,8 @@ import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; +import java.util.Collections; +import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import org.slf4j.Logger; @@ -24,10 +26,17 @@ public class ShellCommandExecutor { private final File executionFolder; private final long timeoutMillis; + private final Map environment; public ShellCommandExecutor(File executionFolder, long timeoutMillis) { + this(executionFolder, timeoutMillis, Collections.emptyMap()); + } + + public ShellCommandExecutor( + File executionFolder, long timeoutMillis, Map environment) { this.executionFolder = executionFolder; this.timeoutMillis = timeoutMillis; + this.environment = environment; } /** @@ -92,6 +101,10 @@ private T executeCommand( ProcessBuilder processBuilder = new ProcessBuilder(command); processBuilder.directory(executionFolder); + if (!environment.isEmpty()) { + processBuilder.environment().putAll(environment); + } + p = processBuilder.start(); StreamConsumer inputStreamConsumer = new StreamConsumer(p.getInputStream()); diff --git a/dd-smoke-tests/gradle/build.gradle b/dd-smoke-tests/gradle/build.gradle index 8063eccd959..99d07403378 100644 --- a/dd-smoke-tests/gradle/build.gradle +++ b/dd-smoke-tests/gradle/build.gradle @@ -1,3 +1,6 @@ +import java.time.Duration +import java.time.temporal.ChronoUnit + plugins { id "com.github.johnrengelman.shadow" } @@ -14,5 +17,9 @@ test { testLogging { events "passed", "skipped", "failed", "standardOut", "standardError" } + + // overriding the default timeout of 9 minutes set in configure_tests.gradle, + // as Gradle smoke tests might run for a longer duration + timeout = Duration.of(15, ChronoUnit.MINUTES) } diff --git a/dd-smoke-tests/gradle/src/test/groovy/datadog/smoketest/AbstractGradleTest.groovy b/dd-smoke-tests/gradle/src/test/groovy/datadog/smoketest/AbstractGradleTest.groovy new file mode 100644 index 00000000000..c9de4587931 --- /dev/null +++ b/dd-smoke-tests/gradle/src/test/groovy/datadog/smoketest/AbstractGradleTest.groovy @@ -0,0 +1,144 @@ +package datadog.smoketest + +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.ObjectMapper +import datadog.trace.api.Platform +import datadog.trace.civisibility.CiVisibilitySmokeTest +import okhttp3.OkHttpClient +import okhttp3.Request +import okhttp3.Response +import org.gradle.internal.impldep.org.apache.commons.io.FileUtils +import org.gradle.util.GradleVersion +import org.junit.jupiter.api.Assumptions +import spock.lang.AutoCleanup +import spock.lang.Shared +import spock.lang.TempDir +import spock.util.environment.Jvm + +import java.nio.charset.StandardCharsets +import java.nio.file.FileVisitResult +import java.nio.file.Files +import java.nio.file.Path +import java.nio.file.Paths +import java.nio.file.SimpleFileVisitor +import java.nio.file.attribute.BasicFileAttributes +import java.util.regex.Matcher +import java.util.regex.Pattern + +class AbstractGradleTest extends CiVisibilitySmokeTest { + + static final String LATEST_GRADLE_VERSION = getLatestGradleVersion() + + // test resources use this instead of ".gradle" to avoid unwanted evaluation + private static final String GRADLE_TEST_RESOURCE_EXTENSION = ".gradleTest" + private static final String GRADLE_REGULAR_EXTENSION = ".gradle" + + @TempDir + protected Path projectFolder + + @Shared + @AutoCleanup + protected MockBackend mockBackend = new MockBackend() + + def setup() { + mockBackend.reset() + } + + private static final Pattern PLACEHOLDER_PATTERN = Pattern.compile('\\$\\{(.+?)\\}') + + protected void givenGradleProjectFiles(String projectFilesSources, Map> replacementsByFileName = [:]) { + def projectResourcesUri = this.getClass().getClassLoader().getResource(projectFilesSources).toURI() + def projectResourcesPath = Paths.get(projectResourcesUri) + FileUtils.copyDirectory(projectResourcesPath.toFile(), projectFolder.toFile()) + + Files.walkFileTree(projectFolder, new SimpleFileVisitor() { + @Override + FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + def replacements = replacementsByFileName.get(file.getFileName().toString()) + if (replacements != null) { + def fileContents = new String(Files.readAllBytes(file), StandardCharsets.UTF_8) + Matcher matcher = PLACEHOLDER_PATTERN.matcher(fileContents) + + StringBuffer result = new StringBuffer() + while (matcher.find()) { + String propertyName = matcher.group(1) + String replacement = replacements.getOrDefault(propertyName, matcher.group(0)) + matcher.appendReplacement(result, Matcher.quoteReplacement(replacement)) + } + matcher.appendTail(result) + + Files.write(file, result.toString().getBytes(StandardCharsets.UTF_8)) + } + + if (file.toString().endsWith(GRADLE_TEST_RESOURCE_EXTENSION)) { + def fileWithFixedExtension = Paths.get(file.toString().replace(GRADLE_TEST_RESOURCE_EXTENSION, GRADLE_REGULAR_EXTENSION)) + Files.move(file, fileWithFixedExtension) + } + + return FileVisitResult.CONTINUE + } + }) + + // creating empty .git directory so that the tracer could detect projectFolder as repo root + Files.createDirectory(projectFolder.resolve(".git")) + } + + protected void givenGradleVersionIsCompatibleWithCurrentJvm(String gradleVersion) { + Assumptions.assumeTrue(isSupported(gradleVersion), + "Current JVM " + Jvm.current.javaVersion + " does not support Gradle version " + gradleVersion) + } + + private static boolean isSupported(String gradleVersion) { + // https://docs.gradle.org/current/userguide/compatibility.html + if (Jvm.current.java21Compatible) { + return gradleVersion >= "8.4" + } else if (Jvm.current.java20) { + return gradleVersion >= "8.1" + } else if (Jvm.current.java19) { + return gradleVersion >= "7.6" + } else if (Jvm.current.java18) { + return gradleVersion >= "7.5" + } else if (Jvm.current.java17) { + return gradleVersion >= "7.3" + } else if (Jvm.current.java16) { + return gradleVersion >= "7.0" + } else if (Jvm.current.java15) { + return gradleVersion >= "6.7" + } else if (Jvm.current.java14) { + return gradleVersion >= "6.3" + } else if (Jvm.current.java13) { + return gradleVersion >= "6.0" + } else if (Jvm.current.java12) { + return gradleVersion >= "5.4" + } else if (Jvm.current.java11) { + return gradleVersion >= "5.0" + } else if (Jvm.current.java10) { + return gradleVersion >= "4.7" + } else if (Jvm.current.java9) { + return gradleVersion >= "4.3" + } else if (Jvm.current.java8) { + return gradleVersion >= "2.0" + } + return false + } + + protected void givenConfigurationCacheIsCompatibleWithCurrentPlatform(boolean configurationCacheEnabled) { + if (configurationCacheEnabled) { + Assumptions.assumeFalse(Platform.isIbm8(), "Configuration cache is not compatible with IBM 8") + } + } + + private static String getLatestGradleVersion() { + OkHttpClient client = new OkHttpClient() + Request request = new Request.Builder().url("https://services.gradle.org/versions/current").build() + try (Response response = client.newCall(request).execute()) { + if (!response.successful) { + return GradleVersion.current().version + } + def responseBody = response.body().string() + ObjectMapper mapper = new ObjectMapper() + JsonNode root = mapper.readTree(responseBody) + return root.get("version").asText() + } + } +} diff --git a/dd-smoke-tests/gradle/src/test/groovy/datadog/smoketest/GradleDaemonSmokeTest.groovy b/dd-smoke-tests/gradle/src/test/groovy/datadog/smoketest/GradleDaemonSmokeTest.groovy index 1b01770120c..ebe0f6a285c 100644 --- a/dd-smoke-tests/gradle/src/test/groovy/datadog/smoketest/GradleDaemonSmokeTest.groovy +++ b/dd-smoke-tests/gradle/src/test/groovy/datadog/smoketest/GradleDaemonSmokeTest.groovy @@ -1,52 +1,32 @@ package datadog.smoketest -import com.fasterxml.jackson.databind.JsonNode -import com.fasterxml.jackson.databind.ObjectMapper + import datadog.trace.api.Config import datadog.trace.api.Platform import datadog.trace.api.config.CiVisibilityConfig import datadog.trace.api.config.GeneralConfig -import datadog.trace.civisibility.CiVisibilitySmokeTest import datadog.trace.util.Strings -import okhttp3.OkHttpClient -import okhttp3.Request -import okhttp3.Response -import org.gradle.internal.impldep.org.apache.commons.io.FileUtils import org.gradle.testkit.runner.BuildResult import org.gradle.testkit.runner.GradleRunner import org.gradle.testkit.runner.TaskOutcome import org.gradle.util.DistributionLocator import org.gradle.util.GradleVersion import org.gradle.wrapper.Download -import org.gradle.wrapper.GradleUserHomeLookup import org.gradle.wrapper.Install import org.gradle.wrapper.PathAssembler import org.gradle.wrapper.WrapperConfiguration -import org.junit.jupiter.api.Assumptions -import spock.lang.AutoCleanup import spock.lang.IgnoreIf import spock.lang.Shared import spock.lang.TempDir -import spock.util.environment.Jvm -import java.nio.file.FileVisitResult import java.nio.file.Files import java.nio.file.Path -import java.nio.file.Paths -import java.nio.file.SimpleFileVisitor -import java.nio.file.attribute.BasicFileAttributes - -class GradleDaemonSmokeTest extends CiVisibilitySmokeTest { - private static final String LATEST_GRADLE_VERSION = getLatestGradleVersion() +class GradleDaemonSmokeTest extends AbstractGradleTest { private static final String TEST_SERVICE_NAME = "test-gradle-service" private static final String TEST_ENVIRONMENT_NAME = "integration-test" - // test resources use this instead of ".gradle" to avoid unwanted evaluation - private static final String GRADLE_TEST_RESOURCE_EXTENSION = ".gradleTest" - private static final String GRADLE_REGULAR_EXTENSION = ".gradle" - private static final int GRADLE_DISTRIBUTION_NETWORK_TIMEOUT = 30_000 // Gradle's default timeout is 10s private static final String JACOCO_PLUGIN_VERSION = Config.get().ciVisibilityJacocoPluginVersion @@ -58,21 +38,10 @@ class GradleDaemonSmokeTest extends CiVisibilitySmokeTest { @TempDir Path testKitFolder - @TempDir - Path projectFolder - - @Shared - @AutoCleanup - MockBackend mockBackend = new MockBackend() - def setupSpec() { givenGradleProperties() } - def setup() { - mockBackend.reset() - } - @IgnoreIf(reason = "Jacoco plugin does not work with OpenJ9 in older Gradle versions", value = { Platform.isJ9() }) @@ -168,26 +137,6 @@ class GradleDaemonSmokeTest extends CiVisibilitySmokeTest { Files.write(testKitFolder.resolve("gradle.properties"), gradleProperties.getBytes()) } - private void givenGradleProjectFiles(String projectFilesSources) { - def projectResourcesUri = this.getClass().getClassLoader().getResource(projectFilesSources).toURI() - def projectResourcesPath = Paths.get(projectResourcesUri) - FileUtils.copyDirectory(projectResourcesPath.toFile(), projectFolder.toFile()) - - Files.walkFileTree(projectFolder, new SimpleFileVisitor() { - @Override - FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - if (file.toString().endsWith(GRADLE_TEST_RESOURCE_EXTENSION)) { - def fileWithFixedExtension = Paths.get(file.toString().replace(GRADLE_TEST_RESOURCE_EXTENSION, GRADLE_REGULAR_EXTENSION)) - Files.move(file, fileWithFixedExtension) - } - return FileVisitResult.CONTINUE - } - }) - - // creating empty .git directory so that the tracer could detect projectFolder as repo root - Files.createDirectory(projectFolder.resolve(".git")) - } - private BuildResult runGradleTests(String gradleVersion, boolean successExpected = true, boolean configurationCache = false) { def arguments = ["test", "--stacktrace"] if (gradleVersion > "4.5") { @@ -255,63 +204,4 @@ class GradleDaemonSmokeTest extends CiVisibilitySmokeTest { assert task.outcome != TaskOutcome.FAILED } } - - void givenGradleVersionIsCompatibleWithCurrentJvm(String gradleVersion) { - Assumptions.assumeTrue(isSupported(gradleVersion), - "Current JVM " + Jvm.current.javaVersion + " does not support Gradle version " + gradleVersion) - } - - private static boolean isSupported(String gradleVersion) { - // https://docs.gradle.org/current/userguide/compatibility.html - if (Jvm.current.java21Compatible) { - return gradleVersion >= "8.4" - } else if (Jvm.current.java20) { - return gradleVersion >= "8.1" - } else if (Jvm.current.java19) { - return gradleVersion >= "7.6" - } else if (Jvm.current.java18) { - return gradleVersion >= "7.5" - } else if (Jvm.current.java17) { - return gradleVersion >= "7.3" - } else if (Jvm.current.java16) { - return gradleVersion >= "7.0" - } else if (Jvm.current.java15) { - return gradleVersion >= "6.7" - } else if (Jvm.current.java14) { - return gradleVersion >= "6.3" - } else if (Jvm.current.java13) { - return gradleVersion >= "6.0" - } else if (Jvm.current.java12) { - return gradleVersion >= "5.4" - } else if (Jvm.current.java11) { - return gradleVersion >= "5.0" - } else if (Jvm.current.java10) { - return gradleVersion >= "4.7" - } else if (Jvm.current.java9) { - return gradleVersion >= "4.3" - } else if (Jvm.current.java8) { - return gradleVersion >= "2.0" - } - return false - } - - void givenConfigurationCacheIsCompatibleWithCurrentPlatform(boolean configurationCacheEnabled) { - if (configurationCacheEnabled) { - Assumptions.assumeFalse(Platform.isIbm8(), "Configuration cache is not compatible with IBM 8") - } - } - - private static String getLatestGradleVersion() { - OkHttpClient client = new OkHttpClient() - Request request = new Request.Builder().url("https://services.gradle.org/versions/current").build() - try (Response response = client.newCall(request).execute()) { - if (!response.successful) { - return GradleVersion.current().version - } - def responseBody = response.body().string() - ObjectMapper mapper = new ObjectMapper() - JsonNode root = mapper.readTree(responseBody) - return root.get("version").asText() - } - } } diff --git a/dd-smoke-tests/gradle/src/test/groovy/datadog/smoketest/GradleLauncherSmokeTest.groovy b/dd-smoke-tests/gradle/src/test/groovy/datadog/smoketest/GradleLauncherSmokeTest.groovy new file mode 100644 index 00000000000..436a6f4b3cb --- /dev/null +++ b/dd-smoke-tests/gradle/src/test/groovy/datadog/smoketest/GradleLauncherSmokeTest.groovy @@ -0,0 +1,76 @@ +package datadog.smoketest + +import datadog.communication.util.IOUtils +import datadog.trace.civisibility.utils.ShellCommandExecutor + +/** + * This test runs Gradle Launcher with the Java Tracer injected + * and verifies that the tracer is injected into the Gradle Daemon. + */ +class GradleLauncherSmokeTest extends AbstractGradleTest { + + private static final int GRADLE_BUILD_TIMEOUT_MILLIS = 30_000 + + private static final String AGENT_JAR = System.getProperty("datadog.smoketest.agent.shadowJar.path") + + def "test Gradle Launcher injects tracer into Gradle Daemon: v#gradleVersion, cmd line - #gradleDaemonCmdLineParams"() { + given: + givenGradleVersionIsCompatibleWithCurrentJvm(gradleVersion) + givenGradleProjectFiles("test-gradle-wrapper", ["gradle-wrapper.properties": ["gradle-version": gradleVersion]]) + givenGradleWrapper(gradleVersion) // we want to check that instrumentation works with different wrapper versions too + + when: + def output = whenRunningGradleLauncherWithJavaTracerInjected(gradleDaemonCmdLineParams) + + then: + gradleDaemonStartCommandContains(output, + // verify that the javaagent is injected into the Gradle Daemon start command + "-javaagent:${AGENT_JAR}", + // verify that existing Gradle Daemon JVM args are preserved: + // org.gradle.jvmargs provided on the command line, if present, + // otherwise org.gradle.jvmargs from gradle.properties file + // ("user.country" is used, as Gradle will filter out properties it is not aware of) + gradleDaemonCmdLineParams ? gradleDaemonCmdLineParams : "-Duser.country=VALUE_FROM_GRADLE_PROPERTIES_FILE") + + where: + gradleVersion | gradleDaemonCmdLineParams + "6.6.1" | null + "6.6.1" | "-Duser.country=VALUE_FROM_CMD_LINE" + "7.6.4" | null + "7.6.4" | "-Duser.country=VALUE_FROM_CMD_LINE" + "8.11.1" | null + "8.11.1" | "-Duser.country=VALUE_FROM_CMD_LINE" + LATEST_GRADLE_VERSION | null + LATEST_GRADLE_VERSION | "-Duser.country=VALUE_FROM_CMD_LINE" + } + + private void givenGradleWrapper(String gradleVersion) { + def shellCommandExecutor = new ShellCommandExecutor(projectFolder.toFile(), GRADLE_BUILD_TIMEOUT_MILLIS) + shellCommandExecutor.executeCommand(IOUtils::readFully, "./gradlew", "wrapper", "--gradle-version", gradleVersion) + } + + private String whenRunningGradleLauncherWithJavaTracerInjected(String gradleDaemonCmdLineParams) { + def shellCommandExecutor = new ShellCommandExecutor(projectFolder.toFile(), GRADLE_BUILD_TIMEOUT_MILLIS, [ + "GRADLE_OPTS" : "-javaagent:${AGENT_JAR}".toString(), + "DD_CIVISIBILITY_ENABLED" : "true", + "DD_CIVISIBILITY_AGENTLESS_ENABLED": "true", + "DD_CIVISIBILITY_AGENTLESS_URL" : "${mockBackend.intakeUrl}".toString(), + "DD_API_KEY" : "dummy" + ]) + String[] command = ["./gradlew", "--no-daemon", "--info"] + if (gradleDaemonCmdLineParams) { + command += "-Dorg.gradle.jvmargs=$gradleDaemonCmdLineParams" + } + return shellCommandExecutor.executeCommand(IOUtils::readFully, command) + } + + private static boolean gradleDaemonStartCommandContains(String buildOutput, String... tokens) { + def daemonStartCommandLog = buildOutput.split("\n").find { it.contains("Starting process 'Gradle build daemon'") } + for (String token : tokens) { + if (!daemonStartCommandLog.contains(token)) { + throw new org.opentest4j.AssertionFailedError("Gradle Daemon start command does not contain " + token, token, daemonStartCommandLog) + } + } + return true + } +} diff --git a/dd-smoke-tests/gradle/src/test/resources/test-gradle-wrapper/build.gradleTest b/dd-smoke-tests/gradle/src/test/resources/test-gradle-wrapper/build.gradleTest new file mode 100644 index 00000000000..bbfeb03c223 --- /dev/null +++ b/dd-smoke-tests/gradle/src/test/resources/test-gradle-wrapper/build.gradleTest @@ -0,0 +1 @@ +apply plugin: 'java' diff --git a/dd-smoke-tests/gradle/src/test/resources/test-gradle-wrapper/gradle.properties b/dd-smoke-tests/gradle/src/test/resources/test-gradle-wrapper/gradle.properties new file mode 100644 index 00000000000..c861b2bd1ce --- /dev/null +++ b/dd-smoke-tests/gradle/src/test/resources/test-gradle-wrapper/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Duser.country=VALUE_FROM_GRADLE_PROPERTIES_FILE diff --git a/dd-smoke-tests/gradle/src/test/resources/test-gradle-wrapper/gradle/wrapper/gradle-wrapper.jar b/dd-smoke-tests/gradle/src/test/resources/test-gradle-wrapper/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 00000000000..f6b961fd5a8 Binary files /dev/null and b/dd-smoke-tests/gradle/src/test/resources/test-gradle-wrapper/gradle/wrapper/gradle-wrapper.jar differ diff --git a/dd-smoke-tests/gradle/src/test/resources/test-gradle-wrapper/gradle/wrapper/gradle-wrapper.properties b/dd-smoke-tests/gradle/src/test/resources/test-gradle-wrapper/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000000..7b0b125d7b8 --- /dev/null +++ b/dd-smoke-tests/gradle/src/test/resources/test-gradle-wrapper/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-${gradle-version}-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/dd-smoke-tests/gradle/src/test/resources/test-gradle-wrapper/gradlew b/dd-smoke-tests/gradle/src/test/resources/test-gradle-wrapper/gradlew new file mode 100755 index 00000000000..cccdd3d517f --- /dev/null +++ b/dd-smoke-tests/gradle/src/test/resources/test-gradle-wrapper/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@"