Skip to content
This repository was archived by the owner on Jan 6, 2024. It is now read-only.

Commit 806b392

Browse files
authored
Merge pull request #1 from LikeTheSalad/release/1.3.0
Release/1.3.0
2 parents a602d63 + f6002aa commit 806b392

16 files changed

+286
-55
lines changed

LICENSE.txt

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2019 LikeTheSalad.
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

android-tools-plugin/build.gradle

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ plugins {
44
}
55

66
dependencies {
7-
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
87
compileOnly "com.android.tools.build:gradle:$androidBuild_version"
98
}
109

Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
package com.likethesalad.tools.android.plugin
22

3-
import com.android.build.gradle.AppExtension
4-
import com.android.build.gradle.BaseExtension
5-
import com.android.build.gradle.LibraryExtension
6-
import com.android.build.gradle.api.BaseVariant
7-
import com.likethesalad.tools.android.plugin.data.impl.DefaultAndroidExtension
8-
import com.likethesalad.tools.android.plugin.data.impl.DefaultAndroidVariantData
3+
import com.likethesalad.tools.android.plugin.data.strategies.PluginStrategy
94
import com.likethesalad.tools.android.plugin.extension.AndroidToolsPluginExtension
105
import com.likethesalad.tools.android.plugin.extension.observable.VariantPublisher
116
import org.gradle.api.Plugin
@@ -14,43 +9,19 @@ import org.gradle.api.Project
149
class AndroidToolsPlugin : Plugin<Project> {
1510

1611
private lateinit var publisher: VariantPublisher
17-
private lateinit var extension: AndroidToolsPluginExtension
1812

1913
companion object {
2014
private const val EXTENSION_NAME = "androidTools"
2115
}
2216

2317
override fun apply(project: Project) {
24-
val androidExtension = project.extensions.getByType(BaseExtension::class.java)
2518
publisher = VariantPublisher()
26-
createExtension(project, androidExtension)
27-
28-
when (androidExtension) {
29-
is AppExtension -> configureAppExtension(project, androidExtension)
30-
is LibraryExtension -> configureLibraryExtension(project, androidExtension)
31-
else -> throw UnsupportedOperationException("Android extension type not supported")
32-
}
33-
}
34-
35-
private fun configureLibraryExtension(project: Project, androidExtension: LibraryExtension) {
36-
androidExtension.libraryVariants.all {
37-
addVariantData(project, it)
38-
}
39-
}
40-
41-
private fun configureAppExtension(project: Project, androidExtension: AppExtension) {
42-
androidExtension.applicationVariants.all {
43-
addVariantData(project, it)
44-
}
45-
}
46-
47-
private fun addVariantData(project: Project, androidVariant: BaseVariant) {
48-
val variant = DefaultAndroidVariantData(project, androidVariant)
49-
publisher.publish(variant)
19+
val extension = createExtension(project)
20+
val pluginStrategy = PluginStrategy.getStrategy(project)
21+
extension.androidExtension = pluginStrategy.configure(project, publisher)
5022
}
5123

52-
private fun createExtension(project: Project, androidExtension: BaseExtension) {
53-
extension = project.extensions.create(EXTENSION_NAME, AndroidToolsPluginExtension::class.java, publisher)
54-
extension.androidExtension = DefaultAndroidExtension(androidExtension)
24+
private fun createExtension(project: Project): AndroidToolsPluginExtension {
25+
return project.extensions.create(EXTENSION_NAME, AndroidToolsPluginExtension::class.java, publisher)
5526
}
5627
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.likethesalad.tools.android.plugin.base
2+
3+
import org.gradle.api.DefaultTask
4+
import org.gradle.api.file.DirectoryProperty
5+
import org.gradle.api.tasks.OutputDirectory
6+
7+
abstract class BaseJavaBytecodeGeneratorTask : DefaultTask() {
8+
9+
@OutputDirectory
10+
val outputDir: DirectoryProperty = project.objects.directoryProperty()
11+
}
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
package com.likethesalad.tools.android.plugin.data
22

3-
import org.gradle.api.Task
3+
import com.likethesalad.tools.android.plugin.base.BaseJavaBytecodeGeneratorTask
44
import org.gradle.api.file.Directory
55
import org.gradle.api.file.FileCollection
66
import org.gradle.api.provider.Provider
7-
import org.gradle.api.tasks.AbstractCopyTask
87
import org.gradle.api.tasks.TaskProvider
98

109
interface AndroidVariantData {
@@ -13,7 +12,8 @@ interface AndroidVariantData {
1312
fun getVariantFlavors(): List<String>
1413
fun getLibrariesResources(): FileCollection
1514
fun getLibrariesJars(): FileCollection
16-
fun getProcessJavaResourcesProvider(): TaskProvider<AbstractCopyTask>
17-
fun getMergeResourcesProvider(): TaskProvider<out Task>
18-
fun registerGeneratedJavaBinaries(generator: TaskProvider<out Task>, outputDir: Provider<Directory>)
15+
fun registerGeneratedJavaBinaries(
16+
generator: TaskProvider<out BaseJavaBytecodeGeneratorTask>,
17+
outputDir: Provider<Directory>
18+
)
1919
}

android-tools-plugin/src/main/java/com/likethesalad/tools/android/plugin/data/impl/DefaultAndroidVariantData.kt

+5-11
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
package com.likethesalad.tools.android.plugin.data.impl
22

33
import com.android.build.gradle.api.BaseVariant
4+
import com.likethesalad.tools.android.plugin.base.BaseJavaBytecodeGeneratorTask
45
import com.likethesalad.tools.android.plugin.data.AndroidVariantData
56
import org.gradle.api.Action
67
import org.gradle.api.Project
7-
import org.gradle.api.Task
88
import org.gradle.api.artifacts.ArtifactView
99
import org.gradle.api.attributes.Attribute
1010
import org.gradle.api.file.Directory
1111
import org.gradle.api.file.FileCollection
1212
import org.gradle.api.provider.Provider
13-
import org.gradle.api.tasks.AbstractCopyTask
1413
import org.gradle.api.tasks.TaskProvider
1514

1615
class DefaultAndroidVariantData(
@@ -36,15 +35,10 @@ class DefaultAndroidVariantData(
3635
return getFilesFromConfiguration("android-classes-jar")
3736
}
3837

39-
override fun getProcessJavaResourcesProvider(): TaskProvider<AbstractCopyTask> {
40-
return variant.processJavaResourcesProvider
41-
}
42-
43-
override fun getMergeResourcesProvider(): TaskProvider<out Task> {
44-
return variant.mergeResourcesProvider
45-
}
46-
47-
override fun registerGeneratedJavaBinaries(generator: TaskProvider<out Task>, outputDir: Provider<Directory>) {
38+
override fun registerGeneratedJavaBinaries(
39+
generator: TaskProvider<out BaseJavaBytecodeGeneratorTask>,
40+
outputDir: Provider<Directory>
41+
) {
4842
val files = project.files(outputDir).builtBy(generator)
4943
variant.registerPreJavacGeneratedBytecode(files)
5044
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.likethesalad.tools.android.plugin.data.impl.componentextension
2+
3+
import com.android.build.api.dsl.CommonExtension
4+
import com.android.build.gradle.internal.api.DefaultAndroidSourceDirectorySet
5+
import com.likethesalad.tools.android.plugin.data.AndroidExtension
6+
import java.io.File
7+
8+
class ComponentAndroidExtension(private val androidExtension: CommonExtension<*, *, *, *>) : AndroidExtension {
9+
10+
override fun getVariantSrcDirs(variantName: String): Set<File> {
11+
return getVariantRes(variantName).srcDirs
12+
}
13+
14+
override fun setVariantSrcDirs(variantName: String, dirs: Set<File>) {
15+
getVariantRes(variantName).setSrcDirs(dirs)
16+
}
17+
18+
override fun addVariantSrcDir(variantName: String, dir: Any) {
19+
getVariantRes(variantName).srcDir(dir)
20+
}
21+
22+
private fun getVariantRes(variantName: String): DefaultAndroidSourceDirectorySet {
23+
return androidExtension.sourceSets.getByName(variantName).res as DefaultAndroidSourceDirectorySet
24+
}
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package com.likethesalad.tools.android.plugin.data.impl.componentextension
2+
3+
import com.android.build.api.artifact.MultipleArtifact
4+
import com.android.build.api.variant.Variant
5+
import com.likethesalad.tools.android.plugin.base.BaseJavaBytecodeGeneratorTask
6+
import com.likethesalad.tools.android.plugin.data.AndroidVariantData
7+
import org.gradle.api.Action
8+
import org.gradle.api.artifacts.ArtifactView
9+
import org.gradle.api.attributes.Attribute
10+
import org.gradle.api.file.Directory
11+
import org.gradle.api.file.FileCollection
12+
import org.gradle.api.provider.Provider
13+
import org.gradle.api.tasks.TaskProvider
14+
15+
@Suppress("UnstableApiUsage")
16+
class ComponentAndroidVariantData(private val variant: Variant) : AndroidVariantData {
17+
18+
companion object {
19+
private val artifactTypeAttr = Attribute.of("artifactType", String::class.java)
20+
}
21+
22+
override fun getVariantName(): String = variant.name
23+
24+
override fun getVariantType(): String = variant.buildType!!
25+
26+
override fun getVariantFlavors(): List<String> {
27+
return variant.productFlavors.map { it.second }
28+
}
29+
30+
override fun getLibrariesResources(): FileCollection {
31+
return getFilesFromConfiguration("android-res")
32+
}
33+
34+
override fun getLibrariesJars(): FileCollection {
35+
return getFilesFromConfiguration("android-classes-jar")
36+
}
37+
38+
override fun registerGeneratedJavaBinaries(
39+
generator: TaskProvider<out BaseJavaBytecodeGeneratorTask>,
40+
outputDir: Provider<Directory>
41+
) {
42+
variant.artifacts.use(generator)
43+
.wiredWith(BaseJavaBytecodeGeneratorTask::outputDir)
44+
.toAppendTo(MultipleArtifact.ALL_CLASSES_DIRS)
45+
}
46+
47+
private fun getFilesFromConfiguration(artifactType: String): FileCollection {
48+
return variant.runtimeConfiguration.incoming
49+
.artifactView(getAndroidArtifactViewAction(artifactType))
50+
.artifacts
51+
.artifactFiles
52+
}
53+
54+
private fun getAndroidArtifactViewAction(artifactType: String): Action<ArtifactView.ViewConfiguration> {
55+
return Action { config ->
56+
config.isLenient = false
57+
config.attributes {
58+
it.attribute(artifactTypeAttr, artifactType)
59+
}
60+
}
61+
}
62+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.likethesalad.tools.android.plugin.data.strategies
2+
3+
import com.likethesalad.tools.android.plugin.data.AndroidExtension
4+
import com.likethesalad.tools.android.plugin.extension.observable.VariantPublisher
5+
import com.likethesalad.tools.android.plugin.version.AgpApiHelper
6+
import org.gradle.api.Project
7+
8+
interface PluginStrategy {
9+
10+
companion object {
11+
fun getStrategy(project: Project): PluginStrategy {
12+
return if (AgpApiHelper.isLegacyApi(project)) {
13+
project.logger.info("Using legacy plugin strategy")
14+
Class.forName("com.likethesalad.tools.android.plugin.data.strategies.impl.LegacyPluginStrategy")
15+
.getDeclaredConstructor().newInstance() as PluginStrategy
16+
} else {
17+
project.logger.info("Using default plugin strategy")
18+
Class.forName("com.likethesalad.tools.android.plugin.data.strategies.impl.DefaultPluginStrategy")
19+
.getDeclaredConstructor().newInstance() as PluginStrategy
20+
}
21+
}
22+
}
23+
24+
fun configure(project: Project, publisher: VariantPublisher): AndroidExtension
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.likethesalad.tools.android.plugin.data.strategies.impl
2+
3+
import com.android.build.api.dsl.CommonExtension
4+
import com.android.build.api.variant.AndroidComponentsExtension
5+
import com.android.build.api.variant.Variant
6+
import com.likethesalad.tools.android.plugin.data.AndroidExtension
7+
import com.likethesalad.tools.android.plugin.data.impl.componentextension.ComponentAndroidExtension
8+
import com.likethesalad.tools.android.plugin.data.impl.componentextension.ComponentAndroidVariantData
9+
import com.likethesalad.tools.android.plugin.data.strategies.PluginStrategy
10+
import com.likethesalad.tools.android.plugin.extension.observable.VariantPublisher
11+
import org.gradle.api.Project
12+
13+
class DefaultPluginStrategy : PluginStrategy {
14+
15+
override fun configure(project: Project, publisher: VariantPublisher): AndroidExtension {
16+
val androidExtension = project.extensions.getByType(CommonExtension::class.java)
17+
val componentsExtension = project.extensions.getByType(AndroidComponentsExtension::class.java)
18+
19+
componentsExtension.onVariants {
20+
addVariantData(it, publisher)
21+
}
22+
23+
return ComponentAndroidExtension(androidExtension)
24+
}
25+
26+
private fun addVariantData(variant: Variant, publisher: VariantPublisher) {
27+
val androidVariantData = ComponentAndroidVariantData(variant)
28+
publisher.publish(androidVariantData)
29+
}
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package com.likethesalad.tools.android.plugin.data.strategies.impl
2+
3+
import com.android.build.gradle.AppExtension
4+
import com.android.build.gradle.BaseExtension
5+
import com.android.build.gradle.LibraryExtension
6+
import com.android.build.gradle.api.BaseVariant
7+
import com.likethesalad.tools.android.plugin.data.AndroidExtension
8+
import com.likethesalad.tools.android.plugin.data.impl.DefaultAndroidExtension
9+
import com.likethesalad.tools.android.plugin.data.impl.DefaultAndroidVariantData
10+
import com.likethesalad.tools.android.plugin.data.strategies.PluginStrategy
11+
import com.likethesalad.tools.android.plugin.extension.observable.VariantPublisher
12+
import org.gradle.api.Project
13+
14+
class LegacyPluginStrategy : PluginStrategy {
15+
16+
override fun configure(project: Project, publisher: VariantPublisher): AndroidExtension {
17+
val androidExtension = project.extensions.getByType(BaseExtension::class.java)
18+
when (androidExtension) {
19+
is AppExtension -> configureAppExtension(project, publisher, androidExtension)
20+
is LibraryExtension -> configureLibraryExtension(project, publisher, androidExtension)
21+
else -> throw UnsupportedOperationException("Android extension type not supported")
22+
}
23+
return DefaultAndroidExtension(androidExtension)
24+
}
25+
26+
private fun configureLibraryExtension(
27+
project: Project,
28+
publisher: VariantPublisher,
29+
androidExtension: LibraryExtension
30+
) {
31+
androidExtension.libraryVariants.all {
32+
addVariantData(project, publisher, it)
33+
}
34+
}
35+
36+
private fun configureAppExtension(project: Project, publisher: VariantPublisher, androidExtension: AppExtension) {
37+
androidExtension.applicationVariants.all {
38+
addVariantData(project, publisher, it)
39+
}
40+
}
41+
42+
private fun addVariantData(project: Project, publisher: VariantPublisher, androidVariant: BaseVariant) {
43+
val variant = DefaultAndroidVariantData(project, androidVariant)
44+
publisher.publish(variant)
45+
}
46+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.likethesalad.tools.android.plugin.version
2+
3+
import org.gradle.api.Project
4+
5+
object AgpApiHelper {
6+
7+
fun isLegacyApi(project: Project): Boolean {
8+
if (!isAndroidComponentsAvailable()) {
9+
return true
10+
}
11+
val componentsHelper = Class.forName("com.likethesalad.tools.android.plugin.version.AgpComponentsHelperImpl")
12+
.getDeclaredConstructor(Project::class.java).newInstance(project) as AgpComponentsHelper
13+
return componentsHelper.isVersionLowerThan(7, 3)
14+
}
15+
16+
private fun isAndroidComponentsAvailable(): Boolean {
17+
return try {
18+
Class.forName("com.android.build.api.variant.AndroidComponentsExtension", false, javaClass.classLoader)
19+
true
20+
} catch (e: ClassNotFoundException) {
21+
false
22+
}
23+
}
24+
}

0 commit comments

Comments
 (0)