Skip to content

Commit

Permalink
Support Android flavors and buildTypes out of the box and add include…
Browse files Browse the repository at this point in the history
… Configuration extension point to Generator. (#9)
  • Loading branch information
vanniktech authored Mar 6, 2018
1 parent fc6512e commit 89dd665
Show file tree
Hide file tree
Showing 5 changed files with 164 additions and 20 deletions.
27 changes: 16 additions & 11 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
language: groovy
language: android

groovy:
- 2.3.6
- 2.3.9

jdk:
- oraclejdk8
jdk: oraclejdk8

before_install:
- pip install --user codecov

install: true
# Download SDK
- yes | sdkmanager "tools" &>/dev/null
- yes | sdkmanager "platform-tools" &>/dev/null
- yes | sdkmanager "build-tools;27.0.3" &>/dev/null
- yes | sdkmanager "platforms;android-27" &>/dev/null
# Update remaining dependencies and accept licenses
- yes | sdkmanager --update &>/dev/null
- yes | sdkmanager --licenses &>/dev/null

script: ./gradlew clean build

Expand All @@ -32,7 +33,11 @@ notifications:

sudo: false

before_cache:
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
- rm -fr $HOME/.gradle/caches/*/plugin-resolution/
cache:
directories:
- $HOME/.gradle
- $HOME/.m2
- $HOME/.gradle/caches/
- $HOME/.gradle/wrapper/
- $HOME/.android/build-cache
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ dependencies {

testImplementation 'junit:junit:4.12'
testImplementation 'org.assertj:assertj-core:3.9.1'
testImplementation 'com.android.tools.build:gradle:3.0.1'
testImplementation "org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion"
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.vanniktech.dependency.graph.generator
import com.vanniktech.dependency.graph.generator.DependencyGraphGeneratorExtension.Generator.Companion.ALL
import com.vanniktech.dependency.graph.generator.dot.GraphFormattingOptions
import com.vanniktech.dependency.graph.generator.dot.Header
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.ResolvedDependency

/**
Expand Down Expand Up @@ -33,7 +34,13 @@ open class DependencyGraphGeneratorExtension {
/** The formatting options for the root - the project this generator is applied too. */
val rootFormattingOptions: GraphFormattingOptions = GraphFormattingOptions(),
/** Optional header that can be displayed wrapped around the graph. */
val header: Header? = null
val header: Header? = null,
/** Return true when you want to include this configuration, false otherwise. */
val includeConfiguration: (Configuration) -> Boolean = {
// By default we'll include everything that's on the compileClassPath except test, UnitTest and AndroidTest configurations.
val raw = it.name.replace("compileClasspath", "", ignoreCase = true)
it.name.contains("compileClassPath", ignoreCase = true) && listOf("test", "AndroidTest", "UnitTest").none { raw.contains(it) }
}
) {
/** Gradle task name that is associated with this generator. */
val gradleTaskName = "generateDependencyGraph${name.capitalize()}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,7 @@ internal class DotGenerator(
.flatMap { project ->
project.configurations
.filter { it.isCanBeResolved }
.filter {
// TODO this is not optimal but will do for now.
val isCompileClassPath = it.name == "compileClasspath"
val isAndroidProjectClassPath = it.name == "debugCompileClasspath" || it.name == "releaseCompileClasspath"
isCompileClassPath || isAndroidProjectClassPath
}
.filter { generator.includeConfiguration.invoke(it) }
.flatMap { it.resolvedConfiguration.firstLevelModuleDependencies }
.map { project to it }
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.vanniktech.dependency.graph.generator

import com.android.build.gradle.AppExtension
import com.android.build.gradle.AppPlugin
import com.vanniktech.dependency.graph.generator.DependencyGraphGeneratorExtension.Generator.Companion.ALL
import com.vanniktech.dependency.graph.generator.dot.Header
import com.vanniktech.dependency.graph.generator.dot.Color.Companion.MAX_COLOR_VALUE
Expand All @@ -10,20 +12,25 @@ import com.vanniktech.dependency.graph.generator.dot.GraphFormattingOptions
import org.assertj.core.api.Java6Assertions.assertThat
import org.gradle.api.Project
import org.gradle.api.artifacts.ResolvedDependency
import org.gradle.api.internal.project.DefaultProject
import org.gradle.api.plugins.JavaLibraryPlugin
import org.gradle.testfixtures.ProjectBuilder
import org.junit.Before
import org.junit.Test
import java.io.File
import java.util.Random

class DotGeneratorTest {
private lateinit var singleEmpty: Project
private lateinit var singleProject: Project

private lateinit var multiProject: Project
private lateinit var androidProject: DefaultProject
private lateinit var androidProjectExtension: AppExtension

@Before fun setUp() {
@Before @Suppress("Detekt.LongMethod") fun setUp() {
singleEmpty = ProjectBuilder.builder().withName("singleempty").build()
singleEmpty.plugins.apply(JavaLibraryPlugin::class.java)
singleEmpty.repositories.run { add(mavenCentral()) }

singleProject = ProjectBuilder.builder().withName("single").build()
singleProject.plugins.apply(JavaLibraryPlugin::class.java)
Expand All @@ -44,6 +51,30 @@ class DotGeneratorTest {
multiProject2.repositories.run { add(mavenCentral()) }
multiProject2.dependencies.add("implementation", "io.reactivex.rxjava2:rxjava:2.1.10")
multiProject2.dependencies.add("implementation", "io.reactivex.rxjava2:rxandroid:2.0.2")

androidProject = ProjectBuilder.builder().withName("android").build() as DefaultProject
androidProject.plugins.apply(AppPlugin::class.java)
androidProject.repositories.run { add(mavenCentral()) }

androidProjectExtension = androidProject.extensions.getByType(AppExtension::class.java)
androidProjectExtension.compileSdkVersion(27)
val manifestFile = File(androidProject.projectDir, "src/main/AndroidManifest.xml")
manifestFile.parentFile.mkdirs()
manifestFile.writeText("""
|<?xml version="1.0" encoding="utf-8"?>
|<manifest package="com.foo.bar" xmlns:android="http://schemas.android.com/apk/res/android">
| <application/>
|</manifest>""".trimMargin())
}

@Test fun singleProjectAllNoTestDependencies() {
singleEmpty.dependencies.add("testImplementation", "junit:junit:4.12")

assertThat(DotGenerator(singleEmpty, ALL).generateContent()).isEqualTo("""
|digraph G {
| singleempty [label="singleempty", shape="box"];
|}
|""".trimMargin())
}

@Test fun singleProjectEmptyAll() {
Expand Down Expand Up @@ -190,4 +221,109 @@ class DotGeneratorTest {
|}
|""".trimMargin())
}

@Test fun androidProjectIncludeAllFlavorsByDefault() {
androidProjectExtension.flavorDimensions("test")
androidProjectExtension.productFlavors {
it.create("flavor1").dimension = "test"
it.create("flavor2").dimension = "test"
}

androidProject.evaluate() // Since we're adding custom productFlavors we need this.

androidProject.dependencies.add("flavor1Implementation", "io.reactivex.rxjava2:rxandroid:2.0.2")
androidProject.dependencies.add("flavor2DebugImplementation", "io.reactivex.rxjava2:rxjava:2.1.10")
androidProject.dependencies.add("flavor2ReleaseImplementation", "org.jetbrains.kotlin:kotlin-stdlib:1.2.30")

assertThat(DotGenerator(androidProject, ALL).generateContent()).isEqualTo("""
|digraph G {
| android [label="android", shape="box"];
| ioreactivexrxjava2rxandroid [label="rxandroid", shape="box"];
| android -> ioreactivexrxjava2rxandroid;
| ioreactivexrxjava2rxjava [label="rxjava", shape="box"];
| ioreactivexrxjava2rxandroid -> ioreactivexrxjava2rxjava;
| orgreactivestreamsreactivestreams [label="reactive-streams", shape="box"];
| ioreactivexrxjava2rxjava -> orgreactivestreamsreactivestreams;
| ioreactivexrxjava2rxjava [label="rxjava", shape="box"];
| android -> ioreactivexrxjava2rxjava;
| orgjetbrainskotlinkotlinstdlib [label="kotlin-stdlib", shape="box"];
| android -> orgjetbrainskotlinkotlinstdlib;
| orgjetbrainsannotations [label="annotations", shape="box"];
| orgjetbrainskotlinkotlinstdlib -> orgjetbrainsannotations;
|}
|""".trimMargin())
}

@Test fun androidProjectIncludeAllBuildTypesByDefault() {
androidProjectExtension.buildTypes {
it.create("staging")
}

androidProject.evaluate() // Since we're adding a custom buildType we need this.

androidProject.dependencies.add("releaseImplementation", "io.reactivex.rxjava2:rxandroid:2.0.2")
androidProject.dependencies.add("debugImplementation", "io.reactivex.rxjava2:rxjava:2.1.10")
androidProject.dependencies.add("stagingImplementation", "org.jetbrains.kotlin:kotlin-stdlib:1.2.30")

assertThat(DotGenerator(androidProject, ALL).generateContent()).isEqualTo("""
|digraph G {
| android [label="android", shape="box"];
| ioreactivexrxjava2rxjava [label="rxjava", shape="box"];
| android -> ioreactivexrxjava2rxjava;
| orgreactivestreamsreactivestreams [label="reactive-streams", shape="box"];
| ioreactivexrxjava2rxjava -> orgreactivestreamsreactivestreams;
| ioreactivexrxjava2rxandroid [label="rxandroid", shape="box"];
| android -> ioreactivexrxjava2rxandroid;
| ioreactivexrxjava2rxjava [label="rxjava", shape="box"];
| ioreactivexrxjava2rxandroid -> ioreactivexrxjava2rxjava;
| orgjetbrainskotlinkotlinstdlib [label="kotlin-stdlib", shape="box"];
| android -> orgjetbrainskotlinkotlinstdlib;
| orgjetbrainsannotations [label="annotations", shape="box"];
| orgjetbrainskotlinkotlinstdlib -> orgjetbrainsannotations;
|}
|""".trimMargin())
}

@Suppress("Detekt.UnnecessaryParentheses") // https://github.com/arturbosch/detekt/issues/767
@Test fun androidProjectIncludeOnlyStagingCompileClasspath() {
androidProjectExtension.buildTypes {
it.create("staging")
}

androidProject.evaluate() // Since we're adding a custom buildType we need this.

androidProject.dependencies.add("releaseImplementation", "io.reactivex.rxjava2:rxandroid:2.0.2")
androidProject.dependencies.add("debugImplementation", "io.reactivex.rxjava2:rxjava:2.1.10")
androidProject.dependencies.add("stagingImplementation", "org.jetbrains.kotlin:kotlin-stdlib:1.2.30")

assertThat(DotGenerator(androidProject, ALL.copy(includeConfiguration = { it.name == "stagingCompileClasspath" })).generateContent()).isEqualTo("""
|digraph G {
| android [label="android", shape="box"];
| orgjetbrainskotlinkotlinstdlib [label="kotlin-stdlib", shape="box"];
| android -> orgjetbrainskotlinkotlinstdlib;
| orgjetbrainsannotations [label="annotations", shape="box"];
| orgjetbrainskotlinkotlinstdlib -> orgjetbrainsannotations;
|}
|""".trimMargin())
}

@Test fun androidProjectDoNotIncludeTestDependency() {
androidProject.dependencies.add("testImplementation", "junit:junit:4.12")

assertThat(DotGenerator(androidProject, ALL).generateContent()).isEqualTo("""
|digraph G {
| android [label="android", shape="box"];
|}
|""".trimMargin())
}

@Test fun androidProjectDoNotIncludeAndroidTestDependency() {
androidProject.dependencies.add("androidTestImplementation", "junit:junit:4.12")

assertThat(DotGenerator(androidProject, ALL).generateContent()).isEqualTo("""
|digraph G {
| android [label="android", shape="box"];
|}
|""".trimMargin())
}
}

0 comments on commit 89dd665

Please sign in to comment.