Skip to content
This repository was archived by the owner on Nov 10, 2023. It is now read-only.

Commit b982228

Browse files
IanChildsfacebook-github-bot
authored andcommitted
refactor GenerateManifest to be generic
Summary: This will let us create a `java_binary` from which we can run `generate_manifest`. Reviewed By: mykola-semko fbshipit-source-id: 1af6e1b29f5c7b111b50bb766bff21f6b297c6ae
1 parent 002bf88 commit b982228

4 files changed

Lines changed: 142 additions & 83 deletions

File tree

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
java_library(
2+
name = "manifest",
3+
srcs = glob(["*.java"]),
4+
visibility = [
5+
"//src/com/facebook/buck/android/...",
6+
"//src/com/facebook/buck/externalactions/...",
7+
"//src/com/facebook/buck/step/isolatedsteps/android/...",
8+
"//test/com/facebook/buck/...",
9+
],
10+
deps = [
11+
"//src/com/facebook/buck/android/apkmodule:apkmodule",
12+
"//src/com/facebook/buck/core/exceptions:exceptions",
13+
"//src/com/facebook/buck/util/environment:platform",
14+
"//third-party/java/aosp:aosp",
15+
"//third-party/java/guava:guava",
16+
],
17+
)
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/*
2+
* Copyright (c) Facebook, Inc. and its affiliates.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.facebook.buck.android.manifest;
18+
19+
import com.android.common.utils.ILogger;
20+
import com.android.manifmerger.ManifestMerger2;
21+
import com.android.manifmerger.MergingReport;
22+
import com.facebook.buck.android.apkmodule.APKModule;
23+
import com.facebook.buck.core.exceptions.HumanReadableException;
24+
import com.facebook.buck.util.environment.Platform;
25+
import com.google.common.collect.ImmutableList;
26+
import com.google.common.collect.ImmutableSet;
27+
import com.google.common.collect.Iterables;
28+
import com.google.common.io.Files;
29+
import java.io.File;
30+
import java.io.IOException;
31+
import java.nio.file.Path;
32+
import java.util.List;
33+
34+
public class GenerateManifest {
35+
36+
public static String generateXml(
37+
Path skeletonManifestPath,
38+
String moduleName,
39+
ImmutableSet<Path> libraryManifestPaths,
40+
Path outManifestPath,
41+
Path mergeReportPath,
42+
ILogger logger)
43+
throws IOException {
44+
if (skeletonManifestPath.getNameCount() == 0) {
45+
throw new HumanReadableException("Skeleton manifest filepath is missing");
46+
}
47+
48+
if (outManifestPath.getNameCount() == 0) {
49+
throw new HumanReadableException("Output Manifest filepath is missing");
50+
}
51+
52+
Files.createParentDirs(outManifestPath.toFile());
53+
54+
List<File> libraryManifestFiles =
55+
libraryManifestPaths.stream().map(Path::toFile).collect(ImmutableList.toImmutableList());
56+
57+
MergingReport mergingReport =
58+
mergeManifests(
59+
moduleName,
60+
skeletonManifestPath.toFile(),
61+
libraryManifestFiles,
62+
mergeReportPath,
63+
logger);
64+
65+
String xmlText = mergingReport.getMergedDocument(MergingReport.MergedManifestKind.MERGED);
66+
67+
if (Platform.detect() == Platform.WINDOWS) {
68+
// Convert line endings to Lf on Windows.
69+
xmlText = xmlText.replace("\r\n", "\n");
70+
}
71+
72+
return xmlText;
73+
}
74+
75+
private static MergingReport mergeManifests(
76+
String moduleName,
77+
File mainManifestFile,
78+
List<File> libraryManifestFiles,
79+
Path mergeReportPath,
80+
ILogger logger) {
81+
try {
82+
ManifestMerger2.Invoker<?> manifestInvoker =
83+
ManifestMerger2.newMerger(
84+
mainManifestFile, logger, ManifestMerger2.MergeType.APPLICATION);
85+
if (!APKModule.isRootModule(moduleName)) {
86+
manifestInvoker.setPlaceHolderValue("split", moduleName);
87+
} else {
88+
manifestInvoker.withFeatures(ManifestMerger2.Invoker.Feature.NO_PLACEHOLDER_REPLACEMENT);
89+
}
90+
91+
MergingReport mergingReport =
92+
manifestInvoker
93+
.withFeatures(
94+
ManifestMerger2.Invoker.Feature.REMOVE_TOOLS_DECLARATIONS,
95+
ManifestMerger2.Invoker.Feature.SKIP_BLAME)
96+
.addLibraryManifests(Iterables.toArray(libraryManifestFiles, File.class))
97+
.setMergeReportFile(mergeReportPath.toFile())
98+
.merge();
99+
if (mergingReport.getResult().isError()) {
100+
for (MergingReport.Record record : mergingReport.getLoggingRecords()) {
101+
logger.error(null, record.toString());
102+
}
103+
throw new HumanReadableException("Error generating manifest file");
104+
}
105+
106+
return mergingReport;
107+
} catch (ManifestMerger2.MergeFailureException e) {
108+
throw new HumanReadableException(
109+
e.getCause(), "Error generating manifest file: %s", e.getMessage());
110+
}
111+
}
112+
}

src/com/facebook/buck/step/isolatedsteps/android/BUCK

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ java_immutables_library(
1818
"//src/com/facebook/buck/android/aapt:mini_aapt",
1919
"//src/com/facebook/buck/android/aapt:r_dot_txt",
2020
"//src/com/facebook/buck/android/apkmodule:apkmodule",
21+
"//src/com/facebook/buck/android/manifest:manifest",
2122
"//src/com/facebook/buck/android/resources:resources",
2223
"//src/com/facebook/buck/core/build/execution/context:context",
2324
"//src/com/facebook/buck/core/filesystems:filesystems",

src/com/facebook/buck/step/isolatedsteps/android/GenerateManifestStep.java

Lines changed: 12 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -17,28 +17,18 @@
1717
package com.facebook.buck.step.isolatedsteps.android;
1818

1919
import com.android.common.utils.ILogger;
20-
import com.android.manifmerger.ManifestMerger2;
21-
import com.android.manifmerger.MergingReport;
2220
import com.facebook.buck.android.BuckEventAndroidLogger;
23-
import com.facebook.buck.android.apkmodule.APKModule;
21+
import com.facebook.buck.android.manifest.GenerateManifest;
2422
import com.facebook.buck.core.build.execution.context.IsolatedExecutionContext;
25-
import com.facebook.buck.core.exceptions.HumanReadableException;
2623
import com.facebook.buck.core.filesystems.AbsPath;
2724
import com.facebook.buck.core.filesystems.RelPath;
2825
import com.facebook.buck.event.IsolatedEventBus;
2926
import com.facebook.buck.io.filesystem.impl.ProjectFilesystemUtils;
3027
import com.facebook.buck.step.StepExecutionResult;
3128
import com.facebook.buck.step.StepExecutionResults;
3229
import com.facebook.buck.step.isolatedsteps.IsolatedStep;
33-
import com.facebook.buck.util.environment.Platform;
3430
import com.google.common.collect.ImmutableSet;
35-
import com.google.common.collect.Iterables;
36-
import com.google.common.io.Files;
37-
import java.io.File;
3831
import java.io.IOException;
39-
import java.nio.file.Path;
40-
import java.util.ArrayList;
41-
import java.util.List;
4232

4333
public class GenerateManifestStep extends IsolatedStep {
4434

@@ -64,85 +54,24 @@ public GenerateManifestStep(
6454
@Override
6555
public StepExecutionResult executeIsolatedStep(IsolatedExecutionContext context)
6656
throws IOException, InterruptedException {
67-
if (skeletonManifestPath.getNameCount() == 0) {
68-
throw new HumanReadableException("Skeleton manifest filepath is missing");
69-
}
70-
71-
if (outManifestPath.getNameCount() == 0) {
72-
throw new HumanReadableException("Output Manifest filepath is missing");
73-
}
74-
75-
Path resolvedOutManifestPath =
76-
ProjectFilesystemUtils.getPathForRelativePath(context.getRuleCellRoot(), outManifestPath);
77-
Files.createParentDirs(resolvedOutManifestPath.toFile());
78-
79-
List<File> libraryManifestFiles = new ArrayList<>();
80-
for (RelPath path : libraryManifestPaths) {
81-
Path manifestPath =
82-
ProjectFilesystemUtils.getPathForRelativePath(context.getRuleCellRoot(), path);
83-
libraryManifestFiles.add(manifestPath.toFile());
84-
}
85-
86-
File skeletonManifestFile =
87-
ProjectFilesystemUtils.getPathForRelativePath(
88-
context.getRuleCellRoot(), skeletonManifestPath)
89-
.toFile();
90-
BuckEventAndroidLogger logger = new ManifestMergerLogger(context.getIsolatedEventBus());
57+
AbsPath root = context.getRuleCellRoot();
58+
String xmlText =
59+
GenerateManifest.generateXml(
60+
ProjectFilesystemUtils.getPathForRelativePath(root, skeletonManifestPath),
61+
moduleName,
62+
libraryManifestPaths.stream()
63+
.map(relPath -> ProjectFilesystemUtils.getPathForRelativePath(root, relPath))
64+
.collect(ImmutableSet.toImmutableSet()),
65+
ProjectFilesystemUtils.getPathForRelativePath(root, outManifestPath),
66+
ProjectFilesystemUtils.getPathForRelativePath(root, mergeReportPath),
67+
new ManifestMergerLogger(context.getIsolatedEventBus()));
9168

92-
MergingReport mergingReport =
93-
mergeManifests(
94-
context.getRuleCellRoot(), skeletonManifestFile, libraryManifestFiles, logger);
95-
96-
String xmlText = mergingReport.getMergedDocument(MergingReport.MergedManifestKind.MERGED);
97-
if (context.getPlatform() == Platform.WINDOWS) {
98-
// Convert line endings to Lf on Windows.
99-
xmlText = xmlText.replace("\r\n", "\n");
100-
}
10169
ProjectFilesystemUtils.writeContentsToPath(
10270
context.getRuleCellRoot(), xmlText, outManifestPath.getPath());
10371

10472
return StepExecutionResults.SUCCESS;
10573
}
10674

107-
private MergingReport mergeManifests(
108-
AbsPath ruleCellRoot,
109-
File mainManifestFile,
110-
List<File> libraryManifestFiles,
111-
BuckEventAndroidLogger logger) {
112-
try {
113-
ManifestMerger2.Invoker<?> manifestInvoker =
114-
ManifestMerger2.newMerger(
115-
mainManifestFile, logger, ManifestMerger2.MergeType.APPLICATION);
116-
if (!APKModule.isRootModule(moduleName)) {
117-
manifestInvoker.setPlaceHolderValue("split", moduleName);
118-
} else {
119-
manifestInvoker.withFeatures(ManifestMerger2.Invoker.Feature.NO_PLACEHOLDER_REPLACEMENT);
120-
}
121-
122-
MergingReport mergingReport =
123-
manifestInvoker
124-
.withFeatures(
125-
ManifestMerger2.Invoker.Feature.REMOVE_TOOLS_DECLARATIONS,
126-
ManifestMerger2.Invoker.Feature.SKIP_BLAME)
127-
.addLibraryManifests(Iterables.toArray(libraryManifestFiles, File.class))
128-
.setMergeReportFile(
129-
ProjectFilesystemUtils.getPathForRelativePath(ruleCellRoot, mergeReportPath)
130-
.toFile())
131-
.merge();
132-
if (mergingReport.getResult().isError()) {
133-
for (MergingReport.Record record : mergingReport.getLoggingRecords()) {
134-
logger.error(null, record.toString());
135-
}
136-
throw new HumanReadableException("Error generating manifest file");
137-
}
138-
139-
return mergingReport;
140-
} catch (ManifestMerger2.MergeFailureException e) {
141-
throw new HumanReadableException(
142-
e.getCause(), "Error generating manifest file: %s", e.getMessage());
143-
}
144-
}
145-
14675
@Override
14776
public String getIsolatedStepDescription(IsolatedExecutionContext context) {
14877
return String.format("generate-manifest %s", skeletonManifestPath);

0 commit comments

Comments
 (0)