aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/objc_tools
diff options
context:
space:
mode:
authorGravatar Googler <noreply@google.com>2015-12-08 20:27:30 +0000
committerGravatar David Chen <dzc@google.com>2015-12-08 22:26:51 +0000
commit8ca78e61630f525d1f97c711952208efd14606f8 (patch)
tree9f12783d3354c8f1ef53b04e4da345249bc5a62e /src/objc_tools
parentdfa6368490224a2f98d967736cef5803a82c3989 (diff)
Plmerge receives arguments by a protobuf, introduces variable substitutions to plmerge.
As of this change plmerge can consume either a protobuf or command line arguments. Once bazel uses plmerge strictly with protobufs, the command line arguments will be deprecated. -- MOS_MIGRATED_REVID=109716003
Diffstat (limited to 'src/objc_tools')
-rw-r--r--src/objc_tools/plmerge/BUILD4
-rw-r--r--src/objc_tools/plmerge/java/com/google/devtools/build/xcode/plmerge/MergingArguments.java117
-rw-r--r--src/objc_tools/plmerge/java/com/google/devtools/build/xcode/plmerge/PlMerge.java115
-rw-r--r--src/objc_tools/plmerge/java/com/google/devtools/build/xcode/plmerge/PlistMerging.java16
4 files changed, 215 insertions, 37 deletions
diff --git a/src/objc_tools/plmerge/BUILD b/src/objc_tools/plmerge/BUILD
index 2dd46af95a..81268bc9b1 100644
--- a/src/objc_tools/plmerge/BUILD
+++ b/src/objc_tools/plmerge/BUILD
@@ -8,6 +8,7 @@ java_binary(
deps = [
":plmerge_lib",
"//src/main/java/com/google/devtools/common/options",
+ "//src/main/protobuf:plmerge_proto",
"//third_party:guava",
"//third_party/java/dd_plist",
],
@@ -17,9 +18,10 @@ java_library(
name = "plmerge_lib",
srcs = glob(
["java/**/*.java"],
- exclude = ["java/**/PlMerge.java"],
),
deps = [
+ "//src/main/java/com/google/devtools/common/options",
+ "//src/main/protobuf:plmerge_proto",
"//src/tools/xcode-common/java/com/google/devtools/build/xcode/common",
"//src/tools/xcode-common/java/com/google/devtools/build/xcode/util",
"//third_party:guava",
diff --git a/src/objc_tools/plmerge/java/com/google/devtools/build/xcode/plmerge/MergingArguments.java b/src/objc_tools/plmerge/java/com/google/devtools/build/xcode/plmerge/MergingArguments.java
new file mode 100644
index 0000000000..d278dc870a
--- /dev/null
+++ b/src/objc_tools/plmerge/java/com/google/devtools/build/xcode/plmerge/MergingArguments.java
@@ -0,0 +1,117 @@
+// Copyright 2015 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.google.devtools.build.xcode.plmerge;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableList.Builder;
+import com.google.common.collect.ImmutableMap;
+import com.google.devtools.build.xcode.plmerge.PlMerge.PlMergeOptions;
+import com.google.devtools.build.xcode.plmerge.proto.PlMergeProtos.Control;
+
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Path;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Container for data consumed by plmerge
+ */
+class MergingArguments {
+
+ private final FileSystem fileSystem = FileSystems.getDefault();
+ private final List<Path> sourceFilePaths;
+ private final String outFile;
+ private final Map<String, String> variableSubstitutions;
+ private final String primaryBundleId;
+ private final String fallbackBundleId;
+
+ /**
+ * Build MergingArguments from a plmerge protobuf.
+ */
+ public MergingArguments(Control control) {
+ ImmutableList.Builder<Path> sourceFilePathsBuilder = new Builder<>();
+ for (String pathString : control.getSourceFileList()) {
+ sourceFilePathsBuilder.add(fileSystem.getPath(pathString));
+ }
+ sourceFilePaths = sourceFilePathsBuilder.build();
+ outFile = control.getOutFile();
+ variableSubstitutions = control.getVariableSubstitutionMap();
+ primaryBundleId = control.getPrimaryBundleId();
+ fallbackBundleId = control.getFallbackBundleId();
+ }
+
+ /**
+ * Build MergingArguments from command line arguments passed to the plmerge executable.
+ */
+ public MergingArguments(PlMergeOptions options) {
+ ImmutableList.Builder<Path> sourceFilePathsBuilder = new Builder<Path>();
+ for (String sourceFile : options.sourceFiles) {
+ sourceFilePathsBuilder.add(fileSystem.getPath(sourceFile));
+ }
+
+ sourceFilePaths = sourceFilePathsBuilder.build();
+ outFile = options.outFile;
+ variableSubstitutions = ImmutableMap.<String, String>of();
+ primaryBundleId = options.primaryBundleId;
+ fallbackBundleId = options.fallbackBundleId;
+ }
+
+ /**
+ * Returns paths to the plist files to merge relative to plmerge. These can be
+ * binary, XML, or ASCII format.
+ */
+ public List<Path> getSourceFilePaths() {
+ return sourceFilePaths;
+ }
+
+ /**
+ * Returns path to the output file to merge relative to plmerge.
+ */
+ public String getOutFile() {
+ return outFile;
+ }
+
+ /**
+ * Returns a reverse-DNS string identifier for this bundle associated with output
+ * binary plist. Overrides the bundle id specified in the CFBundleIdentifier
+ * plist field.
+ */
+ public String getPrimaryBundleId() {
+ return primaryBundleId;
+ }
+
+ /**
+ * Returns a fallback reverse-DNS string identifier for this bundle when bundle
+ * identifier is not specified in primary_bundle_id or an associated plist
+ * file.
+ */
+ public String getFallbackBundleId() {
+ return fallbackBundleId;
+ }
+
+ /**
+ * Returns key-value substitutions to support templating for plists. A substitution
+ * is made if the substitution key appears as a value for any key-value pair
+ * in any source_file.
+ * For example, a plist with the entry:
+ * <pre><key>CFBundleExectuable</key>
+ * <string>EXECUTABLE_NAME</string></pre>
+ * could be templated by passing a variable substitution like
+ * {"EXECUTABLE_NAME", "PrenotCalculator"}
+ */
+ public Map<String, String> getVariableSubstitutions() {
+ return variableSubstitutions;
+ }
+}
diff --git a/src/objc_tools/plmerge/java/com/google/devtools/build/xcode/plmerge/PlMerge.java b/src/objc_tools/plmerge/java/com/google/devtools/build/xcode/plmerge/PlMerge.java
index ea13c29ab9..40eaa57ade 100644
--- a/src/objc_tools/plmerge/java/com/google/devtools/build/xcode/plmerge/PlMerge.java
+++ b/src/objc_tools/plmerge/java/com/google/devtools/build/xcode/plmerge/PlMerge.java
@@ -15,6 +15,7 @@
package com.google.devtools.build.xcode.plmerge;
import com.google.common.collect.ImmutableMap;
+import com.google.devtools.build.xcode.plmerge.proto.PlMergeProtos.Control;
import com.google.devtools.common.options.Option;
import com.google.devtools.common.options.Options;
import com.google.devtools.common.options.OptionsBase;
@@ -24,81 +25,123 @@ import com.google.devtools.common.options.OptionsParsingException;
import com.dd.plist.NSObject;
import java.io.IOException;
+import java.io.InputStream;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
-import java.nio.file.Path;
-import java.util.ArrayList;
+import java.nio.file.Files;
import java.util.List;
/**
* Entry point for the {@code plmerge} tool, which merges the data from one or more plists into a
* single binary plist. This tool's functionality is similar to that of the
* {@code builtin-infoPlistUtility} in Xcode.
+ *
+ * <p>For backwards compatibility, PlMerge can consume either a control protobuf, passed using
+ * --control, or the command line arguments --source_file, --out_file, --primary_bundle_id,
+ * and --fallback_bundle_id. If a --control is not provided, PlMerge will fall back on the other
+ * command line arguments. If --control is provided, all other command line arguments are ignored.
*/
public class PlMerge {
+
/**
* Options for {@link PlMerge}.
*/
public static class PlMergeOptions extends OptionsBase {
+
@Option(
- name = "source_file",
- help = "Paths to the plist files to merge. These can be binary, XML, or ASCII format. "
- + "Repeat this flag to specify multiple files. Required.",
- allowMultiple = true,
- defaultValue = "null")
+ name = "source_file",
+ help =
+ "Paths to the plist files to merge. These can be binary, XML, or ASCII format. "
+ + "Repeat this flag to specify multiple files. Required.",
+ allowMultiple = true,
+ defaultValue = "null"
+ )
public List<String> sourceFiles;
- @Option(
- name = "out_file",
- help = "Path to the output file. Required.",
- defaultValue = "null")
+ @Option(name = "out_file", help = "Path to the output file. Required.", defaultValue = "null")
public String outFile;
@Option(
- name = "primary_bundle_id",
- help = "A reverse-DNS string identifier for this bundle associated with output binary "
- + "plist. This flag overrides the bundle id specified in field CFBundleIdentifier in "
- + "the associated plist file.",
- defaultValue = "null")
+ name = "primary_bundle_id",
+ help =
+ "A reverse-DNS string identifier for this bundle associated with output binary "
+ + "plist. This flag overrides the bundle id specified in field CFBundleIdentifier in "
+ + "the associated plist file.",
+ defaultValue = "null"
+ )
public String primaryBundleId;
@Option(
- name = "fallback_bundle_id",
- help = "A fallback reverse-DNS string identifier for this bundle when the bundle "
- + "identifier is not specified in flag primary_bundle_id or associated plist file",
- defaultValue = "null")
+ name = "fallback_bundle_id",
+ help =
+ "A fallback reverse-DNS string identifier for this bundle when the bundle "
+ + "identifier is not specified in flag primary_bundle_id or associated plist file",
+ defaultValue = "null"
+ )
public String fallbackBundleId;
+
+ @Option(
+ name = "control",
+ help =
+ "Absolute path of the Control protobuf. Data can be passed to plmerge through this "
+ + "protobuf or through source_file, out_file, primary_bundle_id and "
+ + "fallback_bundle_id.",
+ defaultValue = "null"
+ )
+ public String controlPath;
}
+
+ public static void main(String[] args) throws OptionsParsingException, IOException {
- public static void main(String[] args) throws IOException, OptionsParsingException {
+ FileSystem fileSystem = FileSystems.getDefault();
OptionsParser parser = OptionsParser.newOptionsParser(PlMergeOptions.class);
parser.parse(args);
PlMergeOptions options = parser.getOptions(PlMergeOptions.class);
- if (options.sourceFiles.isEmpty()) {
- missingArg("At least one --source_file");
- }
- if (options.outFile == null) {
- missingArg("--out_file");
- }
- FileSystem fileSystem = FileSystems.getDefault();
- List<Path> sourceFilePaths = new ArrayList<>();
- for (String sourceFile : options.sourceFiles) {
- sourceFilePaths.add(fileSystem.getPath(sourceFile));
+ MergingArguments data = null;
+
+ if (usingControlProtobuf(options)) {
+ InputStream in = Files.newInputStream(fileSystem.getPath(options.controlPath));
+ Control control = Control.parseFrom(in);
+ validateControl(control);
+ data = new MergingArguments(control);
+ } else if (usingCommandLineArgs(options)) {
+ data = new MergingArguments(options);
+ } else {
+ missingArg("Either --control or --out_file and at least one --source_file");
}
- PlistMerging merging = PlistMerging.from(sourceFilePaths, ImmutableMap.<String, NSObject>of(),
- ImmutableMap.<String, String>of(), new KeysToRemoveIfEmptyString());
- if (options.primaryBundleId != null || options.fallbackBundleId != null) {
+ PlistMerging merging =
+ PlistMerging.from(
+ data,
+ ImmutableMap.<String, NSObject>of(),
+ new KeysToRemoveIfEmptyString("CFBundleIconFile", "NSPrincipalClass"));
+ if (data.getPrimaryBundleId() != null || data.getFallbackBundleId() != null) {
// Only set the bundle identifier if we were passed arguments to do so.
// This prevents CFBundleIdentifiers being put into strings files.
- merging.setBundleIdentifier(options.primaryBundleId, options.fallbackBundleId);
+ merging.setBundleIdentifier(data.getPrimaryBundleId(), data.getFallbackBundleId());
}
- merging.writePlist(fileSystem.getPath(options.outFile));
+ merging.writePlist(fileSystem.getPath(data.getOutFile()));
}
+ private static void validateControl(Control control) {
+ if (control.getSourceFileList().isEmpty()) {
+ missingArg("At least one source_file");
+ } else if (!control.hasOutFile()) {
+ missingArg("out_file");
+ }
+ }
+
private static void missingArg(String flag) {
throw new IllegalArgumentException(flag + " is required:\n"
+ Options.getUsage(PlMergeOptions.class));
}
+
+ private static boolean usingControlProtobuf(PlMergeOptions options) {
+ return options.controlPath != null;
+ }
+
+ private static boolean usingCommandLineArgs(PlMergeOptions options) {
+ return (!options.sourceFiles.isEmpty()) && (options.outFile != null);
+ }
}
diff --git a/src/objc_tools/plmerge/java/com/google/devtools/build/xcode/plmerge/PlistMerging.java b/src/objc_tools/plmerge/java/com/google/devtools/build/xcode/plmerge/PlistMerging.java
index 31201eeb2b..4dae6fc7fb 100644
--- a/src/objc_tools/plmerge/java/com/google/devtools/build/xcode/plmerge/PlistMerging.java
+++ b/src/objc_tools/plmerge/java/com/google/devtools/build/xcode/plmerge/PlistMerging.java
@@ -176,6 +176,22 @@ public class PlistMerging extends Value<PlistMerging> {
* Generates a Plistmerging combining values from sourceFiles and automaticEntries, and modifying
* them based on subsitutions and keysToRemoveIfEmptyString.
*/
+ public static PlistMerging from(
+ MergingArguments mergingArguments,
+ Map<String, NSObject> automaticEntries,
+ KeysToRemoveIfEmptyString keysToRemoveIfEmptyString)
+ throws IOException {
+ return from(
+ mergingArguments.getSourceFilePaths(),
+ automaticEntries,
+ mergingArguments.getVariableSubstitutions(),
+ keysToRemoveIfEmptyString);
+ }
+
+ /**
+ * Generates a Plistmerging combining values from sourceFiles and automaticEntries, and modifying
+ * them based on subsitutions and keysToRemoveIfEmptyString.
+ */
public static PlistMerging from(List<Path> sourceFiles, Map<String, NSObject> automaticEntries,
Map<String, String> substitutions, KeysToRemoveIfEmptyString keysToRemoveIfEmptyString)
throws IOException {