Giter Site home page Giter Site logo

novoda / gradle-static-analysis-plugin Goto Github PK

View Code? Open in Web Editor NEW
409.0 34.0 32.0 1.62 MB

Easy setup of static analysis tools for Android and Java projects.

License: Apache License 2.0

Groovy 97.53% Java 0.94% Kotlin 1.54%
gradle gradle-plugin pmd checkstyle findbugs code-quality novoda open-source detekt android-lint

gradle-static-analysis-plugin's Introduction

novoda

This repo contains information that is common to all Novoda's Open Source projects.

gradle-static-analysis-plugin's People

Contributors

adammc331 avatar ataulm avatar blundell avatar devisnik avatar eduardb avatar florianmski avatar frapontillo avatar jozefceluch avatar juankysoriano avatar lgvalle avatar mr-archano avatar ouchadam avatar pablisco avatar rock3r avatar takecare avatar tasomaniac avatar tobiasheine avatar zegnus avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gradle-static-analysis-plugin's Issues

Allow to disable Findbugs HTML reports creation

As mentioned in #74, every time we run check a GenerateFindBugsHtmlReport task is created and run.
While this is good when running the plugin on a dev machine, it's just wasting time when it's running on a CI where there are other ways to display the checks report (for example using the Pull Request Builder plugin).

It would be good to have an option to enable/disable the html report directly in the findbugs configuration closure.

More granularity for thresholds

It'd be nice if I could choose to give each analysis type specific thresholds instead of having global ones. I'd like to do something like this:

staticAnalysis {
    checkstyle {
        penalty {
            maxErrors = 0
            maxWarnings = 15
        }
    }
    pmd {
        penalty {
            maxErrors = 4
            maxWarnings = 10
        }
    }
    findbugs {
        penalty {
            maxErrors = 0
            maxWarnings = 0
        }
    }
}

This way I would have more granularity on what needs fixing and what's ok.

Thoughts?

Technical Data Questionnaire Wiki Page

Problem

We want to show our reasoning as to why someone would want to use this particular library and the challenges we have faced with each release. To this end, we have created a Technical Data Questionnaire. This Questionnaire is cloned from novoda/novoda.

Solution

Here's a template, created from the Gradle Build Properties Plugin, that can be used to create a Data Questionnaire for this repository. The Data Questionnaire should be added to this Repository's Wiki Section.

Template

Overview of the project. What are its technical capabilities compared to the industry standard?

Development of a plugin system for open source applications that require private keys and configs to be ran but these should not be shared in public locations. for example an analytics library that needs a key to login to the system but not all people should access to this key. The project focuses on making the possibility of adding private information as seamless as possible, so that the projects can be used simply but not expose information. This offers features not available currently on the market and although other variations of this technique are possible they do not make the solution quite as easy.

What platforms and tools did you use to make it? (encouraged to namedrop components/languages/databases etc)

Groovy, Gradle for development, Guava, Truth and Findbugs for testing

Describe, in detail, the technical challenges faced (specifically what development required more than routine techniques) and what was engineered to overcome them?

It is really important to discuss the iterative journey to explain at each stage of production (each release) what was engineered.

Write this as if you are explaining the challenges to a technical colleague.

Attempt to write at least four paragraphs that cover these points:

  • Technical advances
  • How uncertainties were overcome
  • Any iterative approaches
  • Final solution

Currently to solve the problem of not sharing private keys, developers would cut and paste when they were needed for production and a lot of human interaction was needed to keep these keys private, but still useful. Many repositories would require five or more keys, therefore it required coordination with the build system to make sure each was put in the right place and used at the right time. The gradle build properties plugin automates all of this and allows you to drop in one file, that is read by the gradle system and pulls out the properties or keys and puts them in the right place. This is a technical advancement on any of the current solutions as before it was not centralised or automated meaning keys where in many different places and the chance for security issues was high. With this centralised solution it can allow us to keep all the keys in a secure place and use security credential to access them at the time needed.

A big uncertainty was our knowledge around connecting a remote secure location for the keys to the build system that would be using them. We did not know if we could access or communicate with a secure system in a timely fashion that would allow for the normal build process. This uncertainty was overcome through investigating distribution systems based on maven repositories. With this investigation it was found two way secure communication could happen and therefore we could separate the private keys from the public repository.

When injecting the private keys into a gradle build it has to be done at the correct step. With the creation of this plugin we were unsure in our knowledge of gradle plugins and where we would hook into the build system. This problem was overcome with the development approach of investigating other gradle plugins, this lead us to the Android plugin that also hooks in for other reasons, and we adapted and expanded on this knowledge to allow our key injection to work.

The first approach was to load from a local properties file, take the keys from a separate file, this split apart building and key loading. The second was being able to override at runtime any errors, therefore giving fallback strategies if keys were not available. For example if the properties file was missing a private key, the key could also be set as a system property and we could now fallback from one to the other in a recursive fashion. We then added other fallbacks for secondary files, command line and hard coded values. We then iterated again to allow for the fallback file to be a remote file and take security credentials to open or load it.

The final solution now allows for developers to create open source repositories that use private keys without them needing to be public. The integration is as simple as defining a file, that is not checked into version control but can be in one of multiple places, and then providing fallback strategies if this secure file is not there, for example providing fallback debug keys that can be public and checked into the repository. This simplified any developers use of private keys in a public or private repositories and will likely lead to a decrease in their time spent in this area by a factor of 10x.

Use file output to store violations per-tool

Right now the plugin stores the violations in an in-memory NamedDomainObjectContainer holding an instance of Violations for each of the tool configured. Ideally each tool would instead produce an (xml?) report that can be used as input of the EvaluateViolationsTask. This would also help with the incremental builds, as an input/output file plays nicer with Gradle architecture.

"Global" exclude filters

How hard would it be to have the exclude filters apply to all configurations?

Example:

staticAnalysis {
    penalty {
        maxErrors = 0
        maxWarnings = 10
    }
    checkstyle {
        configFile project.file('path/to/modules.xml')
    }
    pmd {
        ruleSetFiles project.files('path/to/rules.xml')
    }
    findbugs {
        excludeFilter project.file('path/to/exclude.xml')
    }
    all {
        exclude project.fileTree('src/test/java')
    }
}

Having the same practical effect as having exclude project.fileTree('src/test/java') in each configuration.

How do I enable HTML reports for FindBugs?

I tried the following to no avail:

staticAnalysis {
  findbugs {
    reports {
      xml.enabled false
      html.enabled true
    }
  }
}

