1 /* <lambda>null2 * Copyright 2024 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 org.gradle.api.DefaultTask 20 import org.gradle.api.Project 21 import org.gradle.api.artifacts.Configuration 22 import org.gradle.api.attributes.Category 23 import org.gradle.api.attributes.DocsType 24 import org.gradle.api.attributes.LibraryElements 25 import org.gradle.api.attributes.Usage 26 import org.gradle.api.file.ConfigurableFileCollection 27 import org.gradle.api.file.RegularFileProperty 28 import org.gradle.api.tasks.InputFiles 29 import org.gradle.api.tasks.OutputFile 30 import org.gradle.api.tasks.PathSensitive 31 import org.gradle.api.tasks.PathSensitivity 32 import org.gradle.api.tasks.TaskAction 33 import org.gradle.kotlin.dsl.named 34 import org.gradle.work.DisableCachingByDefault 35 36 /** 37 * Used to configure a project that will be providing documentation samples. 38 * 39 * Can only be called once so only one samples library can exist per library b/318840087. 40 */ 41 internal fun Project.configureSamplesProject() { 42 fun Configuration.setResolveSources() { 43 // While a sample library can have more dependencies than the library it has samples 44 // for, in Studio sample code is not executable or inspectable, so we don't need them. 45 isTransitive = false 46 isCanBeConsumed = false 47 attributes { 48 it.attribute(Usage.USAGE_ATTRIBUTE, project.objects.named<Usage>(Usage.JAVA_RUNTIME)) 49 it.attribute( 50 Category.CATEGORY_ATTRIBUTE, 51 project.objects.named<Category>(Category.DOCUMENTATION) 52 ) 53 it.attribute( 54 DocsType.DOCS_TYPE_ATTRIBUTE, 55 project.objects.named<DocsType>(DocsType.SOURCES) 56 ) 57 it.attribute( 58 LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, 59 project.objects.named<LibraryElements>(LibraryElements.JAR) 60 ) 61 } 62 } 63 64 val samplesConfiguration = 65 project.configurations.register("samples") { 66 it.isVisible = false 67 it.isCanBeConsumed = false 68 it.isCanBeResolved = true 69 it.setResolveSources() 70 } 71 72 project.tasks.register("copySampleSourceJars", LazyInputsCopyTask::class.java) { task -> 73 task.inputJars.from(samplesConfiguration.map { it.incoming.artifactView {}.files }) 74 val srcJarFilename = "${project.name}-${project.version}-samples-sources.jar" 75 task.destinationJar.set(project.layout.buildDirectory.file(srcJarFilename)) 76 } 77 } 78 79 /** 80 * This is necessary because we need to delay artifact resolution until after configuration. If one 81 * sample is used by multiple libraries (e.g. paging-samples) it is copied several times. This is to 82 * avoid caching failures. There should be a better way that avoids needing this. 83 */ 84 @DisableCachingByDefault(because = "caching large output files is more expensive than copying") 85 abstract class LazyInputsCopyTask : DefaultTask() { 86 @get:[InputFiles PathSensitive(value = PathSensitivity.RELATIVE)] 87 abstract val inputJars: ConfigurableFileCollection 88 @get:OutputFile abstract val destinationJar: RegularFileProperty 89 90 @TaskAction copyActionnull91 fun copyAction() { 92 inputJars.files.single().copyTo(destinationJar.get().asFile, overwrite = true) 93 } 94 } 95