diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..f47fbff0e6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,20 @@ + +# IntelliJ +*.iml +.idea/ + +# Android Studio 3+ +.navigation/ +captures/ +.externalNativeBuild + +# Gradle files +.gradle/ +build/ + +# Local configuration file (sdk path, etc) +local.properties + +# MacOS garbage +.DS_Store + diff --git a/README.md b/README.md new file mode 100644 index 0000000000..eb9e72670d --- /dev/null +++ b/README.md @@ -0,0 +1,16 @@ +# Datadog Android SDK + +Client-side Android logging library for Datadog. + +## Features + +- Use the library as a logger. Everything is forwarded to Datadog as JSON documents. +- Custom fields, meta and extra attributes +- Automatic Useragent, IP and network information sent +- Automatic bulk +- Network and battery life optimized + +## Quick Start + +TODO + diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000000..604faaed9c --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,26 @@ +buildscript { + repositories { + google() + mavenCentral() + maven { setUrl(com.datadog.gradle.Dependencies.Repositories.Gradle) } + jcenter() + } + + dependencies { + classpath(com.datadog.gradle.Dependencies.ClassPaths.AndroidTools) + classpath(com.datadog.gradle.Dependencies.ClassPaths.Kotlin) + classpath(com.datadog.gradle.Dependencies.ClassPaths.KtLint) + } +} + +allprojects { + repositories { + google() + mavenCentral() + jcenter() + } +} + +task("clean") { + delete(rootProject.buildDir) +} diff --git a/buildSrc/.gitignore b/buildSrc/.gitignore new file mode 100644 index 0000000000..5a032f0558 --- /dev/null +++ b/buildSrc/.gitignore @@ -0,0 +1,18 @@ +# Built application files +*.apk +*.ap_ +*.aab + +# Files for the ART/Dalvik VM +*.dex + +# Java class files +*.class + +# Generated files +bin/ +gen/ +out/ + +# Gradle files +build/ \ No newline at end of file diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts new file mode 100644 index 0000000000..2d92bed261 --- /dev/null +++ b/buildSrc/build.gradle.kts @@ -0,0 +1,48 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + `kotlin-dsl` + id("com.github.ben-manes.versions") version ("0.27.0") + id("org.jlleitschuh.gradle.ktlint") version ("9.1.0") +} + +buildscript { + dependencies { + classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.41") + } + repositories { + mavenCentral() + } +} + +apply(plugin = "kotlin") +apply(plugin = "java-gradle-plugin") + +repositories { + mavenCentral() + google() + maven { setUrl("https://plugins.gradle.org/m2/") } + maven { setUrl("https://maven.google.com") } +} + +dependencies { + + // Dependencies used to configure the gradle plugins + compile("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.41") + compile("org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.41") + compile("io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.1.1") + compile("org.jlleitschuh.gradle:ktlint-gradle:9.1.0") + compile("com.android.tools.build:gradle:3.5.1") + compile("com.github.ben-manes:gradle-versions-plugin:0.27.0") + + testCompile("junit:junit:4.12") +} + +tasks.withType { + kotlinOptions.jvmTarget = JavaVersion.VERSION_1_8.toString() +} + +tasks.named("check") { +// dependsOn("dependencyUpdates") +// dependsOn("ktlintCheck") +} diff --git a/buildSrc/src/main/kotlin/com/datadog/gradle/Dependencies.kt b/buildSrc/src/main/kotlin/com/datadog/gradle/Dependencies.kt new file mode 100644 index 0000000000..9d774777d8 --- /dev/null +++ b/buildSrc/src/main/kotlin/com/datadog/gradle/Dependencies.kt @@ -0,0 +1,47 @@ +package com.datadog.gradle + +object Dependencies { + + object Versions { + // Commons + const val Kotlin = "1.3.41" + const val AndroidToolsPlugin = "3.5.1" + + // Tests + const val Jacoco = "0.8.4" + + // Tools + const val Detekt = "1.0.1" + const val KtLint = "8.2.0" + const val DependencyVersion = "0.27.0" + } + + object Libraries { + + const val Kotlin = "org.jetbrains.kotlin:kotlin-stdlib:${Versions.Kotlin}" + + @JvmField + val JUnit5Extensions = arrayOf( + "org.mockito:mockito-junit-jupiter:2.23.0" + ) + } + + object ClassPaths { + const val AndroidTools = "com.android.tools.build:gradle:${Versions.AndroidToolsPlugin}" + const val Kotlin = "org.jetbrains.kotlin:kotlin-gradle-plugin:${Versions.Kotlin}" + const val KtLint = "org.jlleitschuh.gradle:ktlint-gradle:${Versions.KtLint}" + } + + object Repositories { + const val Gradle = "https://plugins.gradle.org/m2/" + const val Google = "https://maven.google.com" + } + + object PluginNamespaces { + const val Detetk = "io.gitlab.arturbosch" + const val KtLint = "org.jlleitschuh.gradle" + const val DependencyVersion = "com.github.ben-manes" + const val Kotlin = "org.jetbrains.kotlin" + const val KotlinAndroid = "org.jetbrains.kotlin.android" + } +} diff --git a/buildSrc/src/main/kotlin/com/datadog/gradle/config/AndroidConfig.kt b/buildSrc/src/main/kotlin/com/datadog/gradle/config/AndroidConfig.kt new file mode 100644 index 0000000000..e0350767ac --- /dev/null +++ b/buildSrc/src/main/kotlin/com/datadog/gradle/config/AndroidConfig.kt @@ -0,0 +1,9 @@ +package com.datadog.gradle.config + +import com.datadog.gradle.utils.Version + +object AndroidConfig { + const val TARGET_SDK = 28 + const val MIN_SDK = 16 + val VERSION = Version(0, 0, 1) +} diff --git a/buildSrc/src/main/kotlin/com/datadog/gradle/config/BaseExtensionConfig.kt b/buildSrc/src/main/kotlin/com/datadog/gradle/config/BaseExtensionConfig.kt new file mode 100644 index 0000000000..3a2a2f19c2 --- /dev/null +++ b/buildSrc/src/main/kotlin/com/datadog/gradle/config/BaseExtensionConfig.kt @@ -0,0 +1,23 @@ +package com.datadog.gradle.config + +import org.gradle.api.Project +import org.gradle.api.Task +import org.gradle.kotlin.dsl.findByType + +inline fun Project.extensionConfig( + crossinline configure: T.() -> Unit +) { + + project.afterEvaluate { + val ext: T? = extensions.findByType(T::class) + ext?.configure() + } +} + +inline fun Project.taskConfig( + crossinline configure: T.() -> Unit +) { + project.afterEvaluate { + tasks.withType(T::class.java) { configure() } + } +} diff --git a/buildSrc/src/main/kotlin/com/datadog/gradle/config/DependencyUpdateConfig.kt b/buildSrc/src/main/kotlin/com/datadog/gradle/config/DependencyUpdateConfig.kt new file mode 100644 index 0000000000..c6e3600aee --- /dev/null +++ b/buildSrc/src/main/kotlin/com/datadog/gradle/config/DependencyUpdateConfig.kt @@ -0,0 +1,11 @@ +package com.datadog.gradle.config + +import com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask +import org.gradle.api.Project + +fun Project.dependencyUpdateConfig() { + + taskConfig { + revision = "release" + } +} diff --git a/buildSrc/src/main/kotlin/com/datadog/gradle/config/DetektConfig.kt b/buildSrc/src/main/kotlin/com/datadog/gradle/config/DetektConfig.kt new file mode 100644 index 0000000000..d0fd69edef --- /dev/null +++ b/buildSrc/src/main/kotlin/com/datadog/gradle/config/DetektConfig.kt @@ -0,0 +1,24 @@ +package com.datadog.gradle.config + +import io.gitlab.arturbosch.detekt.extensions.DetektExtension +import org.gradle.api.Project + +fun Project.detektConfig() { + + extensionConfig { + version = "1.0.1" + + input = files("$projectDir/src/main/kotlin") + config = files("${project.rootDir}/detekt.yml") + reports { + xml { + enabled = true + destination = file("build/reports/detekt.xml") + } + } + } + + tasks.named("check") { + dependsOn("detekt") + } +} diff --git a/buildSrc/src/main/kotlin/com/datadog/gradle/config/JacocoConfig.kt b/buildSrc/src/main/kotlin/com/datadog/gradle/config/JacocoConfig.kt new file mode 100644 index 0000000000..f8d45e58f5 --- /dev/null +++ b/buildSrc/src/main/kotlin/com/datadog/gradle/config/JacocoConfig.kt @@ -0,0 +1,38 @@ +package com.datadog.gradle.config + +import com.datadog.gradle.Dependencies +import org.gradle.api.Project +import org.gradle.testing.jacoco.plugins.JacocoPluginExtension +import org.gradle.testing.jacoco.tasks.JacocoReport + +fun Project.jacocoConfig() { + + extensionConfig { + toolVersion = Dependencies.Versions.Jacoco + reportsDir = file("$buildDir/jacoco") // Jacoco's output root. + } + + taskConfig { + reports { + csv.isEnabled = false + xml.isEnabled = true + html.isEnabled = true + html.destination = file("$buildDir/jacoco/html") + } + } + +// tasks.withType(JacocoCoverageVerification::class.java) { +// violationRules { +// rule { +// limit { +// minimum = 0.85.toBigDecimal() +// } +// } +// } +// } + + tasks.named("check") { + dependsOn("jacocoTestReport") + dependsOn("jacocoTestCoverageVerification") + } +} diff --git a/buildSrc/src/main/kotlin/com/datadog/gradle/config/KotlinConfig.kt b/buildSrc/src/main/kotlin/com/datadog/gradle/config/KotlinConfig.kt new file mode 100644 index 0000000000..77ca4b18a7 --- /dev/null +++ b/buildSrc/src/main/kotlin/com/datadog/gradle/config/KotlinConfig.kt @@ -0,0 +1,14 @@ +package com.datadog.gradle.config + +import org.gradle.api.JavaVersion +import org.gradle.api.Project +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +fun Project.kotlinConfig() { + + taskConfig { + kotlinOptions { + jvmTarget = JavaVersion.VERSION_1_8.toString() + } + } +} diff --git a/buildSrc/src/main/kotlin/com/datadog/gradle/config/KtLintConfig.kt b/buildSrc/src/main/kotlin/com/datadog/gradle/config/KtLintConfig.kt new file mode 100644 index 0000000000..a2141b048b --- /dev/null +++ b/buildSrc/src/main/kotlin/com/datadog/gradle/config/KtLintConfig.kt @@ -0,0 +1,24 @@ +package com.datadog.gradle.config + +import org.gradle.api.Project +import org.jlleitschuh.gradle.ktlint.KtlintExtension + +fun Project.ktLintConfig() { + + extensionConfig { + debug.set(false) + android.set(true) + outputToConsole.set(true) + ignoreFailures.set(false) + enableExperimentalRules.set(false) + additionalEditorconfigFile.set(file("${project.rootDir}/script/config/.editorconfig")) + filter { + exclude("**/generated/**") + include("**/kotlin/**") + } + } + + tasks.named("check") { + dependsOn("ktlintCheck") + } +} diff --git a/buildSrc/src/main/kotlin/com/datadog/gradle/utils/Version.kt b/buildSrc/src/main/kotlin/com/datadog/gradle/utils/Version.kt new file mode 100644 index 0000000000..2aba684b9d --- /dev/null +++ b/buildSrc/src/main/kotlin/com/datadog/gradle/utils/Version.kt @@ -0,0 +1,31 @@ +package com.datadog.gradle.utils + +data class Version( + val major: Int, + val minor: Int, + val hotfix: Int +) { + + init { + require(major < MAX_MAJOR) { "The minor component must be smaller than $MAX_MAJOR" } + require(minor < MAX_MINOR) { "The minor component must be smaller than $MAX_MINOR" } + require(hotfix < MAX_HOTFIX) { "The hotfix component must be smaller than $MAX_HOTFIX" } + } + + val name: String + get() = "$major.$minor.$hotfix" + + val code: Int + get() { + val minPart = minor * MAX_HOTFIX + val majPart = major * MAX_MINOR * MAX_HOTFIX + + return hotfix + minPart + majPart + } + + companion object { + internal const val MAX_HOTFIX = 10 + internal const val MAX_MINOR = 100 + internal const val MAX_MAJOR = 100 + } +} diff --git a/buildSrc/src/test/kotlin/com/datadog/gradle/utils/VersionTest.kt b/buildSrc/src/test/kotlin/com/datadog/gradle/utils/VersionTest.kt new file mode 100644 index 0000000000..1e6629f5a2 --- /dev/null +++ b/buildSrc/src/test/kotlin/com/datadog/gradle/utils/VersionTest.kt @@ -0,0 +1,50 @@ +package com.datadog.gradle.utils + +import org.junit.Test + +class VersionTest { + + @Test(expected = IllegalArgumentException::class) + fun checkMajorInRange() { + Version(Version.MAX_MAJOR, 0, 0) + } + + @Test(expected = IllegalArgumentException::class) + fun checkMinorInRange() { + Version(0, Version.MAX_MINOR, 0) + } + + @Test(expected = IllegalArgumentException::class) + fun checkHotfixInRange() { + Version(0, 0, Version.MAX_HOTFIX) + } + + @Test + fun computesName() { + val name = Version(3, 12, 7).name + assert(name == "3.12.7") + } + + @Test + fun computesCode() { + val code = Version(3, 12, 7).code + + assert(code == 3127) { "expected code to be 3127 but was $code" } + } + + @Test + fun ensureCodeSequenceHotfix() { + val code = Version(3, 12, Version.MAX_HOTFIX - 1).code + val next = Version(3, 13, 0).code + + assert(code == next - 1) { "expected code to be next - 1 = ${next - 1} but was $code (@next:$next)" } + } + + @Test + fun ensureCodeSequenceMinor() { + val code = Version(3, Version.MAX_MINOR - 1, Version.MAX_HOTFIX - 1).code + val next = Version(4, 0, 0).code + + assert(code == next - 1) { "expected code to be next - 1 = ${next - 1} but was $code (@next:$next)" } + } +} diff --git a/dd-sdk-android/.gitignore b/dd-sdk-android/.gitignore new file mode 100644 index 0000000000..5a032f0558 --- /dev/null +++ b/dd-sdk-android/.gitignore @@ -0,0 +1,18 @@ +# Built application files +*.apk +*.ap_ +*.aab + +# Files for the ART/Dalvik VM +*.dex + +# Java class files +*.class + +# Generated files +bin/ +gen/ +out/ + +# Gradle files +build/ \ No newline at end of file diff --git a/dd-sdk-android/build.gradle.kts b/dd-sdk-android/build.gradle.kts new file mode 100644 index 0000000000..de6ad78300 --- /dev/null +++ b/dd-sdk-android/build.gradle.kts @@ -0,0 +1,44 @@ +import com.datadog.gradle.config.AndroidConfig +import com.datadog.gradle.config.dependencyUpdateConfig +import com.datadog.gradle.config.detektConfig +import com.datadog.gradle.config.kotlinConfig +import com.datadog.gradle.config.ktLintConfig + +plugins { + id("com.android.library") + kotlin("android") + kotlin("android.extensions") + id("com.github.ben-manes.versions") + id("io.gitlab.arturbosch.detekt") + id("org.jlleitschuh.gradle.ktlint") +} + +android { + compileSdkVersion(AndroidConfig.TARGET_SDK) + + defaultConfig { + minSdkVersion(AndroidConfig.MIN_SDK) + targetSdkVersion(AndroidConfig.TARGET_SDK) + versionCode = AndroidConfig.VERSION.code + versionName = AndroidConfig.VERSION.name + } + + sourceSets.named("main") { + java.srcDir("src/main/kotlin") + } + + testOptions { + unitTests.isReturnDefaultValues = true + } +} + +repositories { + google() + mavenCentral() + jcenter() +} + +kotlinConfig() +detektConfig() +ktLintConfig() +dependencyUpdateConfig() diff --git a/dd-sdk-android/src/main/AndroidManifest.xml b/dd-sdk-android/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..c29ed4413c --- /dev/null +++ b/dd-sdk-android/src/main/AndroidManifest.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/detekt.yml b/detekt.yml new file mode 100644 index 0000000000..f07d09a8e1 --- /dev/null +++ b/detekt.yml @@ -0,0 +1,550 @@ +build: + maxIssues: 0 + weights: + # complexity: 2 + # LongParameterList: 1 + # style: 1 + # comments: 1 + +processors: + active: true + exclude: + # - 'FunctionCountProcessor' + # - 'PropertyCountProcessor' + # - 'ClassCountProcessor' + # - 'PackageCountProcessor' + # - 'KtFileCountProcessor' + +console-reports: + active: true + exclude: + # - 'ProjectStatisticsReport' + # - 'ComplexityReport' + # - 'NotificationReport' + # - 'FindingsReport' + # - 'BuildFailureReport' + +comments: + active: true + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + CommentOverPrivateFunction: + active: true + CommentOverPrivateProperty: + active: true + EndOfSentenceFormat: + active: true + endOfSentenceFormat: ([.?!][ \t\n\r\f<])|([.?!:]$) + UndocumentedPublicClass: + active: true + searchInNestedClass: true + searchInInnerClass: true + searchInInnerObject: true + searchInInnerInterface: true + UndocumentedPublicFunction: + active: true + +complexity: + active: true + ComplexCondition: + active: true + threshold: 4 + ComplexInterface: + active: true + threshold: 10 + includeStaticDeclarations: false + ComplexMethod: + active: true + threshold: 10 + ignoreSingleWhenExpression: true + ignoreSimpleWhenEntries: true + LabeledExpression: + active: true + ignoredLabels: "" + LargeClass: + active: true + threshold: 600 + LongMethod: + active: true + threshold: 60 + LongParameterList: + active: true + threshold: 6 + ignoreDefaultParameters: false + MethodOverloading: + active: true + threshold: 6 + NestedBlockDepth: + active: true + threshold: 4 + StringLiteralDuplication: + active: true + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + threshold: 5 + ignoreAnnotation: true + excludeStringsWithLessThan5Characters: true + ignoreStringsRegex: '$^' + TooManyFunctions: + active: true + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + thresholdInFiles: 11 + thresholdInClasses: 11 + thresholdInInterfaces: 11 + thresholdInObjects: 11 + thresholdInEnums: 11 + ignoreDeprecated: false + ignorePrivate: false + ignoreOverridden: false + +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 + ignoreOverriddenFunctions: true + EmptyIfBlock: + active: true + EmptyInitBlock: + active: true + EmptyKtFile: + active: true + EmptySecondaryConstructor: + active: true + EmptyWhenBlock: + active: true + EmptyWhileBlock: + active: true + +exceptions: + active: true + ExceptionRaisedInUnexpectedLocation: + active: true + methodNames: 'toString,hashCode,equals,finalize' + InstanceOfCheckForException: + active: true + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + NotImplementedDeclaration: + active: true + PrintStackTrace: + active: true + RethrowCaughtException: + active: true + ReturnFromFinally: + active: true + SwallowedException: + active: true + ignoredExceptionTypes: 'InterruptedException,NumberFormatException,ParseException,MalformedURLException' + ThrowingExceptionFromFinally: + active: true + ThrowingExceptionInMain: + active: true + ThrowingExceptionsWithoutMessageOrCause: + active: true + exceptions: 'IllegalArgumentException,IllegalStateException,IOException' + ThrowingNewInstanceOfSameException: + active: true + TooGenericExceptionCaught: + active: true + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + exceptionNames: + - ArrayIndexOutOfBoundsException + - Error + - Exception + - IllegalMonitorStateException + - NullPointerException + - IndexOutOfBoundsException + - RuntimeException + - Throwable + allowedExceptionNameRegex: "^(_|(ignore|expected).*)" + TooGenericExceptionThrown: + active: true + exceptionNames: + - Error + - Exception + - Throwable + - RuntimeException + +formatting: + active: false + android: false + autoCorrect: true + AnnotationOnSeparateLine: + active: true + ChainWrapping: + active: true + autoCorrect: true + CommentSpacing: + active: true + autoCorrect: true + Filename: + active: true + FinalNewline: + active: true + autoCorrect: true + ImportOrdering: + active: true + Indentation: + active: true + indentSize: 4 + continuationIndentSize: 4 + MaximumLineLength: + active: true + maxLineLength: 120 + ModifierOrdering: + active: true + autoCorrect: true + MultiLineIfElse: + active: true + autoCorrect: true + NoBlankLineBeforeRbrace: + active: true + autoCorrect: true + NoConsecutiveBlankLines: + active: true + autoCorrect: true + NoEmptyClassBody: + active: true + autoCorrect: true + NoItParamInMultilineLambda: + active: true + NoLineBreakAfterElse: + active: true + autoCorrect: true + NoLineBreakBeforeAssignment: + active: true + autoCorrect: true + NoMultipleSpaces: + active: true + autoCorrect: true + NoSemicolons: + active: true + autoCorrect: true + NoTrailingSpaces: + active: true + autoCorrect: true + NoUnitReturn: + active: true + autoCorrect: true + NoUnusedImports: + active: true + autoCorrect: true + NoWildcardImports: + active: true + autoCorrect: true + PackageName: + active: true + autoCorrect: true + ParameterListWrapping: + active: true + autoCorrect: true + indentSize: 4 + SpacingAroundColon: + active: true + autoCorrect: true + SpacingAroundComma: + active: true + autoCorrect: true + SpacingAroundCurly: + active: true + autoCorrect: true + SpacingAroundDot: + active: true + autoCorrect: true + SpacingAroundKeyword: + active: true + autoCorrect: true + SpacingAroundOperators: + active: true + autoCorrect: true + SpacingAroundParens: + active: true + autoCorrect: true + SpacingAroundRangeOperator: + active: true + autoCorrect: true + SpacingAroundUnaryOperators: + active: true + autoCorrect: true + StringTemplate: + active: true + autoCorrect: true + +naming: + active: true + ClassNaming: + active: true + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + classPattern: '[A-Z$][a-zA-Z0-9$]*' + ConstructorParameterNaming: + active: true + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + parameterPattern: '[a-z][A-Za-z0-9]*' + privateParameterPattern: '[a-z][A-Za-z0-9]*' + excludeClassPattern: '$^' + EnumNaming: + active: true + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + enumEntryPattern: '^[A-Z][_a-zA-Z0-9]*' + ForbiddenClassName: + active: true + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + forbiddenName: '' + FunctionMaxLength: + active: true + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + maximumFunctionNameLength: 30 + FunctionMinLength: + active: true + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + minimumFunctionNameLength: 3 + FunctionNaming: + active: true + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + functionPattern: '^([a-z$][a-zA-Z$0-9]*)|(`.*`)$' + excludeClassPattern: '$^' + ignoreOverridden: true + FunctionParameterNaming: + active: true + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + parameterPattern: '[a-z][A-Za-z0-9]*' + excludeClassPattern: '$^' + ignoreOverriddenFunctions: true + InvalidPackageDeclaration: + active: true + rootPackage: '' + MatchingDeclarationName: + active: true + MemberNameEqualsClassName: + active: true + ignoreOverriddenFunction: true + ObjectPropertyNaming: + active: true + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + constantPattern: '[A-Za-z][_A-Za-z0-9]*' + propertyPattern: '[A-Za-z][_A-Za-z0-9]*' + privatePropertyPattern: '(_)?[A-Za-z][_A-Za-z0-9]*' + PackageNaming: + active: true + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + packagePattern: '^[a-z]+(\.[a-z][A-Za-z0-9]*)*$' + TopLevelPropertyNaming: + active: true + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + constantPattern: '[A-Z][_A-Z0-9]*' + propertyPattern: '[A-Za-z][_A-Za-z0-9]*' + privatePropertyPattern: '_?[A-Za-z][_A-Za-z0-9]*' + VariableMaxLength: + active: true + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + maximumVariableNameLength: 64 + VariableMinLength: + active: true + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + minimumVariableNameLength: 1 + VariableNaming: + active: true + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + variablePattern: '[a-z][A-Za-z0-9]*' + privateVariablePattern: '(_)?[a-z][A-Za-z0-9]*' + excludeClassPattern: '$^' + ignoreOverridden: true + +performance: + active: true + ArrayPrimitive: + active: true + ForEachOnRange: + active: true + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + SpreadOperator: + active: false + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + UnnecessaryTemporaryInstantiation: + active: true + +potential-bugs: + active: true + DuplicateCaseInWhenExpression: + active: true + EqualsAlwaysReturnsTrueOrFalse: + active: true + EqualsWithHashCodeExist: + active: true + ExplicitGarbageCollectionCall: + active: true + InvalidRange: + active: true + IteratorHasNextCallsNextMethod: + active: true + IteratorNotThrowingNoSuchElementException: + active: true + LateinitUsage: + active: false + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + excludeAnnotatedProperties: "" + ignoreOnClassesPattern: "" + MissingWhenCase: + active: true + RedundantElseInWhen: + active: true + UnconditionalJumpStatementInLoop: + active: true + UnreachableCode: + active: true + UnsafeCallOnNullableType: + active: true + UnsafeCast: + active: true + UselessPostfixExpression: + active: true + WrongEqualsTypeParameter: + active: true + +style: + active: false + CollapsibleIfStatements: + active: true + DataClassContainsFunctions: + active: true + conversionFunctionPrefix: 'to' + DataClassShouldBeImmutable: + active: true + EqualsNullCall: + active: true + EqualsOnSignatureLine: + active: true + ExplicitItLambdaParameter: + active: true + ExpressionBodySyntax: + active: false + includeLineWrapping: false + ForbiddenComment: + active: true + values: 'TODO:,FIXME:,STOPSHIP:' + ForbiddenImport: + active: true + imports: '' + ForbiddenVoid: + active: true + ignoreOverridden: false + FunctionOnlyReturningConstant: + active: true + ignoreOverridableFunction: true + excludedFunctions: 'describeContents' + LibraryCodeMustSpecifyReturnType: + active: true + LoopWithTooManyJumpStatements: + active: true + maxJumpCount: 1 + MagicNumber: + active: true + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + ignoreNumbers: '-1,0,1,2' + ignoreHashCodeFunction: true + ignorePropertyDeclaration: false + ignoreConstantDeclaration: true + ignoreCompanionObjectPropertyDeclaration: true + ignoreAnnotation: false + ignoreNamedArgument: true + ignoreEnums: false + ignoreRanges: false + MandatoryBracesIfStatements: + active: true + MaxLineLength: + active: true + maxLineLength: 120 + excludePackageStatements: true + excludeImportStatements: true + excludeCommentStatements: false + MayBeConst: + active: true + ModifierOrder: + active: true + NestedClassesVisibility: + active: true + NewLineAtEndOfFile: + active: false + NoTabs: + active: true + OptionalAbstractKeyword: + active: true + OptionalUnit: + active: true + OptionalWhenBraces: + active: true + PreferToOverPairSyntax: + active: true + ProtectedMemberInFinalClass: + active: true + RedundantVisibilityModifierRule: + active: true + ReturnCount: + active: true + max: 2 + excludedFunctions: "equals" + excludeLabeled: false + excludeReturnFromLambda: true + SafeCast: + active: true + SerialVersionUIDInSerializableClass: + active: true + SpacingBetweenPackageAndImports: + active: true + ThrowsCount: + active: true + max: 2 + TrailingWhitespace: + active: true + UnderscoresInNumericLiterals: + active: true + acceptableDecimalLength: 5 + UnnecessaryAbstractClass: + active: true + excludeAnnotatedClasses: "dagger.Module" + UnnecessaryApply: + active: true + UnnecessaryInheritance: + active: true + UnnecessaryLet: + active: true + UnnecessaryParentheses: + active: true + UntilInsteadOfRangeTo: + active: true + UnusedImports: + active: true + UnusedPrivateClass: + active: true + UnusedPrivateMember: + active: true + allowedNames: "(_|ignored|expected|serialVersionUID)" + UseCheckOrError: + active: true + UseDataClass: + active: true + excludeAnnotatedClasses: "" + UseRequire: + active: true + UselessCallOnNotNull: + active: true + UtilityClassWithPublicConstructor: + active: true + VarCouldBeVal: + active: true + WildcardImport: + active: true + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + excludeImports: 'java.util.*,kotlinx.android.synthetic.*' diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000..0d4a951687 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000..0ebb3108e2 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100755 index 0000000000..af6708ff22 --- /dev/null +++ b/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='"-Xmx64m"' + +# 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/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000000..6d57edc706 --- /dev/null +++ b/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="-Xmx64m" + +@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/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 0000000000..dac6f10cb0 --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1,23 @@ +import com.datadog.gradle.Dependencies + +pluginManagement { + resolutionStrategy { + eachPlugin { + if (requested.id.namespace == Dependencies.PluginNamespaces.Kotlin) { + useVersion(Dependencies.Versions.Kotlin) + } else if (requested.id.namespace == Dependencies.PluginNamespaces.KotlinAndroid) { + useVersion(Dependencies.Versions.Kotlin) + } else if (requested.id.namespace == Dependencies.PluginNamespaces.Detetk) { + useVersion(Dependencies.Versions.Detekt) + } else if (requested.id.namespace == Dependencies.PluginNamespaces.DependencyVersion) { + useVersion(Dependencies.Versions.DependencyVersion) + } else if (requested.id.namespace == Dependencies.PluginNamespaces.KtLint) { + useVersion(Dependencies.Versions.KtLint) + } else { + println("⋄⋄⋄ namespace:${requested.id.namespace} / name:${requested.id.name}") + } + } + } +} + +include(":dd-sdk-android")