and

tasks.withType(FindBugs) {
  reports {
    xml.enabled false
    html.enabled true
  }
}

Up-to-date checks for tasks

I have been using the plugin more and more in a big multi-module codebase. Some tasks have proper up-to-date checks but some not.

I can come up with a list with more details but from what I observe, ktlint and checkstyle has up-to-date support on task level. lint, findbugs and detekt do not. I'm not sure about PMD

Having proper up-to-date support will drastically improve multi-module evaluateViolations task speed.

Opening this issue to track this behavior and ask your opinion.

Trying to configure `lintOptions` twice fails

Problem

In bigger projects, it is common practice to let other gradle files setup such configurations. This means that the common configuration around lintOptions would be applied not in the build.gradle but somewhere else.

But still individual lintOptions configurations can have additional configuration. Even though this should be done very careful, it may be needed for bigger projects.

When lintOptions is used within static-analysis plugin, we try to create and configure tasks 2 times. And build fails because the tasks already exist.

Suggested Fix:

To overcome this, we can check if task exists first, or we can use maybeCreate

Make violations evaluation configurable

The evaluation of the violations at the moment is brought by the EvaluateViolationsTask but doesn't allow to do anything else but breaking the build and logging the outcome of the evaluation. We have already faced the need of being able to plug-in a different type of reporting for instance, but the current architecture is not particularly friendly in that regard.

Sample project

Hi all,

thanks for the plugin. I think we can really take advantage of it. For an easier usage, a complete example with all configs would be nice ;)

Noisy logging

Running ./gradlew evaulateViolations produces lots of unnecessary logs, is it possible to turn them off?

Scanning archives (0 / 221)
Scanning archives (1 / 221)
Scanning archives (2 / 221)
Scanning archives (3 / 221)
Scanning archives (4 / 221)
Scanning archives (5 / 221)
Scanning archives (6 / 221)
Scanning archives (7 / 221)
Scanning archives (8 / 221)
Scanning archives (9 / 221)
Scanning archives (10 / 221)
...

Pass 1: Analyzing classes (0 / 520) - 00% complete
Pass 1: Analyzing classes (1 / 520) - 00% complete
Pass 1: Analyzing classes (2 / 520) - 00% complete
Pass 1: Analyzing classes (3 / 520) - 00% complete
Pass 1: Analyzing classes (4 / 520) - 00% complete
Pass 1: Analyzing classes (5 / 520) - 00% complete
Pass 1: Analyzing classes (6 / 520) - 01% complete
Pass 1: Analyzing classes (7 / 520) - 01% complete
Pass 1: Analyzing classes (8 / 520) - 01% complete
Pass 1: Analyzing classes (9 / 520) - 01% complete
...

Update default tools versions to latest

Currently we default to Checkstyle 7.1.2 and PMD 5.5.1, which are quite old (from September and July 2016, respectively). At the time of writing, Checkstyle is at version 8.8 and PMD at 6.0.1.

Unable to evaluate project with latest version of detekt (1.0.0.RC9)

See #131 (comment) for the correct stacktrace.


When trying to use the gradle-static-analysis-plugin with the latest version of detekt (1.0.0.RC9), I'm getting this error at the project evaluation stage:

 โ–ฒ  xrigau@xrigau-mbp ~/d/pet-project  $ ./gradlew --stacktrace
Parallel execution is an incubating feature.

> Configure project :app 

Project evaluation failed including an error in afterEvaluate {}.
java.lang.IllegalStateException: compileSdkVersion is not specified.
        at com.google.common.base.Preconditions.checkState(Preconditions.java:456)
        at com.android.build.gradle.BasePlugin.createAndroidTasks(BasePlugin.java:590)
        at com.android.build.gradle.BasePlugin.lambda$null$3(BasePlugin.java:555)
        at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:81)
        at com.android.build.gradle.BasePlugin.lambda$createTasks$4(BasePlugin.java:551)
        at org.gradle.internal.event.BroadcastDispatch$ActionInvocationHandler.dispatch(BroadcastDispatch.java:91)
        at org.gradle.internal.event.BroadcastDispatch$ActionInvocationHandler.dispatch(BroadcastDispatch.java:80)
        at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:42)
        at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:230)
        at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:149)
        at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:58)
        at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:324)
        at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:234)
        at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:140)
        at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:37)
        at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
        at com.sun.proxy.$Proxy24.afterEvaluate(Unknown Source)
        at org.gradle.configuration.project.LifecycleProjectEvaluator.notifyAfterEvaluate(LifecycleProjectEvaluator.java:76)
        at org.gradle.configuration.project.LifecycleProjectEvaluator.doConfigure(LifecycleProjectEvaluator.java:70)
        at org.gradle.configuration.project.LifecycleProjectEvaluator.access$100(LifecycleProjectEvaluator.java:34)
        at org.gradle.configuration.project.LifecycleProjectEvaluator$ConfigureProject.run(LifecycleProjectEvaluator.java:110)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:110)
        at org.gradle.configuration.project.LifecycleProjectEvaluator.evaluate(LifecycleProjectEvaluator.java:50)
        at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:667)
        at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:136)
        at org.gradle.execution.TaskPathProjectEvaluator.configure(TaskPathProjectEvaluator.java:35)
        at org.gradle.execution.TaskPathProjectEvaluator.configureHierarchy(TaskPathProjectEvaluator.java:62)
        at org.gradle.configuration.DefaultBuildConfigurer.configure(DefaultBuildConfigurer.java:38)
        at org.gradle.initialization.DefaultGradleLauncher$ConfigureBuild.run(DefaultGradleLauncher.java:249)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:110)
        at org.gradle.initialization.DefaultGradleLauncher.configureBuild(DefaultGradleLauncher.java:167)
        at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:126)
        at org.gradle.initialization.DefaultGradleLauncher.executeTasks(DefaultGradleLauncher.java:109)
        at org.gradle.internal.invocation.GradleBuildController$1.call(GradleBuildController.java:78)
        at org.gradle.internal.invocation.GradleBuildController$1.call(GradleBuildController.java:75)
        at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:152)
        at org.gradle.internal.invocation.GradleBuildController.doBuild(GradleBuildController.java:100)
        at org.gradle.internal.invocation.GradleBuildController.run(GradleBuildController.java:75)
        at org.gradle.tooling.internal.provider.ExecuteBuildActionRunner.run(ExecuteBuildActionRunner.java:28)
        at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
        at org.gradle.tooling.internal.provider.ValidatingBuildActionRunner.run(ValidatingBuildActionRunner.java:32)
        at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$1.run(RunAsBuildOperationBuildActionRunner.java:43)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:110)
        at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner.run(RunAsBuildOperationBuildActionRunner.java:40)
        at org.gradle.tooling.internal.provider.SubscribableBuildActionRunner.run(SubscribableBuildActionRunner.java:51)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:49)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:32)
        at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:39)
        at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:25)
        at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:80)
        at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:53)
        at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:57)
        at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:32)
        at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:36)
        at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:25)
        at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:43)
        at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:29)
        at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:64)
        at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:29)
        at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:59)
        at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:44)
        at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:45)
        at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:30)
        at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:67)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:37)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:26)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:34)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:74)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:72)
        at org.gradle.util.Swapper.swap(Swapper.java:38)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:72)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:55)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:62)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:82)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:50)
        at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:295)
        at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
        at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
        at java.lang.Thread.run(Thread.java:748)


