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 }