Search in sources :

Example 1 with AbstractGenruleStep

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")));
}
Also used : FakeSourcePath(com.facebook.buck.rules.FakeSourcePath) FakeBuildableContext(com.facebook.buck.rules.FakeBuildableContext) SourcePathResolver(com.facebook.buck.rules.SourcePathResolver) SourcePathRuleFinder(com.facebook.buck.rules.SourcePathRuleFinder) AbstractGenruleStep(com.facebook.buck.shell.AbstractGenruleStep) Test(org.junit.Test)

Example 2 with AbstractGenruleStep

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());
}
Also used : MkdirStep(com.facebook.buck.step.fs.MkdirStep) AbstractMap(java.util.AbstractMap) ImmutableSet(com.google.common.collect.ImmutableSet) ImmutableMultimap(com.google.common.collect.ImmutableMultimap) Path(java.nio.file.Path) SourcePath(com.facebook.buck.rules.SourcePath) ExplicitBuildTargetSourcePath(com.facebook.buck.rules.ExplicitBuildTargetSourcePath) SymlinkFilesIntoDirectoryStep(com.facebook.buck.shell.SymlinkFilesIntoDirectoryStep) AbstractGenruleStep(com.facebook.buck.shell.AbstractGenruleStep) ImmutableMap(com.google.common.collect.ImmutableMap) ExecutionContext(com.facebook.buck.step.ExecutionContext) MakeCleanDirectoryStep(com.facebook.buck.step.fs.MakeCleanDirectoryStep)

Example 3 with AbstractGenruleStep

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);
}
Also used : KeystoreBuilder(com.facebook.buck.jvm.java.KeystoreBuilder) JavaLibraryBuilder(com.facebook.buck.jvm.java.JavaLibraryBuilder) FakeBuildRuleParamsBuilder(com.facebook.buck.rules.FakeBuildRuleParamsBuilder) FakeBuildRuleParamsBuilder(com.facebook.buck.rules.FakeBuildRuleParamsBuilder) Step(com.facebook.buck.step.Step) MkdirAndSymlinkFileStep(com.facebook.buck.step.fs.MkdirAndSymlinkFileStep) MakeCleanDirectoryStep(com.facebook.buck.step.fs.MakeCleanDirectoryStep) AbstractGenruleStep(com.facebook.buck.shell.AbstractGenruleStep) BuildRuleResolver(com.facebook.buck.rules.BuildRuleResolver) BuildTarget(com.facebook.buck.model.BuildTarget) FileSystem(java.nio.file.FileSystem) FakeProjectFilesystem(com.facebook.buck.testutil.FakeProjectFilesystem) ProjectFilesystem(com.facebook.buck.io.ProjectFilesystem) DefaultTargetNodeToBuildRuleTransformer(com.facebook.buck.rules.DefaultTargetNodeToBuildRuleTransformer) MkdirAndSymlinkFileStep(com.facebook.buck.step.fs.MkdirAndSymlinkFileStep) FakeSourcePath(com.facebook.buck.rules.FakeSourcePath) Path(java.nio.file.Path) PathSourcePath(com.facebook.buck.rules.PathSourcePath) FakeBuildableContext(com.facebook.buck.rules.FakeBuildableContext) BuildTargetParser(com.facebook.buck.parser.BuildTargetParser) PathSourcePath(com.facebook.buck.rules.PathSourcePath) SourcePathResolver(com.facebook.buck.rules.SourcePathResolver) SourcePathRuleFinder(com.facebook.buck.rules.SourcePathRuleFinder) AbstractGenruleStep(com.facebook.buck.shell.AbstractGenruleStep) ExecutionContext(com.facebook.buck.step.ExecutionContext) TestExecutionContext(com.facebook.buck.step.TestExecutionContext) BuildRuleParams(com.facebook.buck.rules.BuildRuleParams) FakeBuildContext(com.facebook.buck.rules.FakeBuildContext) BuildContext(com.facebook.buck.rules.BuildContext) MakeCleanDirectoryStep(com.facebook.buck.step.fs.MakeCleanDirectoryStep) BuildTargetPatternParser(com.facebook.buck.parser.BuildTargetPatternParser) Test(org.junit.Test)

Aggregations

AbstractGenruleStep (com.facebook.buck.shell.AbstractGenruleStep)3 FakeBuildableContext (com.facebook.buck.rules.FakeBuildableContext)2 FakeSourcePath (com.facebook.buck.rules.FakeSourcePath)2 SourcePathResolver (com.facebook.buck.rules.SourcePathResolver)2 SourcePathRuleFinder (com.facebook.buck.rules.SourcePathRuleFinder)2 ExecutionContext (com.facebook.buck.step.ExecutionContext)2 MakeCleanDirectoryStep (com.facebook.buck.step.fs.MakeCleanDirectoryStep)2 Path (java.nio.file.Path)2 Test (org.junit.Test)2 ProjectFilesystem (com.facebook.buck.io.ProjectFilesystem)1 JavaLibraryBuilder (com.facebook.buck.jvm.java.JavaLibraryBuilder)1 KeystoreBuilder (com.facebook.buck.jvm.java.KeystoreBuilder)1 BuildTarget (com.facebook.buck.model.BuildTarget)1 BuildTargetParser (com.facebook.buck.parser.BuildTargetParser)1 BuildTargetPatternParser (com.facebook.buck.parser.BuildTargetPatternParser)1 BuildContext (com.facebook.buck.rules.BuildContext)1 BuildRuleParams (com.facebook.buck.rules.BuildRuleParams)1 BuildRuleResolver (com.facebook.buck.rules.BuildRuleResolver)1 DefaultTargetNodeToBuildRuleTransformer (com.facebook.buck.rules.DefaultTargetNodeToBuildRuleTransformer)1 ExplicitBuildTargetSourcePath (com.facebook.buck.rules.ExplicitBuildTargetSourcePath)1