FAILURE: Build failed with an exception.

* Where:
Script '/Users/xrigau/development/pet-project/gradle/static-analysis.gradle' line: 2

* What went wrong:
A problem occurred evaluating script.
> org.gradle.api.tasks.TaskContainer.register(Ljava/lang/String;Ljava/lang/Class;Lorg/gradle/api/Action;)Lorg/gradle/api/tasks/TaskProvider;

* Try:
Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Exception is:
org.gradle.api.GradleScriptException: A problem occurred evaluating script.
        at org.gradle.groovy.scripts.internal.DefaultScriptRunnerFactory$ScriptRunnerImpl.run(DefaultScriptRunnerFactory.java:92)
        at org.gradle.configuration.DefaultScriptPluginFactory$ScriptPluginImpl$2.run(DefaultScriptPluginFactory.java:204)
        at org.gradle.configuration.DefaultScriptTarget.addConfiguration(DefaultScriptTarget.java:74)
        at org.gradle.configuration.DefaultScriptPluginFactory$ScriptPluginImpl.apply(DefaultScriptPluginFactory.java:209)
        at org.gradle.configuration.BuildOperationScriptPlugin$1.run(BuildOperationScriptPlugin.java:61)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:110)
        at org.gradle.configuration.BuildOperationScriptPlugin.apply(BuildOperationScriptPlugin.java:58)
        at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction.applyScript(DefaultObjectConfigurationAction.java:109)
        at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction.access$000(DefaultObjectConfigurationAction.java:38)
        at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction$1.run(DefaultObjectConfigurationAction.java:68)
        at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction.execute(DefaultObjectConfigurationAction.java:143)
        at org.gradle.api.internal.project.AbstractPluginAware.apply(AbstractPluginAware.java:46)
        at org.gradle.api.internal.project.ProjectScript.apply(ProjectScript.java:34)
        at org.gradle.api.Script$apply.callCurrent(Unknown Source)
        at build_8npc8zy817oppb2dze4og81lc.run(/Users/xrigau/development/pet-project/app/build.gradle:66)
        at org.gradle.groovy.scripts.internal.DefaultScriptRunnerFactory$ScriptRunnerImpl.run(DefaultScriptRunnerFactory.java:90)
        at org.gradle.configuration.DefaultScriptPluginFactory$ScriptPluginImpl$2.run(DefaultScriptPluginFactory.java:204)
        at org.gradle.configuration.ProjectScriptTarget.addConfiguration(ProjectScriptTarget.java:77)
        at org.gradle.configuration.DefaultScriptPluginFactory$ScriptPluginImpl.apply(DefaultScriptPluginFactory.java:209)
        at org.gradle.configuration.BuildOperationScriptPlugin$1.run(BuildOperationScriptPlugin.java:61)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:110)
        at org.gradle.configuration.BuildOperationScriptPlugin.apply(BuildOperationScriptPlugin.java:58)
        at org.gradle.configuration.project.BuildScriptProcessor.execute(BuildScriptProcessor.java:41)
        at org.gradle.configuration.project.BuildScriptProcessor.execute(BuildScriptProcessor.java:26)
        at org.gradle.configuration.project.ConfigureActionsProjectEvaluator.evaluate(ConfigureActionsProjectEvaluator.java:34)
        at org.gradle.configuration.project.LifecycleProjectEvaluator.doConfigure(LifecycleProjectEvaluator.java:64)
        at org.gradle.configuration.project.LifecycleProjectEvaluator.access$100(LifecycleProjectEvaluator.java:34)
        at org.gradle.configuration.project.LifecycleProjectEvaluator$ConfigureProject.run(LifecycleProjectEvaluator.java:110)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:110)
        at org.gradle.configuration.project.LifecycleProjectEvaluator.evaluate(LifecycleProjectEvaluator.java:50)
        at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:667)
        at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:136)
        at org.gradle.execution.TaskPathProjectEvaluator.configure(TaskPathProjectEvaluator.java:35)
        at org.gradle.execution.TaskPathProjectEvaluator.configureHierarchy(TaskPathProjectEvaluator.java:62)
        at org.gradle.configuration.DefaultBuildConfigurer.configure(DefaultBuildConfigurer.java:38)
        at org.gradle.initialization.DefaultGradleLauncher$ConfigureBuild.run(DefaultGradleLauncher.java:249)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:110)
        at org.gradle.initialization.DefaultGradleLauncher.configureBuild(DefaultGradleLauncher.java:167)
        at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:126)
        at org.gradle.initialization.DefaultGradleLauncher.executeTasks(DefaultGradleLauncher.java:109)
        at org.gradle.internal.invocation.GradleBuildController$1.call(GradleBuildController.java:78)
        at org.gradle.internal.invocation.GradleBuildController$1.call(GradleBuildController.java:75)
        at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:152)
        at org.gradle.internal.invocation.GradleBuildController.doBuild(GradleBuildController.java:100)
        at org.gradle.internal.invocation.GradleBuildController.run(GradleBuildController.java:75)
        at org.gradle.tooling.internal.provider.ExecuteBuildActionRunner.run(ExecuteBuildActionRunner.java:28)
        at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
        at org.gradle.tooling.internal.provider.ValidatingBuildActionRunner.run(ValidatingBuildActionRunner.java:32)
        at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$1.run(RunAsBuildOperationBuildActionRunner.java:43)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:110)
        at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner.run(RunAsBuildOperationBuildActionRunner.java:40)
        at org.gradle.tooling.internal.provider.SubscribableBuildActionRunner.run(SubscribableBuildActionRunner.java:51)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:49)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:32)
        at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:39)
        at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:25)
        at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:80)
        at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:53)
        at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:57)
        at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:32)
        at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:36)
        at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:25)
        at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:43)
        at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:29)
        at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:64)
        at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:29)
        at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:59)
        at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:44)
        at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:45)
        at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:30)
        at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:67)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:37)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:26)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:34)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:74)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:72)
        at org.gradle.util.Swapper.swap(Swapper.java:38)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:72)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:55)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:62)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:82)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:50)
        at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:295)
        at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
        at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
        at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
