blob: cb663e77663606ba531ac42ae7a2e9d89ba0967d [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.shell;
import com.facebook.buck.rules.AbstractCachingBuildRule;
import com.facebook.buck.rules.AbstractCachingBuildRuleBuilder;
import com.facebook.buck.rules.BuildContext;
import com.facebook.buck.rules.BuildRule;
import com.facebook.buck.rules.BuildRuleType;
import com.facebook.buck.rules.CachingBuildRuleParams;
import com.facebook.buck.step.Step;
import com.facebook.buck.step.fs.MkdirAndSymlinkFileStep;
import com.facebook.buck.util.BuckConstant;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Optional;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
/**
* Export a file so that it can be easily referenced by other {@link com.facebook.buck.rules.BuildRule}s. There are several
* valid ways of using export_file (all examples in a build file located at "path/to/buck/BUCK").
* The most common usage of export_file is:
* <pre>
* export_file(name = 'some-file.html')
* </pre>
* This is equivalent to:
* <pre>
* export_file(name = 'some-file.html',
* src = 'some-file.html',
* out = 'some-file.html')
* </pre>
* This results in "//path/to/buck:some-file.html" as the rule, and will export the file
* "some-file.html" as "some-file.html".
* <pre>
* export_file(
* name = 'foobar.html',
* src = 'some-file.html',
* )
* </pre>
* Is equivalent to:
* <pre>
* export_file(name = 'foobar.html', src = 'some-file.html', out = 'foobar.html')
* </pre>
* Finally, it's possible to refer to the exported file with a logical name, while controlling the
* actual file name. For example:
* <pre>
* export_file(name = 'ie-exports',
* src = 'some-file.js',
* out = 'some-file-ie.js',
* )
* </pre>
* As a rule of thumb, if the "out" parameter is missing, the "name" parameter is used as the name
* of the file to be saved.
*/
// TODO(simons): Extend to also allow exporting a rule.
public class ExportFileRule extends AbstractCachingBuildRule {
private final String src;
private final Supplier<File> out;
@VisibleForTesting
ExportFileRule(CachingBuildRuleParams params, Optional<String> src, Optional<String> out) {
super(params);
String shortName = params.getBuildTarget().getShortName();
this.src = src.or(shortName);
final String outName = out.or(shortName);
this.out = Suppliers.memoize(new Supplier<File>() {
@Override
public File get() {
String name = new File(outName).getName();
String outputPath = String.format("%s/%s%s",
BuckConstant.GEN_DIR,
getBuildTarget().getBasePathWithSlash(),
name);
return new File(outputPath);
}
});
}
@Override
public BuildRuleType getType() {
return BuildRuleType.EXPORT_FILE;
}
@Override
protected Iterable<String> getInputsToCompareToOutput(BuildContext context) {
return ImmutableSet.of(src);
}
@Override
protected List<Step> buildInternal(BuildContext context) throws IOException {
File inputFile = context.getProjectFilesystem().getFileForRelativePath(src);
File outputFile = out.get();
ImmutableList.Builder<Step> builder = ImmutableList.<Step>builder()
.add(new MkdirAndSymlinkFileStep(inputFile, outputFile));
return builder.build();
}
@Nullable
@Override
public File getOutput() {
return out.get();
}
public static Builder newExportFileBuilder() {
return new Builder();
}
public static class Builder extends AbstractCachingBuildRuleBuilder {
private Optional<String> src;
private Optional<String> out;
public Builder setSrc(Optional<String> src) {
this.src = src;
return this;
}
public Builder setOut(Optional<String> out) {
this.out = out;
return this;
}
@Override
public ExportFileRule build(Map<String, BuildRule> buildRuleIndex) {
CachingBuildRuleParams params = createCachingBuildRuleParams(buildRuleIndex);
return new ExportFileRule(params, src, out);
}
}
}