Skip to content

Commit

Permalink
Be smarter about locating internal Guava JAR (asciidoctor#424)
Browse files Browse the repository at this point in the history
  • Loading branch information
ysb33r committed Jan 18, 2020
1 parent 6825f22 commit 952f2af
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.asciidoctor.gradle.internal
package org.asciidoctor.gradle.base

import org.asciidoctor.gradle.base.AsciidoctorUtils
import spock.lang.Specification
import spock.lang.Unroll

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,29 @@
package org.asciidoctor.gradle.internal

import groovy.transform.CompileStatic
import groovy.transform.InheritConstructors
import org.asciidoctor.gradle.remote.AsciidoctorJavaExec
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.file.FileCollection
import org.gradle.api.invocation.Gradle
import org.gradle.util.GradleVersion
import org.ysb33r.grolifant.api.FileUtils

import java.util.regex.Pattern

import static org.asciidoctor.gradle.base.AsciidoctorUtils.getClassLocation

/** Utilities for dealing with Asciidoctor in an external JavaExec process.
*
* @since 2.0* @author Sdhalk W. Cronjé
* @author Schalk W. Cronjé
*
* @since 2.0
*/
@CompileStatic
class JavaExecUtils {

/** The name of the Guava JAR used internally by Gradle.
*
*/
public static final String INTERNAL_GUAVA_NAME = internalGuavaName()
private static final FilenameFilter INTERNAL_GUAVA_PATTERN = internalGuavaPattern()

/** Get the classpath that needs to be passed to the external Java process.
*
Expand All @@ -54,7 +57,7 @@ class JavaExecUtils {

FileCollection fc = project.files(entryPoint, groovyJar, asciidoctorClasspath)

addInternalGuava ? project.files(fc, new File(project.gradle.gradleHomeDir, "lib/${INTERNAL_GUAVA_NAME}")) : fc
addInternalGuava ? project.files(fc, getInternalGuavaLocation(project.gradle)) : fc
}

/** The file to which execution configuration data can be serialised to.
Expand Down Expand Up @@ -88,13 +91,46 @@ class JavaExecUtils {
getClassLocation(GroovyObject)
}

private static String internalGuavaName() {
if (GradleVersion.current() >= GradleVersion.version('5.5')) {
'guava-27.1-android.jar'
} else if (GradleVersion.current() >= GradleVersion.version('5.0')) {
'guava-26.0-android.jar'
/** Locate the internal Guava JAR from the Gradle distribution
*
* @param gradle Gradle instance
* @return Return Guava location. Never {@code null}
* @throw InternalGuavaLocationException
*/
static File getInternalGuavaLocation(Gradle gradle) {
File[] files = new File(gradle.gradleHomeDir, 'lib').listFiles(INTERNAL_GUAVA_PATTERN)

if (!files) {
throw new InternalGuavaLocationException('Cannot locate a Guava JAR in the Gradle distribution')
} else if (files.size() > 1) {
throw new InternalGuavaLocationException(
"Found more than one Guava JAR in the Gradle distribution: ${files*.name}"
)
}
files[0]
}

/** Thrown when an internal Guava JAR cannot be located.
*
* @since 3.0
*/
@InheritConstructors
static class InternalGuavaLocationException extends RuntimeException {
}

private static FilenameFilter internalGuavaPattern() {
Pattern filter
if (GradleVersion.current() >= GradleVersion.version('5.0')) {
filter = ~/guava-([\d.]+)-android.jar/
} else {
'guava-jdk5-17.0.jar'
filter = ~/guava-jdk5-([\d.]+).jar/
}

new FilenameFilter() {
@Override
boolean accept(File dir, String name) {
name.matches(filter)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.asciidoctor.gradle.internal

import org.gradle.api.invocation.Gradle
import org.junit.Rule
import org.junit.rules.TemporaryFolder
import spock.lang.Specification

import static org.asciidoctor.gradle.internal.JavaExecUtils.getInternalGuavaLocation

class JavaExecUtilsSpec extends Specification {

@Rule
TemporaryFolder temporaryFolder

void 'Throw exception if internal Guava cannot be found'() {
setup:
def gradle = Stub(Gradle)
gradle.gradleHomeDir >> temporaryFolder.root

when:
getInternalGuavaLocation(gradle)

then:
def e = thrown(JavaExecUtils.InternalGuavaLocationException)
e.message.contains('Cannot locate a Guava JAR in the Gradle distribution')
}

void 'Throw exception if multiple internal Guava JARs are found'() {
setup:
def gradle = Stub(Gradle)
gradle.gradleHomeDir >> temporaryFolder.root
new File(temporaryFolder.root, 'lib').mkdirs()
new File(temporaryFolder.root, 'lib/guava-0.0-android.jar').text = ''
new File(temporaryFolder.root, 'lib/guava-0.1-android.jar').text = ''

when:
getInternalGuavaLocation(gradle)

then:
def e = thrown(JavaExecUtils.InternalGuavaLocationException)
e.message.contains('Found more than one Guava JAR in the Gradle distribution')
}
}

0 comments on commit 952f2af

Please sign in to comment.