Caused by: java.lang.NoSuchMethodError: org.gradle.api.tasks.TaskContainer.register(Ljava/lang/String;Ljava/lang/Class;Lorg/gradle/api/Action;)Lorg/gradle/api/tasks/TaskProvider;
        at io.gitlab.arturbosch.detekt.DetektPlugin.createAndConfigureDetektTask(DetektPlugin.kt:29)
        at io.gitlab.arturbosch.detekt.DetektPlugin.apply(DetektPlugin.kt:21)
        at io.gitlab.arturbosch.detekt.DetektPlugin.apply(DetektPlugin.kt:12)
        at org.gradle.api.internal.plugins.ImperativeOnlyPluginTarget.applyImperative(ImperativeOnlyPluginTarget.java:42)
        at org.gradle.api.internal.plugins.RuleBasedPluginTarget.applyImperative(RuleBasedPluginTarget.java:50)
        at org.gradle.api.internal.plugins.DefaultPluginManager.addPlugin(DefaultPluginManager.java:164)
        at org.gradle.api.internal.plugins.DefaultPluginManager.access$200(DefaultPluginManager.java:47)
        at org.gradle.api.internal.plugins.DefaultPluginManager$AddPluginBuildOperation.run(DefaultPluginManager.java:252)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:110)
        at org.gradle.api.internal.plugins.DefaultPluginManager.doApply(DefaultPluginManager.java:144)
        at org.gradle.api.internal.plugins.DefaultPluginManager.apply(DefaultPluginManager.java:125)
        at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction.applyType(DefaultObjectConfigurationAction.java:120)
        at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction.access$200(DefaultObjectConfigurationAction.java:38)
        at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction$3.run(DefaultObjectConfigurationAction.java:86)
        at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction.execute(DefaultObjectConfigurationAction.java:143)
        at org.gradle.groovy.scripts.DefaultScript.apply(DefaultScript.java:128)
        at org.gradle.api.Script$apply.callCurrent(Unknown Source)
        at static_analysis_703euohp5bpp852g9bj4garzs.run(/Users/xrigau/development/pet-project/gradle/static-analysis.gradle:2)
        at org.gradle.groovy.scripts.internal.DefaultScriptRunnerFactory$ScriptRunnerImpl.run(DefaultScriptRunnerFactory.java:90)
        ... 111 more

I guess the compileSdkVersion is not specified error is just a side-effect of the main error (since the compileSdkVersion is being set in the android configuration).

The fallback solution for now is to revert back to the previous version of detekt (1.0.0.RC8).

New option: "failFast"

When running multiple tools evaluateViolations run all configured tools and output the result at the end.

A new failFast option could stop the build just after a configured tool has done its job and has errors.

[Request] Configure web base URL for CI results

I'm basing this feature request on my previous experience and the output shown in the Readme. It may be this is already obsolete.

When running static analyses the output always refers to local file URLs for reports which is fine on a local machine but unusable for CI logs.
Since it's hard(er) to guess the environment the CI job runs in I propose the easier solution of adding a configuration value to use as a base URL to access the reports via browser on a remote machine.

includeVariants support for Android Lint setup

In the newly added Android Lint feature, we just run lint which runs lint against the whole project with all variants. This also needs a compilation of all variants because lint runs on the compiled code, not on the source.

For this reason, lint can take really too much time.

Suggestion: Add support for includeVariants to just run on certain variants.

And also we can consider supporting includeVariants on upper level to be used on all tools.

Show total count of issues found

Every time I go on a boyscout mission and fix some static analysis issues I end up with the number of issues for each analysis type, but I have to configure a threshold for the total number of issues:

> Checkstyle rule violations were found (58 errors, 43 warnings). See the reports at:
- file:///Users/xrigau/development/git/novoda/some-cool-project/app/build/reports/checkstyle/main.html
> Findbugs rule violations were found (9 errors, 6 warnings). See the reports at:
- file:///Users/xrigau/development/git/novoda/some-cool-project/app/build/reports/findbugs/coolprojectStaging.html
> PMD rule violations were found (11 errors, 13 warnings). See the reports at:
- file:///Users/xrigau/development/git/novoda/some-cool-project/app/build/reports/pmd/main.html

It'd be a lot easier if it printed a line such as:

Total: 78 errors, 62 warnings

So that I can update the thresholds after every boyscoutting more easily.

This wouldn't be needed if #18 was implemented

Use a secrets file for master builds

publish.gradle on develop has been modified to use bintray credentials from the environment.

When we merge develop into master, we will need to modify the build job for master to use the maven.properties file to ensure we are using the right credentials

Address warnings from validateTaskProperties task

> Task :plugin:validateTaskProperties 
Task property validation finished with warnings:
  - Warning: Task type 'com.novoda.staticanalysis.EvaluateViolationsTask': property 'reportUrlRenderer' is not annotated with an input or output annotation.
  - Warning: Task type 'com.novoda.staticanalysis.internal.checkstyle.CollectCheckstyleViolationsTask': property 'htmlReportFile' is not annotated with an input or output annotation.
  - Warning: Task type 'com.novoda.staticanalysis.internal.checkstyle.CollectCheckstyleViolationsTask': property 'xmlReportFile' is not annotated with an input or output annotation.
  - Warning: Task type 'com.novoda.staticanalysis.internal.findbugs.CollectFindbugsViolationsTask': property 'htmlReportFile' is not annotated with an input or output annotation.
  - Warning: Task type 'com.novoda.staticanalysis.internal.findbugs.CollectFindbugsViolationsTask': property 'xmlReportFile' is not annotated with an input or output annotation.
  - Warning: Task type 'com.novoda.staticanalysis.internal.findbugs.GenerateFindBugsHtmlReport': property 'htmlReportFile' is not annotated with an input or output annotation.
  - Warning: Task type 'com.novoda.staticanalysis.internal.findbugs.GenerateFindBugsHtmlReport': property 'xmlReportFile' is not annotated with an input or output annotation.
  - Warning: Task type 'com.novoda.staticanalysis.internal.findbugs.QuietFindbugsPlugin$Task': property 'logger' is not annotated with an input or output annotation.
  - Warning: Task type 'com.novoda.staticanalysis.internal.pmd.CollectPmdViolationsTask': property 'htmlReportFile' is not annotated with an input or output annotation.
  - Warning: Task type 'com.novoda.staticanalysis.internal.pmd.CollectPmdViolationsTask': property 'xmlReportFile' is not annotated with an input or output annotation.

