1 /*
2  * 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.build
18 
19 import com.android.build.api.variant.LibraryAndroidComponentsExtension
20 import java.io.File
21 import java.io.PrintWriter
22 import org.gradle.api.DefaultTask
23 import org.gradle.api.Project
24 import org.gradle.api.file.DirectoryProperty
25 import org.gradle.api.provider.Property
26 import org.gradle.api.tasks.Input
27 import org.gradle.api.tasks.OutputDirectory
28 import org.gradle.api.tasks.TaskAction
29 import org.gradle.api.tasks.TaskProvider
30 import org.gradle.work.DisableCachingByDefault
31 import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
32 
33 /** Task that allows to write a version to a given output file. */
34 @DisableCachingByDefault(because = "Doesn't benefit from caching")
35 abstract class VersionFileWriterTask : DefaultTask() {
36     @get:Input abstract val version: Property<String>
37     @get:Input abstract val relativePath: Property<String>
38     @get:OutputDirectory abstract val outputDir: DirectoryProperty
39 
40     /** The main method for actually writing out the file. */
41     @TaskAction
runnull42     fun run() {
43         val outputFile = File(outputDir.get().asFile, relativePath.get())
44         outputFile.parentFile.mkdirs()
45         val writer = PrintWriter(outputFile)
46         writer.println(version.get())
47         writer.close()
48     }
49 
50     internal companion object {
51         const val TASK_NAME = "writeVersionFile"
52     }
53 }
54 
55 /**
56  * Sets up Android Library project to have a task that generates a version file.
57  *
58  * @receiver an Android Library project.
59  */
Projectnull60 fun Project.configureVersionFileWriter(
61     libraryAndroidComponentsExtension: LibraryAndroidComponentsExtension,
62     androidXExtension: AndroidXExtension
63 ) {
64     val writeVersionFile =
65         tasks.register(VersionFileWriterTask.TASK_NAME, VersionFileWriterTask::class.java)
66 
67     afterEvaluate { configureVersionFile(writeVersionFile, androidXExtension) }
68     libraryAndroidComponentsExtension.onVariants {
69         it.sources.resources!!.addGeneratedSourceDirectory(
70             writeVersionFile,
71             VersionFileWriterTask::outputDir
72         )
73     }
74 }
75 
Projectnull76 fun Project.configureVersionFileWriter(
77     kmpExtension: KotlinMultiplatformExtension,
78     androidXExtension: AndroidXExtension
79 ) {
80     val writeVersionFile =
81         tasks.register(VersionFileWriterTask.TASK_NAME, VersionFileWriterTask::class.java)
82     writeVersionFile.configure {
83         it.outputDir.set(layout.buildDirectory.dir("generatedVersionFile"))
84     }
85     val sourceSet = kmpExtension.sourceSets.getByName("androidMain")
86     val resources = sourceSet.resources
87     val includes = resources.includes
88     resources.srcDir(writeVersionFile.map { it.outputDir })
89     if (includes.isNotEmpty()) {
90         includes.add("META-INF/*.version")
91         resources.setIncludes(includes)
92     }
93     afterEvaluate { configureVersionFile(writeVersionFile, androidXExtension) }
94 }
95 
Projectnull96 private fun Project.configureVersionFile(
97     writeVersionFile: TaskProvider<VersionFileWriterTask>,
98     androidXExtension: AndroidXExtension
99 ) {
100     writeVersionFile.configure {
101         val group = project.getGroup() as String
102         val artifactId = project.getName() as String
103         val version =
104             if (androidXExtension.shouldPublish()) {
105                 version().toString()
106             } else {
107                 "0.0.0"
108             }
109 
110         it.version.set(version)
111         it.relativePath.set(String.format("META-INF/%s_%s.version", group, artifactId))
112 
113         // We only add version file if is a library that is publishing.
114         it.enabled = androidXExtension.shouldPublish()
115     }
116 }
117