diff --git a/src/main/groovy/com/github/j2objccontrib/j2objcgradle/J2objcConfig.groovy b/src/main/groovy/com/github/j2objccontrib/j2objcgradle/J2objcConfig.groovy index dd047866..662bd482 100644 --- a/src/main/groovy/com/github/j2objccontrib/j2objcgradle/J2objcConfig.groovy +++ b/src/main/groovy/com/github/j2objccontrib/j2objcgradle/J2objcConfig.groovy @@ -20,6 +20,7 @@ import com.github.j2objccontrib.j2objcgradle.tasks.Utils import com.google.common.annotations.VisibleForTesting import groovy.transform.CompileStatic import groovy.transform.TypeCheckingMode +import org.gradle.api.DefaultTask import org.gradle.api.InvalidUserDataException import org.gradle.api.Project import org.gradle.api.Task @@ -733,6 +734,20 @@ class J2objcConfig { */ @VisibleForTesting void finalConfigure() { + + // Gradle 2.9 build will fail if it calls configureNativeCompilation: + // https://github.com/j2objc-contrib/j2objc-gradle/issues/568 + // Return early without error to avoid deadlock: + // https://github.com/j2objc-contrib/j2objc-gradle/issues/585 + // Exception is thrown when TranslateTask is run. Safest approach is to disable + // all setup logic even though only NativeCompilation appears to cause any issue. + if (Utils.checkGradleVersion(false)) { + configureNativeCompilationForUnsupported() + // Avoid misleading error message that finalConfigured() wasn't in build.gradle + finalConfigured = true + return + } + validateConfiguration() // Conversion of compile and testCompile dependencies occurs optionally. if (autoConfigureDeps) { @@ -840,6 +855,10 @@ class J2objcConfig { project.file("${project.buildDir}/j2objcSrcGenTest")) } + protected void configureNativeCompilationForUnsupported() { + nativeCompilation.applyForUnsupported() + } + protected void convertDeps() { new DependencyConverter(project, this).configureAll() } diff --git a/src/main/groovy/com/github/j2objccontrib/j2objcgradle/J2objcPlugin.groovy b/src/main/groovy/com/github/j2objccontrib/j2objcgradle/J2objcPlugin.groovy index c773dd16..c7c03db4 100644 --- a/src/main/groovy/com/github/j2objccontrib/j2objcgradle/J2objcPlugin.groovy +++ b/src/main/groovy/com/github/j2objccontrib/j2objcgradle/J2objcPlugin.groovy @@ -32,7 +32,6 @@ import org.gradle.api.Project import org.gradle.api.Task import org.gradle.api.plugins.JavaPlugin import org.gradle.api.logging.LogLevel -import org.gradle.util.GradleVersion /* * Main plugin class for creation of extension object and all the tasks. @@ -56,7 +55,6 @@ class J2objcPlugin implements Plugin { // This avoids a lot of "project." prefixes, such as "project.tasks.create" project.with { - Utils.checkMinGradleVersion(GradleVersion.current()) getPluginManager().apply(JavaPlugin) extensions.create('j2objcConfig', J2objcConfig, project) diff --git a/src/main/groovy/com/github/j2objccontrib/j2objcgradle/NativeCompilation.groovy b/src/main/groovy/com/github/j2objccontrib/j2objcgradle/NativeCompilation.groovy index a04a0520..00210eda 100644 --- a/src/main/groovy/com/github/j2objccontrib/j2objcgradle/NativeCompilation.groovy +++ b/src/main/groovy/com/github/j2objccontrib/j2objcgradle/NativeCompilation.groovy @@ -19,6 +19,7 @@ package com.github.j2objccontrib.j2objcgradle import com.github.j2objccontrib.j2objcgradle.tasks.Utils import groovy.transform.PackageScope import org.gradle.api.Action +import org.gradle.api.DefaultTask import org.gradle.api.InvalidUserDataException import org.gradle.api.NamedDomainObjectContainer import org.gradle.api.Project @@ -121,6 +122,18 @@ class NativeCompilation { }) } + // Creates fake tasks to satisfy dependencies for J2objcPlugin.apply(...) + // Should only be used as an alternative to NativeComplication.apply(...) when + // the Gradle Version is unsupported and no build can be done. + void applyForUnsupported() { + project.with { + tasks.create(name: 'debugTestJ2objcExecutable', type: DefaultTask) + tasks.create(name: 'releaseTestJ2objcExecutable', type: DefaultTask) + tasks.create(name: 'j2objcBuildObjcDebug', type: DefaultTask) + tasks.create(name: 'j2objcBuildObjcRelease', type: DefaultTask) + } + } + @PackageScope @SuppressWarnings("grvy:org.codenarc.rule.size.NestedBlockDepthRule") void apply(File srcGenMainDir, File srcGenTestDir) { diff --git a/src/main/groovy/com/github/j2objccontrib/j2objcgradle/tasks/TranslateTask.groovy b/src/main/groovy/com/github/j2objccontrib/j2objcgradle/tasks/TranslateTask.groovy index e64bf1eb..7508a39a 100644 --- a/src/main/groovy/com/github/j2objccontrib/j2objcgradle/tasks/TranslateTask.groovy +++ b/src/main/groovy/com/github/j2objccontrib/j2objcgradle/tasks/TranslateTask.groovy @@ -135,6 +135,11 @@ class TranslateTask extends DefaultTask { @TaskAction void translate(IncrementalTaskInputs inputs) { + // Exceptions must be delayed until Plugin tasks are run + // Doing it earlier causes Gradle deadlock: + // https://github.com/j2objc-contrib/j2objc-gradle/issues/585 + Utils.checkGradleVersion(true) + List translateArgs = getTranslateArgs() // Don't evaluate this expensive property multiple times. FileCollection originalMainSrcFiles = getMainSrcFiles() diff --git a/src/main/groovy/com/github/j2objccontrib/j2objcgradle/tasks/Utils.groovy b/src/main/groovy/com/github/j2objccontrib/j2objcgradle/tasks/Utils.groovy index 9009aa25..c6810806 100644 --- a/src/main/groovy/com/github/j2objccontrib/j2objcgradle/tasks/Utils.groovy +++ b/src/main/groovy/com/github/j2objccontrib/j2objcgradle/tasks/Utils.groovy @@ -55,12 +55,33 @@ class Utils { // Prevent construction of this class, confines usage to static methods private Utils() { } - static void checkMinGradleVersion(GradleVersion gradleVersion) { + static boolean checkGradleVersion(boolean throwIfUnsupported) { + return checkGradleVersion(GradleVersion.current(), throwIfUnsupported) + } + + @VisibleForTesting + static boolean checkGradleVersion(GradleVersion gradleVersion, boolean throwIfUnsupported) { + String errorMsg = '' + final GradleVersion minGradleVersion = GradleVersion.version('2.4') - if (gradleVersion.compareTo(minGradleVersion) < 0) { - throw new InvalidUserDataException( - "J2ObjC Gradle Plugin requires minimum Gradle version: $minGradleVersion") + if (gradleVersion.compareTo(GradleVersion.version('2.4')) < 0) { + errorMsg = "J2ObjC Gradle Plugin requires minimum Gradle version: $minGradleVersion" + } + + final GradleVersion unsupportedGradleVersion = GradleVersion.version('2.9') + if (gradleVersion.compareTo(unsupportedGradleVersion) >= 0) { + errorMsg = "Please use Gradle 2.8 as $unsupportedGradleVersion is unsupported:\n" + + "https://github.com/j2objc-contrib/j2objc-gradle/issues/568" + } + + if (!errorMsg.isEmpty()) { + if (throwIfUnsupported) { + throw new InvalidUserDataException(errorMsg) + } else { + return true + } } + return false } static List parseVersionComponents(String ver) { diff --git a/src/test/groovy/com/github/j2objccontrib/j2objcgradle/tasks/UtilsTest.groovy b/src/test/groovy/com/github/j2objccontrib/j2objcgradle/tasks/UtilsTest.groovy index cfb8e06c..73ac2d10 100644 --- a/src/test/groovy/com/github/j2objccontrib/j2objcgradle/tasks/UtilsTest.groovy +++ b/src/test/groovy/com/github/j2objccontrib/j2objcgradle/tasks/UtilsTest.groovy @@ -58,17 +58,32 @@ class UtilsTest { } @Test - void testCheckMinGradleVersion_valid() { - Utils.checkMinGradleVersion(GradleVersion.version('2.4')) - Utils.checkMinGradleVersion(GradleVersion.version('2.4.1')) - Utils.checkMinGradleVersion(GradleVersion.version('2.5')) - Utils.checkMinGradleVersion(GradleVersion.version('3.0')) - Utils.checkMinGradleVersion(GradleVersion.version('10.0')) + void testCheckGradleVersion_invalid() { + assert Utils.checkGradleVersion(GradleVersion.version('2.3'), false) + assert Utils.checkGradleVersion(GradleVersion.version('2.9'), false) + } + + @Test + void testCheckGradleVersion_valid() { + assert !Utils.checkGradleVersion(GradleVersion.version('2.4'), false) + assert !Utils.checkGradleVersion(GradleVersion.version('2.4.1'), false) + assert !Utils.checkGradleVersion(GradleVersion.version('2.5'), false) + assert !Utils.checkGradleVersion(GradleVersion.version('2.8'), false) + + assert !Utils.checkGradleVersion(GradleVersion.version('2.4'), true) + assert !Utils.checkGradleVersion(GradleVersion.version('2.4.1'), true) + assert !Utils.checkGradleVersion(GradleVersion.version('2.5'), true) + assert !Utils.checkGradleVersion(GradleVersion.version('2.8'), true) + } + + @Test(expected=InvalidUserDataException) + void testCheckGradleVersion_belowMinimumException() { + Utils.checkGradleVersion(GradleVersion.version('2.3'), true) } @Test(expected=InvalidUserDataException) - void testCheckMinGradleVersion_invalid() { - Utils.checkMinGradleVersion(GradleVersion.version('2.3')) + void testCheckGradleVersion_aboveMaximum() { + Utils.checkGradleVersion(GradleVersion.version('2.9'), true) } @Test