From a23f3c83fb8b99175a135eabf8f5dc040ca494d3 Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Thu, 14 Nov 2024 12:11:53 +0100 Subject: [PATCH 01/14] Checking for android libs --- .../animalsniffer/AnimalSnifferPlugin.groovy | 63 ++++++++++++------- 1 file changed, 39 insertions(+), 24 deletions(-) diff --git a/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AnimalSnifferPlugin.groovy b/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AnimalSnifferPlugin.groovy index c376d26..af1f49f 100644 --- a/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AnimalSnifferPlugin.groovy +++ b/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AnimalSnifferPlugin.groovy @@ -1,8 +1,12 @@ package ru.vyarus.gradle.plugin.animalsniffer + +import com.android.build.api.variant.LibraryAndroidComponentsExtension +import com.android.build.api.variant.LibraryVariant import groovy.transform.CompileStatic import groovy.transform.Memoized import groovy.transform.TypeCheckingMode +import org.gradle.api.Action import org.gradle.api.GradleException import org.gradle.api.Plugin import org.gradle.api.Project @@ -56,17 +60,19 @@ class AnimalSnifferPlugin implements Plugin { @Override void apply(Project project) { - // activated only when java plugin is enabled - project.plugins.withType(JavaBasePlugin) { - this.project = project - project.plugins.apply(ReportingBasePlugin) + this.project = project + project.plugins.apply(ReportingBasePlugin) - checkGradleCompatibility() - registerShortcuts() - registerConfigurations() - registerExtensions() - registerCheckTasks() - registerBuildTasks() + checkGradleCompatibility() + registerShortcuts() + registerConfigurations() + registerExtensions() + registerBuildTasks() + project.plugins.withType(JavaBasePlugin) { + registerJavaCheckTasks() + } + project.plugins.withId("com.android.library") { + registerAndroidCheckTasks() } } @@ -119,7 +125,7 @@ class AnimalSnifferPlugin implements Plugin { @SuppressWarnings(['Indentation', 'NestedBlockDepth']) @CompileStatic(TypeCheckingMode.SKIP) - private void registerCheckTasks() { + private void registerJavaCheckTasks() { // create tasks for each source set project.sourceSets.all { SourceSet sourceSet -> String sourceSetName = sourceSet.name @@ -137,7 +143,7 @@ class AnimalSnifferPlugin implements Plugin { }) } } - configureCheckTask(checkTask, sourceSet) + configureCheckTask(checkTask, sourceSet.allJava.srcDirs, sourceSet.getTaskName(ANIMALSNIFFER_CACHE, null), sourceSet.classesTaskName, sourceSet.compileClasspath) } // include required animalsniffer tasks in check lifecycle @@ -148,16 +154,25 @@ class AnimalSnifferPlugin implements Plugin { } } + void registerAndroidCheckTasks() { + def androidComponents = project.extensions.getByType(LibraryAndroidComponentsExtension) + androidComponents.onVariants(androidComponents.selector().all(), new Action() { + @Override + void execute(LibraryVariant libraryVariant) { + + } + }) + } + @SuppressWarnings(['Indentation', 'MethodSize', 'UnnecessaryGetter']) @CompileStatic(TypeCheckingMode.SKIP) - private void configureCheckTask(TaskProvider checkTask, SourceSet sourceSet) { + private void configureCheckTask(TaskProvider checkTask, Set srcDirs, String signatureTaskName, String classesTaskName, FileCollection compileClasspath) { Configuration animalsnifferConfiguration = project.configurations[CHECK_SIGNATURE] // build special signature from provided signatures and all jars to be able to cache it // and perform much faster checks after the first run TaskProvider signatureTask = project.tasks - . register(sourceSet.getTaskName(ANIMALSNIFFER_CACHE, null), - BuildSignatureTask) { + . register(signatureTaskName, BuildSignatureTask) { // this special task can be skipped if animalsniffer check supposed to be skipped // note that task is still created because signatures could be registered dynamically onlyIf { !extension.signatures.empty && extension.cache.enabled } @@ -165,7 +180,7 @@ class AnimalSnifferPlugin implements Plugin { conventionMapping.with { animalsnifferClasspath = { animalsnifferConfiguration } signatures = { extension.signatures } - files = { excludeJars(getClasspathWithoutModules(sourceSet)) } + files = { excludeJars(getClasspathWithoutModules(compileClasspath)) } exclude = { extension.cache.exclude as Set } mergeSignatures = { extension.cache.mergeSignatures } // debug for cache tasks controlled by check debug @@ -173,19 +188,19 @@ class AnimalSnifferPlugin implements Plugin { } } checkTask.configure { - dependsOn(sourceSet.classesTaskName) + dependsOn(classesTaskName) // skip if no signatures configured or no sources to check onlyIf { !getAnimalsnifferSignatures().empty && getSource().size() > 0 } conventionMapping.with { classpath = { extension.cache.enabled ? - getModulesFromClasspath(sourceSet) : excludeJars(sourceSet.compileClasspath) + getModulesFromClasspath(compileClasspath) : excludeJars(compileClasspath) } animalsnifferSignatures = { extension.cache.enabled ? signatureTask.get().outputFiles : extension.signatures } animalsnifferClasspath = { animalsnifferConfiguration } - sourcesDirs = { sourceSet.allJava.srcDirs } + sourcesDirs = { srcDirs } ignoreFailures = { extension.ignoreFailures } annotation = { extension.annotation } ignoreClasses = { extension.ignore } @@ -246,12 +261,12 @@ class AnimalSnifferPlugin implements Plugin { */ @Memoized @CompileStatic(TypeCheckingMode.SKIP) - private FileCollection getClasspathWithoutModules(SourceSet sourceSet) { + private FileCollection getClasspathWithoutModules(FileCollection compileClasspath) { Set excludeJars = moduleJars if (excludeJars.empty) { - return sourceSet.compileClasspath + return compileClasspath } - sourceSet.compileClasspath.filter new NotSpec(new ContainFilesSpec(excludeJars)) + compileClasspath.filter new NotSpec(new ContainFilesSpec(excludeJars)) } /** @@ -263,12 +278,12 @@ class AnimalSnifferPlugin implements Plugin { */ @Memoized @CompileStatic(TypeCheckingMode.SKIP) - private FileCollection getModulesFromClasspath(SourceSet sourceSet) { + private FileCollection getModulesFromClasspath(FileCollection compileClasspath) { Set includeJars = moduleJars if (includeJars.empty) { return null } - sourceSet.compileClasspath.filter new ContainFilesSpec(includeJars) + compileClasspath.filter new ContainFilesSpec(includeJars) } /** From b6897ec892b1668d44fbb4159efb5b9bfb2d305e Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Thu, 14 Nov 2024 14:09:21 +0100 Subject: [PATCH 02/14] Installing it in android lib projects --- .../AndroidClassesCollector.groovy | 35 +++++++++++ .../plugin/animalsniffer/AnimalSniffer.groovy | 4 +- .../animalsniffer/AnimalSnifferPlugin.groovy | 60 +++++++++++++++++-- 3 files changed, 93 insertions(+), 6 deletions(-) create mode 100644 src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AndroidClassesCollector.groovy diff --git a/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AndroidClassesCollector.groovy b/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AndroidClassesCollector.groovy new file mode 100644 index 0000000..2372c3e --- /dev/null +++ b/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AndroidClassesCollector.groovy @@ -0,0 +1,35 @@ +package ru.vyarus.gradle.plugin.animalsniffer + + +import org.gradle.api.DefaultTask +import org.gradle.api.file.Directory +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.RegularFile +import org.gradle.api.provider.ListProperty +import org.gradle.api.tasks.InputFiles +import org.gradle.api.tasks.OutputDirectory +import org.gradle.api.tasks.TaskAction + +abstract class AndroidClassesCollector extends DefaultTask { + + @InputFiles + abstract ListProperty getJarFiles() + + @InputFiles + abstract ListProperty getClassesDirs() + + @OutputDirectory + abstract DirectoryProperty getOutputDirectory() + + AndroidClassesCollector() { + getOutputDirectory().value(project.layout.buildDirectory.dir("intermediates/animal_sniffer/" + name)) + } + + @TaskAction + void execute() { + project.copy { + from(classesDirs) + into(outputDirectory) + } + } +} diff --git a/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AnimalSniffer.groovy b/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AnimalSniffer.groovy index 7f32b5f..649f5ce 100644 --- a/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AnimalSniffer.groovy +++ b/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AnimalSniffer.groovy @@ -66,7 +66,7 @@ class AnimalSniffer extends SourceTask implements VerificationTask, Reporting sourcesDirs + FileCollection sourcesDirs /** * Annotation class name to avoid check @@ -298,7 +298,7 @@ class AnimalSniffer extends SourceTask implements VerificationTask, Reporting collectSourceDirs() { Set res = [] as Set - res.addAll(getSourcesDirs()) + res.addAll(getSourcesDirs().getFiles()) // HACK to support kotlin multiplatform source path for jvm case (when withJava() active) // this MUST BE rewritten into separate support for multiplatform if (project.plugins.findPlugin('org.jetbrains.kotlin.multiplatform')) { diff --git a/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AnimalSnifferPlugin.groovy b/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AnimalSnifferPlugin.groovy index af1f49f..d5540c6 100644 --- a/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AnimalSnifferPlugin.groovy +++ b/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AnimalSnifferPlugin.groovy @@ -1,22 +1,26 @@ package ru.vyarus.gradle.plugin.animalsniffer - +import com.android.build.api.artifact.ScopedArtifact import com.android.build.api.variant.LibraryAndroidComponentsExtension import com.android.build.api.variant.LibraryVariant +import com.android.build.api.variant.ScopedArtifacts import groovy.transform.CompileStatic import groovy.transform.Memoized import groovy.transform.TypeCheckingMode +import kotlin.jvm.functions.Function1 import org.gradle.api.Action import org.gradle.api.GradleException import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.artifacts.Configuration import org.gradle.api.artifacts.Dependency +import org.gradle.api.file.Directory import org.gradle.api.file.FileCollection import org.gradle.api.file.RegularFile import org.gradle.api.plugins.ExtraPropertiesExtension import org.gradle.api.plugins.JavaBasePlugin import org.gradle.api.plugins.ReportingBasePlugin +import org.gradle.api.provider.ListProperty import org.gradle.api.reporting.ReportingExtension import org.gradle.api.specs.NotSpec import org.gradle.api.tasks.SourceSet @@ -143,7 +147,11 @@ class AnimalSnifferPlugin implements Plugin { }) } } - configureCheckTask(checkTask, sourceSet.allJava.srcDirs, sourceSet.getTaskName(ANIMALSNIFFER_CACHE, null), sourceSet.classesTaskName, sourceSet.compileClasspath) + configureCheckTask(checkTask, + project.files(sourceSet.allJava.srcDirs), + sourceSet.getTaskName(ANIMALSNIFFER_CACHE, null), + sourceSet.classesTaskName, + sourceSet.compileClasspath) } // include required animalsniffer tasks in check lifecycle @@ -154,19 +162,63 @@ class AnimalSnifferPlugin implements Plugin { } } + @CompileStatic(TypeCheckingMode.SKIP) void registerAndroidCheckTasks() { def androidComponents = project.extensions.getByType(LibraryAndroidComponentsExtension) androidComponents.onVariants(androidComponents.selector().all(), new Action() { @Override void execute(LibraryVariant libraryVariant) { + String sourceSetName = libraryVariant.name + String capitalizedSourceSetName = sourceSetName.capitalize() + String classesCollectorTaskName = sourceSetName + "AnimalSnifferCollectClasses" + TaskProvider classesCollector = createAndroidClassesCollector(classesCollectorTaskName, libraryVariant) + TaskProvider checkTask = project.tasks + . register(CHECK_SIGNATURE + capitalizedSourceSetName, + AnimalSniffer) { + description = "Run AnimalSniffer checks for ${sourceSetName} classes" + // task operates on classes instead of sources + source = classesCollector.flatMap { it.outputDirectory } + reports.all { report -> + report.required.convention(true) + report.outputLocation.convention(project.provider { + { -> + new File(extension.reportsDir, "${sourceSetName}.${report.name}") + } as RegularFile + }) + } + } + + configureCheckTask(checkTask, + project.files(libraryVariant.sources.java.all, libraryVariant.sources.kotlin.all), + ANIMALSNIFFER_CACHE + capitalizedSourceSetName, + classesCollectorTaskName, + libraryVariant.compileClasspath) } + }) } + private TaskProvider createAndroidClassesCollector(String taskName, LibraryVariant libraryVariant) { + TaskProvider collectClasses = project.tasks.register(taskName, AndroidClassesCollector) + libraryVariant.artifacts.forScope(ScopedArtifacts.Scope.PROJECT).use(collectClasses) + .toGet(ScopedArtifact.CLASSES.INSTANCE, new Function1>() { + @Override + ListProperty invoke(AndroidClassesCollector task) { + return task.jarFiles + } + }, new Function1>() { + @Override + ListProperty invoke(AndroidClassesCollector task) { + return task.classesDirs + } + }) + return collectClasses + } + @SuppressWarnings(['Indentation', 'MethodSize', 'UnnecessaryGetter']) @CompileStatic(TypeCheckingMode.SKIP) - private void configureCheckTask(TaskProvider checkTask, Set srcDirs, String signatureTaskName, String classesTaskName, FileCollection compileClasspath) { + private void configureCheckTask(TaskProvider checkTask, FileCollection srcDirs, String signatureTaskName, String classesTaskName, FileCollection compileClasspath) { Configuration animalsnifferConfiguration = project.configurations[CHECK_SIGNATURE] // build special signature from provided signatures and all jars to be able to cache it @@ -200,7 +252,7 @@ class AnimalSnifferPlugin implements Plugin { extension.cache.enabled ? signatureTask.get().outputFiles : extension.signatures } animalsnifferClasspath = { animalsnifferConfiguration } - sourcesDirs = { srcDirs } + sourcesDirs = srcDirs ignoreFailures = { extension.ignoreFailures } annotation = { extension.annotation } ignoreClasses = { extension.ignore } From 25d775068e227f7e92e5a98f212c75a7fd87152e Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Thu, 14 Nov 2024 14:12:17 +0100 Subject: [PATCH 03/14] Using sync to collect classes --- .../gradle/plugin/animalsniffer/AndroidClassesCollector.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AndroidClassesCollector.groovy b/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AndroidClassesCollector.groovy index 2372c3e..7169125 100644 --- a/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AndroidClassesCollector.groovy +++ b/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AndroidClassesCollector.groovy @@ -27,7 +27,7 @@ abstract class AndroidClassesCollector extends DefaultTask { @TaskAction void execute() { - project.copy { + project.sync { from(classesDirs) into(outputDirectory) } From 73912bf6c466884294c6fa5cff93f7c5f073d494 Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Thu, 14 Nov 2024 14:16:45 +0100 Subject: [PATCH 04/14] Renaming classes collector task --- .../gradle/plugin/animalsniffer/AnimalSnifferPlugin.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AnimalSnifferPlugin.groovy b/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AnimalSnifferPlugin.groovy index d5540c6..0b00808 100644 --- a/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AnimalSnifferPlugin.groovy +++ b/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AnimalSnifferPlugin.groovy @@ -170,7 +170,7 @@ class AnimalSnifferPlugin implements Plugin { void execute(LibraryVariant libraryVariant) { String sourceSetName = libraryVariant.name String capitalizedSourceSetName = sourceSetName.capitalize() - String classesCollectorTaskName = sourceSetName + "AnimalSnifferCollectClasses" + String classesCollectorTaskName = sourceSetName + "AnimalSnifferClassesCollector" TaskProvider classesCollector = createAndroidClassesCollector(classesCollectorTaskName, libraryVariant) TaskProvider checkTask = project.tasks . register(CHECK_SIGNATURE + capitalizedSourceSetName, From e1fcc7a1dcf018b7090ba647c014e5dfa0c705bd Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Thu, 14 Nov 2024 14:30:47 +0100 Subject: [PATCH 05/14] Removing android plugin types --- .../animalsniffer/AnimalSnifferPlugin.groovy | 68 +++++++++---------- 1 file changed, 31 insertions(+), 37 deletions(-) diff --git a/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AnimalSnifferPlugin.groovy b/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AnimalSnifferPlugin.groovy index 0b00808..8b67e5b 100644 --- a/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AnimalSnifferPlugin.groovy +++ b/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AnimalSnifferPlugin.groovy @@ -1,14 +1,9 @@ package ru.vyarus.gradle.plugin.animalsniffer -import com.android.build.api.artifact.ScopedArtifact -import com.android.build.api.variant.LibraryAndroidComponentsExtension -import com.android.build.api.variant.LibraryVariant -import com.android.build.api.variant.ScopedArtifacts import groovy.transform.CompileStatic import groovy.transform.Memoized import groovy.transform.TypeCheckingMode import kotlin.jvm.functions.Function1 -import org.gradle.api.Action import org.gradle.api.GradleException import org.gradle.api.Plugin import org.gradle.api.Project @@ -162,47 +157,46 @@ class AnimalSnifferPlugin implements Plugin { } } + @SuppressWarnings('GroovyAssignabilityCheck') @CompileStatic(TypeCheckingMode.SKIP) void registerAndroidCheckTasks() { - def androidComponents = project.extensions.getByType(LibraryAndroidComponentsExtension) - androidComponents.onVariants(androidComponents.selector().all(), new Action() { - @Override - void execute(LibraryVariant libraryVariant) { - String sourceSetName = libraryVariant.name - String capitalizedSourceSetName = sourceSetName.capitalize() - String classesCollectorTaskName = sourceSetName + "AnimalSnifferClassesCollector" - TaskProvider classesCollector = createAndroidClassesCollector(classesCollectorTaskName, libraryVariant) - TaskProvider checkTask = project.tasks - . register(CHECK_SIGNATURE + capitalizedSourceSetName, - AnimalSniffer) { - description = "Run AnimalSniffer checks for ${sourceSetName} classes" - // task operates on classes instead of sources - source = classesCollector.flatMap { it.outputDirectory } - reports.all { report -> - report.required.convention(true) - report.outputLocation.convention(project.provider { - { -> - new File(extension.reportsDir, "${sourceSetName}.${report.name}") - } as RegularFile - }) - } + def androidComponents = project.androidComponents + androidComponents.onVariants(androidComponents.selector().all(), { variant -> + String sourceSetName = variant.name + String capitalizedSourceSetName = sourceSetName.capitalize() + String classesCollectorTaskName = sourceSetName + "AnimalSnifferClassesCollector" + TaskProvider classesCollector = createAndroidClassesCollector(classesCollectorTaskName, variant) + TaskProvider checkTask = project.tasks + . register(CHECK_SIGNATURE + capitalizedSourceSetName, + AnimalSniffer) { + description = "Run AnimalSniffer checks for ${sourceSetName} classes" + // task operates on classes instead of sources + source = classesCollector.flatMap { it.outputDirectory } + reports.all { report -> + report.required.convention(true) + report.outputLocation.convention(project.provider { + { -> + new File(extension.reportsDir, "${sourceSetName}.${report.name}") + } as RegularFile + }) } + } - configureCheckTask(checkTask, - project.files(libraryVariant.sources.java.all, libraryVariant.sources.kotlin.all), - ANIMALSNIFFER_CACHE + capitalizedSourceSetName, - classesCollectorTaskName, - libraryVariant.compileClasspath) - - } + configureCheckTask(checkTask, + project.files(variant.sources.java.all, variant.sources.kotlin.all), + ANIMALSNIFFER_CACHE + capitalizedSourceSetName, + classesCollectorTaskName, + variant.compileClasspath) }) + } - private TaskProvider createAndroidClassesCollector(String taskName, LibraryVariant libraryVariant) { + @CompileStatic(TypeCheckingMode.SKIP) + private TaskProvider createAndroidClassesCollector(String taskName, Object variant) { TaskProvider collectClasses = project.tasks.register(taskName, AndroidClassesCollector) - libraryVariant.artifacts.forScope(ScopedArtifacts.Scope.PROJECT).use(collectClasses) - .toGet(ScopedArtifact.CLASSES.INSTANCE, new Function1>() { + variant.artifacts.forScope(com.android.build.api.variant.ScopedArtifacts.Scope.PROJECT).use(collectClasses) + .toGet(com.android.build.api.artifact.ScopedArtifact.CLASSES.INSTANCE, new Function1>() { @Override ListProperty invoke(AndroidClassesCollector task) { return task.jarFiles From c3f91474c023b2a2f7346d4b7a4bae2514ad33fd Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Thu, 14 Nov 2024 14:32:25 +0100 Subject: [PATCH 06/14] Updating docs --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 630e4ff..fe491e2 100644 --- a/README.md +++ b/README.md @@ -99,9 +99,7 @@ Example projects (with intentional errors to see output): #### Compatibility -**IMPORTANT**: Plugin only works when `java-base` plugin (activated by any java-related plugin like `java-library`, `groovy`, `scala`, `org.jetbrains.kotlin.jvm`, etc.) is enabled, -otherwise nothing will be registered. -There is **no support for the Android plugin** (`java-base` plugin must be used to perform animalsniffer check). +Support for the Android plugin requires Android plugin version `7.4.0` or greater. For *kotlin multiplatform* plugin enable java support: From 5a3b4c7e37eb07a7defd70b0b31d578ee3c2fac0 Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Thu, 14 Nov 2024 14:35:06 +0100 Subject: [PATCH 07/14] Reorganizing files --- .../gradle/plugin/animalsniffer/AnimalSnifferPlugin.groovy | 1 + .../animalsniffer/{ => util}/AndroidClassesCollector.groovy | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) rename src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/{ => util}/AndroidClassesCollector.groovy (94%) diff --git a/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AnimalSnifferPlugin.groovy b/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AnimalSnifferPlugin.groovy index 8b67e5b..27c17a8 100644 --- a/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AnimalSnifferPlugin.groovy +++ b/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AnimalSnifferPlugin.groovy @@ -25,6 +25,7 @@ import org.gradle.util.GradleVersion import ru.vyarus.gradle.plugin.animalsniffer.info.SignatureInfoTask import ru.vyarus.gradle.plugin.animalsniffer.signature.AnimalSnifferSignatureExtension import ru.vyarus.gradle.plugin.animalsniffer.signature.BuildSignatureTask +import ru.vyarus.gradle.plugin.animalsniffer.util.AndroidClassesCollector import ru.vyarus.gradle.plugin.animalsniffer.util.ContainFilesSpec import ru.vyarus.gradle.plugin.animalsniffer.util.ExcludeFilePatternSpec diff --git a/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AndroidClassesCollector.groovy b/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/util/AndroidClassesCollector.groovy similarity index 94% rename from src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AndroidClassesCollector.groovy rename to src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/util/AndroidClassesCollector.groovy index 7169125..9ce23e6 100644 --- a/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AndroidClassesCollector.groovy +++ b/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/util/AndroidClassesCollector.groovy @@ -1,4 +1,4 @@ -package ru.vyarus.gradle.plugin.animalsniffer +package ru.vyarus.gradle.plugin.animalsniffer.util import org.gradle.api.DefaultTask From ddb10074df849f223c150081983fc780a3ea7b34 Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Thu, 14 Nov 2024 14:43:49 +0100 Subject: [PATCH 08/14] Fixing missing symbols issue --- .../gradle/plugin/animalsniffer/AnimalSnifferPlugin.groovy | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AnimalSnifferPlugin.groovy b/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AnimalSnifferPlugin.groovy index 27c17a8..b1f6b45 100644 --- a/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AnimalSnifferPlugin.groovy +++ b/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AnimalSnifferPlugin.groovy @@ -196,8 +196,10 @@ class AnimalSnifferPlugin implements Plugin { @CompileStatic(TypeCheckingMode.SKIP) private TaskProvider createAndroidClassesCollector(String taskName, Object variant) { TaskProvider collectClasses = project.tasks.register(taskName, AndroidClassesCollector) - variant.artifacts.forScope(com.android.build.api.variant.ScopedArtifacts.Scope.PROJECT).use(collectClasses) - .toGet(com.android.build.api.artifact.ScopedArtifact.CLASSES.INSTANCE, new Function1>() { + def scopedArtifactsScopeType = Class.forName("com.android.build.api.variant.ScopedArtifacts\$Scope") + def scopedArtifactTypeClasses = Class.forName("com.android.build.api.artifact.ScopedArtifact\$CLASSES") + variant.artifacts.forScope(scopedArtifactsScopeType.PROJECT).use(collectClasses) + .toGet(scopedArtifactTypeClasses.INSTANCE, new Function1>() { @Override ListProperty invoke(AndroidClassesCollector task) { return task.jarFiles From 3c9a70f239cf56c877a5505b8a74c7e2d7461148 Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Fri, 15 Nov 2024 09:20:12 +0100 Subject: [PATCH 09/14] Adding support for android app projects --- .../gradle/plugin/animalsniffer/AnimalSnifferPlugin.groovy | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AnimalSnifferPlugin.groovy b/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AnimalSnifferPlugin.groovy index b1f6b45..6ccfa4b 100644 --- a/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AnimalSnifferPlugin.groovy +++ b/src/main/groovy/ru/vyarus/gradle/plugin/animalsniffer/AnimalSnifferPlugin.groovy @@ -74,6 +74,9 @@ class AnimalSnifferPlugin implements Plugin { project.plugins.withId("com.android.library") { registerAndroidCheckTasks() } + project.plugins.withId("com.android.application") { + registerAndroidCheckTasks() + } } private void checkGradleCompatibility() { From 6d1ffd1551b63376c2adfe758a4956e5bb63058d Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Fri, 15 Nov 2024 09:37:37 +0100 Subject: [PATCH 10/14] Adding android lib example --- examples/android-lib/build.gradle | 23 +++++++++++++++++++ .../android-lib/src/main/AndroidManifest.xml | 2 ++ .../src/main/java/invalid/Sample.java | 17 ++++++++++++++ examples/settings.gradle | 2 ++ 4 files changed, 44 insertions(+) create mode 100644 examples/android-lib/build.gradle create mode 100644 examples/android-lib/src/main/AndroidManifest.xml create mode 100644 examples/android-lib/src/main/java/invalid/Sample.java diff --git a/examples/android-lib/build.gradle b/examples/android-lib/build.gradle new file mode 100644 index 0000000..17bebf9 --- /dev/null +++ b/examples/android-lib/build.gradle @@ -0,0 +1,23 @@ +plugins { + id 'com.android.library' version '7.4.0' + id 'ru.vyarus.animalsniffer' +} + +android { + compileSdk 33 + namespace 'com.example.namespace' +} + +animalsniffer { +// debug = true + // only show errors + ignoreFailures = true +} + +repositories { mavenCentral() } +dependencies { + signature 'org.codehaus.mojo.signature:java16-sun:1.0@signature' + signature 'net.sf.androidscents.signature:android-api-level-14:4.0_r4@signature' + + implementation 'org.slf4j:slf4j-api:1.7.25' +} \ No newline at end of file diff --git a/examples/android-lib/src/main/AndroidManifest.xml b/examples/android-lib/src/main/AndroidManifest.xml new file mode 100644 index 0000000..5c3d365 --- /dev/null +++ b/examples/android-lib/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + diff --git a/examples/android-lib/src/main/java/invalid/Sample.java b/examples/android-lib/src/main/java/invalid/Sample.java new file mode 100644 index 0000000..3d0053e --- /dev/null +++ b/examples/android-lib/src/main/java/invalid/Sample.java @@ -0,0 +1,17 @@ +package invalid; + +import java.io.File; + +public class Sample { + + public static void main(String[] args) { + // method added in 1.7 + Boolean.compare(true, true); + } + + public void someth() { + // not available in android + File file = new File(""); + file.toPath(); + } +} \ No newline at end of file diff --git a/examples/settings.gradle b/examples/settings.gradle index 1eb29c2..d0c2344 100644 --- a/examples/settings.gradle +++ b/examples/settings.gradle @@ -9,6 +9,7 @@ pluginManagement { repositories { mavenLocal() gradlePluginPortal() + google() maven { url 'https://jitpack.io' } } } @@ -16,6 +17,7 @@ pluginManagement { enableFeaturePreview "STABLE_CONFIGURATION_CACHE" include 'java', 'groovy', 'kotlin', 'scala', + 'android-lib', 'buildSignature:fromClasses', 'buildSignature:fromJars', 'buildSignature:fromSignatures', From be83dd17b9ff1e163186e360b22d8fae65aef08b Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Fri, 15 Nov 2024 10:04:34 +0100 Subject: [PATCH 11/14] Adding kotlin example to android-lib --- examples/android-lib/README.md | 21 +++++++++++++++++++ examples/android-lib/build.gradle | 15 +++++++++++-- .../src/main/java/invalid/Sample.java | 4 ++-- .../src/main/java/invalid/SampleKotlin.kt | 11 ++++++++++ 4 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 examples/android-lib/README.md create mode 100644 examples/android-lib/src/main/java/invalid/SampleKotlin.kt diff --git a/examples/android-lib/README.md b/examples/android-lib/README.md new file mode 100644 index 0000000..950d03c --- /dev/null +++ b/examples/android-lib/README.md @@ -0,0 +1,21 @@ +# Java project with animalsniffer check + +Output: + +``` +> Task :android-lib:animalsnifferDebug + +4 AnimalSniffer violations were found in 2 files. See the report at: file:////{PATH_FROM_ROOT}/gradle-animalsniffer-plugin/examples/android-lib/build/reports/animalsniffer/debug.text + +[Undefined reference | java18-1.0] invalid.(Sample.java:9) + >> String String.repeat(int) + +[Undefined reference | android-api-level-21-5.0.1_r2] invalid.(Sample.java:9) + >> String String.repeat(int) + +[Undefined reference | android-api-level-21-5.0.1_r2] invalid.(Sample.java:15) + >> java.nio.file.Path java.io.File.toPath() + +[Undefined reference | android-api-level-21-5.0.1_r2] invalid.(SampleKotlin.kt:9) + >> java.nio.file.Path java.io.File.toPath() +``` \ No newline at end of file diff --git a/examples/android-lib/build.gradle b/examples/android-lib/build.gradle index 17bebf9..292987c 100644 --- a/examples/android-lib/build.gradle +++ b/examples/android-lib/build.gradle @@ -1,11 +1,22 @@ plugins { id 'com.android.library' version '7.4.0' + id 'org.jetbrains.kotlin.android' version '1.9.23' id 'ru.vyarus.animalsniffer' } android { compileSdk 33 namespace 'com.example.namespace' + def javaVersion = JavaVersion.VERSION_1_8 + + compileOptions { + sourceCompatibility(javaVersion) + targetCompatibility(javaVersion) + } + + kotlinOptions { + jvmTarget = javaVersion.toString() + } } animalsniffer { @@ -16,8 +27,8 @@ animalsniffer { repositories { mavenCentral() } dependencies { - signature 'org.codehaus.mojo.signature:java16-sun:1.0@signature' - signature 'net.sf.androidscents.signature:android-api-level-14:4.0_r4@signature' + signature 'org.codehaus.mojo.signature:java18:1.0@signature' + signature 'net.sf.androidscents.signature:android-api-level-21:5.0.1_r2@signature' implementation 'org.slf4j:slf4j-api:1.7.25' } \ No newline at end of file diff --git a/examples/android-lib/src/main/java/invalid/Sample.java b/examples/android-lib/src/main/java/invalid/Sample.java index 3d0053e..53b2068 100644 --- a/examples/android-lib/src/main/java/invalid/Sample.java +++ b/examples/android-lib/src/main/java/invalid/Sample.java @@ -5,8 +5,8 @@ public class Sample { public static void main(String[] args) { - // method added in 1.7 - Boolean.compare(true, true); + // method added in 11 + "".repeat(5); } public void someth() { diff --git a/examples/android-lib/src/main/java/invalid/SampleKotlin.kt b/examples/android-lib/src/main/java/invalid/SampleKotlin.kt new file mode 100644 index 0000000..e593537 --- /dev/null +++ b/examples/android-lib/src/main/java/invalid/SampleKotlin.kt @@ -0,0 +1,11 @@ +package invalid + +import java.io.File + +class SampleKotlin { + fun someth() { + // not available in android + val file = File("") + file.toPath() + } +} \ No newline at end of file From 2346728f1744543f03596e78e347bcaa23a30849 Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Fri, 15 Nov 2024 10:09:55 +0100 Subject: [PATCH 12/14] Adding android-app example --- examples/android-app/README.md | 21 ++++++++++++ examples/android-app/build.gradle | 34 +++++++++++++++++++ .../android-app/src/main/AndroidManifest.xml | 2 ++ .../src/main/java/invalid/Sample.java | 17 ++++++++++ .../src/main/java/invalid/SampleKotlin.kt | 11 ++++++ 5 files changed, 85 insertions(+) create mode 100644 examples/android-app/README.md create mode 100644 examples/android-app/build.gradle create mode 100644 examples/android-app/src/main/AndroidManifest.xml create mode 100644 examples/android-app/src/main/java/invalid/Sample.java create mode 100644 examples/android-app/src/main/java/invalid/SampleKotlin.kt diff --git a/examples/android-app/README.md b/examples/android-app/README.md new file mode 100644 index 0000000..bc3dd75 --- /dev/null +++ b/examples/android-app/README.md @@ -0,0 +1,21 @@ +# Java project with animalsniffer check + +Output: + +``` +> Task :android-app:animalsnifferDebug + +4 AnimalSniffer violations were found in 2 files. See the report at: file:////{PATH_FROM_ROOT}/gradle-animalsniffer-plugin/examples/android-app/build/reports/animalsniffer/debug.text + +[Undefined reference | java18-1.0] invalid.(Sample.java:9) + >> String String.repeat(int) + +[Undefined reference | android-api-level-21-5.0.1_r2] invalid.(Sample.java:9) + >> String String.repeat(int) + +[Undefined reference | android-api-level-21-5.0.1_r2] invalid.(Sample.java:15) + >> java.nio.file.Path java.io.File.toPath() + +[Undefined reference | android-api-level-21-5.0.1_r2] invalid.(SampleKotlin.kt:9) + >> java.nio.file.Path java.io.File.toPath() +``` \ No newline at end of file diff --git a/examples/android-app/build.gradle b/examples/android-app/build.gradle new file mode 100644 index 0000000..7acf440 --- /dev/null +++ b/examples/android-app/build.gradle @@ -0,0 +1,34 @@ +plugins { + id 'com.android.application' version '7.4.0' + id 'org.jetbrains.kotlin.android' version '1.9.23' + id 'ru.vyarus.animalsniffer' +} + +android { + compileSdk 33 + namespace 'com.example.namespace' + def javaVersion = JavaVersion.VERSION_1_8 + + compileOptions { + sourceCompatibility(javaVersion) + targetCompatibility(javaVersion) + } + + kotlinOptions { + jvmTarget = javaVersion.toString() + } +} + +animalsniffer { +// debug = true + // only show errors + ignoreFailures = true +} + +repositories { mavenCentral(); google() } +dependencies { + signature 'org.codehaus.mojo.signature:java18:1.0@signature' + signature 'net.sf.androidscents.signature:android-api-level-21:5.0.1_r2@signature' + + implementation 'org.slf4j:slf4j-api:1.7.25' +} \ No newline at end of file diff --git a/examples/android-app/src/main/AndroidManifest.xml b/examples/android-app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..5c3d365 --- /dev/null +++ b/examples/android-app/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + diff --git a/examples/android-app/src/main/java/invalid/Sample.java b/examples/android-app/src/main/java/invalid/Sample.java new file mode 100644 index 0000000..53b2068 --- /dev/null +++ b/examples/android-app/src/main/java/invalid/Sample.java @@ -0,0 +1,17 @@ +package invalid; + +import java.io.File; + +public class Sample { + + public static void main(String[] args) { + // method added in 11 + "".repeat(5); + } + + public void someth() { + // not available in android + File file = new File(""); + file.toPath(); + } +} \ No newline at end of file diff --git a/examples/android-app/src/main/java/invalid/SampleKotlin.kt b/examples/android-app/src/main/java/invalid/SampleKotlin.kt new file mode 100644 index 0000000..e593537 --- /dev/null +++ b/examples/android-app/src/main/java/invalid/SampleKotlin.kt @@ -0,0 +1,11 @@ +package invalid + +import java.io.File + +class SampleKotlin { + fun someth() { + // not available in android + val file = File("") + file.toPath() + } +} \ No newline at end of file From 586ad7face9219f8e71bd34892f62ad262a22a32 Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Fri, 15 Nov 2024 10:11:10 +0100 Subject: [PATCH 13/14] Updating android readmes --- examples/android-app/README.md | 2 +- examples/android-lib/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/android-app/README.md b/examples/android-app/README.md index bc3dd75..4658ed2 100644 --- a/examples/android-app/README.md +++ b/examples/android-app/README.md @@ -1,4 +1,4 @@ -# Java project with animalsniffer check +# Android library project with animalsniffer check Output: diff --git a/examples/android-lib/README.md b/examples/android-lib/README.md index 950d03c..a7b479e 100644 --- a/examples/android-lib/README.md +++ b/examples/android-lib/README.md @@ -1,4 +1,4 @@ -# Java project with animalsniffer check +# Android application project with animalsniffer check Output: From f833c1e5be4039e16575225505a7692bb034ef8e Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Fri, 15 Nov 2024 10:11:30 +0100 Subject: [PATCH 14/14] Adding modules --- examples/settings.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/settings.gradle b/examples/settings.gradle index d0c2344..652334d 100644 --- a/examples/settings.gradle +++ b/examples/settings.gradle @@ -17,7 +17,7 @@ pluginManagement { enableFeaturePreview "STABLE_CONFIGURATION_CACHE" include 'java', 'groovy', 'kotlin', 'scala', - 'android-lib', + 'android-lib', 'android-app', 'buildSignature:fromClasses', 'buildSignature:fromJars', 'buildSignature:fromSignatures',