blob: 9a0dc723958b19a8dbb0653e4e1a145a45b244fc [file] [log] [blame]
/*
* Copyright 2012-present Facebook, Inc.
*
* 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.facebook.buck.rules;
import com.facebook.buck.android.AndroidPlatformTarget;
import com.facebook.buck.android.NoAndroidSdkException;
import com.facebook.buck.event.BuckEventBus;
import com.facebook.buck.event.ConsoleEvent;
import com.facebook.buck.event.ThrowableConsoleEvent;
import com.facebook.buck.io.ProjectFilesystem;
import com.facebook.buck.java.JavaPackageFinder;
import com.facebook.buck.model.BuildId;
import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.step.StepRunner;
import com.facebook.buck.timing.Clock;
import com.facebook.buck.util.immutables.BuckStyleImmutable;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableMap;
import org.immutables.value.Value;
import java.io.File;
import java.nio.file.Path;
import java.util.List;
import java.util.Map;
@Value.Immutable
@BuckStyleImmutable
public abstract class BuildContext {
private static Function<AndroidPlatformTarget, String> bootclasspathForAndroidPlatformTarget =
new Function<AndroidPlatformTarget, String>() {
@Override
public String apply(AndroidPlatformTarget androidPlatformTarget) {
List<Path> bootclasspathEntries = androidPlatformTarget.getBootclasspathEntries();
Preconditions.checkState(
!bootclasspathEntries.isEmpty(),
"There should be entries for the bootclasspath");
return Joiner.on(File.pathSeparator).join(bootclasspathEntries);
}
};
private static final Supplier<String> DEFAULT_ANDROID_BOOTCLASSPATH_SUPPLIER =
new Supplier<String>() {
@Override
public String get() {
throw new NoAndroidSdkException();
}
};
public abstract ActionGraph getActionGraph();
public abstract StepRunner getStepRunner();
/**
* By design, there is no public getter for {@link ProjectFilesystem}. At the point where a
* {@link BuildRule} is using a {@link BuildContext} to generate its
* {@link com.facebook.buck.step.Step}s, it should not be doing any I/O on local disk. Any reads
* should be mediated through {@link OnDiskBuildInfo}, and {@link BuildInfoRecorder} will take
* care of writes after the fact. The {@link BuildRule} should be working with relative file paths
* so that builds can ultimately be distributed.
* <p>
* The primary reason this method exists is so that someone who blindly tries to add such a getter
* will encounter a compilation error and will [hopefully] discover this comment.
*/
protected abstract ProjectFilesystem getProjectFilesystem();
protected abstract Clock getClock();
public abstract ArtifactCache getArtifactCache();
public abstract JavaPackageFinder getJavaPackageFinder();
public abstract BuckEventBus getEventBus();
@Value.Default
public Supplier<String> getAndroidBootclasspathSupplier() {
return DEFAULT_ANDROID_BOOTCLASSPATH_SUPPLIER;
}
@Value.Default
public BuildDependencies getBuildDependencies() {
return BuildDependencies.getDefault();
}
protected abstract BuildId getBuildId();
protected abstract Map<String, String> getEnvironment();
public Path getProjectRoot() {
return getProjectFilesystem().getRootPath();
}
/**
* Creates an {@link OnDiskBuildInfo}.
* <p>
* This method should be visible to {@link AbstractBuildRule}, but not {@link BuildRule}s
* in general.
*/
OnDiskBuildInfo createOnDiskBuildInfoFor(BuildTarget target) {
return new DefaultOnDiskBuildInfo(target, getProjectFilesystem());
}
/**
* Creates an {@link BuildInfoRecorder}.
* <p>
* This method should be visible to {@link AbstractBuildRule}, but not {@link BuildRule}s
* in general.
*/
BuildInfoRecorder createBuildInfoRecorder(BuildTarget buildTarget,
RuleKey ruleKey,
RuleKey ruleKeyWithoutDeps) {
return new BuildInfoRecorder(
buildTarget,
getProjectFilesystem(),
getClock(),
getBuildId(),
ImmutableMap.copyOf(getEnvironment()),
ruleKey,
ruleKeyWithoutDeps);
}
public void logBuildInfo(String format, Object... args) {
getEventBus().post(ConsoleEvent.fine(format, args));
}
public void logError(Throwable error, String msg, Object... formatArgs) {
getEventBus().post(ThrowableConsoleEvent.create(error, msg, formatArgs));
}
public void logError(String msg, Object... formatArgs) {
getEventBus().post(ConsoleEvent.severe(msg, formatArgs));
}
public static Supplier<String> createBootclasspathSupplier(
Supplier<AndroidPlatformTarget> androidPlatformTarget) {
return Suppliers.memoize(
Suppliers.compose(bootclasspathForAndroidPlatformTarget, androidPlatformTarget));
}
}