diff options
author | ajmichael <ajmichael@google.com> | 2018-04-05 13:43:03 -0700 |
---|---|---|
committer | Copybara-Service <copybara-piper@google.com> | 2018-04-05 13:44:42 -0700 |
commit | 2660ffe3c9303466d86fff4643c0c1b5e34a8061 (patch) | |
tree | 6fca6e40aa9b0783e011fa7e4acb86f87b37a392 /tools/android | |
parent | 58fe737d06b63c44d0a1991ada772e78de9e0056 (diff) |
Remove legacy manifest merging from Bazel.
RELNOTES: android_binary.manifest_merger is no longer supported.
PiperOrigin-RevId: 191791177
Diffstat (limited to 'tools/android')
-rw-r--r-- | tools/android/BUILD | 17 | ||||
-rw-r--r-- | tools/android/BUILD.tools | 11 | ||||
-rw-r--r-- | tools/android/android_permissions.py | 146 | ||||
-rw-r--r-- | tools/android/merge_manifests.py | 469 | ||||
-rw-r--r-- | tools/android/merge_manifests_test.py | 627 |
5 files changed, 0 insertions, 1270 deletions
diff --git a/tools/android/BUILD b/tools/android/BUILD index b036998da3..4f1eb3c08c 100644 --- a/tools/android/BUILD +++ b/tools/android/BUILD @@ -1,23 +1,6 @@ package(default_visibility = ["//tools:__pkg__"]) py_binary( - name = "merge_manifests", - srcs = [ - "android_permissions.py", - "merge_manifests.py", - ], - deps = [ - "//third_party/py/gflags", - ], -) - -py_test( - name = "merge_manifests_test", - srcs = ["merge_manifests_test.py"], - deps = [":merge_manifests"], -) - -py_binary( name = "build_incremental_dexmanifest", srcs = [":build_incremental_dexmanifest.py"], ) diff --git a/tools/android/BUILD.tools b/tools/android/BUILD.tools index 07ed642df7..4a12571b60 100644 --- a/tools/android/BUILD.tools +++ b/tools/android/BUILD.tools @@ -161,17 +161,6 @@ py_binary( ) py_binary( - name = "merge_manifests", - srcs = [ - "android_permissions.py", - "merge_manifests.py", - ], - deps = [ - "//third_party/py/gflags", - ], -) - -py_binary( name = "build_incremental_dexmanifest", srcs = [":build_incremental_dexmanifest.py"], deps = [], diff --git a/tools/android/android_permissions.py b/tools/android/android_permissions.py deleted file mode 100644 index 7fb2328f7c..0000000000 --- a/tools/android/android_permissions.py +++ /dev/null @@ -1,146 +0,0 @@ -# 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. - -"""List of valid android permissions as they are for android version 4.0.3. - - This list is to be used by manifest merge to verify the exclude_permission - values. -""" - -PERMISSIONS = frozenset([ - 'android.permission.ACCESS_CHECKIN_PROPERTIES', - 'android.permission.ACCESS_COARSE_LOCATION', - 'android.permission.ACCESS_FINE_LOCATION', - 'android.permission.ACCESS_LOCATION_EXTRA_COMMANDS', - 'android.permission.ACCESS_MOCK_LOCATION', - 'android.permission.ACCESS_NETWORK_STATE', - 'android.permission.ACCESS_SURFACE_FLINGER', - 'android.permission.ACCESS_WIFI_STATE', - 'android.permission.ACCOUNT_MANAGER', - 'android.permission.AUTHENTICATE_ACCOUNTS', - 'android.permission.BATTERY_STATS', - 'android.permission.BIND_APPWIDGET', - 'android.permission.BIND_DEVICE_ADMIN', - 'android.permission.BIND_INPUT_METHOD', - 'android.permission.BIND_REMOTEVIEWS', - 'android.permission.BIND_TEXT_SERVICE', - 'android.permission.BIND_VPN_SERVICE', - 'android.permission.BIND_WALLPAPER', - 'android.permission.BLUETOOTH', - 'android.permission.BLUETOOTH_ADMIN', - 'android.permission.BRICK', - 'android.permission.BROADCAST_PACKAGE_REMOVED', - 'android.permission.BROADCAST_SMS', - 'android.permission.BROADCAST_STICKY', - 'android.permission.BROADCAST_WAP_PUSH', - 'android.permission.CALL_PHONE', - 'android.permission.CALL_PRIVILEGED', - 'android.permission.CAMERA', - 'android.permission.CHANGE_COMPONENT_ENABLED_STATE', - 'android.permission.CHANGE_CONFIGURATION', - 'android.permission.CHANGE_NETWORK_STATE', - 'android.permission.CHANGE_WIFI_MULTICAST_STATE', - 'android.permission.CHANGE_WIFI_STATE', - 'android.permission.CLEAR_APP_CACHE', - 'android.permission.CLEAR_APP_USER_DATA', - 'android.permission.CONTROL_LOCATION_UPDATES', - 'android.permission.DELETE_CACHE_FILES', - 'android.permission.DELETE_PACKAGES', - 'android.permission.DEVICE_POWER', - 'android.permission.DIAGNOSTIC', - 'android.permission.DISABLE_KEYGUARD', - 'android.permission.DUMP', - 'android.permission.EXPAND_STATUS_BAR', - 'android.permission.FACTORY_TEST', - 'android.permission.FLASHLIGHT', - 'android.permission.FORCE_BACK', - 'android.permission.GET_ACCOUNTS', - 'android.permission.GET_PACKAGE_SIZE', - 'android.permission.GET_TASKS', - 'android.permission.GLOBAL_SEARCH', - 'android.permission.HARDWARE_TEST', - 'android.permission.INJECT_EVENTS', - 'android.permission.INSTALL_LOCATION_PROVIDER', - 'android.permission.INSTALL_PACKAGES', - 'android.permission.INTERNAL_SYSTEM_WINDOW', - 'android.permission.INTERNET', - 'android.permission.KILL_BACKGROUND_PROCESSES', - 'android.permission.MANAGE_ACCOUNTS', - 'android.permission.MANAGE_APP_TOKENS', - 'android.permission.MASTER_CLEAR', - 'android.permission.MODIFY_AUDIO_SETTINGS', - 'android.permission.MODIFY_PHONE_STATE', - 'android.permission.MOUNT_FORMAT_FILESYSTEMS', - 'android.permission.MOUNT_UNMOUNT_FILESYSTEMS', - 'android.permission.NFC', - 'android.permission.PERSISTENT_ACTIVITY', - 'android.permission.PROCESS_OUTGOING_CALLS', - 'android.permission.READ_CALENDAR', - 'android.permission.READ_CONTACTS', - 'android.permission.READ_FRAME_BUFFER', - 'android.permission.READ_INPUT_STATE', - 'android.permission.READ_LOGS', - 'android.permission.READ_PHONE_STATE', - 'android.permission.READ_PROFILE', - 'android.permission.READ_SMS', - 'android.permission.READ_SOCIAL_STREAM', - 'android.permission.READ_SYNC_SETTINGS', - 'android.permission.READ_SYNC_STATS', - 'android.permission.REBOOT', - 'android.permission.RECEIVE_BOOT_COMPLETED', - 'android.permission.RECEIVE_MMS', - 'android.permission.RECEIVE_SMS', - 'android.permission.RECEIVE_WAP_PUSH', - 'android.permission.RECORD_AUDIO', - 'android.permission.REORDER_TASKS', - 'android.permission.RESTART_PACKAGES', - 'android.permission.SEND_SMS', - 'android.permission.SET_ACTIVITY_WATCHER', - 'android.permission.SET_ALWAYS_FINISH', - 'android.permission.SET_ANIMATION_SCALE', - 'android.permission.SET_DEBUG_APP', - 'android.permission.SET_ORIENTATION', - 'android.permission.SET_POINTER_SPEED', - 'android.permission.SET_PREFERRED_APPLICATIONS', - 'android.permission.SET_PROCESS_LIMIT', - 'android.permission.SET_TIME', - 'android.permission.SET_TIME_ZONE', - 'android.permission.SET_WALLPAPER', - 'android.permission.SET_WALLPAPER_HINTS', - 'android.permission.SIGNAL_PERSISTENT_PROCESSES', - 'android.permission.STATUS_BAR', - 'android.permission.SUBSCRIBED_FEEDS_READ', - 'android.permission.SUBSCRIBED_FEEDS_WRITE', - 'android.permission.SYSTEM_ALERT_WINDOW', - 'android.permission.UPDATE_DEVICE_STATS', - 'android.permission.USE_CREDENTIALS', - 'android.permission.USE_SIP', - 'android.permission.VIBRATE', - 'android.permission.WAKE_LOCK', - 'android.permission.WRITE_APN_SETTINGS', - 'android.permission.WRITE_CALENDAR', - 'android.permission.WRITE_CONTACTS', - 'android.permission.WRITE_EXTERNAL_STORAGE', - 'android.permission.WRITE_GSERVICES', - 'android.permission.WRITE_PROFILE', - 'android.permission.WRITE_SECURE_SETTINGS', - 'android.permission.WRITE_SETTINGS', - 'android.permission.WRITE_SMS', - 'android.permission.WRITE_SOCIAL_STREAM', - 'android.permission.WRITE_SYNC_SETTINGS', - 'com.android.alarm.permission.SET_ALARM', - 'com.android.browser.permission.READ_HISTORY_BOOKMARKS', - 'com.android.browser.permission.WRITE_HISTORY_BOOKMARKS', - 'com.android.voicemail.permission.ADD_VOICEMAIL']) - diff --git a/tools/android/merge_manifests.py b/tools/android/merge_manifests.py deleted file mode 100644 index 520b03219c..0000000000 --- a/tools/android/merge_manifests.py +++ /dev/null @@ -1,469 +0,0 @@ -# pylint: disable=g-direct-third-party-import -# 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. - -"""Merges two android manifest xml files.""" - -from __future__ import print_function - -import re -import sys -import xml.dom.minidom - -from tools.android import android_permissions -from third_party.py import gflags - -FLAGS = gflags.FLAGS -EXCLUDE_ALL_ARG = 'all' - -gflags.DEFINE_multistring( - 'exclude_permission', None, - 'Permissions to be excluded, e.g.: "android.permission.READ_LOGS".' - 'This is a multistring, so multiple of those flags can be provided.' - 'Pass "%s" to exclude all permissions contributed by mergees.' - % EXCLUDE_ALL_ARG) -gflags.DEFINE_multistring( - 'mergee', None, - 'Mergee manifest that will be merged to merger manifest.' - 'This is a multistring, so multiple of those flags can be provided.') -gflags.DEFINE_string('merger', None, - 'Merger AndroidManifest file to be merged.') -gflags.DEFINE_string('output', None, 'Output file with merged manifests.') - -USAGE = """Error, invalid arguments. -Usage: merge_manifests.py --merger=<merger> --mergee=<mergee1> --mergee=<merge2> - --exclude_permission=[Exclude permissions from mergee] --output=<output> -Examples: - merge_manifests.py --merger=manifest.xml --mergee=manifest2.xml - --mergee=manifest3.xml --exclude_permission=android.permission.READ_LOGS - --output=AndroidManifest.xml - - merge_manifests.py --merger=manifest.xml --mergee=manifest2.xml - --mergee=manifest3.xml --exclude_permission=%s - --output=AndroidManifest.xml -""" % EXCLUDE_ALL_ARG - - -class UndefinedPlaceholderException(Exception): - """Exception thrown when encountering a placeholder without a replacement. - """ - pass - - -class MalformedManifestException(Exception): - """Exception thrown when encountering a fatally malformed manifest. - """ - pass - - -class MergeManifests(object): - """A utility class for merging two android manifest.xml files. - - This is useful when including another app as android library. - """ - _ACTIVITY = 'activity' - _ANDROID_NAME = 'android:name' - _ANDROID_LABEL = 'android:label' - _INTENT_FILTER = 'intent-filter' - _MANIFEST = 'manifest' - _USES_PERMISSION = 'uses-permission' - _USES_PERMISSION_SDK_23 = 'uses-permission-sdk-23' - _NODES_TO_COPY_FROM_MERGEE = { - _MANIFEST: [ - 'instrumentation', - 'permission', - _USES_PERMISSION, - _USES_PERMISSION_SDK_23, - 'uses-feature', - 'permission-group', - ], - 'application': [ - 'activity', - 'activity-alias', - 'provider', - 'receiver', - 'service', - 'uses-library', - 'meta-data', - ], - } - _NODES_TO_REMOVE_FROM_MERGER = [] - _PACKAGE = 'package' - - def __init__(self, merger, mergees, exclude_permissions=None): - """Constructs and initializes the MergeManifests object. - - Args: - merger: First (merger) AndroidManifest.xml string. - mergees: mergee AndroidManifest.xml strings, a list. - exclude_permissions: Permissions to be excludeed from merging, - string list. "all" means don't include any permissions. - """ - self._merger = merger - self._mergees = mergees - self._exclude_permissions = exclude_permissions - self._merger_dom = xml.dom.minidom.parseString(self._merger[0]) - - def _ApplyExcludePermissions(self, dom): - """Apply exclude filters. - - Args: - dom: Document dom object from which to exclude permissions. - """ - if self._exclude_permissions: - exclude_all_permissions = EXCLUDE_ALL_ARG in self._exclude_permissions - for element in (dom.getElementsByTagName(self._USES_PERMISSION) + - dom.getElementsByTagName(self._USES_PERMISSION_SDK_23)): - if element.hasAttribute(self._ANDROID_NAME): - attrib = element.getAttribute(self._ANDROID_NAME) - if exclude_all_permissions or attrib in self._exclude_permissions: - element.parentNode.removeChild(element) - - def _ExpandPackageName(self, node): - """Set the package name if it is in a short form. - - Filtering logic for what elements have package expansion: - If the name starts with a dot, always prefix it with the package. - If the name has a dot anywhere else, do not prefix it. - If the name has no dot at all, also prefix it with the package. - - The massageManifest function shows where this rule is applied: - - In the application element, on the name and backupAgent attributes. - In the activity, service, receiver, provider, and activity-alias elements, - on the name attribute. - In the activity-alias element, on the targetActivity attribute. - - Args: - node: Xml Node for which to expand package name. - """ - package_name = node.getElementsByTagName(self._MANIFEST).item( - 0).getAttribute(self._PACKAGE) - - if not package_name: - return - - for element in node.getElementsByTagName('*'): - if element.nodeName not in [ - 'activity', - 'activity-alias', - 'application', - 'service', - 'receiver', - 'provider', - ]: - continue - - self._ExpandPackageNameHelper(package_name, element, self._ANDROID_NAME) - - if element.nodeName == 'activity': - self._ExpandPackageNameHelper(package_name, element, - 'android:parentActivityName') - - if element.nodeName == 'activity-alias': - self._ExpandPackageNameHelper(package_name, element, - 'android:targetActivity') - continue - - if element.nodeName == 'application': - self._ExpandPackageNameHelper(package_name, element, - 'android:backupAgent') - - def _ExpandPackageNameHelper(self, package_name, element, attribute_name): - if element.hasAttribute(attribute_name): - class_name = element.getAttribute(attribute_name) - - if class_name.startswith('.'): - pass - elif '.' not in class_name: - class_name = '.' + class_name - else: - return - - element.setAttribute(attribute_name, package_name + class_name) - - def _RemoveFromMerger(self): - """Remove from merger.""" - for tag_name in self._NODES_TO_REMOVE_FROM_MERGER: - elements = self._merger_dom.getElementsByTagName(tag_name) - for element in elements: - element.parentNode.removeChild(element) - - def _RemoveAndroidLabel(self, node): - """Remove android:label. - - We do this because it is not required by merger manifest, - and it might contain @string references that will not allow compilation. - - Args: - node: Node for which to remove Android labels. - """ - if node.hasAttribute(self._ANDROID_LABEL): - node.removeAttribute(self._ANDROID_LABEL) - - def _IsDuplicate(self, node_to_copy, node): - """Is element a duplicate?""" - for merger_node in self._merger_dom.getElementsByTagName(node_to_copy): - if (merger_node.getAttribute(self._ANDROID_NAME) == - node.getAttribute(self._ANDROID_NAME)): - return True - return False - - def _RemoveIntentFilters(self, node): - """Remove intent-filter in activity element. - - So there are no duplicate apps. - - Args: - node: Node for which to remove intent filters. - """ - intent_filters = node.getElementsByTagName(self._INTENT_FILTER) - if intent_filters.length > 0: - for sub_node in intent_filters: - node.removeChild(sub_node) - - def _FindElementComment(self, node): - """Find element's comment. - - Assumes that element's comment can be just above the element. - Searches previous siblings and looks for the first non text element - that is of a nodeType of comment node. - - Args: - node: Node for which to find a comment. - Returns: - Elements's comment node, None if not found. - """ - while node.previousSibling: - node = node.previousSibling - if node.nodeType is node.COMMENT_NODE: - return node - if node.nodeType is not node.TEXT_NODE: - return None - return None - - def _ReplaceArgumentPlaceholders(self, dom): - """Replaces argument placeholders with their values. - - Modifies the attribute values of the input node. - - Args: - dom: Xml node that should get placeholders replaced. - """ - - placeholders = { - 'packageName': self._merger_dom.getElementsByTagName( - self._MANIFEST).item(0).getAttribute(self._PACKAGE), - } - - for element in dom.getElementsByTagName('*'): - for i in range(element.attributes.length): - attr = element.attributes.item(i) - attr.value = self._ReplaceArgumentHelper(placeholders, attr.value) - - def _ReplaceArgumentHelper(self, placeholders, attr): - """Replaces argument placeholders within a single string. - - Args: - placeholders: A dict mapping between placeholder names and their - replacement values. - attr: A string in which to replace argument placeholders. - - Returns: - A string with placeholders replaced, or the same string if no placeholders - were found. - """ - match_placeholder = '\\${([a-zA-Z]*)}' - - # Returns the replacement string for found matches. - def PlaceholderReplacer(matchobj): - found_placeholder = matchobj.group(1) - if found_placeholder not in placeholders: - raise UndefinedPlaceholderException( - 'Undefined placeholder when substituting arguments: ' - + found_placeholder) - return placeholders[found_placeholder] - - attr = re.sub(match_placeholder, PlaceholderReplacer, attr) - - return attr - - def _SortAliases(self): - applications = self._merger_dom.getElementsByTagName('application') - if not applications: - return - for alias in applications[0].getElementsByTagName('activity-alias'): - comment_node = self._FindElementComment(alias) - while comment_node is not None: - applications[0].appendChild(comment_node) - comment_node = self._FindElementComment(alias) - applications[0].appendChild(alias) - - def _FindMergerParent(self, tag_to_copy, destination_tag_name, mergee_dom): - """Finds merger parent node, or appends mergee equivalent node if none.""" - # Merger parent element to which to add merged elements. - if self._merger_dom.getElementsByTagName(destination_tag_name): - return self._merger_dom.getElementsByTagName(destination_tag_name)[0] - else: - mergee_element = mergee_dom.getElementsByTagName(destination_tag_name)[0] - # find the parent - parents = self._merger_dom.getElementsByTagName( - mergee_element.parentNode.tagName) - if not parents: - raise MalformedManifestException( - 'Malformed manifest has tag %s but no parent tag %s', - (tag_to_copy, destination_tag_name)) - # append the mergee child as the first child. - return parents[0].insertBefore(mergee_element, parents[0].firstChild) - - def _OrderManifestChildren(self): - """Moves elements of the manifest tag into the correct order.""" - manifest = self._merger_dom.getElementsByTagName('manifest')[0] - # The application element must be the last element in the manifest tag. - applications = self._merger_dom.getElementsByTagName('application') - if applications: - manifest.appendChild(applications[0]) - - def _MergeTopLevelNamespaces(self, mergee_dom): - """Merge the xmlns declarations in the top-level manifest nodes. - - This does not handle and ignores xmlns declarations in child nodes. - Overall, this manifest merger does not try to interpret any attributes that - use the android "tools" namespace either. E.g., tools:node="remove". - - This functionality is just to help migrate from this manifest merger, - to a new manifest merger that does handle tools annotations (a manifest - may be sent to both mergers during migration). - - Args: - mergee_dom: The dom of the mergee manifest. - Raises: - MalformedManifestException: if the mergee and merger manifests contain - xmlns declarations that don't agree. - """ - manifest = self._merger_dom.getElementsByTagName('manifest')[0] - mergee_manifest = mergee_dom.getElementsByTagName('manifest')[0] - for i in range(mergee_manifest.attributes.length): - attr = mergee_manifest.attributes.item(i) - if attr.prefix and attr.prefix == 'xmlns': - if manifest.hasAttribute(attr.name): - main_attr_value = manifest.getAttribute(attr.name) - if main_attr_value != attr.value: - raise MalformedManifestException( - 'different values for namespace %s ("%s" vs "%s")' % ( - attr.name, main_attr_value, attr.value)) - else: - manifest.setAttribute(attr.name, attr.value) - - def Merge(self): - """Takes two manifests, and merges them together to produce a third.""" - self._RemoveFromMerger() - self._ExpandPackageName(self._merger_dom) - - for dom, filename in self._mergees: - mergee_dom = xml.dom.minidom.parseString(dom) - self._ReplaceArgumentPlaceholders(mergee_dom) - self._ExpandPackageName(mergee_dom) - self._ApplyExcludePermissions(mergee_dom) - self._MergeTopLevelNamespaces(mergee_dom) - - for destination, values in sorted( - self._NODES_TO_COPY_FROM_MERGEE.items()): - for node_to_copy in values: - for node in mergee_dom.getElementsByTagName(node_to_copy): - if self._IsDuplicate(node_to_copy, node): - continue - - merger_parent = self._FindMergerParent(node_to_copy, - destination, - mergee_dom) - - # Append the merge comment. - merger_parent.appendChild( - self._merger_dom.createComment(' Merged from file: %s ' % - filename)) - - # Append mergee's comment, if present. - comment_node = self._FindElementComment(node) - if comment_node: - merger_parent.appendChild(comment_node) - - # Append element from mergee to merger. - merger_parent.appendChild(node) - - # Insert top level comment about the merge. - top_comment = ( - ' *** WARNING *** DO NOT EDIT! THIS IS GENERATED MANIFEST BY ' - 'MERGE_MANIFEST TOOL.\n' - ' Merger manifest:\n %s\n' % self._merger[1] + - ' Mergee manifests:\n%s' % '\n'.join( - [' %s' % mergee[1] for mergee in self._mergees]) + - '\n ') - manifest_element = self._merger_dom.getElementsByTagName('manifest')[0] - manifest_element.insertBefore(self._merger_dom.createComment(top_comment), - manifest_element.firstChild) - - self._SortAliases() - self._OrderManifestChildren() - return self._merger_dom.toprettyxml(indent=' ') - - -def _ReadFiles(files): - results = [] - for file_name in files: - results.append(_ReadFile(file_name)) - return results - - -def _ReadFile(file_name): - with open(file_name, 'rb') as my_file: - return (my_file.read(), file_name,) - - -def _ValidateAndWarnPermissions(exclude_permissions): - unknown_permissions = ( - set(exclude_permissions) - - set([EXCLUDE_ALL_ARG]) - - android_permissions.PERMISSIONS) - return '\n'.join([ - 'WARNING:\n\t Specified permission "%s" is not a standard permission. ' - 'Is it a typo?' % perm for perm in unknown_permissions]) - - -def main(): - if not FLAGS.merger: - raise RuntimeError('Missing merger value.\n' + USAGE) - if len(FLAGS.mergee) < 1: - raise RuntimeError('Missing mergee value.\n' + USAGE) - if not FLAGS.output: - raise RuntimeError('Missing output value.\n' + USAGE) - if FLAGS.exclude_permission: - warning = _ValidateAndWarnPermissions(FLAGS.exclude_permission) - if warning: - print(warning) - - merged_manifests = MergeManifests(_ReadFile(FLAGS.merger), - _ReadFiles(FLAGS.mergee), - FLAGS.exclude_permission - ).Merge() - - with open(FLAGS.output, 'wb') as out_file: - for line in merged_manifests.split('\n'): - if not line.strip(): - continue - out_file.write(line.encode('utf8') + '\n') - -if __name__ == '__main__': - FLAGS(sys.argv) - main() diff --git a/tools/android/merge_manifests_test.py b/tools/android/merge_manifests_test.py deleted file mode 100644 index dd5a205fb0..0000000000 --- a/tools/android/merge_manifests_test.py +++ /dev/null @@ -1,627 +0,0 @@ -# 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. - -"""This file contains unit tests for the merge_manifests script.""" - -import re -import unittest -import xml.dom.minidom - -from tools.android import merge_manifests - -FIRST_MANIFEST = """<?xml version='1.0' encoding='utf-8'?> -<manifest - xmlns:android="http://schemas.android.com/apk/res/android" - package="com.google.android.apps.testapp" - android:versionCode="70" - android:versionName="1.0"> - <uses-sdk android:minSdkVersion="10"/> - <uses-feature android:name="android.hardware.nfc" android:required="true" /> - <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> - <application - android:icon="@drawable/icon" - android:name="com.google.android.apps.testapp.TestApplication" - android:theme="@style/Theme.Test" - android:label="@string/app_name"> - <!-- START LIBRARIES (Maintain Alphabetic order) --> - <!-- NFC extras --> - <uses-library android:name="com.google.android.nfc_extras" android:required="false"/> - <!-- END LIBRARIES --> - <!-- START ACTIVITIES (Maintain Alphabetic order) --> - <!-- Entry point activity - navigation and title bar. --> - <activity - android:name=".entrypoint.EntryPointActivityGroup" - android:screenOrientation="portrait" - android:launchMode="singleTop"/> - <activity android:name=".ui.topup.TopUpActivity" /> - <service android:name=".nfcevent.NfcEventService" /> - <receiver - android:name="com.receiver.TestReceiver" - android:process="@string/receiver_service_name"> - <!-- Receive the actual message --> - <intent-filter> - <action - android:name="android.intent.action.USER_PRESENT"/> - </intent-filter> - </receiver> - <provider - android:name=".dataaccess.persistence.ContentProvider" - android:authorities="com.google.android.apps.testapp" - android:exported="false" /> - </application> -</manifest> -""" - -SECOND_MANIFEST = """<?xml version='1.0' encoding='utf-8'?> -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.google.android.apps.testapp2" - android:versionCode="1" - android:versionName="1.0"> - <permission android:name="com.google.android.apps.foo.C2D_MESSAGE" - android:protectionLevel="signature" /> - <uses-sdk android:minSdkVersion="5" /> - <uses-feature android:name="android.hardware.nfc" android:required="true" /> - <uses-permission android:name="android.permission.READ_LOGS" /> - <uses-permission android:name="android.permission.INTERNET" /> - <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> - <!-- Comment for permission android.permission.GET_ACCOUNTS. - This is just to make sure the comment is being merged correctly. - --> - <uses-permission android:name="android.permission.GET_ACCOUNTS" /> - <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> - - <application - android:icon="@drawable/icon" - android:name="com.google.android.apps.testapp.TestApplication2" - android:theme="@style/Theme.Test2" - android:label="@string/app_name" - android:backupAgent="FooBar"> - <activity android:name=".ui.home.HomeActivity" - android:label="@string/app_name" > - <intent-filter> - <action android:name="android.intent.action.MAIN"/> - <category android:name="android.intent.category.LAUNCHER"/> - </intent-filter> - </activity> - <activity android:name=".TestActivity2"></activity> - <activity android:name=".PreviewActivity"></activity> - <activity android:name=".ShowTextActivity" android:excludeFromRecents="true"></activity> - <activity android:name=".ShowStringListActivity" - android:excludeFromRecents="true" - android:parentActivityName=".ui.home.HomeActivity"> - </activity> - <service android:name=".TestService"> - <meta-data android:name="param" android:value="value"/> - </service> - <service android:name=".nfcevent.NfcEventService" /> - <receiver android:name=".ConnectivityReceiver" android:enabled="false" > - <intent-filter> - <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> - </intent-filter> - </receiver> - <activity-alias android:name="BarFoo" android:targetActivity=".FooBar" /> - <provider - android:name="some.package.with.inner.class$AnInnerClass" /> - <provider - android:name="${packageName}" - android:authorities="${packageName}.${packageName}" - android:exported="false" /> - <provider - android:name="${packageName}.PlaceHolderProviderName" - android:authorities="PlaceHolderProviderAuthorities.${packageName}" - android:exported="false" /> - <activity - android:name="activityPrefix.${packageName}.activitySuffix"> - <intent-filter> - <action android:name="actionPrefix.${packageName}.actionSuffix" /> - </intent-filter> - </activity> - </application> -</manifest> -""" - -THIRD_MANIFEST = """<?xml version='1.0' encoding='utf-8'?> -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.google.android.apps.testapp3" - android:versionCode="3" - android:versionName="1.30"> - <uses-sdk android:minSdkVersion="14" /> - <uses-feature android:name="android.hardware.nfc" android:required="true" /> - <uses-permission android:name="android.permission.READ_LOGS" /> - <uses-permission android:name="android.permission.INTERNET" /> - <application> - <activity android:name=".ui.home.HomeActivity" - android:label="@string/app_name" > - <intent-filter> - <action android:name="android.intent.action.MAIN"/> - <category android:name="android.intent.category.LAUNCHER"/> - </intent-filter> - </activity> - <activity android:name="TestActivity"></activity> - <service android:name=".TestService" /> - <receiver android:name=".ConnectivityReceiver" android:enabled="true" > - <intent-filter> - <action android:name="android.net.conn.CONNECTIVITY_CHANGER" /> - </intent-filter> - </receiver> - </application> -</manifest> -""" - -MANUALLY_MERGED = """<?xml version='1.0' encoding='utf-8'?> -<manifest - xmlns:android="http://schemas.android.com/apk/res/android" - package="com.google.android.apps.testapp" - android:versionCode="70" - android:versionName="1.0"> - <!-- *** WARNING *** DO NOT EDIT! THIS IS GENERATED MANIFEST BY MERGE_MANIFEST TOOL. - Merger manifest: - FIRST_MANIFEST - Mergee manifests: - SECOND_MANIFEST - THIRD_MANIFEST - --> - <uses-sdk android:minSdkVersion="10"/> - <uses-feature android:name="android.hardware.nfc" android:required="true" /> - <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> - <!-- Merged from file: SECOND_MANIFEST --> - <permission android:name="com.google.android.apps.foo.C2D_MESSAGE" android:protectionLevel="signature" /> - <!-- Merged from file: SECOND_MANIFEST --> - <uses-permission android:name="android.permission.INTERNET" /> - <!-- Merged from file: SECOND_MANIFEST --> - <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> - <!-- Merged from file: SECOND_MANIFEST --> - <!-- Comment for permission android.permission.GET_ACCOUNTS. - This is just to make sure the comment is being merged correctly. - --> - <uses-permission android:name="android.permission.GET_ACCOUNTS" /> - <application - android:icon="@drawable/icon" - android:name="com.google.android.apps.testapp.TestApplication" - android:theme="@style/Theme.Test" - android:label="@string/app_name"> - <!-- START LIBRARIES (Maintain Alphabetic order) --> - <!-- NFC extras --> - <uses-library android:name="com.google.android.nfc_extras" android:required="false"/> - <!-- END LIBRARIES --> - <!-- START ACTIVITIES (Maintain Alphabetic order) --> - <!-- Entry point activity - navigation and title bar. --> - <activity - android:name="com.google.android.apps.testapp.entrypoint.EntryPointActivityGroup" - android:screenOrientation="portrait" - android:launchMode="singleTop"/> - <activity android:name="com.google.android.apps.testapp.ui.topup.TopUpActivity" /> - <service android:name="com.google.android.apps.testapp.nfcevent.NfcEventService" /> - <receiver - android:name="com.receiver.TestReceiver" - android:process="@string/receiver_service_name"> - <!-- Receive the actual message --> - <intent-filter> - <action - android:name="android.intent.action.USER_PRESENT"/> - </intent-filter> - </receiver> - <provider android:authorities="com.google.android.apps.testapp" android:exported="false" - android:name="com.google.android.apps.testapp.dataaccess.persistence.ContentProvider"/> - <!-- Merged from file: SECOND_MANIFEST --> - <activity android:label="@string/app_name" android:name="com.google.android.apps.testapp2.ui.home.HomeActivity"> - <intent-filter> - <action android:name="android.intent.action.MAIN"/> - <category android:name="android.intent.category.LAUNCHER"/> - </intent-filter> - </activity> - <!-- Merged from file: SECOND_MANIFEST --> - <activity android:name="com.google.android.apps.testapp2.TestActivity2"></activity> - <!-- Merged from file: SECOND_MANIFEST --> - <activity android:name="com.google.android.apps.testapp2.PreviewActivity"></activity> - <!-- Merged from file: SECOND_MANIFEST --> - <activity android:name="com.google.android.apps.testapp2.ShowTextActivity" - android:excludeFromRecents="true"></activity> - <!-- Merged from file: SECOND_MANIFEST --> - <activity android:name="com.google.android.apps.testapp2.ShowStringListActivity" - android:excludeFromRecents="true" - android:parentActivityName="com.google.android.apps.testapp2.ui.home.HomeActivity"> - </activity> - <!-- Merged from file: SECOND_MANIFEST --> - <activity - android:name="activityPrefix.com.google.android.apps.testapp.activitySuffix"> - <intent-filter> - <action android:name="actionPrefix.com.google.android.apps.testapp.actionSuffix" /> - </intent-filter> - </activity> - <!-- Merged from file: SECOND_MANIFEST --> - <provider - android:name="some.package.with.inner.class$AnInnerClass" /> - <!-- Merged from file: SECOND_MANIFEST --> - <provider - android:name="com.google.android.apps.testapp" - android:authorities="com.google.android.apps.testapp.com.google.android.apps.testapp" - android:exported="false" /> - <!-- Merged from file: SECOND_MANIFEST --> - <provider - android:name="com.google.android.apps.testapp.PlaceHolderProviderName" - android:authorities="PlaceHolderProviderAuthorities.com.google.android.apps.testapp" - android:exported="false" /> - <!-- Merged from file: SECOND_MANIFEST --> - <receiver android:name="com.google.android.apps.testapp2.ConnectivityReceiver" - android:enabled="false" > - <intent-filter> - <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> - </intent-filter> - </receiver> - <!-- Merged from file: SECOND_MANIFEST --> - <service android:name="com.google.android.apps.testapp2.TestService"> - <meta-data android:name="param" android:value="value"/> - </service> - <!-- Merged from file: SECOND_MANIFEST --> - <service android:name="com.google.android.apps.testapp2.nfcevent.NfcEventService"/> - <!-- Merged from file: THIRD_MANIFEST --> - <activity android:label="@string/app_name" android:name="com.google.android.apps.testapp3.ui.home.HomeActivity"> - <intent-filter> - <action android:name="android.intent.action.MAIN"/> - <category android:name="android.intent.category.LAUNCHER"/> - </intent-filter> - </activity> - <!-- Merged from file: THIRD_MANIFEST --> - <activity android:name="com.google.android.apps.testapp3.TestActivity"/> - <!-- Merged from file: THIRD_MANIFEST --> - <receiver android:enabled="true" - android:name="com.google.android.apps.testapp3.ConnectivityReceiver"> - <intent-filter> - <action android:name="android.net.conn.CONNECTIVITY_CHANGER"/> - </intent-filter> - </receiver> - <!-- Merged from file: THIRD_MANIFEST --> - <service android:name="com.google.android.apps.testapp3.TestService"/> - <!-- Merged from file: SECOND_MANIFEST --> - <activity-alias android:name="com.google.android.apps.testapp2.BarFoo" - android:targetActivity="com.google.android.apps.testapp2.FooBar"/> - </application> -</manifest> -""" - - -ALIAS_MANIFEST = """<?xml version='1.0' encoding='utf-8'?> -<manifest - xmlns:android="http://schemas.android.com/apk/res/android" - package="com.google.android.apps.testapp" - android:versionCode="70" - android:versionName="1.0"> - <uses-sdk android:minSdkVersion="10"/> - <uses-feature android:name="android.hardware.nfc" android:required="true" /> - <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> - <application - android:icon="@drawable/icon" - android:name="com.google.android.apps.testapp.TestApplication" - android:theme="@style/Theme.Test" - android:label="@string/app_name"> - <activity-alias android:name="com.google.foo.should.not.be.first" - android:targetActivity=".entrypoint.EntryPointActivityGroup"/> - <!-- START LIBRARIES (Maintain Alphabetic order) --> - <!-- NFC extras --> - <uses-library android:name="com.google.android.nfc_extras" android:required="false"/> - <!-- END LIBRARIES --> - <!-- START ACTIVITIES (Maintain Alphabetic order) --> - <!-- Entry point activity - navigation and title bar. --> - <activity - android:name=".entrypoint.EntryPointActivityGroup" - android:screenOrientation="portrait" - android:launchMode="singleTop"/> - <activity android:name=".ui.topup.TopUpActivity" /> - <service android:name=".nfcevent.NfcEventService" /> - <receiver - android:name="com.receiver.TestReceiver" - android:process="@string/receiver_service_name"> - <!-- Receive the actual message --> - <intent-filter> - <action - android:name="android.intent.action.USER_PRESENT"/> - </intent-filter> - </receiver> - <provider - android:name=".dataaccess.persistence.ContentProvider" - android:authorities="com.google.android.apps.testapp" - android:exported="false" /> - </application> -</manifest> -""" - - -# This case exists when a library manifest relies on -# dependent manifests to provide required elements, i.e. a <application> -INVALID_MERGER_MANIFEST = """ -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.google.android.invalid" - android:versionCode="9100000" - android:versionName="9.1.0.0x"> - <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" /> -</manifest> -""" - - -INVALID_MERGEE_MANIFEST = """ -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.google.android.invalid" - android:versionCode="9100000" - android:versionName="9.1.0.0x"> - <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" /> - <permission android:name="com.google.android.apps.foo.C2D_MESSAGE" android:protectionLevel="signature"/> - <uses-feature android:name="android.hardware.nfc" android:required="true"/> -</manifest> -""" - -VALID_MANIFEST = """ -<manifest - android:versionCode="9100000" - android:versionName="9.1.0.0x" - package="com.google.android.invalid" - xmlns:android="http://schemas.android.com/apk/res/android"> - <!-- *** WARNING *** DO NOT EDIT! THIS IS GENERATED MANIFEST BY MERGE_MANIFEST TOOL. - Merger manifest: - INVALID_MANIFEST - Mergee manifests: - SECOND_MANIFEST - --> - <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21"/> - <!-- Merged from file: SECOND_MANIFEST --> - <permission android:name="com.google.android.apps.foo.C2D_MESSAGE" android:protectionLevel="signature"/> - <!-- Merged from file: SECOND_MANIFEST --> - <uses-feature android:name="android.hardware.nfc" android:required="true"/> - <application - android:backupAgent="com.google.android.apps.testapp2.FooBar" - android:icon="@drawable/icon" - android:label="@string/app_name" - android:name="com.google.android.apps.testapp.TestApplication2" - android:theme="@style/Theme.Test2"> - <activity - android:name="com.google.android.apps.testapp2.TestActivity2"/> - <activity - android:name="com.google.android.apps.testapp2.PreviewActivity"/> - <activity android:excludeFromRecents="true" - android:name="com.google.android.apps.testapp2.ShowTextActivity"/> - <activity android:excludeFromRecents="true" - android:name="com.google.android.apps.testapp2.ShowStringListActivity" - android:parentActivityName="com.google.android.apps.testapp2.ui.home.HomeActivity"> - </activity> - <service - android:name="com.google.android.apps.testapp2.TestService"> - <meta-data android:name="param" - android:value="value"/> - </service> - <service - android:name="com.google.android.apps.testapp2.nfcevent.NfcEventService"/> - <receiver - android:enabled="false" - android:name="com.google.android.apps.testapp2.ConnectivityReceiver"> - <intent-filter> - <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/> - </intent-filter> - </receiver> - <provider android:name="some.package.with.inner.class$AnInnerClass"/> - <provider - android:authorities="com.google.android.invalid.com.google.android.invalid" - android:exported="false" android:name="com.google.android.invalid"/> - <provider android:authorities="PlaceHolderProviderAuthorities.com.google.android.invalid" - android:exported="false" - android:name="com.google.android.invalid.PlaceHolderProviderName"/> - <activity android:name="activityPrefix.com.google.android.invalid.activitySuffix"> - <intent-filter> - <action android:name="actionPrefix.com.google.android.invalid.actionSuffix"/> - </intent-filter> - </activity> - <!-- Merged from file: SECOND_MANIFEST --> - <activity android:label="@string/app_name" - android:name="com.google.android.apps.testapp2.ui.home.HomeActivity"> - <intent-filter> - <action android:name="android.intent.action.MAIN"/> - <category android:name="android.intent.category.LAUNCHER"/> - </intent-filter> - </activity> - <activity-alias - android:name="com.google.android.apps.testapp2.BarFoo" - android:targetActivity="com.google.android.apps.testapp2.FooBar"/> - </application> -</manifest> -""" - -MANIFEST_WITHOUT_EXTRA_NAMESPACE = """ -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.google.android.test" - android:versionCode="1" - android:versionName="1.0.0.0"> - <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" /> - <application> - <activity android:name=".ui.home.HomeActivity" - android:label="@string/app_name" > - <intent-filter> - <action android:name="android.intent.action.MAIN"/> - <category android:name="android.intent.category.LAUNCHER"/> - </intent-filter> - </activity> - </application> -</manifest> -""" - -MANIFEST_WITH_EXTRA_NAMESPACE = """ -<manifest - xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" - package="com.google.android.library"> - <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" /> - <application> - <service android:name=".nfcevent.NfcEventService" - android:exported="true" - tools:replace="exported" /> - </application> -</manifest> -""" - -MERGED_MANIFEST_WITH_EXTRA_NAMESPACE = """ -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" - package="com.google.android.test" - android:versionCode="1" - android:versionName="1.0.0.0"> - <!-- *** WARNING *** DO NOT EDIT! THIS IS GENERATED MANIFEST BY MERGE_MANIFEST TOOL. - Merger manifest: - MANIFEST_WITHOUT_EXTRA_NAMESPACE - Mergee manifests: - MANIFEST_WITH_EXTRA_NAMESPACE - --> - <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" /> - <application> - <activity android:name="com.google.android.test.ui.home.HomeActivity" - android:label="@string/app_name" > - <intent-filter> - <action android:name="android.intent.action.MAIN"/> - <category android:name="android.intent.category.LAUNCHER"/> - </intent-filter> - </activity> - <!-- Merged from file: MANIFEST_WITH_EXTRA_NAMESPACE --> - <service android:exported="true" android:name="com.google.android.library.nfcevent.NfcEventService" tools:replace="exported"/> - </application> -</manifest> -""" - -MANIFEST_WITH_CONFLICTING_NAMESPACE = """ -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="not_tools" - package="com.google.android.test" - android:versionCode="1" - android:versionName="1.0.0.0"> - <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" /> - <application> - <activity android:name=".ui.home.HomeActivity" - android:label="@string/app_name" > - <intent-filter> - <action android:name="android.intent.action.MAIN"/> - <category android:name="android.intent.category.LAUNCHER"/> - </intent-filter> - </activity> - </application> -</manifest> -""" - - -def Reformat(string): - """Reformat for comparison.""" - string = re.compile(r'^[ \t]*\n?', re.MULTILINE).sub('', string) - return string - - -class MergeManifestsTest(unittest.TestCase): - """Unit tests for the MergeManifest class.""" - - def testMerge(self): - self.maxDiff = None - merger = merge_manifests.MergeManifests( - (FIRST_MANIFEST, 'FIRST_MANIFEST'), - [(SECOND_MANIFEST, 'SECOND_MANIFEST'), - (THIRD_MANIFEST, 'THIRD_MANIFEST')], - ['android.permission.READ_LOGS']) - result = merger.Merge() - expected = xml.dom.minidom.parseString(MANUALLY_MERGED).toprettyxml() - self.assertEqual(Reformat(expected), Reformat(result)) - - def testReformat(self): - text = ' a\n b\n\n\n \t c' - expected = 'a\nb\nc' - self.assertEqual(expected, Reformat(text)) - - def testValidateAndWarnPermissions(self): - permissions = ['android.permission.VIBRATE', 'android.permission.LAUGH'] - warnings = merge_manifests._ValidateAndWarnPermissions(permissions) - self.assertTrue('android.permission.VIBRATE' not in warnings) - self.assertTrue('android.permission.LAUGH' in warnings) - - def testExcludeAllPermissions(self): - merger = merge_manifests.MergeManifests( - (FIRST_MANIFEST, 'FIRST_MANIFEST'), - [(SECOND_MANIFEST, 'SECOND_MANIFEST'), - (THIRD_MANIFEST, 'THIRD_MANIFEST')], - ['all']) - result = merger.Merge() - self.assertFalse('android.permission.READ_LOGS' in result) - self.assertFalse('android.permission.INTERNET' in result) - self.assertTrue('android.permission.ACCESS_COARSE_LOCATION' in result) - - def testUndefinedArgumentPlaceholder(self): - bad_manifest = SECOND_MANIFEST.replace( - '${packageName}', '${unknownPlaceHolder}') - merger = merge_manifests.MergeManifests( - (FIRST_MANIFEST, 'FIRST_MANIFEST'), - [(bad_manifest, 'invalidManifest'), - (THIRD_MANIFEST, 'THIRD_MANIFEST')]) - try: - merger.Merge() - self.fail('merging manifests with unknown placeholders didn\'t fail') - except merge_manifests.UndefinedPlaceholderException: - pass - - def testActivityAliasesAreAlwaysLast(self): - merger = merge_manifests.MergeManifests( - (FIRST_MANIFEST, 'FIRST_MANIFEST'), - [(SECOND_MANIFEST, 'SECOND_MANIFEST'), - (ALIAS_MANIFEST, 'THIRD_MANIFEST')], - ['all']) - result = merger.Merge() - last_occurence_of_activity = result.rfind('<activity ') - first_occurence_of_alias = result.find('<activity-alias ') - self.assertLess(last_occurence_of_activity, first_occurence_of_alias, - msg='First activity-alias is not after the last activity!') - - def testMergeToCreateValidManifest(self): - self.maxDiff = None - merger = merge_manifests.MergeManifests( - (INVALID_MERGER_MANIFEST, 'INVALID_MANIFEST'), - [(SECOND_MANIFEST, 'SECOND_MANIFEST')], - ['all']) - result = merger.Merge() - expected = xml.dom.minidom.parseString(VALID_MANIFEST).toprettyxml() - self.assertEqual(Reformat(expected), Reformat(result)) - - def testMergeWithNoApplication(self): - merger = merge_manifests.MergeManifests( - (INVALID_MERGER_MANIFEST, 'INVALID_MERGER_MANIFEST'), - [(INVALID_MERGEE_MANIFEST, 'INVALID_MERGEE_MANIFEST')], - ['all']) - merger.Merge() - - def testMergeWithNamespaces(self): - self.maxDiff = None - merger = merge_manifests.MergeManifests( - (MANIFEST_WITHOUT_EXTRA_NAMESPACE, 'MANIFEST_WITHOUT_EXTRA_NAMESPACE'), - [(MANIFEST_WITH_EXTRA_NAMESPACE, 'MANIFEST_WITH_EXTRA_NAMESPACE')], - ['all']) - result = merger.Merge() - expected = xml.dom.minidom.parseString( - MERGED_MANIFEST_WITH_EXTRA_NAMESPACE).toprettyxml() - # Make sure the result is valid xml (not missing xmlns declarations) - result_reparsed = xml.dom.minidom.parseString(result).toprettyxml() - self.assertEqual(Reformat(expected), Reformat(result_reparsed)) - - def testMergeConflictingNamespaces(self): - self.maxDiff = None - merger = merge_manifests.MergeManifests( - (MANIFEST_WITH_CONFLICTING_NAMESPACE, - 'MANIFEST_WITH_CONFLICTING_NAMESPACE'), - [(MANIFEST_WITH_EXTRA_NAMESPACE, 'MANIFEST_WITH_EXTRA_NAMESPACE')], - ['all']) - with self.assertRaisesRegexp(merge_manifests.MalformedManifestException, - 'different values for namespace xmlns:tools'): - merger.Merge() - - -if __name__ == '__main__': - unittest.main() |