blob: d8170023aea4e589212fd60ec6a4e77f5598c654 [file] [log] [blame]
/*
* Copyright (C) 2015 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 com.android.build.gradle.internal.scope;
import static com.android.build.gradle.internal.publishing.AndroidArtifacts.ARTIFACT_TYPE;
import static com.android.build.gradle.internal.publishing.AndroidArtifacts.MOCKABLE_JAR_RETURN_DEFAULT_VALUES;
import static com.android.builder.core.BuilderConstants.FD_REPORTS;
import static com.android.builder.model.AndroidProject.FD_INTERMEDIATES;
import static com.android.builder.model.AndroidProject.FD_OUTPUTS;
import static com.google.common.base.Preconditions.checkNotNull;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.build.gradle.BaseExtension;
import com.android.build.gradle.internal.SdkComponents;
import com.android.build.gradle.internal.api.dsl.DslScope;
import com.android.build.gradle.internal.dsl.BaseAppModuleExtension;
import com.android.build.gradle.internal.publishing.AndroidArtifacts;
import com.android.build.gradle.options.ProjectOptions;
import com.android.builder.model.OptionalCompilationStep;
import com.android.builder.utils.FileCache;
import com.android.ide.common.blame.MessageReceiver;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import java.io.File;
import java.util.Set;
import org.gradle.api.Action;
import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.attributes.AttributeContainer;
import org.gradle.api.component.SoftwareComponentFactory;
import org.gradle.api.file.ConfigurableFileCollection;
import org.gradle.api.file.FileCollection;
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry;
/** A scope containing data for the Android plugin. */
public class GlobalScope {
@NonNull private final Project project;
@NonNull private BaseExtension extension;
@NonNull private final SdkComponents sdkComponents;
@NonNull private final ToolingModelBuilderRegistry toolingRegistry;
@NonNull private final Set<OptionalCompilationStep> optionalCompilationSteps;
@Nullable private final FileCache buildCache;
@NonNull private final MessageReceiver messageReceiver;
@NonNull private final SoftwareComponentFactory componentFactory;
@NonNull private final String createdBy;
@NonNull private final DslScope dslScope;
@NonNull private Configuration lintChecks;
@NonNull private Configuration lintPublish;
private Configuration androidJarConfig;
@NonNull private final BuildArtifactsHolder globalArtifacts;
@Nullable private ConfigurableFileCollection bootClasspath = null;
public GlobalScope(
@NonNull Project project,
@NonNull String createdBy,
@NonNull DslScope dslScope,
@NonNull SdkComponents sdkComponents,
@NonNull ToolingModelBuilderRegistry toolingRegistry,
@Nullable FileCache buildCache,
@NonNull MessageReceiver messageReceiver,
@NonNull SoftwareComponentFactory componentFactory) {
// Attention: remember that this code runs early in the build lifecycle, project may not
// have been fully configured yet (e.g. buildDir can still change).
this.project = checkNotNull(project);
this.createdBy = createdBy;
this.dslScope = checkNotNull(dslScope);
this.sdkComponents = checkNotNull(sdkComponents);
this.toolingRegistry = checkNotNull(toolingRegistry);
this.optionalCompilationSteps =
checkNotNull(dslScope.getProjectOptions().getOptionalCompilationSteps());
this.buildCache = buildCache;
this.messageReceiver = messageReceiver;
this.componentFactory = componentFactory;
this.globalArtifacts = new GlobalBuildArtifactsHolder(project, this::getBuildDir);
// Create empty configurations before these have been set.
this.lintChecks = project.getConfigurations().detachedConfiguration();
}
public void setExtension(@NonNull BaseExtension extension) {
this.extension = checkNotNull(extension);
}
@NonNull
public BuildFeatureValues getBuildFeatures() {
return dslScope.getBuildFeatures();
}
@NonNull
public Project getProject() {
return project;
}
@NonNull
public String getCreatedBy() {
return createdBy;
}
@NonNull
public BaseExtension getExtension() {
return extension;
}
@NonNull
public String getProjectBaseName() {
return (String) project.property("archivesBaseName");
}
@NonNull
public SdkComponents getSdkComponents() {
return sdkComponents;
}
@NonNull
public ToolingModelBuilderRegistry getToolingRegistry() {
return toolingRegistry;
}
@NonNull
public File getBuildDir() {
return project.getBuildDir();
}
@NonNull
public File getIntermediatesDir() {
return new File(getBuildDir(), FD_INTERMEDIATES);
}
@NonNull
public File getReportsDir() {
return new File(getBuildDir(), FD_REPORTS);
}
public File getTestResultsFolder() {
return new File(getBuildDir(), "test-results");
}
public File getTestReportFolder() {
return new File(getBuildDir(), "reports/tests");
}
@NonNull
public File getTmpFolder() {
return new File(getIntermediatesDir(), "tmp");
}
@NonNull
public File getOutputsDir() {
return new File(getBuildDir(), FD_OUTPUTS);
}
public boolean isActive(OptionalCompilationStep step) {
return optionalCompilationSteps.contains(step);
}
@NonNull
public String getArchivesBaseName() {
return (String)getProject().getProperties().get("archivesBaseName");
}
@NonNull
public File getJacocoAgentOutputDirectory() {
return new File(getIntermediatesDir(), "jacoco");
}
@NonNull
public File getJacocoAgent() {
return new File(getJacocoAgentOutputDirectory(), "jacocoagent.jar");
}
@NonNull
public ProjectOptions getProjectOptions() {
return dslScope.getProjectOptions();
}
@Nullable
public FileCache getBuildCache() {
return buildCache;
}
public void setLintChecks(@NonNull Configuration lintChecks) {
this.lintChecks = lintChecks;
}
public void setLintPublish(@NonNull Configuration lintPublish) {
this.lintPublish = lintPublish;
}
public void setAndroidJarConfig(@NonNull Configuration androidJarConfig) {
this.androidJarConfig = androidJarConfig;
}
@NonNull
public FileCollection getMockableJarArtifact() {
return getMockableJarArtifact(
getExtension().getTestOptions().getUnitTests().isReturnDefaultValues());
}
@NonNull
public FileCollection getMockableJarArtifact(boolean returnDefaultValues) {
Preconditions.checkNotNull(androidJarConfig);
Action<AttributeContainer> attributes =
container ->
container
.attribute(ARTIFACT_TYPE, AndroidArtifacts.TYPE_MOCKABLE_JAR)
.attribute(MOCKABLE_JAR_RETURN_DEFAULT_VALUES, returnDefaultValues);
return androidJarConfig
.getIncoming()
.artifactView(config -> config.attributes(attributes))
.getArtifacts()
.getArtifactFiles();
}
@NonNull
public FileCollection getPlatformAttrs() {
Preconditions.checkNotNull(androidJarConfig);
Action<AttributeContainer> attributes =
container ->
container.attribute(ARTIFACT_TYPE, AndroidArtifacts.TYPE_PLATFORM_ATTR);
return androidJarConfig
.getIncoming()
.artifactView(config -> config.attributes(attributes))
.getArtifacts()
.getArtifactFiles();
}
@NonNull
public DslScope getDslScope() {
return dslScope;
}
@NonNull
public MessageReceiver getMessageReceiver() {
return messageReceiver;
}
/**
* Gets the lint JAR from the lint checking configuration.
*
* @return the resolved lint.jar ArtifactFile from the lint checking configuration
*/
@NonNull
public FileCollection getLocalCustomLintChecks() {
// Query for JAR instead of PROCESSED_JAR as we want to get the original lint.jar
Action<AttributeContainer> attributes =
container ->
container.attribute(
ARTIFACT_TYPE, AndroidArtifacts.ArtifactType.JAR.getType());
return lintChecks
.getIncoming()
.artifactView(config -> config.attributes(attributes))
.getArtifacts()
.getArtifactFiles();
}
/**
* Gets the lint JAR from the lint publishing configuration.
*
* @return the resolved lint.jar ArtifactFile from the lint publishing configuration
*/
@NonNull
public FileCollection getPublishedCustomLintChecks() {
// Query for JAR instead of PROCESSED_JAR as we want to get the original lint.jar
Action<AttributeContainer> attributes =
container ->
container.attribute(
ARTIFACT_TYPE, AndroidArtifacts.ArtifactType.JAR.getType());
return lintPublish
.getIncoming()
.artifactView(config -> config.attributes(attributes))
.getArtifacts()
.getArtifactFiles();
}
@NonNull
public BuildArtifactsHolder getArtifacts() {
return globalArtifacts;
}
public boolean hasDynamicFeatures() {
final BaseExtension extension = getExtension();
if (extension instanceof BaseAppModuleExtension) {
return !((BaseAppModuleExtension) extension).getDynamicFeatures().isEmpty();
}
return false;
}
/**
* Returns the boot classpath to be used during compilation with the core lambdas stubs.
*
* @return {@link FileCollection} for the boot classpath.
*/
@NonNull
public FileCollection getBootClasspath() {
if (bootClasspath == null) {
bootClasspath = project.files(getFilteredBootClasspath());
if (extension.getCompileOptions().getTargetCompatibility().isJava8Compatible()) {
bootClasspath.from(getSdkComponents().getCoreLambdaStubsProvider());
}
}
return bootClasspath;
}
/**
* Returns the boot classpath to be used during compilation with all available additional jars
* but only the requested optional ones.
*
* <p>Requested libraries not found will be reported to the issue handler.
*
* @return a {@link FileCollection} that forms the filtered classpath.
*/
public FileCollection getFilteredBootClasspath() {
return BootClasspathBuilder.INSTANCE.computeClasspath(
project,
getDslScope().getIssueReporter(),
getSdkComponents().getTargetBootClasspathProvider(),
getSdkComponents().getTargetAndroidVersionProvider(),
getSdkComponents().getAdditionalLibrariesProvider(),
getSdkComponents().getOptionalLibrariesProvider(),
getSdkComponents().getAnnotationsJarProvider(),
false,
ImmutableList.copyOf(getExtension().getLibraryRequests()));
}
/**
* Returns the boot classpath to be used during compilation with all available additional jars
* including all optional libraries.
*
* @return a {@link FileCollection} that forms the filtered classpath.
*/
@NonNull
public FileCollection getFullBootClasspath() {
return BootClasspathBuilder.INSTANCE.computeClasspath(
project,
getDslScope().getIssueReporter(),
getSdkComponents().getTargetBootClasspathProvider(),
getSdkComponents().getTargetAndroidVersionProvider(),
getSdkComponents().getAdditionalLibrariesProvider(),
getSdkComponents().getOptionalLibrariesProvider(),
getSdkComponents().getAnnotationsJarProvider(),
true,
ImmutableList.of());
}
@NonNull
public SoftwareComponentFactory getComponentFactory() {
return componentFactory;
}
}