Detekt configuration fails with RC6-4

Breaking changes with detekt/detekt#719. systemOrDefaultProfile() is no longer available.

* Where:
Script '.../gradle-static-analysis-plugin/sample-multi-module/team-props/static-analysis.gradle' line: 36

* What went wrong:
A problem occurred evaluating script.
> Could not find method systemOrDefaultProfile() for arguments [] on DetektExtension(version='latest.release', debug=false, profile='main', ideaExtension=IdeaExtension(path=null, codeStyleScheme=null, inspectionsProfile=null, report=null, mask='*.kt'), profiles=[ProfileExtension(name='main', input=.../gradle-static-analysis-plugin/sample-multi-module/app/src/main/java, config=.../gradle-static-analysis-plugin/sample-multi-module/team-props/detekt-config.yml, configResource=/default-detekt-config.yml, filters=.*test.*,.*/resources/.*,.*/tmp/.*, ruleSets=null, output=.../gradle-static-analysis-plugin/sample-multi-module/app/build/reports/detekt, outputName=null, baseline=null, parallel=false, disableDefaultRuleSets=false)]) of type io.gitlab.arturbosch.detekt.extensions.DetektExtension.

Gradle 4.4 deprecation

Currently this plugin produces this error on Gradle 4.4:

Gradle now uses separate output directories for each JVM language, but this build assumes a single directory for all classes from a source set. This behaviour has been deprecated and is scheduled to be removed in Gradle 5.0
	at org.gradle.api.internal.tasks.DefaultSourceSetOutput.getClassesDir(DefaultSourceSetOutput.java:80)
	at org.gradle.api.internal.tasks.DefaultSourceSetOutput_Decorated.getClassesDir(Unknown Source)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
	at org.codehaus.groovy.runtime.metaclass.MultipleSetterProperty.getProperty(MultipleSetterProperty.java:49)
	at org.gradle.internal.metaobject.BeanDynamicObject$MetaClassAdapter.getProperty(BeanDynamicObject.java:228)
	at org.gradle.internal.metaobject.BeanDynamicObject.tryGetProperty(BeanDynamicObject.java:171)
	at org.gradle.internal.metaobject.CompositeDynamicObject.tryGetProperty(CompositeDynamicObject.java:55)
	at org.gradle.internal.metaobject.AbstractDynamicObject.getProperty(AbstractDynamicObject.java:59)
	at org.gradle.api.internal.tasks.DefaultSourceSetOutput_Decorated.getProperty(Unknown Source)
	at org.codehaus.groovy.runtime.callsite.PogoGetPropertySite.getProperty(PogoGetPropertySite.java:50)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGetProperty(AbstractCallSite.java:296)
	at com.novoda.staticanalysis.internal.findbugs.FindbugsConfigurator.createClassesTreeFrom(FindbugsConfigurator.groovy:117)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoCachedMethodSiteNoUnwrapNoCoerce.invoke(PogoMetaMethodSite.java:210)
	at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.callCurrent(PogoMetaMethodSite.java:59)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:166)
	at com.novoda.staticanalysis.internal.findbugs.FindbugsConfigurator.getJavaClasses(FindbugsConfigurator.groovy:109)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
	at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:384)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
	at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:69)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:174)
	at com.novoda.staticanalysis.internal.findbugs.FindbugsConfigurator$_configureJavaProject_closure2$_closure14.doCall(FindbugsConfigurator.groovy:86)
	at com.novoda.staticanalysis.internal.findbugs.FindbugsConfigurator$_configureJavaProject_closure2$_closure14.doCall(FindbugsConfigurator.groovy)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
	at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
	at groovy.lang.Closure.call(Closure.java:414)
	at groovy.lang.Closure.call(Closure.java:408)
	at org.gradle.util.GUtil.uncheckedCall(GUtil.java:436)
	at org.gradle.api.internal.ConventionAwareHelper$2.getValue(ConventionAwareHelper.java:87)
	at org.gradle.api.internal.ConventionAwareHelper$MappedPropertyImpl.getValue(ConventionAwareHelper.java:136)
	at org.gradle.api.internal.ConventionAwareHelper.getConventionValue(ConventionAwareHelper.java:114)
	at com.novoda.staticanalysis.internal.findbugs.QuietFindbugsPlugin$Task_Decorated.getClasses(Unknown Source)
	at org.gradle.api.plugins.quality.FindBugs.generateSpec(FindBugs.java:250)
	at org.gradle.api.plugins.quality.FindBugs.run(FindBugs.java:238)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:73)
	at org.gradle.api.internal.project.taskfactory.StandardTaskAction.doExecute(StandardTaskAction.java:46)
	at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:39)
	at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:26)
	at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:780)
	at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:747)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$1.run(ExecuteActionsTaskExecuter.java:121)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:110)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:110)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:92)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:70)
	at org.gradle.api.internal.tasks.execution.OutputDirectoryCreatingTaskExecuter.execute(OutputDirectoryCreatingTaskExecuter.java:51)
	at org.gradle.api.internal.tasks.execution.SkipCachedTaskExecuter.execute(SkipCachedTaskExecuter.java:108)
	at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:62)
	at org.gradle.api.internal.tasks.execution.ResolveTaskOutputCachingStateExecuter.execute(ResolveTaskOutputCachingStateExecuter.java:54)
	at org.gradle.api.internal.tasks.execution.ResolveBuildCacheKeyExecuter.execute(ResolveBuildCacheKeyExecuter.java:61)
	at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:60)
	at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:97)
	at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:87)
	at org.gradle.api.internal.tasks.execution.ResolveTaskArtifactStateTaskExecuter.execute(ResolveTaskArtifactStateTaskExecuter.java:52)
	at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52)
	at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:54)
	at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
	at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:34)
	at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker$1.run(DefaultTaskGraphExecuter.java:248)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:110)
	at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:241)
	at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:230)
	at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.processTask(DefaultTaskPlanExecutor.java:123)
	at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.access$200(DefaultTaskPlanExecutor.java:79)
	at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:104)
	at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:98)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionPlan.execute(DefaultTaskExecutionPlan.java:626)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionPlan.executeWithTask(DefaultTaskExecutionPlan.java:581)
	at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.run(DefaultTaskPlanExecutor.java:98)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
	at java.lang.Thread.run(Thread.java:745)

