use of com.facebook.buck.shell.AbstractGenruleStep in project buck by facebook.
the class ExternallyBuiltApplePackageTest method commandContainsCorrectCommand.
@Test
public void commandContainsCorrectCommand() {
SourcePathResolver pathResolver = new SourcePathResolver(new SourcePathRuleFinder(this.resolver));
ExternallyBuiltApplePackage rule = new ExternallyBuiltApplePackage(params, config, new FakeSourcePath("Fake/Bundle/Location"), true);
resolver.addToIndex(rule);
AbstractGenruleStep step = Iterables.getOnlyElement(Iterables.filter(rule.getBuildSteps(FakeBuildContext.withSourcePathResolver(pathResolver), new FakeBuildableContext()), AbstractGenruleStep.class));
assertThat(step.getScriptFileContents(TestExecutionContext.newInstance()), is(equalTo("echo $SDKROOT $OUT")));
}
use of com.facebook.buck.shell.AbstractGenruleStep in project buck by facebook.
the class AndroidBinary method addFinalDxSteps.
/**
* Adds steps to do the final dexing or dex merging before building the apk.
*/
private DexFilesInfo addFinalDxSteps(BuildableContext buildableContext, SourcePathResolver resolver, ImmutableList.Builder<Step> steps) {
AndroidPackageableCollection packageableCollection = enhancementResult.getPackageableCollection();
ImmutableSet<Path> classpathEntriesToDex = Stream.concat(enhancementResult.getClasspathEntriesToDex().stream(), RichStream.of(enhancementResult.getCompiledUberRDotJava().getSourcePathToOutput())).map(resolver::getRelativePath).collect(MoreCollectors.toImmutableSet());
ImmutableMultimap.Builder<APKModule, Path> additionalDexStoreToJarPathMapBuilder = ImmutableMultimap.builder();
additionalDexStoreToJarPathMapBuilder.putAll(enhancementResult.getPackageableCollection().getModuleMappedClasspathEntriesToDex().entries().stream().map(input -> new AbstractMap.SimpleEntry<>(input.getKey(), resolver.getRelativePath(input.getValue()))).collect(MoreCollectors.toImmutableSet()));
ImmutableMultimap<APKModule, Path> additionalDexStoreToJarPathMap = additionalDexStoreToJarPathMapBuilder.build();
// Execute preprocess_java_classes_binary, if appropriate.
if (preprocessJavaClassesBash.isPresent()) {
// Symlink everything in dexTransitiveDependencies.classpathEntriesToDex to the input
// directory. Expect parallel outputs in the output directory and update classpathEntriesToDex
// to reflect that.
final Path preprocessJavaClassesInDir = getBinPath("java_classes_preprocess_in_%s");
final Path preprocessJavaClassesOutDir = getBinPath("java_classes_preprocess_out_%s");
steps.add(new MakeCleanDirectoryStep(getProjectFilesystem(), preprocessJavaClassesInDir));
steps.add(new MakeCleanDirectoryStep(getProjectFilesystem(), preprocessJavaClassesOutDir));
steps.add(new SymlinkFilesIntoDirectoryStep(getProjectFilesystem(), getProjectFilesystem().getRootPath(), classpathEntriesToDex, preprocessJavaClassesInDir));
classpathEntriesToDex = classpathEntriesToDex.stream().map(preprocessJavaClassesOutDir::resolve).collect(MoreCollectors.toImmutableSet());
AbstractGenruleStep.CommandString commandString = new AbstractGenruleStep.CommandString(/* cmd */
Optional.empty(), /* bash */
preprocessJavaClassesBash.map(macroExpander::apply), /* cmdExe */
Optional.empty());
steps.add(new AbstractGenruleStep(getProjectFilesystem(), this.getBuildTarget(), commandString, getProjectFilesystem().getRootPath().resolve(preprocessJavaClassesInDir)) {
@Override
protected void addEnvironmentVariables(ExecutionContext context, ImmutableMap.Builder<String, String> environmentVariablesBuilder) {
environmentVariablesBuilder.put("IN_JARS_DIR", getProjectFilesystem().resolve(preprocessJavaClassesInDir).toString());
environmentVariablesBuilder.put("OUT_JARS_DIR", getProjectFilesystem().resolve(preprocessJavaClassesOutDir).toString());
AndroidPlatformTarget platformTarget = context.getAndroidPlatformTarget();
String bootclasspath = Joiner.on(':').join(Iterables.transform(platformTarget.getBootclasspathEntries(), getProjectFilesystem()::resolve));
environmentVariablesBuilder.put("ANDROID_BOOTCLASSPATH", bootclasspath);
}
});
}
// Execute proguard if desired (transforms input classpaths).
if (packageType.isBuildWithObfuscation()) {
classpathEntriesToDex = addProguardCommands(classpathEntriesToDex, packageableCollection.getProguardConfigs().stream().map(resolver::getAbsolutePath).collect(MoreCollectors.toImmutableSet()), skipProguard, steps, buildableContext, resolver);
}
Supplier<ImmutableMap<String, HashCode>> classNamesToHashesSupplier;
boolean classFilesHaveChanged = preprocessJavaClassesBash.isPresent() || packageType.isBuildWithObfuscation();
if (classFilesHaveChanged) {
classNamesToHashesSupplier = addAccumulateClassNamesStep(classpathEntriesToDex, steps);
} else {
classNamesToHashesSupplier = packageableCollection.getClassNamesToHashesSupplier();
}
// Create the final DEX (or set of DEX files in the case of split dex).
// The APK building command needs to take a directory of raw files, so primaryDexPath
// can only contain .dex files from this build rule.
// Create dex artifacts. If split-dex is used, the assets/ directory should contain entries
// that look something like the following:
//
// assets/secondary-program-dex-jars/metadata.txt
// assets/secondary-program-dex-jars/secondary-1.dex.jar
// assets/secondary-program-dex-jars/secondary-2.dex.jar
// assets/secondary-program-dex-jars/secondary-3.dex.jar
//
// The contents of the metadata.txt file should look like:
// secondary-1.dex.jar fffe66877038db3af2cbd0fe2d9231ed5912e317 secondary.dex01.Canary
// secondary-2.dex.jar b218a3ea56c530fed6501d9f9ed918d1210cc658 secondary.dex02.Canary
// secondary-3.dex.jar 40f11878a8f7a278a3f12401c643da0d4a135e1a secondary.dex03.Canary
//
// The scratch directories that contain the metadata.txt and secondary-N.dex.jar files must be
// listed in secondaryDexDirectoriesBuilder so that their contents will be compressed
// appropriately for Froyo.
ImmutableSet.Builder<Path> secondaryDexDirectoriesBuilder = ImmutableSet.builder();
Optional<PreDexMerge> preDexMerge = enhancementResult.getPreDexMerge();
if (!preDexMerge.isPresent()) {
steps.add(new MkdirStep(getProjectFilesystem(), primaryDexPath.getParent()));
addDexingSteps(classpathEntriesToDex, classNamesToHashesSupplier, secondaryDexDirectoriesBuilder, steps, primaryDexPath, dexReorderToolFile, dexReorderDataDumpFile, additionalDexStoreToJarPathMap, resolver);
} else if (!ExopackageMode.enabledForSecondaryDexes(exopackageModes)) {
secondaryDexDirectoriesBuilder.addAll(preDexMerge.get().getSecondaryDexDirectories());
}
return new DexFilesInfo(primaryDexPath, secondaryDexDirectoriesBuilder.build());
}
use of com.facebook.buck.shell.AbstractGenruleStep in project buck by facebook.
the class ApkGenruleTest method testCreateAndRunApkGenrule.
@Test
@SuppressWarnings("PMD.AvoidUsingHardCodedIP")
public void testCreateAndRunApkGenrule() throws IOException, NoSuchBuildTargetException {
ProjectFilesystem projectFilesystem = FakeProjectFilesystem.createJavaOnlyFilesystem();
FileSystem fileSystem = projectFilesystem.getRootPath().getFileSystem();
BuildRuleResolver ruleResolver = new BuildRuleResolver(TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer());
createSampleAndroidBinaryRule(ruleResolver, projectFilesystem);
// From the Python object, create a ApkGenruleBuildRuleFactory to create a ApkGenrule.Builder
// that builds a ApkGenrule from the Python object.
BuildTargetParser parser = EasyMock.createNiceMock(BuildTargetParser.class);
final BuildTarget apkTarget = BuildTargetFactory.newInstance(projectFilesystem.getRootPath(), "//:fb4a");
EasyMock.expect(parser.parse(EasyMock.eq(":fb4a"), EasyMock.anyObject(BuildTargetPatternParser.class), EasyMock.anyObject())).andStubReturn(apkTarget);
EasyMock.replay(parser);
BuildTarget buildTarget = BuildTargetFactory.newInstance(projectFilesystem.getRootPath(), "//src/com/facebook:sign_fb4a");
ApkGenruleDescription description = new ApkGenruleDescription();
ApkGenruleDescription.Arg arg = description.createUnpopulatedConstructorArg();
SourcePathResolver pathResolver = new SourcePathResolver(new SourcePathRuleFinder(ruleResolver));
arg.apk = new FakeInstallable(apkTarget, pathResolver).getBuildTarget();
arg.bash = Optional.of("");
arg.cmd = Optional.of("python signer.py $APK key.properties > $OUT");
arg.cmdExe = Optional.of("");
arg.type = Optional.empty();
arg.out = "signed_fb4a.apk";
arg.srcs = ImmutableList.of(new PathSourcePath(projectFilesystem, fileSystem.getPath("src/com/facebook/signer.py")), new PathSourcePath(projectFilesystem, fileSystem.getPath("src/com/facebook/key.properties")));
arg.tests = ImmutableSortedSet.of();
BuildRuleParams params = new FakeBuildRuleParamsBuilder(buildTarget).setProjectFilesystem(projectFilesystem).build();
ApkGenrule apkGenrule = (ApkGenrule) description.createBuildRule(TargetGraph.EMPTY, params, ruleResolver, arg);
ruleResolver.addToIndex(apkGenrule);
// Verify all of the observers of the Genrule.
String expectedApkOutput = projectFilesystem.resolve(projectFilesystem.getBuckPaths().getGenDir().toString() + "/src/com/facebook/sign_fb4a/sign_fb4a.apk").toString();
assertEquals(expectedApkOutput, apkGenrule.getAbsoluteOutputFilePath(pathResolver));
assertEquals("The apk that this rule is modifying must have the apk in its deps.", ImmutableSet.of(apkTarget.toString()), apkGenrule.getDeps().stream().map(Object::toString).collect(MoreCollectors.toImmutableSet()));
BuildContext buildContext = FakeBuildContext.withSourcePathResolver(pathResolver);
Iterable<Path> expectedInputsToCompareToOutputs = ImmutableList.of(fileSystem.getPath("src/com/facebook/signer.py"), fileSystem.getPath("src/com/facebook/key.properties"));
MoreAsserts.assertIterablesEquals(expectedInputsToCompareToOutputs, pathResolver.filterInputsToCompareToOutput(apkGenrule.getSrcs()));
// Verify that the shell commands that the genrule produces are correct.
List<Step> steps = apkGenrule.getBuildSteps(buildContext, new FakeBuildableContext());
assertEquals(6, steps.size());
ExecutionContext executionContext = newEmptyExecutionContext();
Step firstStep = steps.get(0);
assertTrue(firstStep instanceof MakeCleanDirectoryStep);
MakeCleanDirectoryStep mkdirCommand = (MakeCleanDirectoryStep) firstStep;
Path mkdirDir = projectFilesystem.getBuckPaths().getGenDir().resolve("src/com/facebook/sign_fb4a");
assertEquals("First command should make sure the output directory exists and is empty.", mkdirDir, mkdirCommand.getPath());
Step secondStep = steps.get(1);
assertTrue(secondStep instanceof MakeCleanDirectoryStep);
MakeCleanDirectoryStep secondMkdirCommand = (MakeCleanDirectoryStep) secondStep;
Path relativePathToTmpDir = projectFilesystem.getBuckPaths().getGenDir().resolve("src/com/facebook/sign_fb4a__tmp");
assertEquals("Second command should make sure the temp directory exists.", relativePathToTmpDir, secondMkdirCommand.getPath());
Step thirdStep = steps.get(2);
assertTrue(thirdStep instanceof MakeCleanDirectoryStep);
MakeCleanDirectoryStep thirdMkdirCommand = (MakeCleanDirectoryStep) thirdStep;
Path relativePathToSrcDir = projectFilesystem.getBuckPaths().getGenDir().resolve("src/com/facebook/sign_fb4a__srcs");
assertEquals("Third command should make sure the temp directory exists.", relativePathToSrcDir, thirdMkdirCommand.getPath());
MkdirAndSymlinkFileStep linkSource1 = (MkdirAndSymlinkFileStep) steps.get(3);
assertEquals(fileSystem.getPath("src/com/facebook/signer.py"), linkSource1.getSource());
assertEquals(fileSystem.getPath(relativePathToSrcDir + "/signer.py"), linkSource1.getTarget());
MkdirAndSymlinkFileStep linkSource2 = (MkdirAndSymlinkFileStep) steps.get(4);
assertEquals(fileSystem.getPath("src/com/facebook/key.properties"), linkSource2.getSource());
assertEquals(fileSystem.getPath(relativePathToSrcDir + "/key.properties"), linkSource2.getTarget());
Step sixthStep = steps.get(5);
assertTrue(sixthStep instanceof AbstractGenruleStep);
AbstractGenruleStep genruleCommand = (AbstractGenruleStep) sixthStep;
assertEquals("genrule", genruleCommand.getShortName());
ImmutableMap<String, String> environmentVariables = genruleCommand.getEnvironmentVariables(executionContext);
assertEquals(new ImmutableMap.Builder<String, String>().put("APK", projectFilesystem.resolve(BuildTargets.getGenPath(projectFilesystem, apkTarget, "%s.apk")).toString()).put("OUT", expectedApkOutput).build(), environmentVariables);
Path scriptFilePath = genruleCommand.getScriptFilePath(executionContext);
String scriptFileContents = genruleCommand.getScriptFileContents(executionContext);
assertEquals(ImmutableList.of("/bin/bash", "-e", scriptFilePath.toString()), genruleCommand.getShellCommand(executionContext));
assertEquals("python signer.py $APK key.properties > $OUT", scriptFileContents);
EasyMock.verify(parser);
}
Aggregations