| // 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.lib.rules.objc; |
| |
| import com.google.common.base.Preconditions; |
| import com.google.common.collect.ImmutableMap; |
| import com.google.common.io.ByteSource; |
| import com.google.devtools.build.lib.actions.Artifact; |
| import com.google.devtools.build.lib.collect.nestedset.NestedSet; |
| import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; |
| import com.google.devtools.build.lib.collect.nestedset.Order; |
| import com.google.devtools.build.xcode.plmerge.proto.PlMergeProtos; |
| import com.google.devtools.build.xcode.plmerge.proto.PlMergeProtos.Control; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.util.Map; |
| import javax.annotation.Nullable; |
| |
| /** |
| * A byte source that can be used the generate a control file for the tool plmerge. |
| */ |
| public final class PlMergeControlBytes extends ByteSource { |
| |
| private final NestedSet<Artifact> inputPlists; |
| private final NestedSet<Artifact> immutableInputPlists; |
| @Nullable private final String primaryBundleId; |
| @Nullable private final String fallbackBundleId; |
| @Nullable private final Map<String, String> variableSubstitutions; |
| @Nullable private final String executableName; |
| private final Artifact mergedPlist; |
| private final OutputFormat outputFormat; |
| |
| /** |
| * Creates a control based on the passed bundling's plists and values. |
| * |
| * @param bundling bundle for which to create a merged plist |
| * @param mergedPlist the plist that should be created as an output |
| */ |
| static PlMergeControlBytes fromBundling(Bundling bundling, Artifact mergedPlist) { |
| |
| NestedSetBuilder<Artifact> immutableInputPlists = NestedSetBuilder.stableOrder(); |
| if (bundling.getAutomaticInfoPlist() != null) { |
| immutableInputPlists.add(bundling.getAutomaticInfoPlist()); |
| } |
| |
| return new PlMergeControlBytes( |
| NestedSetBuilder.<Artifact>stableOrder() |
| .addTransitive(bundling.getBundleInfoplistInputs()) |
| .build(), |
| immutableInputPlists.build(), |
| bundling.getPrimaryBundleId(), |
| bundling.getFallbackBundleId(), |
| bundling.variableSubstitutions(), |
| bundling.getExecutableName(), |
| mergedPlist, |
| OutputFormat.BINARY); |
| } |
| |
| /** |
| * Creates a control that merges the given plists into the merged plist. |
| */ |
| static PlMergeControlBytes fromPlists( |
| NestedSet<Artifact> inputPlists, |
| Artifact mergedPlist, |
| OutputFormat outputFormat) { |
| return new PlMergeControlBytes( |
| inputPlists, |
| NestedSetBuilder.<Artifact>emptySet(Order.STABLE_ORDER), |
| null, |
| null, |
| ImmutableMap.<String, String>of(), |
| null, |
| mergedPlist, |
| outputFormat); |
| } |
| |
| private PlMergeControlBytes( |
| NestedSet<Artifact> inputPlists, |
| NestedSet<Artifact> immutableInputPlists, |
| @Nullable String primaryBundleId, |
| @Nullable String fallbackBundleId, |
| @Nullable Map<String, String> variableSubstitutions, |
| @Nullable String executableName, |
| Artifact mergedPlist, |
| OutputFormat outputFormat) { |
| this.inputPlists = inputPlists; |
| this.immutableInputPlists = immutableInputPlists; |
| this.primaryBundleId = primaryBundleId; |
| this.fallbackBundleId = fallbackBundleId; |
| this.variableSubstitutions = variableSubstitutions; |
| this.executableName = executableName; |
| this.mergedPlist = mergedPlist; |
| this.outputFormat = Preconditions.checkNotNull(outputFormat); |
| } |
| |
| @Override |
| public InputStream openStream() throws IOException { |
| return control().toByteString().newInput(); |
| } |
| |
| private Control control() { |
| PlMergeProtos.Control.Builder control = |
| PlMergeProtos.Control.newBuilder() |
| .addAllSourceFile(Artifact.toExecPaths(inputPlists)) |
| .addAllImmutableSourceFile(Artifact.toExecPaths(immutableInputPlists)) |
| .putAllVariableSubstitutionMap(variableSubstitutions) |
| .setOutFile(mergedPlist.getExecPathString()); |
| |
| if (primaryBundleId != null) { |
| control.setPrimaryBundleId(primaryBundleId); |
| } |
| |
| if (fallbackBundleId != null) { |
| control.setFallbackBundleId(fallbackBundleId); |
| } |
| |
| if (executableName != null) { |
| control.setExecutableName(executableName); |
| } |
| |
| control.setOutputFormat(outputFormat.getProtoOutputFormat()); |
| |
| return control.build(); |
| } |
| |
| /** |
| * Plist output formats. |
| */ |
| public enum OutputFormat { |
| BINARY(Control.OutputFormat.BINARY), |
| XML(Control.OutputFormat.XML); |
| |
| private final Control.OutputFormat protoOutputFormat; |
| |
| private OutputFormat(Control.OutputFormat protoOutputFormat) { |
| this.protoOutputFormat = protoOutputFormat; |
| } |
| |
| Control.OutputFormat getProtoOutputFormat() { |
| return protoOutputFormat; |
| } |
| } |
| } |