Skip to content

Commit 8f9d0ed

Browse files
authored
Merge pull request #124 from policeman-tools/fixes/gradle4
Remove warning in Gradle 4. This closes #120
2 parents 355dbc7 + 7e9fd78 commit 8f9d0ed

File tree

3 files changed

+51
-20
lines changed

3 files changed

+51
-20
lines changed

src/main/java/de/thetaphi/forbiddenapis/gradle/CheckForbiddenApis.java

+44-15
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import java.net.URL;
2828
import java.net.URLClassLoader;
2929
import java.util.EnumSet;
30+
import java.util.LinkedHashSet;
3031
import java.util.List;
3132
import java.util.Locale;
3233
import java.util.Set;
@@ -43,7 +44,7 @@
4344
import org.gradle.api.tasks.Input;
4445
import org.gradle.api.tasks.InputFiles;
4546
import org.gradle.api.tasks.Optional;
46-
import org.gradle.api.tasks.OutputDirectory;
47+
import org.gradle.api.tasks.OutputDirectories;
4748
import org.gradle.api.tasks.ParallelizableTask;
4849
import org.gradle.api.tasks.SkipWhenEmpty;
4950
import org.gradle.api.tasks.TaskAction;
@@ -109,23 +110,49 @@ public class CheckForbiddenApis extends DefaultTask implements PatternFilterable
109110

110111
private final CheckForbiddenApisExtension data = new CheckForbiddenApisExtension();
111112
private final PatternSet patternSet = new PatternSet().include("**/*.class");
112-
private File classesDir;
113+
private FileCollection classesDirs;
113114
private FileCollection classpath;
114115
private String targetCompatibility;
115116

117+
/**
118+
* Directories with the class files to check.
119+
* Defaults to current sourseSet's output directory (Gradle 2/3) or output directories (Gradle 4.0+).
120+
*/
121+
@OutputDirectories
122+
// no @InputDirectories, we use separate getter for a list of all input files
123+
public FileCollection getClassesDirs() {
124+
return classesDirs;
125+
}
126+
127+
/** @see #getClassesDirs */
128+
public void setClassesDirs(FileCollection classesDirs) {
129+
if (classesDirs == null) throw new NullPointerException("classesDirs");
130+
this.classesDirs = classesDirs;
131+
}
132+
116133
/**
117134
* Directory with the class files to check.
118-
* Defaults to current sourseSet's output directory.
135+
* Defaults to current sourseSet's output directory (Gradle 2/3 only).
136+
* @deprecated use {@link #getClassesDirs()} instead. If there are more than one
137+
* {@code classesDir} set by {@link #setClassesDirs(FileCollection)}, this getter may
138+
* throw an exception!
119139
*/
120-
@OutputDirectory
121-
// no @InputDirectory, we use separate getter for a list of all input files
140+
@Deprecated
122141
public File getClassesDir() {
123-
return classesDir;
142+
final FileCollection col = getClassesDirs();
143+
return (col == null) ? null : col.getSingleFile();
124144
}
125145

126-
/** @see #getClassesDir */
146+
/** Sets the directory where to look for classes. Overwrites any value set by {@link #setClassesDirs(FileCollection)}!
147+
* @deprecated use {@link #setClassesDirs(FileCollection)} instead.
148+
* @see #getClassesDir
149+
*/
150+
@Deprecated
127151
public void setClassesDir(File classesDir) {
128-
this.classesDir = classesDir;
152+
if (classesDir == null) throw new NullPointerException("classesDir");
153+
getLogger().warn("The 'classesDir' property on the '{}' task is deprecated. Use 'classesDirs' of type FileCollection instead!",
154+
getName());
155+
setClassesDirs(getProject().files(classesDir));
129156
}
130157

