diff --git a/README.md b/README.md
index bbe962f..f63c2fe 100644
--- a/README.md
+++ b/README.md
@@ -81,7 +81,7 @@ This will enable all the tools with their default settings. For more advanced co
[advanced usage](docs/advanced-usage.md) and to the [supported tools](docs/supported-tools.md) pages.
## Sample app
-There's a sample Android project available [here](https://github.com/novoda/gradle-static-analysis-plugin/tree/master/sample). This sample showcases a simple setup featuring Checkstyle, FindBugs, PMD, Lint and Detekt.
+There are two sample Android projects available, one consisting of a regular app - available [here](https://github.com/novoda/gradle-static-analysis-plugin/tree/master/sample) - and the other comprising a multi-module setup available [here](https://github.com/novoda/gradle-static-analysis-plugin/tree/master/sample-multi-module). Both sample projects showcase a setup featuring Checkstyle, FindBugs, PMD, Lint and Detekt.
## Roadmap
The plugin is under active development and to be considered in **beta stage**. It is routinely used by many Novoda projects and
diff --git a/sample-multi-module/app/build.gradle b/sample-multi-module/app/build.gradle
new file mode 100644
index 0000000..263b25d
--- /dev/null
+++ b/sample-multi-module/app/build.gradle
@@ -0,0 +1,34 @@
+apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
+apply plugin: 'kotlin-android-extensions'
+
+android {
+ compileSdkVersion 27
+ buildToolsVersion '27.0.3'
+
+ defaultConfig {
+ applicationId 'com.novoda.staticanalysis.sample'
+ minSdkVersion 16
+ targetSdkVersion 27
+ versionCode 1
+ versionName '1.0'
+ }
+
+ buildTypes {
+ debug {
+ }
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt')
+ }
+ }
+}
+
+dependencies {
+ implementation project(path: ':core')
+ implementation 'com.android.support:appcompat-v7:27.1.0'
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+ testImplementation 'junit:junit:4.12'
+}
+
+apply from: rootProject.file('team-props/static-analysis.gradle')
diff --git a/sample-multi-module/app/src/main/AndroidManifest.xml b/sample-multi-module/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..1f6fb82
--- /dev/null
+++ b/sample-multi-module/app/src/main/AndroidManifest.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sample-multi-module/app/src/main/java/com/novoda/staticanalysisplugin/sample/MyActivity.kt b/sample-multi-module/app/src/main/java/com/novoda/staticanalysisplugin/sample/MyActivity.kt
new file mode 100644
index 0000000..ba0e566
--- /dev/null
+++ b/sample-multi-module/app/src/main/java/com/novoda/staticanalysisplugin/sample/MyActivity.kt
@@ -0,0 +1,26 @@
+package com.novoda.staticanalysisplugin.sample
+
+import android.content.Intent
+import android.os.Bundle
+import android.support.v7.app.AppCompatActivity
+import android.widget.Toast
+import com.novoda.buildpropertiesplugin.sample.R
+import kotlinx.android.synthetic.main.activity_my.*
+
+class MyActivity : AppCompatActivity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_my)
+
+ val another: AnotherCoreClass
+
+ button.setOnClickListener({
+ LOOK_ANOTHER_CRAZY_LONG_LONG_LONG_METHOD_NAME_FOR_NO_APPARENT_REASON_WHY_IS_THIS_METHOD_NAMED_LIKE_THIS_WHY_IT_LITERALLY_MAKES_NO_SENSE_WHATSOEVER(1)
+ startActivity(Intent(this, SomeOtherActivity::class.java))
+ })
+ }
+
+ private fun LOOK_ANOTHER_CRAZY_LONG_LONG_LONG_METHOD_NAME_FOR_NO_APPARENT_REASON_WHY_IS_THIS_METHOD_NAMED_LIKE_THIS_WHY_IT_LITERALLY_MAKES_NO_SENSE_WHATSOEVER(duration: Int) = Toast.makeText(this, "some useless message", duration).show()
+
+}
diff --git a/sample-multi-module/app/src/main/java/com/novoda/staticanalysisplugin/sample/MyClass.java b/sample-multi-module/app/src/main/java/com/novoda/staticanalysisplugin/sample/MyClass.java
new file mode 100644
index 0000000..991bc58
--- /dev/null
+++ b/sample-multi-module/app/src/main/java/com/novoda/staticanalysisplugin/sample/MyClass.java
@@ -0,0 +1,4 @@
+package com.novoda.staticanalysisplugin.sample;
+
+public class MyClass {
+}
diff --git a/sample-multi-module/app/src/main/java/com/novoda/staticanalysisplugin/sample/SomeOtherActivity.java b/sample-multi-module/app/src/main/java/com/novoda/staticanalysisplugin/sample/SomeOtherActivity.java
new file mode 100644
index 0000000..6bdc84c
--- /dev/null
+++ b/sample-multi-module/app/src/main/java/com/novoda/staticanalysisplugin/sample/SomeOtherActivity.java
@@ -0,0 +1,30 @@
+package com.novoda.staticanalysisplugin.sample;
+
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v7.app.AppCompatActivity;
+import android.util.Log;
+import android.widget.Toast;
+
+import com.novoda.buildpropertiesplugin.sample.R;
+
+public class SomeOtherActivity extends AppCompatActivity {
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_some_other);
+
+ THIS_IS_A_VERY_VERY_VERY_LONG_NAME_FOR_A_METHOD_IT_IS_IN_FACT_VERY_LONG_INDEED_NO_NEED_TO_COUNT_THE_NUMBER_OF_CHARACTERS_YOU_CAN_CLEARLY_SEE_THIS_IS_WAY_LONGER_THAN_IT_SHOULD(0);
+
+ String extra = getIntent().getStringExtra("nope");
+ if (extra != null) {
+ Log.d(SomeOtherActivity.class.getSimpleName(), extra);
+ }
+ int boom = extra.length();
+ }
+
+ private void THIS_IS_A_VERY_VERY_VERY_LONG_NAME_FOR_A_METHOD_IT_IS_IN_FACT_VERY_LONG_INDEED_NO_NEED_TO_COUNT_THE_NUMBER_OF_CHARACTERS_YOU_CAN_CLEARLY_SEE_THIS_IS_WAY_LONGER_THAN_IT_SHOULD(int duration) {
+ Toast.makeText(this, "i have no idea what to write here", duration).show();
+ }
+}
diff --git a/sample-multi-module/app/src/main/res/layout/activity_my.xml b/sample-multi-module/app/src/main/res/layout/activity_my.xml
new file mode 100644
index 0000000..a37e25b
--- /dev/null
+++ b/sample-multi-module/app/src/main/res/layout/activity_my.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
diff --git a/sample-multi-module/app/src/main/res/layout/activity_some_other.xml b/sample-multi-module/app/src/main/res/layout/activity_some_other.xml
new file mode 100644
index 0000000..ce49da7
--- /dev/null
+++ b/sample-multi-module/app/src/main/res/layout/activity_some_other.xml
@@ -0,0 +1,7 @@
+
+
+
+
diff --git a/sample-multi-module/app/src/main/res/mipmap-hdpi/ic_launcher.png b/sample-multi-module/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..cde69bc
Binary files /dev/null and b/sample-multi-module/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/sample-multi-module/app/src/main/res/mipmap-mdpi/ic_launcher.png b/sample-multi-module/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..c133a0c
Binary files /dev/null and b/sample-multi-module/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/sample-multi-module/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/sample-multi-module/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..bfa42f0
Binary files /dev/null and b/sample-multi-module/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/sample-multi-module/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/sample-multi-module/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..324e72c
Binary files /dev/null and b/sample-multi-module/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/sample-multi-module/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/sample-multi-module/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..aee44e1
Binary files /dev/null and b/sample-multi-module/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/sample-multi-module/app/src/main/res/values/colors.xml b/sample-multi-module/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..5a077b3
--- /dev/null
+++ b/sample-multi-module/app/src/main/res/values/colors.xml
@@ -0,0 +1,6 @@
+
+
+ #3F51B5
+ #303F9F
+ #FF4081
+
diff --git a/sample-multi-module/app/src/main/res/values/strings.xml b/sample-multi-module/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..e2bf5b7
--- /dev/null
+++ b/sample-multi-module/app/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ Static Analysis Plugin Sample
+
diff --git a/sample-multi-module/app/src/main/res/values/styles.xml b/sample-multi-module/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..705be27
--- /dev/null
+++ b/sample-multi-module/app/src/main/res/values/styles.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
diff --git a/sample-multi-module/app/src/test/java/com/novoda/buildpropertiesplugin/sample/MyClassTest.java b/sample-multi-module/app/src/test/java/com/novoda/buildpropertiesplugin/sample/MyClassTest.java
new file mode 100644
index 0000000..0f1ee6a
--- /dev/null
+++ b/sample-multi-module/app/src/test/java/com/novoda/buildpropertiesplugin/sample/MyClassTest.java
@@ -0,0 +1,11 @@
+package com.novoda.buildpropertiesplugin.sample;
+
+import org.junit.Test;
+
+public class MyClassTest {
+
+ @Test
+ public void testNametestNametestNametestNametestNametestNametestNametestNametestNametestNametestNametestNametestNametestNametestNametestNametestName() {
+
+ }
+}
diff --git a/sample-multi-module/build.gradle b/sample-multi-module/build.gradle
new file mode 100644
index 0000000..5493a8a
--- /dev/null
+++ b/sample-multi-module/build.gradle
@@ -0,0 +1,30 @@
+buildscript {
+ ext.kotlin_version = '1.2.30'
+
+ repositories {
+ google()
+ maven { url "https://plugins.gradle.org/m2/" }
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:3.0.1'
+ classpath "gradle.plugin.io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.0.0.RC6-3"
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ }
+}
+
+apply from: "$rootDir/team-props/tasks.gradle"
+
+subprojects { subproject ->
+
+ buildscript {
+ repositories {
+ jcenter()
+ }
+ }
+
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
diff --git a/sample-multi-module/buildSrc/build.gradle b/sample-multi-module/buildSrc/build.gradle
new file mode 100644
index 0000000..a995c56
--- /dev/null
+++ b/sample-multi-module/buildSrc/build.gradle
@@ -0,0 +1,15 @@
+repositories {
+ jcenter()
+}
+
+apply plugin: 'groovy'
+
+dependencies {
+ compile gradleApi()
+}
+
+sourceSets {
+ main {
+ groovy { srcDir '../../plugin/src/main/groovy' }
+ }
+}
diff --git a/sample-multi-module/core/build.gradle b/sample-multi-module/core/build.gradle
new file mode 100644
index 0000000..2d9c112
--- /dev/null
+++ b/sample-multi-module/core/build.gradle
@@ -0,0 +1,34 @@
+apply plugin: 'java-library'
+apply plugin: 'kotlin'
+
+buildscript {
+ ext.kotlin_version = '1.2.30'
+ repositories {
+ mavenCentral()
+ }
+ dependencies {
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ }
+}
+
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
+}
+
+compileKotlin {
+ kotlinOptions {
+ jvmTarget = "1.8"
+ }
+}
+
+compileTestKotlin {
+ kotlinOptions {
+ jvmTarget = "1.8"
+ }
+}
+
+apply from: rootProject.file('team-props/static-analysis.gradle')
diff --git a/sample-multi-module/core/src/main/java/com/novoda/staticanalysisplugin/sample/AnotherCoreClass.kt b/sample-multi-module/core/src/main/java/com/novoda/staticanalysisplugin/sample/AnotherCoreClass.kt
new file mode 100644
index 0000000..e63f6f1
--- /dev/null
+++ b/sample-multi-module/core/src/main/java/com/novoda/staticanalysisplugin/sample/AnotherCoreClass.kt
@@ -0,0 +1,17 @@
+package com.novoda.staticanalysisplugin.sample
+
+class AnotherCoreClass {
+
+ private fun A_LOOK_ANOTHER_CRAZY_LONG_LONG_LONG_METHOD_NAME_FOR_NO_APPARENT_REASON_WHY_IS_THIS_METHOD_NAMED_LIKE_THIS_WHY_IT_LITERALLY_MAKES_NO_SENSE_WHATSOEVER(duration: Int) = print("some useless message")
+ private fun B_LOOK_ANOTHER_CRAZY_LONG_LONG_LONG_METHOD_NAME_FOR_NO_APPARENT_REASON_WHY_IS_THIS_METHOD_NAMED_LIKE_THIS_WHY_IT_LITERALLY_MAKES_NO_SENSE_WHATSOEVER(duration: Int) = print("some useless message")
+ private fun C_LOOK_ANOTHER_CRAZY_LONG_LONG_LONG_METHOD_NAME_FOR_NO_APPARENT_REASON_WHY_IS_THIS_METHOD_NAMED_LIKE_THIS_WHY_IT_LITERALLY_MAKES_NO_SENSE_WHATSOEVER(duration: Int) = print("some useless message")
+ private fun D_LOOK_ANOTHER_CRAZY_LONG_LONG_LONG_METHOD_NAME_FOR_NO_APPARENT_REASON_WHY_IS_THIS_METHOD_NAMED_LIKE_THIS_WHY_IT_LITERALLY_MAKES_NO_SENSE_WHATSOEVER(duration: Int) = print("some useless message")
+ private fun E_LOOK_ANOTHER_CRAZY_LONG_LONG_LONG_METHOD_NAME_FOR_NO_APPARENT_REASON_WHY_IS_THIS_METHOD_NAMED_LIKE_THIS_WHY_IT_LITERALLY_MAKES_NO_SENSE_WHATSOEVER(duration: Int) = print("some useless message")
+ private fun F_LOOK_ANOTHER_CRAZY_LONG_LONG_LONG_METHOD_NAME_FOR_NO_APPARENT_REASON_WHY_IS_THIS_METHOD_NAMED_LIKE_THIS_WHY_IT_LITERALLY_MAKES_NO_SENSE_WHATSOEVER(duration: Int) = print("some useless message")
+ private fun G_LOOK_ANOTHER_CRAZY_LONG_LONG_LONG_METHOD_NAME_FOR_NO_APPARENT_REASON_WHY_IS_THIS_METHOD_NAMED_LIKE_THIS_WHY_IT_LITERALLY_MAKES_NO_SENSE_WHATSOEVER(duration: Int) = print("some useless message")
+ private fun H_LOOK_ANOTHER_CRAZY_LONG_LONG_LONG_METHOD_NAME_FOR_NO_APPARENT_REASON_WHY_IS_THIS_METHOD_NAMED_LIKE_THIS_WHY_IT_LITERALLY_MAKES_NO_SENSE_WHATSOEVER(duration: Int) = print("some useless message")
+ private fun I_LOOK_ANOTHER_CRAZY_LONG_LONG_LONG_METHOD_NAME_FOR_NO_APPARENT_REASON_WHY_IS_THIS_METHOD_NAMED_LIKE_THIS_WHY_IT_LITERALLY_MAKES_NO_SENSE_WHATSOEVER(duration: Int) = print("some useless message")
+ private fun J_LOOK_ANOTHER_CRAZY_LONG_LONG_LONG_METHOD_NAME_FOR_NO_APPARENT_REASON_WHY_IS_THIS_METHOD_NAMED_LIKE_THIS_WHY_IT_LITERALLY_MAKES_NO_SENSE_WHATSOEVER(duration: Int) = print("some useless message")
+ private fun K_LOOK_ANOTHER_CRAZY_LONG_LONG_LONG_METHOD_NAME_FOR_NO_APPARENT_REASON_WHY_IS_THIS_METHOD_NAMED_LIKE_THIS_WHY_IT_LITERALLY_MAKES_NO_SENSE_WHATSOEVER(duration: Int) = print("some useless message")
+
+}
diff --git a/sample-multi-module/core/src/main/java/com/novoda/staticanalysisplugin/sample/SomeJavaClass.java b/sample-multi-module/core/src/main/java/com/novoda/staticanalysisplugin/sample/SomeJavaClass.java
new file mode 100644
index 0000000..2fd1406
--- /dev/null
+++ b/sample-multi-module/core/src/main/java/com/novoda/staticanalysisplugin/sample/SomeJavaClass.java
@@ -0,0 +1,4 @@
+package com.novoda.staticanalysisplugin.sample;
+
+public class SomeJavaClass {
+}
diff --git a/sample-multi-module/gradle/wrapper/gradle-wrapper.jar b/sample-multi-module/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..7a3265e
Binary files /dev/null and b/sample-multi-module/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/sample-multi-module/gradle/wrapper/gradle-wrapper.properties b/sample-multi-module/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..f5737a2
--- /dev/null
+++ b/sample-multi-module/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Mon Mar 12 18:00:46 GMT 2018
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
diff --git a/sample-multi-module/gradlew b/sample-multi-module/gradlew
new file mode 100755
index 0000000..cccdd3d
--- /dev/null
+++ b/sample-multi-module/gradlew
@@ -0,0 +1,172 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+ cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git a/sample-multi-module/gradlew.bat b/sample-multi-module/gradlew.bat
new file mode 100644
index 0000000..e95643d
--- /dev/null
+++ b/sample-multi-module/gradlew.bat
@@ -0,0 +1,84 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/sample-multi-module/settings.gradle b/sample-multi-module/settings.gradle
new file mode 100644
index 0000000..ebf6dd7
--- /dev/null
+++ b/sample-multi-module/settings.gradle
@@ -0,0 +1,3 @@
+rootProject.name = 'gradle-static-analysis-plugin-sample'
+include ':app'
+include ':core'
diff --git a/sample-multi-module/team-props/checkstyle-modules.xml b/sample-multi-module/team-props/checkstyle-modules.xml
new file mode 100644
index 0000000..b017e2c
--- /dev/null
+++ b/sample-multi-module/team-props/checkstyle-modules.xml
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sample-multi-module/team-props/detekt-config.yml b/sample-multi-module/team-props/detekt-config.yml
new file mode 100644
index 0000000..cf14ee4
--- /dev/null
+++ b/sample-multi-module/team-props/detekt-config.yml
@@ -0,0 +1,356 @@
+autoCorrect: true
+failFast: false
+
+test-pattern:
+ active: true
+ patterns:
+ - '.*/test/.*'
+ - '.*Test.kt'
+ - '.*Spec.kt'
+ exclude-rule-sets:
+ - 'comments'
+ exclude-rules:
+ - 'NamingRules'
+ - 'WildcardImport'
+ - 'MagicNumber'
+ - 'MaxLineLength'
+ - 'LateinitUsage'
+ - 'StringLiteralDuplication'
+ - 'SpreadOperator'
+ - 'TooManyFunctions'
+
+build:
+ warningThreshold: 5
+ failThreshold: 500
+ maxIssues: 500
+ weights:
+ complexity: 2
+ LongParameterList: 1
+ style: 1
+ comments: 1
+
+processors:
+ active: true
+
+console-reports:
+ active: true
+
+output-reports:
+ active: true
+
+comments:
+ active: true
+ CommentOverPrivateFunction:
+ active: false
+ CommentOverPrivateProperty:
+ active: false
+ EndOfSentenceFormat:
+ active: false
+ endOfSentenceFormat: ([.?!][ \t\n\r\f<])|([.?!]$)
+ UndocumentedPublicClass:
+ active: false
+ searchInNestedClass: true
+ searchInInnerClass: true
+ searchInInnerObject: true
+ searchInInnerInterface: true
+ UndocumentedPublicFunction:
+ active: false
+
+complexity:
+ active: true
+ ComplexCondition:
+ active: true
+ ComplexInterface:
+ active: false
+ includeStaticDeclarations: false
+ ComplexMethod:
+ active: true
+ ignoreSingleWhenExpression: false
+ LabeledExpression:
+ active: false
+ LargeClass:
+ active: true
+ LongMethod:
+ active: true
+ LongParameterList:
+ active: true
+ ignoreDefaultParameters: false
+ MethodOverloading:
+ active: false
+ NestedBlockDepth:
+ active: true
+ StringLiteralDuplication:
+ active: false
+ ignoreAnnotation: true
+ excludeStringsWithLessThan5Characters: true
+ ignoreStringsRegex: '$^'
+ TooManyFunctions:
+ active: true
+ thresholdInFiles: 11
+ thresholdInClasses: 11
+ thresholdInInterfaces: 11
+ thresholdInObjects: 11
+ thresholdInEnums: 11
+
+empty-blocks:
+ active: true
+ EmptyCatchBlock:
+ active: true
+ allowedExceptionNameRegex: "^(ignore|expected).*"
+ EmptyClassBlock:
+ active: true
+ EmptyDefaultConstructor:
+ active: true
+ EmptyDoWhileBlock:
+ active: true
+ EmptyElseBlock:
+ active: true
+ EmptyFinallyBlock:
+ active: true
+ EmptyForBlock:
+ active: true
+ EmptyFunctionBlock:
+ active: true
+ EmptyIfBlock:
+ active: true
+ EmptyInitBlock:
+ active: true
+ EmptyKtFile:
+ active: true
+ EmptySecondaryConstructor:
+ active: true
+ EmptyWhenBlock:
+ active: true
+ EmptyWhileBlock:
+ active: true
+
+exceptions:
+ active: true
+ ExceptionRaisedInUnexpectedLocation:
+ active: false
+ methodNames: 'toString,hashCode,equals,finalize'
+ InstanceOfCheckForException:
+ active: false
+ NotImplementedDeclaration:
+ active: false
+ PrintStackTrace:
+ active: false
+ RethrowCaughtException:
+ active: false
+ ReturnFromFinally:
+ active: false
+ SwallowedException:
+ active: false
+ ThrowingExceptionFromFinally:
+ active: false
+ ThrowingExceptionInMain:
+ active: false
+ ThrowingExceptionsWithoutMessageOrCause:
+ active: false
+ exceptions: 'IllegalArgumentException,IllegalStateException,IOException'
+ ThrowingNewInstanceOfSameException:
+ active: false
+ TooGenericExceptionCaught:
+ active: true
+ exceptionNames:
+ - ArrayIndexOutOfBoundsException
+ - Error
+ - Exception
+ - IllegalMonitorStateException
+ - NullPointerException
+ - IndexOutOfBoundsException
+ - RuntimeException
+ - Throwable
+ TooGenericExceptionThrown:
+ active: true
+ exceptionNames:
+ - Error
+ - Exception
+ - Throwable
+ - RuntimeException
+
+naming:
+ active: true
+ ClassNaming:
+ active: true
+ classPattern: '[A-Z$][a-zA-Z0-9$]*'
+ EnumNaming:
+ active: true
+ enumEntryPattern: '^[A-Z][_a-zA-Z0-9]*'
+ ForbiddenClassName:
+ active: false
+ forbiddenName: ''
+ FunctionMaxLength:
+ active: false
+ maximumFunctionNameLength: 30
+ FunctionMinLength:
+ active: false
+ minimumFunctionNameLength: 3
+ FunctionNaming:
+ active: true
+ functionPattern: '^([a-z$][a-zA-Z$0-9]*)|(`.*`)$'
+ excludeClassPattern: '$^'
+ MatchingDeclarationName:
+ active: true
+ MemberNameEqualsClassName:
+ active: false
+ ignoreOverriddenFunction: true
+ ObjectPropertyNaming:
+ active: true
+ propertyPattern: '[A-Za-z][_A-Za-z0-9]*'
+ PackageNaming:
+ active: true
+ packagePattern: '^[a-z]+(\.[a-z][a-z0-9]*)*$'
+ TopLevelPropertyNaming:
+ active: true
+ constantPattern: '[A-Z][_A-Z0-9]*'
+ propertyPattern: '[a-z][A-Za-z\d]*'
+ privatePropertyPattern: '(_)?[a-z][A-Za-z0-9]*'
+ VariableMaxLength:
+ active: false
+ maximumVariableNameLength: 64
+ VariableMinLength:
+ active: false
+ minimumVariableNameLength: 1
+ VariableNaming:
+ active: true
+ variablePattern: '[a-z][A-Za-z0-9]*'
+ privateVariablePattern: '(_)?[a-z][A-Za-z0-9]*'
+ excludeClassPattern: '$^'
+
+performance:
+ active: true
+ ForEachOnRange:
+ active: true
+ SpreadOperator:
+ active: true
+ UnnecessaryTemporaryInstantiation:
+ active: true
+
+potential-bugs:
+ active: true
+ DuplicateCaseInWhenExpression:
+ active: true
+ EqualsAlwaysReturnsTrueOrFalse:
+ active: false
+ EqualsWithHashCodeExist:
+ active: true
+ ExplicitGarbageCollectionCall:
+ active: true
+ InvalidRange:
+ active: false
+ IteratorHasNextCallsNextMethod:
+ active: false
+ IteratorNotThrowingNoSuchElementException:
+ active: false
+ LateinitUsage:
+ active: false
+ excludeAnnotatedProperties: ""
+ ignoreOnClassesPattern: ""
+ UnconditionalJumpStatementInLoop:
+ active: false
+ UnreachableCode:
+ active: true
+ UnsafeCallOnNullableType:
+ active: false
+ UnsafeCast:
+ active: false
+ UselessPostfixExpression:
+ active: false
+ WrongEqualsTypeParameter:
+ active: false
+
+style:
+ active: true
+ CollapsibleIfStatements:
+ active: false
+ DataClassContainsFunctions:
+ active: false
+ conversionFunctionPrefix: 'to'
+ EqualsNullCall:
+ active: false
+ ExpressionBodySyntax:
+ active: false
+ ForbiddenComment:
+ active: true
+ values: 'TODO:,FIXME:,STOPSHIP:'
+ ForbiddenImport:
+ active: false
+ imports: ''
+ FunctionOnlyReturningConstant:
+ active: false
+ ignoreOverridableFunction: true
+ excludedFunctions: 'describeContents'
+ LoopWithTooManyJumpStatements:
+ active: false
+ maxJumpCount: 1
+ MagicNumber:
+ active: true
+ ignoreNumbers: '-1,0,1,2'
+ ignoreHashCodeFunction: false
+ ignorePropertyDeclaration: false
+ ignoreConstantDeclaration: true
+ ignoreCompanionObjectPropertyDeclaration: true
+ ignoreAnnotation: false
+ ignoreNamedArgument: true
+ ignoreEnums: false
+ MaxLineLength:
+ active: true
+ maxLineLength: 120
+ excludePackageStatements: false
+ excludeImportStatements: false
+ MayBeConst:
+ active: false
+ ModifierOrder:
+ active: true
+ NestedClassesVisibility:
+ active: false
+ NewLineAtEndOfFile:
+ active: true
+ NoTabs:
+ active: false
+ OptionalAbstractKeyword:
+ active: true
+ OptionalUnit:
+ active: false
+ OptionalWhenBraces:
+ active: false
+ ProtectedMemberInFinalClass:
+ active: false
+ RedundantVisibilityModifierRule:
+ active: false
+ ReturnCount:
+ active: true
+ max: 2
+ excludedFunctions: "equals"
+ SafeCast:
+ active: true
+ SerialVersionUIDInSerializableClass:
+ active: false
+ SpacingBetweenPackageAndImports:
+ active: false
+ ThrowsCount:
+ active: true
+ max: 2
+ TrailingWhitespace:
+ active: false
+ UnnecessaryAbstractClass:
+ active: false
+ UnnecessaryInheritance:
+ active: false
+ UnnecessaryParentheses:
+ active: false
+ UntilInsteadOfRangeTo:
+ active: false
+ UnusedImports:
+ active: false
+ UnusedPrivateMember:
+ active: false
+ UseDataClass:
+ active: false
+ excludeAnnotatedClasses: ""
+ UtilityClassWithPublicConstructor:
+ active: false
+ WildcardImport:
+ active: true
+ excludeImports: 'java.util.*,kotlinx.android.synthetic.*'
diff --git a/sample-multi-module/team-props/findbugs-excludes.xml b/sample-multi-module/team-props/findbugs-excludes.xml
new file mode 100644
index 0000000..b0bf1a4
--- /dev/null
+++ b/sample-multi-module/team-props/findbugs-excludes.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sample-multi-module/team-props/lint-config.xml b/sample-multi-module/team-props/lint-config.xml
new file mode 100644
index 0000000..5d5c2c5
--- /dev/null
+++ b/sample-multi-module/team-props/lint-config.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
diff --git a/sample-multi-module/team-props/pmd-rules.xml b/sample-multi-module/team-props/pmd-rules.xml
new file mode 100644
index 0000000..a74ad7e
--- /dev/null
+++ b/sample-multi-module/team-props/pmd-rules.xml
@@ -0,0 +1,61 @@
+
+
+
+ Mandatory PMD rules description.
+
+
+ .*\.kt
+ .*\.R\$.*
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sample-multi-module/team-props/static-analysis.gradle b/sample-multi-module/team-props/static-analysis.gradle
new file mode 100644
index 0000000..ec8f1cd
--- /dev/null
+++ b/sample-multi-module/team-props/static-analysis.gradle
@@ -0,0 +1,44 @@
+apply plugin: com.novoda.staticanalysis.StaticAnalysisPlugin
+apply plugin: 'io.gitlab.arturbosch.detekt'
+
+staticAnalysis {
+
+ penalty none
+
+ checkstyle {
+ toolVersion '8.8'
+ exclude project.fileTree('src/test/java')
+ exclude '**/*.kt'
+ configFile rootProject.file('team-props/checkstyle-modules.xml')
+ includeVariants { variant -> variant.name.contains('debug') }
+ }
+
+ pmd {
+ toolVersion '6.1.0'
+ exclude project.fileTree('src/test/java')
+ ruleSetFiles = rootProject.files('team-props/pmd-rules.xml')
+ ruleSets = [] // https://stackoverflow.com/questions/32247190/pmd-exclude-pattern-with-gradle
+ includeVariants { variant -> variant.name.contains('debug') }
+ }
+
+ findbugs {
+ toolVersion '3.0.1'
+ excludeFilter rootProject.file('team-props/findbugs-excludes.xml')
+ includeVariants { variant -> variant.name.contains('debug') }
+ }
+
+ lintOptions {
+ lintConfig rootProject.file('team-props/lint-config.xml')
+ checkReleaseBuilds false
+ warningsAsErrors true
+ }
+
+ detekt {
+ profile('main') {
+ input = project.file("src/main/java")
+ config = rootProject.file('team-props/detekt-config.yml')
+ filters = '.*test.*,.*/resources/.*,.*/tmp/.*'
+ output = project.file("build/reports/detekt")
+ }
+ }
+}
diff --git a/sample-multi-module/team-props/tasks.gradle b/sample-multi-module/team-props/tasks.gradle
new file mode 100644
index 0000000..1da46dc
--- /dev/null
+++ b/sample-multi-module/team-props/tasks.gradle
@@ -0,0 +1 @@
+task build(dependsOn: [rootProject.task('assemble'), rootProject.task('check')])
diff --git a/sample/app/build.gradle b/sample/app/build.gradle
old mode 100644
new mode 100755
diff --git a/sample/app/src/main/AndroidManifest.xml b/sample/app/src/main/AndroidManifest.xml
old mode 100644
new mode 100755
diff --git a/sample/app/src/main/java/com/novoda/staticanalysisplugin/sample/MyActivity.kt b/sample/app/src/main/java/com/novoda/staticanalysisplugin/sample/MyActivity.kt
old mode 100644
new mode 100755
diff --git a/sample/app/src/main/java/com/novoda/staticanalysisplugin/sample/MyClass.java b/sample/app/src/main/java/com/novoda/staticanalysisplugin/sample/MyClass.java
old mode 100644
new mode 100755
diff --git a/sample/app/src/main/java/com/novoda/staticanalysisplugin/sample/SomeOtherActivity.java b/sample/app/src/main/java/com/novoda/staticanalysisplugin/sample/SomeOtherActivity.java
old mode 100644
new mode 100755
diff --git a/sample/app/src/main/res/layout/activity_my.xml b/sample/app/src/main/res/layout/activity_my.xml
old mode 100644
new mode 100755
diff --git a/sample/app/src/main/res/layout/activity_some_other.xml b/sample/app/src/main/res/layout/activity_some_other.xml
old mode 100644
new mode 100755
diff --git a/sample/app/src/main/res/mipmap-hdpi/ic_launcher.png b/sample/app/src/main/res/mipmap-hdpi/ic_launcher.png
old mode 100644
new mode 100755
diff --git a/sample/app/src/main/res/mipmap-mdpi/ic_launcher.png b/sample/app/src/main/res/mipmap-mdpi/ic_launcher.png
old mode 100644
new mode 100755
diff --git a/sample/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/sample/app/src/main/res/mipmap-xhdpi/ic_launcher.png
old mode 100644
new mode 100755
diff --git a/sample/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/sample/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
old mode 100644
new mode 100755
diff --git a/sample/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/sample/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
old mode 100644
new mode 100755
diff --git a/sample/app/src/main/res/values/colors.xml b/sample/app/src/main/res/values/colors.xml
old mode 100644
new mode 100755
diff --git a/sample/app/src/main/res/values/strings.xml b/sample/app/src/main/res/values/strings.xml
old mode 100644
new mode 100755
diff --git a/sample/app/src/main/res/values/styles.xml b/sample/app/src/main/res/values/styles.xml
old mode 100644
new mode 100755
diff --git a/sample/app/src/test/java/com/novoda/buildpropertiesplugin/sample/MyClassTest.java b/sample/app/src/test/java/com/novoda/buildpropertiesplugin/sample/MyClassTest.java
old mode 100644
new mode 100755
diff --git a/sample/build.gradle b/sample/build.gradle
old mode 100644
new mode 100755
diff --git a/sample/buildSrc/build.gradle b/sample/buildSrc/build.gradle
old mode 100644
new mode 100755
diff --git a/sample/gradle/wrapper/gradle-wrapper.jar b/sample/gradle/wrapper/gradle-wrapper.jar
old mode 100644
new mode 100755
diff --git a/sample/gradle/wrapper/gradle-wrapper.properties b/sample/gradle/wrapper/gradle-wrapper.properties
old mode 100644
new mode 100755
diff --git a/sample/gradlew.bat b/sample/gradlew.bat
old mode 100644
new mode 100755
diff --git a/sample/settings.gradle b/sample/settings.gradle
old mode 100644
new mode 100755
diff --git a/sample/team-props/checkstyle-modules.xml b/sample/team-props/checkstyle-modules.xml
old mode 100644
new mode 100755
diff --git a/sample/team-props/detekt-config.yml b/sample/team-props/detekt-config.yml
old mode 100644
new mode 100755
diff --git a/sample/team-props/findbugs-excludes.xml b/sample/team-props/findbugs-excludes.xml
old mode 100644
new mode 100755
diff --git a/sample/team-props/lint-config.xml b/sample/team-props/lint-config.xml
old mode 100644
new mode 100755
diff --git a/sample/team-props/pmd-rules.xml b/sample/team-props/pmd-rules.xml
old mode 100644
new mode 100755