/*
* Copyright 2017-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.android;
import com.facebook.buck.android.resources.ExoResourcesRewriter;
import com.facebook.buck.model.BuildTargets;
import com.facebook.buck.rules.AbstractBuildRule;
import com.facebook.buck.rules.AddToRuleKey;
import com.facebook.buck.rules.BuildContext;
import com.facebook.buck.rules.BuildRule;
import com.facebook.buck.rules.BuildRuleParams;
import com.facebook.buck.rules.BuildableContext;
import com.facebook.buck.rules.ExplicitBuildTargetSourcePath;
import com.facebook.buck.rules.SourcePath;
import com.facebook.buck.rules.SourcePathResolver;
import com.facebook.buck.rules.SourcePathRuleFinder;
import com.facebook.buck.step.ExecutionContext;
import com.facebook.buck.step.Step;
import com.facebook.buck.step.StepExecutionResult;
import com.facebook.buck.step.fs.MakeCleanDirectoryStep;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import java.io.IOException;
import java.nio.file.Path;
import javax.annotation.Nullable;
public class SplitResources extends AbstractBuildRule {
@AddToRuleKey(stringify = true)
private final Path exoResourcesOutputPath;
@AddToRuleKey(stringify = true)
private final Path primaryResourcesOutputPath;
@AddToRuleKey(stringify = true)
private final Path rDotTxtOutputPath;
@AddToRuleKey private final SourcePath pathToAaptResources;
@AddToRuleKey private final SourcePath pathToOriginalRDotTxt;
public SplitResources(
BuildRuleParams buildRuleParams,
SourcePathRuleFinder ruleFinder,
SourcePath pathToAaptResources,
SourcePath pathToOriginalRDotTxt) {
super(
buildRuleParams.copyAppendingExtraDeps(
getAllDeps(ruleFinder, pathToAaptResources, pathToOriginalRDotTxt)));
this.pathToAaptResources = pathToAaptResources;
this.pathToOriginalRDotTxt = pathToOriginalRDotTxt;
this.exoResourcesOutputPath = getOutputDirectory().resolve("exo-resources.apk");
this.primaryResourcesOutputPath = getOutputDirectory().resolve("primary-resources.apk");
this.rDotTxtOutputPath = getOutputDirectory().resolve("R.txt");
}
private Path getOutputDirectory() {
return BuildTargets.getGenPath(getProjectFilesystem(), getBuildTarget(), "%s/");
}
private static ImmutableSet<BuildRule> getAllDeps(
SourcePathRuleFinder ruleFinder, SourcePath aaptOutputPath, SourcePath aaptRDotTxtPath) {
return ruleFinder.filterBuildRuleInputs(aaptOutputPath, aaptRDotTxtPath);
}
@Override
public ImmutableList<Step> getBuildSteps(
BuildContext context, BuildableContext buildableContext) {
buildableContext.recordArtifact(getOutputDirectory());
return ImmutableList.<Step>builder()
.addAll(MakeCleanDirectoryStep.of(getProjectFilesystem(), getOutputDirectory()))
.addAll(MakeCleanDirectoryStep.of(getProjectFilesystem(), getScratchDirectory()))
.add(new SplitResourcesStep(context.getSourcePathResolver()))
.add(
new ZipalignStep(
getProjectFilesystem().getRootPath(),
getUnalignedExoPath(),
exoResourcesOutputPath))
.build();
}
private Path getUnalignedExoPath() {
return getScratchDirectory().resolve("exo-resources.unaligned.zip");
}
@Nullable
@Override
public SourcePath getSourcePathToOutput() {
return null;
}
public SourcePath getPathToRDotTxt() {
return new ExplicitBuildTargetSourcePath(getBuildTarget(), rDotTxtOutputPath);
}
public SourcePath getPathToPrimaryResources() {
return new ExplicitBuildTargetSourcePath(getBuildTarget(), primaryResourcesOutputPath);
}
public SourcePath getPathToExoResources() {
return new ExplicitBuildTargetSourcePath(getBuildTarget(), exoResourcesOutputPath);
}
public Path getScratchDirectory() {
return BuildTargets.getScratchPath(getProjectFilesystem(), getBuildTarget(), "%s/");
}
private class SplitResourcesStep implements Step {
private Path absolutePathToAaptResources;
private Path absolutePathToOriginalRDotTxt;
public SplitResourcesStep(SourcePathResolver sourcePathResolver) {
absolutePathToAaptResources = sourcePathResolver.getAbsolutePath(pathToAaptResources);
absolutePathToOriginalRDotTxt = sourcePathResolver.getAbsolutePath(pathToOriginalRDotTxt);
}
@Override
public StepExecutionResult execute(ExecutionContext context)
throws IOException, InterruptedException {
ExoResourcesRewriter.rewrite(
absolutePathToAaptResources,
absolutePathToOriginalRDotTxt,
getProjectFilesystem().getPathForRelativePath(primaryResourcesOutputPath),
getProjectFilesystem().getPathForRelativePath(getUnalignedExoPath()),
getProjectFilesystem().getPathForRelativePath(rDotTxtOutputPath));
return StepExecutionResult.SUCCESS;
}
@Override
public String getShortName() {
return "splitting_exo_resources";
}
@Override
public String getDescription(ExecutionContext context) {
return String.format(
"split_exo_resources %s %s", absolutePathToAaptResources, absolutePathToOriginalRDotTxt);
}
}
}