131158
/** Returns the pattern set to match against class files in {@link #getClassesDir()}. */
@@ -149,6 +176,7 @@ public FileCollection getClasspath() {
149176

150177
/** @see #getClasspath */
151178
public void setClasspath(FileCollection classpath) {
179+
if (classpath == null) throw new NullPointerException("classpath");
152180
this.classpath = classpath;
153181
}
154182

@@ -453,16 +481,16 @@ public CheckForbiddenApis include(@SuppressWarnings("rawtypes") Closure arg0) {
453481
@InputFiles
454482
@SkipWhenEmpty
455483
public FileTree getClassFiles() {
456-
return getProject().files(getClassesDir()).getAsFileTree().matching(getPatternSet());
484+
return getClassesDirs().getAsFileTree().matching(getPatternSet());
457485
}
458486

459487
/** Executes the forbidden apis task. */
460488
@TaskAction
461489
public void checkForbidden() throws ForbiddenApiException {
462-
final File classesDir = getClassesDir();
490+
final FileCollection classesDirs = getClassesDirs();
463491
final FileCollection classpath = getClasspath();
464-
if (classesDir == null || classpath == null) {
465-
throw new InvalidUserDataException("Missing 'classesDir' or 'classpath' property.");
492+
if (classesDirs == null || classpath == null) {
493+
throw new InvalidUserDataException("Missing 'classesDirs' or 'classpath' property.");
466494
}
467495

468496
final Logger log = new Logger() {
@@ -482,14 +510,15 @@ public void info(String msg) {
482510
}
483511
};
484512

485-
final Set<File> cpElements = classpath.getFiles();
486-
final URL[] urls = new URL[cpElements.size() + 1];
513+
final Set<File> cpElements = new LinkedHashSet<File>();
514+
cpElements.addAll(classpath.getFiles());
515+
cpElements.addAll(classesDirs.getFiles());
516+
final URL[] urls = new URL[cpElements.size()];
487517
try {
488518
int i = 0;
489519
for (final File cpElement : cpElements) {
490520
urls[i++] = cpElement.toURI().toURL();
491521
}
492-
urls[i++] = classesDir.toURI().toURL();
493522
assert i == urls.length;
494523
} catch (MalformedURLException mfue) {
495524
throw new InvalidUserDataException("Failed to build classpath URLs.", mfue);

src/main/resources/de/thetaphi/forbiddenapis/gradle/plugin-init.groovy

+5-4
Original file line numberDiff line numberDiff line change
@@ -45,19 +45,20 @@ def extensionProps = CheckForbiddenApisExtension.class.declaredFields.findAll{ f
4545

4646
// Define our tasks (one for each SourceSet):
4747
def forbiddenTasks = project.sourceSets.collect{ sourceSet ->
48+
def getClassesDirs = { sourceSet.output.hasProperty('classesDirs') ? sourceSet.output.classesDirs : project.files(sourceSet.output.classesDir) }
4849
project.tasks.create(sourceSet.getTaskName(FORBIDDEN_APIS_TASK_NAME, null), CheckForbiddenApis.class) {
4950
description = "Runs forbidden-apis checks on '${sourceSet.name}' classes.";
5051
conventionMapping.with{
5152
extensionProps.each{ key ->
5253
map(key, { extension[key] });
5354
}
54-
classesDir = { sourceSet.output.classesDir }
55+
classesDirs = { getClassesDirs() }
5556
classpath = { sourceSet.compileClasspath }
5657
targetCompatibility = { project.targetCompatibility?.toString() }
5758
}
58-
// add dependency to compile task after evaluation, if the classesDir is from our SourceSet:
59-
project.afterEvaluate{
60-
if (classesDir == sourceSet.output.classesDir) {
59+
// add dependency to compile task after evaluation, if the classesDirs collection has overlaps with our SourceSet:
60+
project.afterEvaluate{
61+
if (!classesDirs.minus(getClassesDirs()).isEmpty()) {
6162
dependsOn(sourceSet.output);
6263
}
6364
}

src/test/gradle/build.gradle

+2-1
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,13 @@ forbiddenApis {
3737
}
3838

3939
forbiddenApisMain {
40-
classesDir = new File(forbiddenRootDir, 'build/main')
40+
classesDirs = files(new File(forbiddenRootDir, 'build/main'))
4141
classpath = files(forbiddenClasspath.tokenize(File.pathSeparator))
4242
bundledSignatures += 'jdk-system-out'
4343
}
4444

4545
forbiddenApisTest {
46+
// use classesDir here to check backwards compatibility!:
4647
classesDir = new File(forbiddenRootDir, 'build/test')
4748
classpath = files(forbiddenTestClasspath.tokenize(File.pathSeparator))
4849
}

0 commit comments

Comments
 (0)