diff options
Diffstat (limited to 'gradle/src/main/groovy/com/android/build/gradle/tasks/Lint.groovy')
-rw-r--r-- | gradle/src/main/groovy/com/android/build/gradle/tasks/Lint.groovy | 273 |
1 files changed, 149 insertions, 124 deletions
diff --git a/gradle/src/main/groovy/com/android/build/gradle/tasks/Lint.groovy b/gradle/src/main/groovy/com/android/build/gradle/tasks/Lint.groovy index 17d62cf..088ee72 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/tasks/Lint.groovy +++ b/gradle/src/main/groovy/com/android/build/gradle/tasks/Lint.groovy @@ -20,37 +20,39 @@ import com.android.annotations.NonNull import com.android.annotations.Nullable import com.android.build.gradle.BasePlugin import com.android.build.gradle.internal.LintGradleClient +import com.android.build.gradle.internal.model.ModelBuilder +import com.android.builder.model.AndroidProject +import com.android.builder.model.Variant import com.android.tools.lint.HtmlReporter import com.android.tools.lint.LintCliFlags import com.android.tools.lint.Reporter +import com.android.tools.lint.Warning import com.android.tools.lint.XmlReporter import com.android.tools.lint.checks.BuiltinIssueRegistry import com.android.tools.lint.client.api.IssueRegistry -import com.android.tools.lint.detector.api.LintUtils +import com.android.tools.lint.detector.api.Severity +import com.google.common.collect.Maps import org.gradle.api.DefaultTask import org.gradle.api.GradleException +import org.gradle.api.Project import org.gradle.api.tasks.TaskAction +import static com.android.SdkConstants.DOT_XML + public class Lint extends DefaultTask { @NonNull private BasePlugin mPlugin - @Nullable private List<File> mCustomRules @Nullable private File mConfigFile @Nullable private File mHtmlOutput @Nullable private File mXmlOutput - @Nullable private List<Collection<File>> mSourceSets - @Nullable private String mClassPath - @Nullable private List<Collection<File>> mResourceSets - private boolean mQuiet + @Nullable private String mVariantName + private boolean mQuiet = true public void setPlugin(@NonNull BasePlugin plugin) { mPlugin = plugin } - public void addCustomRule(@NonNull File jar) { - if (mCustomRules == null) { - mCustomRules = new ArrayList<File>() - } - mCustomRules.add(jar) + public void setVariantName(@NonNull String variantName) { + mVariantName = variantName } public void setQuiet() { @@ -66,95 +68,84 @@ public class Lint extends DefaultTask { } public void setXmlOutput(@NonNull File xmlOutput) { - mXmlOutput = xmlOutput; - } - - /** - * Adds all files in sourceSets as a source file for lint. - * - * @param sourceSets files to be added to sources. - */ - public void setSources(@NonNull List<Collection<File>> sourceSets) { - mSourceSets = sourceSets - } - - /** - * Adds all class files in directory specified by paths for lint. - * - * @param paths A set of paths to class files separated with path separators - */ - public void setClasspath(@NonNull String paths) { - mClassPath = paths - } - - /** - * Adds all files in resourceSets as a resource file for lint. - * - * @param resourceSets files to be added to resources. - */ - public void setLintResources(@NonNull List<Set<File>> resourceSets) { - mResourceSets = resourceSets + mXmlOutput = xmlOutput } @SuppressWarnings("GroovyUnusedDeclaration") @TaskAction public void lint() { - IssueRegistry registry = new BuiltinIssueRegistry() - LintCliFlags flags = new LintCliFlags() - LintGradleClient client = new LintGradleClient(flags, mPlugin) - - // Configure Reporters + def modelProject = createAndroidProject(mPlugin.getProject()) + if (mVariantName != null) { + lintSingleVariant(modelProject, mVariantName) + } else { + lintAllVariants(modelProject) + } + } - if (mHtmlOutput != null) { - mHtmlOutput = mHtmlOutput.getAbsoluteFile() - if (mHtmlOutput.exists()) { - boolean delete = mHtmlOutput.delete() - if (!delete) { - throw new GradleException("Could not delete old " + mHtmlOutput) - } - } - if (mHtmlOutput.getParentFile() != null && !mHtmlOutput.getParentFile().canWrite()) { - throw new GradleException("Cannot write HTML output file " + mHtmlOutput) - } + /** + * Runs lint individually on all the variants, and then compares the results + * across variants and reports these + */ + public void lintAllVariants(@NonNull AndroidProject modelProject) { + Map<Variant,List<Warning>> warningMap = Maps.newHashMap() + for (Variant variant : modelProject.getVariants()) { try { - flags.getReporters().add(new HtmlReporter(client, mHtmlOutput)) + List<Warning> warnings = runLint(modelProject, variant.getName()) + warningMap.put(variant, warnings) } catch (IOException e) { - throw new GradleException("HTML invalid argument.", e) + throw new GradleException("Invalid arguments.", e) } } - if (mXmlOutput != null) { - mXmlOutput = mXmlOutput.getAbsoluteFile() - if (mXmlOutput.exists()) { - boolean delete = mXmlOutput.delete(); - if (!delete) { - throw new GradleException("Could not delete old " + mXmlOutput) - } - } - if (mXmlOutput.getParentFile() != null && !mXmlOutput.getParentFile().canWrite()) { - throw new GradleException("Cannot write XML output file " + mXmlOutput) - } - try { - flags.getReporters().add(new XmlReporter(client, mXmlOutput)) - } catch (IOException e) { - throw new GradleException("XML invalid argument.", e) - } + // Compute error matrix + for (Map.Entry<Variant,List<Warning>> entry : warningMap.entrySet()) { + def variant = entry.getKey() + def warnings = entry.getValue() + println "Ran lint on variant " + variant.getName() + ": " + warnings.size() + + " issues found" } - List<Reporter> reporters = flags.getReporters() - if (reporters.isEmpty()) { - throw new GradleException("No reporter specified.") + List<Warning> mergedWarnings = LintGradleClient.merge(warningMap, modelProject) + int errorCount = 0 + int warningCount = 0 + for (Warning warning : mergedWarnings) { + if (warning.severity == Severity.ERROR || warning.severity == Severity.FATAL) { + errorCount++ + } else if (warning.severity == Severity.WARNING) { + warningCount++ + } } - Map<String, String> map = new HashMap<String, String>(){{ - put("", "file://") - }} - for (Reporter reporter : reporters) { - reporter.setUrlMap(map) + IssueRegistry registry = new BuiltinIssueRegistry() + LintCliFlags flags = new LintCliFlags() + LintGradleClient client = new LintGradleClient(registry, flags, mPlugin, modelProject, + null) + configureReporters(client, flags, null) + for (Reporter reporter : flags.getReporters()) { + reporter.write(errorCount, warningCount, mergedWarnings) } + } - // Flags + /** + * Runs lint on a single specified variant + */ + public void lintSingleVariant(@NonNull AndroidProject modelProject, String variantName) { + runLint(modelProject, variantName) + } + + /** Runs lint on the given variant and returns the set of warnings */ + private List<Warning> runLint( + @NonNull AndroidProject modelProject, + @NonNull String variantName) { + IssueRegistry registry = new BuiltinIssueRegistry() + LintCliFlags flags = new LintCliFlags() + LintGradleClient client = new LintGradleClient(registry, flags, mPlugin, modelProject, + variantName) + + // Configure Reporters + configureReporters(client, flags, variantName) + // Flags if (mQuiet) { flags.setQuiet(true) } @@ -162,59 +153,93 @@ public class Lint extends DefaultTask { flags.setDefaultConfiguration(client.createConfigurationFromFile(mConfigFile)) } - // Flags: sources, resources, classes + // Finally perform lint run + try { + return client.run(registry) + } catch (IOException e) { + throw new GradleException("Invalid arguments.", e) + } + } - for (Collection<File> args : mSourceSets) { - for (File input : args) { - if (input.exists()) { - List<File> sources = flags.getSourcesOverride() - if (sources == null) { - sources = new ArrayList<File>() - flags.setSourcesOverride(sources) - } - sources.add(input) - } + private void configureReporters(@NonNull LintGradleClient client, @NonNull LintCliFlags flags, + @Nullable String variantName) { + StringBuilder base = new StringBuilder() + base.append("lint-results/") + if (variantName != null) { + base.append(variantName) + base.append("/") + } + base.append("lint-results") + if (variantName != null) { + base.append("-") + base.append(variantName) + } + File htmlOutput = mHtmlOutput + File xmlOutput = mXmlOutput + if (htmlOutput == null) { + htmlOutput = project.file(base.toString() + ".html") + File parent = htmlOutput.parentFile + if (!parent.exists()) { + parent.mkdirs() } } - for (String path : LintUtils.splitPath(mClassPath)) { - File input = new File(path); - if (!input.exists()) { - throw new GradleException("Class path entry " + input + " does not exist.") - } - List<File> classes = flags.getClassesOverride(); - if (classes == null) { - classes = new ArrayList<File>(); - flags.setClassesOverride(classes); - } - classes.add(input); - } - - for (Collection<File> args : mResourceSets) { - for (File input : args) { - if (input.exists()) { - List<File> resources = flags.getResourcesOverride() - if (resources == null) { - resources = new ArrayList<File>() - flags.setResourcesOverride(resources) - } - resources.add(input) - } + if (xmlOutput == null) { + xmlOutput = project.file(base.toString() + DOT_XML) + File parent = xmlOutput.parentFile + if (!parent.exists()) { + parent.mkdirs() } } - // Client setup - - if (mCustomRules != null) { - client.setCustomRules(mCustomRules) + htmlOutput = htmlOutput.getAbsoluteFile() + if (htmlOutput.exists()) { + boolean delete = htmlOutput.delete() + if (!delete) { + throw new GradleException("Could not delete old " + htmlOutput) + } + } + if (htmlOutput.getParentFile() != null && !htmlOutput.getParentFile().canWrite()) { + throw new GradleException("Cannot write HTML output file " + htmlOutput) + } + try { + flags.getReporters().add(new HtmlReporter(client, htmlOutput)) + } catch (IOException e) { + throw new GradleException("HTML invalid argument.", e) } - // Finally perform lint run - + xmlOutput = xmlOutput.getAbsoluteFile() + if (xmlOutput.exists()) { + boolean delete = xmlOutput.delete() + if (!delete) { + throw new GradleException("Could not delete old " + xmlOutput) + } + } + if (xmlOutput.getParentFile() != null && !xmlOutput.getParentFile().canWrite()) { + throw new GradleException("Cannot write XML output file " + xmlOutput) + } try { - client.run(registry, Arrays.asList(project.projectDir)); + flags.getReporters().add(new XmlReporter(client, xmlOutput)) } catch (IOException e) { - throw new GradleException("Invalid arguments.", e) + throw new GradleException("XML invalid argument.", e) } + + List<Reporter> reporters = flags.getReporters() + if (reporters.isEmpty()) { + throw new GradleException("No reporter specified.") + } + + Map<String, String> map = new HashMap<String, String>() {{ + put("", "file://") + }} + for (Reporter reporter : reporters) { + reporter.setUrlMap(map) + } + } + + private static AndroidProject createAndroidProject(@NonNull Project gradleProject) { + String modelName = AndroidProject.class.getName() + ModelBuilder builder = new ModelBuilder() + return (AndroidProject) builder.buildAll(modelName, gradleProject) } } |