/*
* Copyright 2013-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.shell;
import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.model.UnflavoredBuildTarget;
import com.facebook.buck.rules.BuildRuleParams;
import com.facebook.buck.rules.BuildRuleResolver;
import com.facebook.buck.rules.CellPathResolver;
import com.facebook.buck.rules.CommonDescriptionArg;
import com.facebook.buck.rules.Description;
import com.facebook.buck.rules.ImplicitInputsInferringDescription;
import com.facebook.buck.rules.PathSourcePath;
import com.facebook.buck.rules.SourcePath;
import com.facebook.buck.rules.SourcePathResolver;
import com.facebook.buck.rules.SourcePathRuleFinder;
import com.facebook.buck.rules.TargetGraph;
import com.facebook.buck.util.HumanReadableException;
import com.facebook.buck.util.immutables.BuckStyleImmutable;
import com.google.common.collect.ImmutableList;
import java.nio.file.Path;
import java.util.Optional;
import org.immutables.value.Value;
public class ExportFileDescription
implements Description<ExportFileDescriptionArg>,
ImplicitInputsInferringDescription<ExportFileDescriptionArg> {
@Override
public Class<ExportFileDescriptionArg> getConstructorArgType() {
return ExportFileDescriptionArg.class;
}
@Override
public ExportFile createBuildRule(
TargetGraph targetGraph,
BuildRuleParams params,
BuildRuleResolver resolver,
CellPathResolver cellRoots,
ExportFileDescriptionArg args) {
BuildTarget target = params.getBuildTarget();
Mode mode = args.getMode().orElse(Mode.COPY);
String name;
if (args.getOut().isPresent()) {
if (mode == ExportFileDescription.Mode.REFERENCE) {
throw new HumanReadableException(
"%s: must not set `out` for `export_file` when using `REFERENCE` mode",
params.getBuildTarget());
}
name = args.getOut().get();
} else {
name = target.getShortNameAndFlavorPostfix();
}
SourcePath src;
SourcePathRuleFinder ruleFinder = new SourcePathRuleFinder(resolver);
SourcePathResolver pathResolver = new SourcePathResolver(ruleFinder);
if (args.getSrc().isPresent()) {
if (mode == ExportFileDescription.Mode.REFERENCE
&& !pathResolver
.getFilesystem(args.getSrc().get())
.equals(params.getProjectFilesystem())) {
throw new HumanReadableException(
"%s: must use `COPY` mode for `export_file` when source (%s) uses a different cell",
target, args.getSrc().get());
}
src = args.getSrc().get();
} else {
src =
new PathSourcePath(
params.getProjectFilesystem(),
target.getBasePath().resolve(target.getShortNameAndFlavorPostfix()));
}
return new ExportFile(params, ruleFinder, pathResolver, name, mode, src);
}
/** If the src field is absent, add the name field to the list of inputs. */
@Override
public Iterable<Path> inferInputsFromConstructorArgs(
UnflavoredBuildTarget buildTarget, ExportFileDescriptionArg constructorArg) {
ImmutableList.Builder<Path> inputs = ImmutableList.builder();
if (!constructorArg.getSrc().isPresent()) {
inputs.add(buildTarget.getBasePath().resolve(buildTarget.getShortName()));
}
return inputs.build();
}
/** Controls how `export_file` exports it's wrapped source. */
public enum Mode {
/**
* Forward the wrapped {@link SourcePath} reference without any build time overhead (e.g.
* copying, caching, etc).
*/
REFERENCE,
/**
* Create and export a copy of the wrapped {@link SourcePath} (incurring the cost of copying and
* caching this copy at build time).
*/
COPY,
}
@BuckStyleImmutable
@Value.Immutable
interface AbstractExportFileDescriptionArg extends CommonDescriptionArg {
Optional<SourcePath> getSrc();
Optional<String> getOut();
Optional<Mode> getMode();
}
}