Findbugs HTML report not generated

With a standard project set up, when I run gradlew check, if the build fails due to static analysis issues it prints the following lines:

> Violations limit exceeded by 0 errors, 1 warnings.
  
  > Checkstyle rule violations were found (461 errors, 54 warnings). See the reports at:
  - file:///Users/xrigau/Desktop/fooproject/app/build/reports/checkstyle/main.html
  > Findbugs rule violations were found (10 errors, 50 warnings). See the reports at:
  - file:///Users/xrigau/Desktop/fooproject/app/build/reports/findbugs/fooprojectDebug.html
  > PMD rule violations were found (126 errors, 587 warnings). See the reports at:
  - file:///Users/xrigau/Desktop/fooproject/app/build/reports/pmd/main.html

But actually the fooprojectDebug.html file doesn't exist and only an XML file is created:

screen shot 2017-02-15 at 3 57 46 pm

Exclude kotlin files for Checkstyle, PMD and Findbugs

As mentioned by @rock3r we don't want to run the built-in static analysis tools (Checkstyle, PMD, FindBugs) on Kotlin files as we have dedicated tools for them.
To streamline the usage of the plugin we could just add default exclude rules to each of the tools above.

Multiple different ' ktlint' plugin references

I'm was going through the project documentation and code to setup a new ktlint integration and I found three different references to ktlint plugins:

Which one is the recommended one?
I believe only the first one is supported since is the one the configurator expects. If that the case we should ammend the documentation.

Execution failed for task ':kepler:findbugsDebug'.

FAILURE: Build failed with an exception.

  • What went wrong:
    Execution failed for task ':kepler:findbugsDebug'.

