1 /*
<lambda>null2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package androidx.navigation.safeargs.gradle
18
19 import com.android.build.gradle.AppExtension
20 import com.android.build.gradle.api.BaseVariant
21 import groovy.util.XmlSlurper
22 import org.gradle.api.GradleException
23 import org.gradle.api.Plugin
24 import org.gradle.api.Project
25 import java.io.File
26
27 private const val PLUGIN_DIRNAME = "navigation-args"
28 internal const val GENERATED_PATH = "generated/source/$PLUGIN_DIRNAME"
29 internal const val INTERMEDIATES_PATH = "intermediates/$PLUGIN_DIRNAME"
30
31 @Suppress("unused")
32 class SafeArgsPlugin : Plugin<Project> {
33
34 override fun apply(project: Project) {
35 val appExtension = project.extensions.findByType(AppExtension::class.java)
36 ?: throw GradleException("safeargs plugin must be used with android plugin")
37 appExtension.applicationVariants.all { variant ->
38 val task = project.tasks.create("generateSafeArgs${variant.name.capitalize()}",
39 ArgumentsGenerationTask::class.java) { task ->
40 task.rFilePackage = variant.rFilePackage()
41 task.applicationId = variant.applicationId
42 task.navigationFiles = navigationFiles(variant)
43 task.outputDir = File(project.buildDir, "$GENERATED_PATH/${variant.dirName}")
44 task.incrementalFolder = File(project.buildDir,
45 "$INTERMEDIATES_PATH/${variant.dirName}")
46 task.variantName = variant.name
47 }
48 variant.registerJavaGeneratingTask(task, task.outputDir)
49 }
50 }
51 }
52
navigationFilesnull53 private fun navigationFiles(variant: BaseVariant) = variant.sourceSets
54 .flatMap { it.resDirectories }
<lambda>null55 .mapNotNull {
56 File(it, "navigation").let { navFolder ->
57 if (navFolder.exists() && navFolder.isDirectory) navFolder else null
58 }
59 }
navFoldernull60 .flatMap { navFolder -> navFolder.listFiles().asIterable() }
filenull61 .groupBy { file -> file.name }
entrynull62 .map { entry -> entry.value.last() }
63
BaseVariantnull64 private fun BaseVariant.rFilePackage(): String {
65 val mainSourceSet = sourceSets.find { it.name == "main" }
66 val sourceSet = mainSourceSet ?: sourceSets[0]
67 val manifest = sourceSet.manifestFile
68 val parsed = XmlSlurper(false, false).parse(manifest)
69 return parsed.getProperty("@package").toString()
70 }