| /* |
| * Copyright 2019 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package androidx.build |
| |
| import org.gradle.api.DefaultTask |
| import org.gradle.api.GradleException |
| import org.gradle.api.Project |
| import org.gradle.api.Task |
| import org.gradle.api.provider.Property |
| import org.gradle.api.tasks.Input |
| import org.gradle.api.tasks.OutputFile |
| import org.gradle.api.tasks.TaskAction |
| import java.io.File |
| |
| /** |
| * Finds the outputs of every task and saves this mapping into a file |
| */ |
| abstract class ListTaskOutputsTask() : DefaultTask() { |
| @OutputFile |
| val outputFile: Property<File> = project.objects.property(File::class.java) |
| @Input |
| val removePrefixes: MutableList<String> = mutableListOf() |
| @Input |
| val tasks: MutableList<Task> = mutableListOf() |
| |
| init { |
| group = "Help" |
| outputs.upToDateWhen { false } |
| } |
| |
| fun setOutput(f: File) { |
| outputFile.set(f) |
| description = "Finds the outputs of every task and saves the resulting mapping into $f" |
| } |
| |
| fun removePrefix(prefix: String) { |
| removePrefixes.add(prefix + "/") |
| } |
| |
| fun format(tasksByOutput: Map<File, Task>): String { |
| val messages: MutableList<String> = mutableListOf() |
| for ((output, task) in tasksByOutput) { |
| var filePath = output.path |
| for (prefix in removePrefixes) { |
| filePath = filePath.removePrefix(prefix) |
| } |
| |
| val keyLength = filePath.length.toInt() |
| val roundedKeyLength = ((keyLength / 32) + 1) * 32 |
| val extraSpaces = " ".repeat(roundedKeyLength - keyLength) |
| messages.add("$filePath $extraSpaces - ${task.path}") |
| } |
| messages.sort() |
| val text = messages.joinToString("\n") |
| return text |
| } |
| |
| @TaskAction |
| fun exec() { |
| val tasksByOutput = project.rootProject.findAllTasksByOutput() |
| val text = format(tasksByOutput) |
| val outputFile = outputFile.get() |
| outputFile.writeText(text) |
| logger.lifecycle("Wrote ${outputFile.path}") |
| } |
| } |
| |
| // TODO(149103692): remove all elements of this set |
| val taskNamesKnownToDuplicateOutputs = setOf( |
| "buildOnServer", |
| "dist", |
| "generateReleaseNotes", |
| "jarRelease", |
| "jarDebug", |
| "kotlinSourcesJar", |
| "lint", |
| "lintFix", |
| "lintVital", |
| "sourceJar", |
| "zipResultsOfJvmTest", |
| "zipResultsOfTestDebugUnitTest", |
| "zipResultsOfTestReleaseUnitTest", |
| "zipResultsOfTestTipOfTreeDebugUnitTest", |
| "zipResultsOfTestTipOfTreeReleaseUnitTest", |
| "zipResultsOfTestPublicDebugUnitTest", |
| "zipResultsOfTestPublicReleaseUnitTest" |
| ) |
| |
| // For this project and all subprojects, collects all tasks and creates a map keyed by their output files |
| fun Project.findAllTasksByOutput(): Map<File, Task> { |
| // find list of all tasks |
| val allTasks = mutableListOf<Task>() |
| project.allprojects { otherProject -> |
| otherProject.tasks.all { task -> |
| allTasks.add(task) |
| } |
| } |
| |
| // group tasks by their outputs |
| val tasksByOutput: MutableMap<File, Task> = hashMapOf() |
| for (otherTask in allTasks) { |
| for (otherTaskOutput in otherTask.outputs.files.files) { |
| val existingTask = tasksByOutput[otherTaskOutput] |
| if (existingTask != null) { |
| if (!taskNamesKnownToDuplicateOutputs.contains(otherTask.name) || |
| !taskNamesKnownToDuplicateOutputs.contains(existingTask.name)) { |
| throw GradleException("Output file " + otherTaskOutput + |
| " was declared as an output of multiple tasks: " + otherTask + " and " + |
| existingTask) |
| } |
| } |
| tasksByOutput.put(otherTaskOutput, otherTask) |
| } |
| } |
| return tasksByOutput |
| } |