Failed to run Gradle FindBugs Worker
[Ljavax/annotation/meta/When;

  • Try:
    Run with --info or --debug option to get more log output.

  • Exception is:
    org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':kepler:findbugsDebug'.
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:69)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:46)
    at org.gradle.api.internal.tasks.execution.PostExecutionAnalysisTaskExecuter.execute(PostExecutionAnalysisTaskExecuter.java:35)
    at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:66)
    at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58)
    at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:52)
    at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52)
    at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:53)
    at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
    at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:203)
    at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:185)
    at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.processTask(AbstractTaskPlanExecutor.java:66)
    at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.run(AbstractTaskPlanExecutor.java:50)
    at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:54)
    at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:40)
    Caused by: org.gradle.process.internal.worker.WorkerProcessException: Failed to run Gradle FindBugs Worker
    at org.gradle.process.internal.worker.WorkerProcessException.runFailed(WorkerProcessException.java:29)
    at org.gradle.process.internal.worker.request.Receiver.infrastructureFailed(Receiver.java:82)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$BoundedDispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:128)
    at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$BoundedDispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:112)
    at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:377)
    ... 2 more
    Caused by: java.lang.NoClassDefFoundError: [Ljavax/annotation/meta/When;
    at edu.umd.cs.findbugs.ba.jsr305.TypeQualifierAnnotation.(TypeQualifierAnnotation.java:95)
    at edu.umd.cs.findbugs.FindBugs2.clearCaches(FindBugs2.java:318)
    at edu.umd.cs.findbugs.FindBugs2.execute(FindBugs2.java:301)
    at org.gradle.api.plugins.quality.internal.findbugs.FindBugsExecuter.runFindbugs(FindBugsExecuter.java:39)
    at org.gradle.process.internal.worker.request.WorkerAction.run(WorkerAction.java:87)
    at org.gradle.process.internal.worker.request.WorkerAction.runThenStop(WorkerAction.java:71)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    ... 3 more
    Caused by: java.lang.ClassNotFoundException: javax.annotation.meta.When
    ... 11 more

BUILD FAILED

KtLintConfigurator fails to find tasks

Just tried to integrate it into our project. Unfortunately SAP is failing to resolve the ktlint tasks even thought tasks are actually present. I think it is a timing issue.

Caused by: org.gradle.api.UnknownTaskException: Task with name 'ktlintWayfairTangoDisabledDebugAndroidTestCheck' not found in project ':app'.
        at org.gradle.api.internal.tasks.DefaultTaskCollection.createNotFoundException(DefaultTaskCollection.java:88)
        at org.gradle.api.internal.tasks.DefaultTaskCollection.createNotFoundException(DefaultTaskCollection.java:39)
        at org.gradle.api.internal.DefaultNamedDomainObjectCollection.getByName(DefaultNamedDomainObjectCollection.java:320)
        at org.gradle.api.internal.DefaultNamedDomainObjectCollection.getAt(DefaultNamedDomainObjectCollection.java:339)
        at org.gradle.api.internal.tasks.DefaultTaskCollection.getAt(DefaultTaskCollection.java:39)
        at com.novoda.staticanalysis.internal.ktlint.KtlintConfigurator$_createCollectViolationsTask_closure6.doCall(KtlintConfigurator.groovy:94)

Make evaluateViolations task run for specific buildVariant

When running evaluateViolations in a project with multiple buildFlavors. The task compile all the buildVariants even if we're running the build for a specific buildVariant. Because of this behavior it's increases the time it's take for all the checks to run even on small projects.

Add support for Android Lint

The aim would be to have all the static analysis covered by this plugin in one go (obviously this only applies to Android modules)

Running tasks from command line

When building the project the only static analysis tool check is detekt even when verifying the list of tasks available I don't see findbugs,pmd,checkstyle tasks . Is there's any way to run all the checks ?

Lazy evaluate exclude filters

At the moment the exclude filter does not support any lazy evaluation so values are evaluated at configuration time. Ideally SourceFilter would be amended to add support to closures.

[RFC] Static analysis tools: Opting-in vs Opting-out

At the moment the plugin is not opting in any of the static analysis tools supported. To enable one of them you need to explicitly provide a configuration for the tool of choice. For instance, having this in your build script:

staticAnalysis {
    checkstyle {
        configFile project.file 'blah'
    }
}

will only enable Checkstyle, while PMD and FindBugs will be not. The rationale of this choice is that you need anyway a minimal setup for such tools to use them, like providing a configuration file. This unfortunately doesn't apply to FindBugs, where no minimal configuration is required, forcing you to have something ugly like:

staticAnalysis {
    checkstyle {
        configFile project.file 'blah'
    }
    findbugs {} // this empty config :puke:
}

How do we want to evolve this? Should we move to opting-out all the tools and exposing an API to disable them if needed? What do you reckon is the average case?
Let's discuss.

Lint exclude support

Seems like the lint configurator doesn't support the exclude functionality, would be great if it did!

Timing issue with lint configuration

Our Android lint configurator just early return when the Android plugin is not found yet.

I was trying to modify out integration in a project to add lint but I realized that it silently fails and just does configure lint.

The reason is that the static-analysis plugin is applied in a subprojects closure in the root build.gradle when it is applied, the android plugin is not configured yet.

Just like other configurators, using plugins.withId may fix this because closure provided with withId will be called once the android plugin is applied.

Re-visit definition/structure of internal packages

Since v0.5.0 we have exposed the ViolationsEvaluator interface in the public API (see #45). The interface has a single method, which takes in a Set<Violations>, but the Violations class is in the internal package. It should be moved up one level to be officially part of the public API.

We should also double check if anything is in the wrong package (@mr-archano mentioned all the integration tests being in the internal package, which is not necessary). We may also want to annotate non-public API with the @RestrictTo annotation to formally mark them as private (since Groovy has no internal modifier like Kotlin, it's the best we can do)

Strange intermittent crash on Jenkins CI

When running a build on Jenkins machine from times to times a crash raises when collecting pmd. If that is important - pmd violation number is zero in that cases. Any ideas what can be wrong? Thanks.

* What went wrong:
Execution failed for task ':android:android-library:collectPmdMainViolations'.
> Bad <init> method call from inside of a branch
  Exception Details:
    Location:
      com/novoda/staticanalysis/internal/pmd/PmdViolationsEvaluator.<init>(Ljava/io/File;)V @83: invokespecial
    Reason:
      Error exists in the bytecode

java version "1.8.0_20"
Java(TM) SE Runtime Environment (build 1.8.0_20-b26)
Java HotSpot(TM) 64-Bit Server VM (build 25.20-b23, mixed mode)

Mac OS Sierra 10.12.6

detekt requires output to be configured

In case no output is configured for detekt, the plugin fails with an exception.

Configuration

detekt {
        profile('main') {
            config = rules.novoda['detekt.yml'].asFile().path
            //output = "$project.rootDir/reports/detekt.xml"
        }
    }

Exception

org.gradle.api.GradleScriptException: A problem occurred evaluating project ':app'.
        at org.gradle.groovy.scripts.internal.DefaultScriptRunnerFactory$ScriptRunnerImpl.run(DefaultScriptRunnerFactory.java:92)
        at org.gradle.configuration.DefaultScriptPluginFactory$ScriptPluginImpl$2.run(DefaultScriptPluginFactory.java:187)
        at org.gradle.configuration.ProjectScriptTarget.addConfiguration(ProjectScriptTarget.java:77)
        at org.gradle.configuration.DefaultScriptPluginFactory$ScriptPluginImpl.apply(DefaultScriptPluginFactory.java:192)
        at org.gradle.configuration.BuildOperationScriptPlugin$1.run(BuildOperationScriptPlugin.java:61)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:197)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:107)
        at org.gradle.configuration.BuildOperationScriptPlugin.apply(BuildOperationScriptPlugin.java:58)
        at org.gradle.configuration.project.BuildScriptProcessor.execute(BuildScriptProcessor.java:39)
        at org.gradle.configuration.project.BuildScriptProcessor.execute(BuildScriptProcessor.java:26)
        at org.gradle.configuration.project.ConfigureActionsProjectEvaluator.evaluate(ConfigureActionsProjectEvaluator.java:34)
        at org.gradle.configuration.project.LifecycleProjectEvaluator.doConfigure(LifecycleProjectEvaluator.java:63)
        at org.gradle.configuration.project.LifecycleProjectEvaluator.access$100(LifecycleProjectEvaluator.java:33)
        at org.gradle.configuration.project.LifecycleProjectEvaluator$ConfigureProject.run(LifecycleProjectEvaluator.java:103)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:197)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:107)
        at org.gradle.configuration.project.LifecycleProjectEvaluator.evaluate(LifecycleProjectEvaluator.java:49)
        at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:651)
        at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:133)
        at org.gradle.execution.TaskPathProjectEvaluator.configure(TaskPathProjectEvaluator.java:35)
        at org.gradle.execution.TaskPathProjectEvaluator.configureHierarchy(TaskPathProjectEvaluator.java:62)
        at org.gradle.configuration.DefaultBuildConfigurer.configure(DefaultBuildConfigurer.java:38)
        at org.gradle.initialization.DefaultGradleLauncher$ConfigureBuild.run(DefaultGradleLauncher.java:246)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:197)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:107)
        at org.gradle.initialization.DefaultGradleLauncher.configureBuild(DefaultGradleLauncher.java:165)
        at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:124)
        at org.gradle.initialization.DefaultGradleLauncher.executeTasks(DefaultGradleLauncher.java:107)
        at org.gradle.internal.invocation.GradleBuildController$1.call(GradleBuildController.java:78)
        at org.gradle.internal.invocation.GradleBuildController$1.call(GradleBuildController.java:75)
        at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:152)
        at org.gradle.internal.invocation.GradleBuildController.doBuild(GradleBuildController.java:100)
        at org.gradle.internal.invocation.GradleBuildController.run(GradleBuildController.java:75)
        at org.gradle.tooling.internal.provider.ExecuteBuildActionRunner.run(ExecuteBuildActionRunner.java:28)
        at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
        at org.gradle.tooling.internal.provider.ValidatingBuildActionRunner.run(ValidatingBuildActionRunner.java:32)
        at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$1.run(RunAsBuildOperationBuildActionRunner.java:43)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:197)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:107)
        at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner.run(RunAsBuildOperationBuildActionRunner.java:40)
        at org.gradle.tooling.internal.provider.SubscribableBuildActionRunner.run(SubscribableBuildActionRunner.java:51)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:45)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:29)
        at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:39)
        at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:25)
        at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:71)
        at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:45)
        at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:51)
        at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:32)
        at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:36)
        at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:25)
        at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:43)
        at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:29)
        at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:64)
        at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:29)
        at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:55)
        at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:42)
        at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:58)
        at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:33)
        at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:67)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:37)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:26)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:34)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:74)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:72)
        at org.gradle.util.Swapper.swap(Swapper.java:38)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:72)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:55)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:62)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:82)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:50)
        at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:297)
        at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
        at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
        at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
