blob: 8faeee15be4db14c108de3c2315321ca5b1c891d [file] [log] [blame]
/*
* Copyright 2014-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.apple;
import com.facebook.buck.io.DirectoryTraverser;
import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.model.BuildTargets;
import com.facebook.buck.rules.AbstractBuildRule;
import com.facebook.buck.rules.BuildContext;
import com.facebook.buck.rules.BuildRuleParams;
import com.facebook.buck.rules.BuildRules;
import com.facebook.buck.rules.BuildableContext;
import com.facebook.buck.rules.RuleKey;
import com.facebook.buck.rules.SourcePath;
import com.facebook.buck.rules.SourcePathResolver;
import com.facebook.buck.step.Step;
import com.facebook.buck.step.fs.CopyStep;
import com.facebook.buck.step.fs.MakeCleanDirectoryStep;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSortedSet;
import java.nio.file.Path;
import java.util.Map;
import javax.annotation.Nullable;
/**
* Copies the image, sound, NIB/XIB, and other resources
* of an iOS or OS X library.
* <p>
* Example rule:
* <pre>
* apple_resource(
* name = 'res',
* dirs = ['MyLibrary.bundle'],
* files = glob(['Resources/**']),
* variants = {
* 'Resources/Localizable.strings' : {
* 'en' : 'Resources/en.lproj/Localizable.strings',
* 'fr' : 'Resources/fr.lproj/Localizable.strings',
* },
* },
* )
* </pre>
*/
public class AppleResource extends AbstractBuildRule {
private final DirectoryTraverser directoryTraverser;
private final ImmutableSortedSet<Path> dirs;
private final ImmutableSortedSet<SourcePath> files;
private final ImmutableMap<String, ImmutableMap<String, SourcePath>> variants;
private final Path outputDirectory;
AppleResource(
BuildRuleParams params,
SourcePathResolver resolver,
DirectoryTraverser directoryTraverser,
AppleResourceDescription.Arg args) {
super(params, resolver);
this.directoryTraverser = directoryTraverser;
this.dirs = ImmutableSortedSet.copyOf(args.dirs);
this.files = ImmutableSortedSet.copyOf(args.files);
if (args.variants.isPresent()) {
Map<String, Map<String, SourcePath>> variants = args.variants.get();
ImmutableMap.Builder<String, ImmutableMap<String, SourcePath>> variantsBuilder =
ImmutableMap.builder();
for (String path : variants.keySet()) {
variantsBuilder.put(path, ImmutableMap.copyOf(variants.get(path)));
}
this.variants = variantsBuilder.build();
} else {
this.variants = ImmutableMap.of();
}
BuildTarget target = params.getBuildTarget();
// TODO(user): This is hokey, just a hack to get started.
// TODO(grp): Support copying into a bundle's resources subdirectory.
this.outputDirectory = BuildTargets.getBinPath(target, "%s.app");
}
/**
* Returns the set of directories to recursively copy for this resource rule.
*/
public ImmutableSortedSet<Path> getDirs() {
return dirs;
}
/**
* Returns the set of files to copy for this resource rule.
*/
public ImmutableSortedSet<SourcePath> getFiles() {
return files;
}
@Override
public ImmutableCollection<Path> getInputsToCompareToOutput() {
ImmutableSortedSet.Builder<Path> inputsToConsiderForCachingPurposes = ImmutableSortedSet
.naturalOrder();
for (Path dir : dirs) {
BuildRules.addInputsToSortedSet(
dir,
inputsToConsiderForCachingPurposes,
directoryTraverser);
}
for (String virtualPathName : variants.keySet()) {
Map<String, SourcePath> variant =
Preconditions.checkNotNull(variants.get(virtualPathName));
inputsToConsiderForCachingPurposes.addAll(
getResolver().filterInputsToCompareToOutput(variant.values()));
}
inputsToConsiderForCachingPurposes.addAll(getResolver().filterInputsToCompareToOutput(files));
return inputsToConsiderForCachingPurposes.build();
}
@Override
public RuleKey.Builder appendDetailsToRuleKey(RuleKey.Builder builder) {
return builder;
}
@Override
@Nullable
public Path getPathToOutputFile() {
return null;
}
@Override
public ImmutableList<Step> getBuildSteps(
BuildContext context,
BuildableContext buildableContext) {
ImmutableList.Builder<Step> steps = ImmutableList.builder();
steps.add(new MakeCleanDirectoryStep(outputDirectory));
for (Path dir : dirs) {
steps.add(
CopyStep.forDirectory(
dir,
outputDirectory,
CopyStep.DirectoryMode.DIRECTORY_AND_CONTENTS));
}
for (SourcePath file : files) {
Path path = getResolver().getPath(file);
steps.add(CopyStep.forFile(path, outputDirectory.resolve(path.getFileName())));
}
// TODO(grp): Support copying variant resources like Xcode.
return steps.build();
}
}