use of com.facebook.buck.step.ExecutionContext in project buck by facebook.
the class WriteFileStepTest method testFileIsWrittenWithNewline.
@Test
public void testFileIsWrittenWithNewline() throws Exception {
FakeProjectFilesystem filesystem = new FakeProjectFilesystem();
WriteFileStep writeFileStep = new WriteFileStep(filesystem, "Hello world", Paths.get("foo.txt"), /* executable */
false);
ExecutionContext executionContext = TestExecutionContext.newInstance();
writeFileStep.execute(executionContext);
assertThat(filesystem.readFileIfItExists(Paths.get("foo.txt")), equalTo(Optional.of("Hello world\n")));
}
use of com.facebook.buck.step.ExecutionContext in project buck by facebook.
the class ShellStepTest method testDescriptionWithEnvironmentAndPath.
@Test
public void testDescriptionWithEnvironmentAndPath() {
ShellStep command = createCommand(ENV, ARGS, PATH);
ExecutionContext context = TestExecutionContext.newBuilder().setProcessExecutor(new FakeProcessExecutor()).build();
String template = Platform.detect() == Platform.WINDOWS ? "(cd %s && V1=\"two words\" V2=$foo'bar' bash -c \"echo $V1 $V2\")" : "(cd %s && V1='two words' V2='$foo'\\''bar'\\''' bash -c 'echo $V1 $V2')";
assertEquals(String.format(template, Escaper.escapeAsBashString(PATH)), command.getDescription(context));
}
use of com.facebook.buck.step.ExecutionContext in project buck by facebook.
the class ShellStepTest method testStdErrPrintedOnErrorIfShouldPrintStdErrEvenIfSilent.
@Test
public void testStdErrPrintedOnErrorIfShouldPrintStdErrEvenIfSilent() throws Exception {
ShellStep command = createCommand(/*shouldPrintStdErr*/
true, /*shouldPrintStdOut*/
false);
ProcessExecutorParams params = createParams();
FakeProcess process = new FakeProcess(EXIT_FAILURE, OUTPUT_MSG, ERROR_MSG);
TestConsole console = new TestConsole(Verbosity.SILENT);
ExecutionContext context = createContext(ImmutableMap.of(params, process), console);
command.launchAndInteractWithProcess(context, params);
assertEquals(ERROR_MSG, console.getTextWrittenToStdErr());
}
use of com.facebook.buck.step.ExecutionContext 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.step.ExecutionContext in project buck by facebook.
the class NdkLibrary method getBuildSteps.
@Override
public ImmutableList<Step> getBuildSteps(BuildContext context, final BuildableContext buildableContext) {
ImmutableList.Builder<Step> steps = ImmutableList.builder();
// .so files are written to the libs/ subdirectory of the output directory.
// All of them should be recorded via the BuildableContext.
Path binDirectory = buildArtifactsDirectory.resolve("libs");
steps.add(new RmStep(getProjectFilesystem(), makefile));
steps.add(new MkdirStep(getProjectFilesystem(), makefile.getParent()));
steps.add(new WriteFileStep(getProjectFilesystem(), makefileContents, makefile, false));
steps.add(new NdkBuildStep(getProjectFilesystem(), root, makefile, buildArtifactsDirectory, binDirectory, flags, macroExpander));
steps.add(new MakeCleanDirectoryStep(getProjectFilesystem(), genDirectory));
steps.add(CopyStep.forDirectory(getProjectFilesystem(), binDirectory, genDirectory, CopyStep.DirectoryMode.CONTENTS_ONLY));
buildableContext.recordArtifact(genDirectory);
// Some tools need to inspect .so files whose symbols haven't been stripped, so cache these too.
// However, the intermediate object files are huge and we have no interest in them, so filter
// them out.
steps.add(new AbstractExecutionStep("cache_unstripped_so") {
@Override
public StepExecutionResult execute(ExecutionContext context) {
try {
Set<Path> unstrippedSharedObjs = getProjectFilesystem().getFilesUnderPath(buildArtifactsDirectory, input -> input.toString().endsWith(".so"));
for (Path path : unstrippedSharedObjs) {
buildableContext.recordArtifact(path);
}
} catch (IOException e) {
context.logError(e, "Failed to cache intermediate artifacts of %s.", getBuildTarget());
return StepExecutionResult.ERROR;
}
return StepExecutionResult.SUCCESS;
}
});
return steps.build();
}
Aggregations