Caused by: java.lang.IllegalArgumentException: path may not be null or empty string. path='null'
        at org.gradle.api.internal.file.AbstractBaseDirFileResolver.doResolve(AbstractBaseDirFileResolver.java:65)
        at org.gradle.api.internal.file.AbstractFileResolver.resolve(AbstractFileResolver.java:86)
        at org.gradle.api.internal.file.AbstractFileResolver.resolve(AbstractFileResolver.java:68)
        at org.gradle.api.internal.file.DefaultFileOperations.file(DefaultFileOperations.java:82)
        at org.gradle.api.internal.project.DefaultProject.file(DefaultProject.java:824)
        at org.gradle.api.Project$file$3.call(Unknown Source)
        at com.novoda.staticanalysis.internal.detekt.DetektConfigurator.createCollectViolationsTask(DetektConfigurator.groovy:67)
        at com.novoda.staticanalysis.internal.detekt.DetektConfigurator.configureToolTask(DetektConfigurator.groovy:61)
        at com.novoda.staticanalysis.internal.detekt.DetektConfigurator$_execute_closure1.doCall(DetektConfigurator.groovy:50)
        at org.gradle.internal.metaobject.BeanDynamicObject$MetaClassAdapter.invokeMethod(BeanDynamicObject.java:479)
        at org.gradle.internal.metaobject.BeanDynamicObject.tryInvokeMethod(BeanDynamicObject.java:191)
        at org.gradle.internal.metaobject.MixInClosurePropertiesAsMethodsDynamicObject.tryInvokeMethod(MixInClosurePropertiesAsMethodsDynamicObject.java:42)
        at org.gradle.internal.metaobject.ConfigureDelegate.invokeMethod(ConfigureDelegate.java:59)
        at build_5qwpqpu5xy2q8odyk5tg9yc9x$_run_closure2.doCall(/Users/tobiasheine/Documents/repos/DetektPlayground/app/build.gradle:47)
        at org.gradle.api.internal.ClosureBackedAction.execute(ClosureBackedAction.java:71)
        at org.gradle.util.ConfigureUtil.configureTarget(ConfigureUtil.java:160)
        at org.gradle.util.ConfigureUtil.configure(ConfigureUtil.java:106)
        at org.gradle.util.ConfigureUtil$1.execute(ConfigureUtil.java:123)
        at org.gradle.api.internal.plugins.ExtensionsStorage$ExtensionHolder.configure(ExtensionsStorage.java:173)
        at org.gradle.api.internal.plugins.ExtensionsStorage.configureExtension(ExtensionsStorage.java:70)
        at org.gradle.api.internal.plugins.DefaultConvention.configureExtension(DefaultConvention.java:367)
        at org.gradle.api.internal.plugins.DefaultConvention.access$500(DefaultConvention.java:45)
        at org.gradle.api.internal.plugins.DefaultConvention$ExtensionsDynamicObject.tryInvokeMethod(DefaultConvention.java:310)
        at org.gradle.internal.metaobject.CompositeDynamicObject.tryInvokeMethod(CompositeDynamicObject.java:98)
        at org.gradle.internal.metaobject.MixInClosurePropertiesAsMethodsDynamicObject.tryInvokeMethod(MixInClosurePropertiesAsMethodsDynamicObject.java:30)
        at org.gradle.groovy.scripts.BasicScript$ScriptDynamicObject.tryInvokeMethod(BasicScript.java:134)
        at org.gradle.internal.metaobject.AbstractDynamicObject.invokeMethod(AbstractDynamicObject.java:160)
        at org.gradle.groovy.scripts.BasicScript.invokeMethod(BasicScript.java:83)
        at build_5qwpqpu5xy2q8odyk5tg9yc9x.run(/Users/tobiasheine/Documents/repos/DetektPlayground/app/build.gradle:29)
        at org.gradle.groovy.scripts.internal.DefaultScriptRunnerFactory$ScriptRunnerImpl.run(DefaultScriptRunnerFactory.java:90)
        ... 93 more

How do I disable failOnErrors?

I'd like to set failOnErrors false so that the Gradle task doesn't fail when bugs are detected. How can I do that?

I tried:

staticAnalysis {
 failOnErrors false
  //...
}

and

staticAnalysis {
  penalty {
    failOnErrors false
    maxErrors 0
    maxWarnings 0
  }
  //...
}

and

staticAnalysis {
  penalty {
    none
  }
  //...
}

Detekt: Exception when output is null

It seems that the output is not mandatory in detekt. When you don't have any output defined, it simply skips writing to files and only does console output.

But when it is integrated through our plugin, we just throw IllegalArgumentException with a cryptic message. Instead, maybe we should validate it and require output to be define.

Caused by: java.lang.IllegalArgumentException: path may not be null or empty string. path='null' at org.gradle.api.internal.file.AbstractBaseDirFileResolver.doResolve(AbstractBaseDirFileResolver.java:65) at org.gradle.api.internal.file.AbstractFileResolver.resolve(AbstractFileResolver.java:85) at org.gradle.api.internal.file.AbstractFileResolver.resolve(AbstractFileResolver.java:67) at org.gradle.api.internal.file.DefaultFileOperations.file(DefaultFileOperations.java:89) at org.gradle.api.internal.project.DefaultProject.file(DefaultProject.java:840) at org.gradle.api.Project$file$3.call(Unknown Source) at com.novoda.staticanalysis.internal.detekt.DetektConfigurator.createCollectViolationsTask(DetektConfigurator.groovy:67) at com.novoda.staticanalysis.internal.detekt.DetektConfigurator.configureToolTask(DetektConfigurator.groovy:61) at com.novoda.staticanalysis.internal.detekt.DetektConfigurator$_execute_closure1.doCall(DetektConfigurator.groovy:50)

Merging the results in a multi-module environment

At the moment in a multi-module setup, evaluateViolations task will run individually on each Gradle project. They have no way of communicate to each other. When multiple modules fail, it is somewhat hard to identify which ones have been failed. Especially when --continue param is used.

Also in such scenario, maxErrors does not make much sense individually for each submodule. It would only makes sense when maxErrors = 0 (simply because 0 * noOfModules = 0)

Defining a root level task that will collect all the results from each task from subprojects and give a single report would be nice.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.