in tools/plisttool/plisttool.py [0:0]
def _validate_children(plist, child_plists, child_required_values, target):
"""Validates a target's plist is consistent with its children.
This function checks each of the given child plists (which are typically
extensions or sub-apps embedded in another application) and fails the build
if there are any issues.
Args:
plist: The final plist of the target being built.
child_plists: The plists of child targets that the target being built
depends on.
child_required_values: Mapping of any key/value pairs to validate in
the children.
target: The name of the target being processed.
Raises:
PlistToolError: if there was an inconsistency between a child target's
plist and the current target's plist, with a message describing what
was incorrect.
"""
if child_required_values is None:
child_required_values = dict()
prefix = plist['CFBundleIdentifier'] + '.'
version = plist.get('CFBundleVersion')
short_version = plist.get('CFBundleShortVersionString')
for label, p in child_plists.items():
child_plist = PlistIO.get_dict(p, target)
child_id = child_plist['CFBundleIdentifier']
if not child_id.startswith(prefix):
raise PlistToolError(CHILD_BUNDLE_ID_MISMATCH_MSG % (
target, label, prefix, child_id))
# - TN2420 calls out CFBundleVersion and CFBundleShortVersionString
# has having to match for watchOS targets.
# https://developer.apple.com/library/content/technotes/tn2420/_index.html
# - The Application Loader (and Xcode) have also given errors for
# iOS Extensions that don't share the same values for the two
# version keys as they parent App. So we enforce this for all
# platforms just to be safe even though it isn't otherwise
# documented.
# https://stackoverflow.com/questions/30441750/use-same-cfbundleversion-and-cfbundleshortversionstring-in-all-targets
child_version = child_plist.get('CFBundleVersion')
if version != child_version:
raise PlistToolError(CHILD_BUNDLE_VERSION_MISMATCH_MSG % (
target, 'CFBundleVersion', label, version, child_version))
child_version = child_plist.get('CFBundleShortVersionString')
if short_version != child_version:
raise PlistToolError(CHILD_BUNDLE_VERSION_MISMATCH_MSG % (
target, 'CFBundleShortVersionString', label, short_version,
child_version))
required_info = child_required_values.get(label, [])
for pair in required_info:
if not isinstance(pair, list) or len(pair) != 2:
raise PlistToolError(REQUIRED_CHILD_NOT_PAIR % (target, label, pair))
[key_path, expected] = pair
value = GetWithKeyPath(child_plist, key_path)
if value is None:
key_path_str = ":".join([str(x) for x in key_path])
raise PlistToolError(REQUIRED_CHILD_KEYPATH_NOT_FOUND % (
target, label, key_path_str, expected))
if value != expected:
key_path_str = ":".join([str(x) for x in key_path])
raise PlistToolError(REQUIRED_CHILD_KEYPATH_NOT_MATCHING % (
target, label, key_path_str, expected, value))
# Make sure there wasn't anything listed in required that wasn't listed
# as a child.
for label in child_required_values.keys():
if label not in child_plists:
raise PlistToolError(REQUIRED_CHILD_MISSING_MSG % (target, label))