aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/test/java/com/google/devtools/build/lib/rules/objc/BinaryRuleTypePair.java
blob: 47a8601180229978f657143eb9974b47ca7e0aa2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
// Copyright 2017 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 static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.BundlingRule.FAMILIES_ATTR;
import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.BundlingRule.INFOPLIST_ATTR;
import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.ReleaseBundlingRule.APP_ICON_ATTR;
import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.ReleaseBundlingRule.BUNDLE_ID_ATTR;
import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.ReleaseBundlingRule.ENTITLEMENTS_ATTR;
import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.ReleaseBundlingRule.LAUNCH_IMAGE_ATTR;
import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.ReleaseBundlingRule.LAUNCH_STORYBOARD_ATTR;
import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.ReleaseBundlingRule.PROVISIONING_PROFILE_ATTR;

import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.testutil.Scratch;
import com.google.devtools.build.lib.util.Preconditions;
import java.io.IOException;
import java.util.Arrays;

/**
 * Represents a pair of rule types, one being a binary and one an bundling type.
 *
 * <p>TODO(bazel-team): Remove this class and refactor tests using it when the binary rule types and
 * bundling rule types are merged.
 */
final class BinaryRuleTypePair {
  private final RuleType binaryType;
  private final RuleType bundlingType;
  private final String bundleDirFormat;
  private final String bundleName;

  /**
   * Creates a rule pair.
   *
   * @param binaryType rule type for the binary half of the pair (e.g. ios_extension_binary)
   * @param bundlingType rule type for wrapper (e.g. ios_extension)
   * @param bundleDirFormat path format for location inside of bundle (e.g. Plugins/%s.appex),
   *     will be substituted with bundle name
   * @param bundleName name of the bundle
   */
  BinaryRuleTypePair(RuleType binaryType, RuleType bundlingType, String bundleDirFormat,
      String bundleName) {
    this.binaryType = binaryType;
    this.bundlingType = bundlingType;
    this.bundleDirFormat = bundleDirFormat;
    this.bundleName = bundleName;
  }

  /**
   * Creates a binary rule pair with bundle name of "x".
   */
  BinaryRuleTypePair(RuleType binaryType, RuleType bundlingType, String bundleDirFormat) {
    this(binaryType, bundlingType, bundleDirFormat, "x");
  }

  /**
   * Returns the name of this bundle.
   */
  String getBundleName() {
    return bundleName;
  }
  
  /**
   * Returns a bundle dir path by combining {@code bundleDirFormat} and {@code bundleName}.
   */
  String getBundleDir() {
    return String.format(bundleDirFormat, bundleName);
  }

  /**
   * Returns the binary type as it appears in {@code BUILD} files, such as {@code objc_binary}.
   */
  RuleType getBinaryRuleType() {
    return binaryType;
  }

  /**
   * Returns the bundling type as it appears in {@code BUILD} files, such as
   * {@code ios_application}.
   */
  RuleType getBundlingRuleType() {
    return bundlingType;
  }

  /**
   * Generates the String necessary to define a bundling and binary rule of these types.
   * This includes an "x" (bundling) and "bin" (binary) target in the given package, setting binary
   * attributes in {@code checkSpecificAttrs} on the binary target, and all other attributes on the
   * bundling target.
   */
  String targets(Scratch scratch, String packageName, String... checkSpecificAttrs)
      throws IOException {
    Preconditions.checkArgument(checkSpecificAttrs.length % 2 == 0,
        "An even number of attribute parameters (kev and value pairs) is required but got: %s",
        Arrays.asList(checkSpecificAttrs));

    ImmutableList.Builder<String> binaryAttributes = new ImmutableList.Builder<>();
    ImmutableList.Builder<String> bundlingAttributes = new ImmutableList.Builder<>();
    bundlingAttributes.add("binary", "':bin'");

    for (int i = 0; i < checkSpecificAttrs.length; i += 2) {
      String attributeName = checkSpecificAttrs[i];
      String value = checkSpecificAttrs[i + 1];
      switch (attributeName) {
        case APP_ICON_ATTR:
        case LAUNCH_IMAGE_ATTR:
        case LAUNCH_STORYBOARD_ATTR:
        case BUNDLE_ID_ATTR:
        case FAMILIES_ATTR:
        case PROVISIONING_PROFILE_ATTR:
        case ENTITLEMENTS_ATTR:
        case INFOPLIST_ATTR:
          bundlingAttributes.add(attributeName, value);
          break;
        default:
          binaryAttributes.add(attributeName, value);
      }
    }
    return binaryType.target(scratch, packageName, "bin",
        binaryAttributes.build().toArray(new String[0]))
        + "\n"
        + bundlingType.target(scratch, packageName, "x",
            bundlingAttributes.build().toArray(new String[0]));
  }

  /**
   * Creates targets at //x:x and //x:bin which are the only targets in the BUILD file.
   */
  void scratchTargets(Scratch scratch, String... checkSpecificAttrs) throws IOException {
    scratch.file("x/BUILD", targets(scratch, "x", checkSpecificAttrs));
  }
}