public Result createBuildableForAndroidResources( BuildRuleResolver ruleResolver, boolean createBuildableIfEmptyDeps) { ImmutableSortedSet<BuildRule> originalDeps = originalBuildRuleParams.getDeps(); ImmutableList<HasAndroidResourceDeps> androidResourceDeps = UberRDotJavaUtil.getAndroidResourceDeps(originalDeps); if (androidResourceDeps.isEmpty() && !createBuildableIfEmptyDeps) { return new Result(originalBuildRuleParams, Optional.<DummyRDotJava>absent()); } BuildRule dummyRDotJavaBuildRule = ruleResolver.buildAndAddToIndex( DummyRDotJava.newDummyRDotJavaBuildableBuilder(buildRuleBuilderParams) .setBuildTarget(dummyRDotJavaBuildTarget) .setAndroidResourceDeps(androidResourceDeps)); final DummyRDotJava dummyRDotJava = (DummyRDotJava) dummyRDotJavaBuildRule.getBuildable(); ImmutableSortedSet<BuildRule> totalDeps = ImmutableSortedSet.<BuildRule>naturalOrder() .addAll(originalDeps) .add(dummyRDotJavaBuildRule) .build(); BuildRuleParams newBuildRuleParams = originalBuildRuleParams.copyWithChangedDeps(totalDeps); return new Result(newBuildRuleParams, Optional.of(dummyRDotJava)); }
@Override protected ImmutableList<HasAndroidResourceDeps> getAndroidResourceDepsInternal( DependencyGraph graph) { // Filter out the AndroidResourceRules that are needed by this APK but not the APK under test. ImmutableSet<HasAndroidResourceDeps> originalResources = ImmutableSet.copyOf(UberRDotJavaUtil.getAndroidResourceDeps(apkUnderTest, graph)); ImmutableList<HasAndroidResourceDeps> instrumentationResources = UberRDotJavaUtil.getAndroidResourceDeps(this, graph); // Include all of the instrumentation resources first, in their original order. ImmutableList.Builder<HasAndroidResourceDeps> allResources = ImmutableList.builder(); for (HasAndroidResourceDeps resource : instrumentationResources) { if (!originalResources.contains(resource)) { allResources.add(resource); } } return allResources.build(); }
@Override public List<Step> getBuildSteps(BuildContext context, final BuildableContext buildableContext) { ImmutableList.Builder<Step> steps = ImmutableList.builder(); final Path rDotJavaSrcFolder = getRDotJavaSrcFolder(buildTarget); steps.add(new MakeCleanDirectoryStep(rDotJavaSrcFolder)); // Generate the .java files and record where they will be written in javaSourceFilePaths. Set<SourcePath> javaSourceFilePaths = Sets.newHashSet(); if (androidResourceDeps.isEmpty()) { // In this case, the user is likely running a Robolectric test that does not happen to // depend on any resources. However, if Robolectric doesn't find an R.java file, it flips // out, so we have to create one, anyway. // TODO(mbolin): Stop hardcoding com.facebook. This should match the package in the // associated TestAndroidManifest.xml file. String rDotJavaPackage = "com.facebook"; String javaCode = MergeAndroidResourcesStep.generateJavaCodeForPackageWithoutResources(rDotJavaPackage); steps.add(new MakeCleanDirectoryStep(rDotJavaSrcFolder.resolve("com/facebook"))); Path rDotJavaFile = rDotJavaSrcFolder.resolve("com/facebook/R.java"); steps.add(new WriteFileStep(javaCode, rDotJavaFile)); javaSourceFilePaths.add(new PathSourcePath(rDotJavaFile)); } else { Map<Path, String> symbolsFileToRDotJavaPackage = Maps.newHashMap(); for (HasAndroidResourceDeps res : androidResourceDeps) { String rDotJavaPackage = res.getRDotJavaPackage(); symbolsFileToRDotJavaPackage.put(res.getPathToTextSymbolsFile(), rDotJavaPackage); Path rDotJavaFilePath = MergeAndroidResourcesStep.getOutputFilePath(rDotJavaSrcFolder, rDotJavaPackage); javaSourceFilePaths.add(new PathSourcePath(rDotJavaFilePath)); } steps.add(new MergeAndroidResourcesStep(symbolsFileToRDotJavaPackage, rDotJavaSrcFolder)); } // Clear out the directory where the .class files will be generated. final Path rDotJavaClassesFolder = getRDotJavaBinFolder(); steps.add(new MakeCleanDirectoryStep(rDotJavaClassesFolder)); Path pathToAbiOutputDir = getPathToAbiOutputDir(buildTarget); steps.add(new MakeCleanDirectoryStep(pathToAbiOutputDir)); Path pathToAbiOutputFile = pathToAbiOutputDir.resolve("abi"); // Compile the .java files. final JavacStep javacStep = UberRDotJavaUtil.createJavacStepForDummyRDotJavaFiles( javaSourceFilePaths, rDotJavaClassesFolder, Optional.of(pathToAbiOutputFile), javacOptions, buildTarget); steps.add(javacStep); steps.add( new AbstractExecutionStep("record_abi_key") { @Override public int execute(ExecutionContext context) { Sha1HashCode abiKey = javacStep.getAbiKey(); Preconditions.checkNotNull( abiKey, "Javac step must create a non-null ABI key for this rule."); buildableContext.addMetadata(METADATA_KEY_FOR_ABI_KEY, abiKey.getHash()); return 0; } }); buildableContext.recordArtifactsInDirectory(rDotJavaClassesFolder); return steps.build(); }