| Index: tools/compare_build_artifacts/compare_build_artifacts.py
|
| diff --git a/tools/compare_build_artifacts/compare_build_artifacts.py b/tools/compare_build_artifacts/compare_build_artifacts.py
|
| deleted file mode 100755
|
| index 57bb236e8541f0335cd3c06733820837e0998e78..0000000000000000000000000000000000000000
|
| --- a/tools/compare_build_artifacts/compare_build_artifacts.py
|
| +++ /dev/null
|
| @@ -1,596 +0,0 @@
|
| -#!/usr/bin/env python
|
| -# Copyright 2014 The Chromium Authors. All rights reserved.
|
| -# Use of this source code is governed by a BSD-style license that can be
|
| -# found in the LICENSE file.
|
| -
|
| -"""Compare the artifacts from two builds."""
|
| -
|
| -import difflib
|
| -import json
|
| -import optparse
|
| -import os
|
| -import struct
|
| -import sys
|
| -import time
|
| -
|
| -BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
| -
|
| -
|
| -# List of files that are known to be non deterministic. This is a "temporary"
|
| -# workaround to find regression on the deterministic builders.
|
| -#
|
| -# PNaCl general bug: https://crbug.com/429358
|
| -#
|
| -# TODO(sebmarchand): Remove this once all the files are deterministic.
|
| -WHITELIST = {
|
| - # https://crbug.com/383340
|
| - 'android': {
|
| - 'flatc',
|
| - },
|
| -
|
| - # https://crbug.com/330263
|
| - 'linux': {
|
| - # Completed.
|
| - },
|
| -
|
| - # https://crbug.com/330262
|
| - 'mac': {
|
| - 'accelerated_widget_mac_unittests',
|
| - 'accessibility_unittests',
|
| - 'angle_end2end_tests',
|
| - 'angle_unittests',
|
| - 'App Shell',
|
| - 'app_shell_unittests',
|
| - 'ar_sample_test_driver',
|
| - 'audio_unittests',
|
| - 'base_unittests',
|
| - 'battor_agent_unittests',
|
| - 'blink_heap_unittests',
|
| - 'blink_platform_perftests',
|
| - 'blink_platform_unittests',
|
| - 'bluetooth_metrics_hash',
|
| - 'boringssl_unittests',
|
| - 'browser_tests',
|
| - 'cacheinvalidation_unittests',
|
| - 'capture_unittests',
|
| - 'cast_benchmarks',
|
| - 'cast_receiver_app',
|
| - 'cast_sender_app',
|
| - 'cast_simulator',
|
| - 'cast_unittests',
|
| - 'cc_blink_unittests',
|
| - 'cc_perftests',
|
| - 'cc_unittests',
|
| - 'chrome_app_unittests',
|
| - 'chromedriver',
|
| - 'chromedriver_tests',
|
| - 'chromedriver_unittests',
|
| - 'chromoting_test_driver',
|
| - 'command_buffer_gles2_tests',
|
| - 'components_browsertests',
|
| - 'components_perftests',
|
| - 'components_unittests',
|
| - 'compositor_unittests',
|
| - 'content_browsertests',
|
| - 'content_perftests',
|
| - 'content_unittests',
|
| - 'courgette_unittests',
|
| - 'crashpad_handler',
|
| - 'crypto_unittests',
|
| - 'device_unittests',
|
| - 'display_compositor_benchmark',
|
| - 'display_compositor_gl_tests',
|
| - 'display_unittests',
|
| - 'events_unittests',
|
| - 'extensions_browsertests',
|
| - 'extensions_unittests',
|
| - 'ffmpeg_regression_tests',
|
| - 'filesystem_service_unittests',
|
| - 'filter_fuzz_stub',
|
| - 'flatc',
|
| - 'gcm_unit_tests',
|
| - 'generate_barcode_video',
|
| - 'generate_timecode_audio',
|
| - 'gfx_unittests',
|
| - 'gin_unittests',
|
| - 'gles2_conform_support',
|
| - 'gles2_conform_test',
|
| - 'gl_tests',
|
| - 'gl_unittests',
|
| - 'gn_unittests',
|
| - 'google_apis_unittests',
|
| - 'gpu_ipc_service_unittests',
|
| - 'gpu_perftests',
|
| - 'gpu_unittests',
|
| - 'interactive_ui_tests',
|
| - 'ipc_fuzzer',
|
| - 'ipc_fuzzer_replay',
|
| - 'ipc_message_dump.so',
|
| - 'ipc_message_list',
|
| - 'ipc_message_util',
|
| - 'ipc_tests',
|
| - 'it2me_standalone_host_main',
|
| - 'jingle_unittests',
|
| - 'khronos_glcts_test',
|
| - 'leveldb_service_unittests',
|
| - 'libaddressinput_unittests',
|
| - 'libapp_shell_framework.dylib',
|
| - 'libcommand_buffer_gles2.dylib',
|
| - 'libmedia_library.dylib',
|
| - 'libphonenumber_unittests',
|
| - 'mac_installer_unittests',
|
| - 'macviews_interactive_ui_tests',
|
| - 'media_blink_unittests',
|
| - 'media_mojo_shell_unittests',
|
| - 'media_mojo_unittests',
|
| - 'media_perftests',
|
| - 'media_pipeline_integration_unittests',
|
| - 'media_unittests',
|
| - 'message_center_unittests',
|
| - 'midi_unittests',
|
| - 'mojo_common_unittests',
|
| - 'mojo_js_integration_tests',
|
| - 'mojo_js_unittests',
|
| - 'mojo_public_bindings_unittests',
|
| - 'mojo_public_system_unittests',
|
| - 'mojo_runner_host_unittests',
|
| - 'mojo_shell_unittests',
|
| - 'mojo_system_unittests',
|
| - 'nacl_loader_unittests',
|
| - 'native_theme_unittests',
|
| - 'net_unittests',
|
| - 'osmesa.so',
|
| - 'performance_browser_tests',
|
| - 'ppapi_perftests',
|
| - 'ppapi_unittests',
|
| - 'printing_unittests',
|
| - 'proximity_auth_unittests',
|
| - 'remoting_perftests',
|
| - 'remoting_start_host',
|
| - 'remoting_unittests',
|
| - 'sandbox_mac_unittests',
|
| - 'shell_dialogs_unittests',
|
| - 'skia_unittests',
|
| - 'snapshot_unittests',
|
| - 'sql_unittests',
|
| - 'sync_client',
|
| - 'sync_integration_tests',
|
| - 'sync_listen_notifications',
|
| - 'sync_performance_tests',
|
| - 'sync_unit_tests',
|
| - 'udp_proxy',
|
| - 'ui_base_unittests',
|
| - 'ui_struct_traits_unittests',
|
| - 'ui_touch_selection_unittests',
|
| - 'unit_tests',
|
| - 'url_ipc_unittests',
|
| - 'url_unittests',
|
| - 'video_encode_accelerator_unittest',
|
| - 'views_examples_exe',
|
| - 'views_examples_with_content_exe',
|
| - 'views_unittests',
|
| - 'webkit_unit_tests',
|
| - 'wtf_unittests',
|
| - },
|
| -
|
| - # https://crbug.com/330260
|
| - 'win': {
|
| - 'accessibility_unittests.exe',
|
| - 'angle_end2end_tests.exe',
|
| - 'angle_perftests.exe',
|
| - 'angle_unittests.exe',
|
| - 'app_driver_library.dll',
|
| - 'app_list_demo.exe',
|
| - 'app_list_presenter_unittests.exe',
|
| - 'app_list_unittests.exe',
|
| - 'app_shell.exe',
|
| - 'app_shell_unittests.exe',
|
| - 'ar_sample_test_driver.exe',
|
| - 'ash_library.dll',
|
| - 'ash_shell_with_content.exe',
|
| - 'ash_sysui_library.dll',
|
| - 'ash_unittests.exe',
|
| - 'audio_unittests.exe',
|
| - 'aura_demo.exe',
|
| - 'aura_unittests.exe',
|
| - 'base_i18n_perftests.exe',
|
| - 'base_perftests.exe',
|
| - 'base_unittests.exe',
|
| - 'blink_converters_unittests.exe',
|
| - 'blink_deprecated_test_plugin.dll',
|
| - 'blink_heap_unittests.exe',
|
| - 'blink_platform_perftests.exe',
|
| - 'blink_platform_unittests.exe',
|
| - 'blink_test_plugin.dll',
|
| - 'bluetooth_metrics_hash.exe',
|
| - 'browser_library.dll',
|
| - 'browser_tests.exe',
|
| - 'capture_unittests.exe',
|
| - 'cast_benchmarks.exe',
|
| - 'cast_receiver_app.exe',
|
| - 'cast_sender_app.exe',
|
| - 'cast_simulator.exe',
|
| - 'cast_unittests.exe',
|
| - 'catalog_viewer_library.dll',
|
| - 'cc_blink_unittests.exe',
|
| - 'cc_perftests.exe',
|
| - 'cctest.exe',
|
| - 'cc_unittests.exe',
|
| - 'ced_unittests.exe',
|
| - 'cert_verify_tool.exe',
|
| - 'chrome_app_unittests.exe',
|
| - 'chrome_child.dll',
|
| - 'chrome.dll',
|
| - 'chromedriver.exe',
|
| - 'chromedriver_tests.exe',
|
| - 'chromedriver_unittests.exe',
|
| - 'chrome_elf_unittests.exe',
|
| - 'chrome.exe',
|
| - 'chromoting_test_driver.exe',
|
| - 'command_buffer_gles2.dll',
|
| - 'components_browsertests.exe',
|
| - 'components_perftests.exe',
|
| - 'components_unittests.exe',
|
| - 'compositor_unittests.exe',
|
| - 'content_browsertests.exe',
|
| - 'content_perftests.exe',
|
| - 'content_shell.exe',
|
| - 'content_unittests.exe',
|
| - 'courgette64.exe',
|
| - 'crypto_unittests.exe',
|
| - 'd8.exe',
|
| - 'device_unittests.exe',
|
| - 'display_compositor_benchmark.exe',
|
| - 'display_compositor_gl_tests.exe',
|
| - 'display_unittests.exe',
|
| - 'events_unittests.exe',
|
| - 'extensions_browsertests.exe',
|
| - 'extensions_unittests.exe',
|
| - 'ffmpeg_regression_tests.exe',
|
| - 'filesystem_service_unittests.exe',
|
| - 'filter_fuzz_stub.exe',
|
| - 'force_mic_volume_max.exe',
|
| - 'gcapi_test.exe',
|
| - 'gcm_unit_tests.exe',
|
| - 'generate_barcode_video.exe',
|
| - 'generate-bytecode-expectations.exe',
|
| - 'generate_timecode_audio.exe',
|
| - 'get_server_time.exe',
|
| - 'gfx_unittests.exe',
|
| - 'gin_shell.exe',
|
| - 'gin_unittests.exe',
|
| - 'gles2_conform_support.exe',
|
| - 'gles2_conform_test.exe',
|
| - 'gl_tests.exe',
|
| - 'gl_unittests.exe',
|
| - 'google_apis_unittests.exe',
|
| - 'gpu_ipc_service_unittests.exe',
|
| - 'gpu_perftests.exe',
|
| - 'gpu_unittests.exe',
|
| - 'image_operations_bench.exe',
|
| - 'input_device_unittests.exe',
|
| - 'interactive_ui_tests.exe',
|
| - 'ipc_perftests.exe',
|
| - 'ipc_tests.exe',
|
| - 'it2me_standalone_host_main.exe',
|
| - 'jingle_unittests.exe',
|
| - 'keyboard_unittests.exe',
|
| - 'khronos_glcts_test.exe',
|
| - 'leveldb_service_unittests.exe',
|
| - 'libaddressinput_unittests.exe',
|
| - 'login_library.dll',
|
| - 'mash_init_library.dll',
|
| - 'mash_unittests.exe',
|
| - 'media_blink_unittests.exe',
|
| - 'media_library.dll',
|
| - 'media_mojo_shell_unittests.exe',
|
| - 'media_mojo_unittests.exe',
|
| - 'media_perftests.exe',
|
| - 'media_pipeline_integration_unittests.exe',
|
| - 'media_unittests.exe',
|
| - 'message_center_unittests.exe',
|
| - 'midi_unittests.exe',
|
| - 'mini_installer.exe',
|
| - 'mksnapshot.exe',
|
| - 'mojo_js_integration_tests.exe',
|
| - 'mojo_js_unittests.exe',
|
| - 'mojo_message_pipe_perftests.exe',
|
| - 'mojo_public_bindings_perftests.exe',
|
| - 'mojo_public_bindings_unittests.exe',
|
| - 'mojo_public_system_perftests.exe',
|
| - 'mojo_public_system_unittests.exe',
|
| - 'mojo_system_unittests.exe',
|
| - 'mus_clipboard_unittests.exe',
|
| - 'mus_common_unittests.exe',
|
| - 'mus_demo_library.dll',
|
| - 'mus_demo_unittests.exe',
|
| - 'mus_gpu_unittests.exe',
|
| - 'mus_ime_unittests.exe',
|
| - 'mus_public_unittests.exe',
|
| - 'mus_ws_unittests.exe',
|
| - 'nacl_irt_x86_32.nexe',
|
| - 'nacl_irt_x86_64.nexe',
|
| - 'nacl_loader_unittests.exe',
|
| - 'native_theme_unittests.exe',
|
| - 'navigation.exe',
|
| - 'navigation_unittests.exe',
|
| - 'net_perftests.exe',
|
| - 'net_unittests.exe',
|
| - 'next_version_mini_installer.exe',
|
| - 'pdfium_embeddertests.exe',
|
| - 'pdfium_test.exe',
|
| - 'performance_browser_tests.exe',
|
| - 'power_saver_test_plugin.dll',
|
| - 'ppapi_nacl_tests_newlib_x86_32.nexe',
|
| - 'ppapi_nacl_tests_newlib_x86_64.nexe',
|
| - 'ppapi_nacl_tests_pnacl_newlib_x32.nexe',
|
| - 'ppapi_nacl_tests_pnacl_newlib_x32_nonsfi.nexe',
|
| - 'ppapi_nacl_tests_pnacl_newlib_x64.nexe',
|
| - 'ppapi_perftests.exe',
|
| - 'ppapi_tests.dll',
|
| - 'ppapi_unittests.exe',
|
| - 'printing_unittests.exe',
|
| - 'proximity_auth_unittests.exe',
|
| - 'quic_client.exe',
|
| - 'quick_launch_library.dll',
|
| - 'quic_packet_printer.exe',
|
| - 'quic_server.exe',
|
| - 'remoting_breakpad_tester.exe',
|
| - 'remoting_core.dll',
|
| - 'remoting_perftests.exe',
|
| - 'remoting_unittests.exe',
|
| - 'sbox_unittests.exe',
|
| - 'screenlock_library.dll',
|
| - 'shell_dialogs_unittests.exe',
|
| - 'skia_unittests.exe',
|
| - 'snapshot_unittests.exe',
|
| - 'sql_unittests.exe',
|
| - 'sync_client.exe',
|
| - 'sync_integration_tests.exe',
|
| - 'sync_listen_notifications.exe',
|
| - 'sync_performance_tests.exe',
|
| - 'sync_unit_tests.exe',
|
| - 'task_viewer_library.dll',
|
| - 'test_ime_driver_library.dll',
|
| - 'test_wm_library.dll',
|
| - 'touch_hud_library.dll',
|
| - 'udp_proxy.exe',
|
| - 'ui_base_unittests.exe',
|
| - 'ui_library.dll',
|
| - 'ui_struct_traits_unittests.exe',
|
| - 'ui_touch_selection_unittests.exe',
|
| - 'unit_tests.exe',
|
| - 'unittests.exe',
|
| - 'url_unittests.exe',
|
| - 'v8_hello_world.exe',
|
| - 'v8_parser_shell.exe',
|
| - 'v8_sample_process.exe',
|
| - 'v8_shell.exe',
|
| - 'v8_simple_json_fuzzer.exe',
|
| - 'v8_simple_parser_fuzzer.exe',
|
| - 'v8_simple_regexp_fuzzer.exe',
|
| - 'v8_simple_wasm_asmjs_fuzzer.exe',
|
| - 'v8_simple_wasm_fuzzer.exe',
|
| - 'video_decode_accelerator_unittest.exe',
|
| - 'video_encode_accelerator_unittest.exe',
|
| - 'views_examples_exe.exe',
|
| - 'views_examples_library.dll',
|
| - 'views_examples_with_content_exe.exe',
|
| - 'views_mus_interactive_ui_tests.exe',
|
| - 'views_mus_unittests.exe',
|
| - 'views_unittests.exe',
|
| - 'webkit_unit_tests.exe',
|
| - 'webtest_library.dll',
|
| - 'window_type_launcher_library.dll',
|
| - 'wm_unittests.exe',
|
| - 'wtf_unittests.exe',
|
| - },
|
| -}
|
| -
|
| -def get_files_to_compare(build_dir, recursive=False):
|
| - """Get the list of files to compare."""
|
| - # TODO(maruel): Add '.pdb'.
|
| - allowed = frozenset(
|
| - ('', '.apk', '.app', '.dll', '.dylib', '.exe', '.nexe', '.so'))
|
| - non_x_ok_exts = frozenset(('.apk', '.isolated'))
|
| - def check(f):
|
| - if not os.path.isfile(f):
|
| - return False
|
| - if os.path.basename(f).startswith('.'):
|
| - return False
|
| - ext = os.path.splitext(f)[1]
|
| - if ext in non_x_ok_exts:
|
| - return True
|
| - return ext in allowed and os.access(f, os.X_OK)
|
| -
|
| - ret_files = set()
|
| - for root, dirs, files in os.walk(build_dir):
|
| - if not recursive:
|
| - dirs[:] = [d for d in dirs if d.endswith('_apk')]
|
| - for f in (f for f in files if check(os.path.join(root, f))):
|
| - ret_files.add(os.path.relpath(os.path.join(root, f), build_dir))
|
| - return ret_files
|
| -
|
| -
|
| -def diff_dict(a, b):
|
| - """Returns a yaml-like textural diff of two dict.
|
| -
|
| - It is currently optimized for the .isolated format.
|
| - """
|
| - out = ''
|
| - for key in set(a) | set(b):
|
| - va = a.get(key)
|
| - vb = b.get(key)
|
| - if va.__class__ != vb.__class__:
|
| - out += '- %s: %r != %r\n' % (key, va, vb)
|
| - elif isinstance(va, dict):
|
| - c = diff_dict(va, vb)
|
| - if c:
|
| - out += '- %s:\n%s\n' % (
|
| - key, '\n'.join(' ' + l for l in c.splitlines()))
|
| - elif va != vb:
|
| - out += '- %s: %s != %s\n' % (key, va, vb)
|
| - return out.rstrip()
|
| -
|
| -
|
| -def diff_binary(first_filepath, second_filepath, file_len):
|
| - """Returns a compact binary diff if the diff is small enough."""
|
| - CHUNK_SIZE = 32
|
| - MAX_STREAMS = 10
|
| - diffs = 0
|
| - streams = []
|
| - offset = 0
|
| - with open(first_filepath, 'rb') as lhs:
|
| - with open(second_filepath, 'rb') as rhs:
|
| - while True:
|
| - lhs_data = lhs.read(CHUNK_SIZE)
|
| - rhs_data = rhs.read(CHUNK_SIZE)
|
| - if not lhs_data:
|
| - break
|
| - if lhs_data != rhs_data:
|
| - diffs += sum(l != r for l, r in zip(lhs_data, rhs_data))
|
| - if streams is not None:
|
| - if len(streams) < MAX_STREAMS:
|
| - streams.append((offset, lhs_data, rhs_data))
|
| - else:
|
| - streams = None
|
| - offset += len(lhs_data)
|
| - del lhs_data
|
| - del rhs_data
|
| - if not diffs:
|
| - return None
|
| - result = '%d out of %d bytes are different (%.2f%%)' % (
|
| - diffs, file_len, 100.0 * diffs / file_len)
|
| - if streams:
|
| - encode = lambda text: ''.join(i if 31 < ord(i) < 128 else '.' for i in text)
|
| - for offset, lhs_data, rhs_data in streams:
|
| - lhs_line = '%s \'%s\'' % (lhs_data.encode('hex'), encode(lhs_data))
|
| - rhs_line = '%s \'%s\'' % (rhs_data.encode('hex'), encode(rhs_data))
|
| - diff = list(difflib.Differ().compare([lhs_line], [rhs_line]))[-1][2:-1]
|
| - result += '\n 0x%-8x: %s\n %s\n %s' % (
|
| - offset, lhs_line, rhs_line, diff)
|
| - return result
|
| -
|
| -
|
| -def compare_files(first_filepath, second_filepath):
|
| - """Compares two binaries and return the number of differences between them.
|
| -
|
| - Returns None if the files are equal, a string otherwise.
|
| - """
|
| - if first_filepath.endswith('.isolated'):
|
| - with open(first_filepath, 'rb') as f:
|
| - lhs = json.load(f)
|
| - with open(second_filepath, 'rb') as f:
|
| - rhs = json.load(f)
|
| - diff = diff_dict(lhs, rhs)
|
| - if diff:
|
| - return '\n' + '\n'.join(' ' + line for line in diff.splitlines())
|
| - # else, falls through binary comparison, it must be binary equal too.
|
| -
|
| - file_len = os.stat(first_filepath).st_size
|
| - if file_len != os.stat(second_filepath).st_size:
|
| - return 'different size: %d != %d' % (
|
| - file_len, os.stat(second_filepath).st_size)
|
| -
|
| - return diff_binary(first_filepath, second_filepath, file_len)
|
| -
|
| -
|
| -def compare_build_artifacts(first_dir, second_dir, target_platform,
|
| - recursive=False):
|
| - """Compares the artifacts from two distinct builds."""
|
| - if not os.path.isdir(first_dir):
|
| - print >> sys.stderr, '%s isn\'t a valid directory.' % first_dir
|
| - return 1
|
| - if not os.path.isdir(second_dir):
|
| - print >> sys.stderr, '%s isn\'t a valid directory.' % second_dir
|
| - return 1
|
| -
|
| - epoch_hex = struct.pack('<I', int(time.time())).encode('hex')
|
| - print('Epoch: %s' %
|
| - ' '.join(epoch_hex[i:i+2] for i in xrange(0, len(epoch_hex), 2)))
|
| -
|
| - with open(os.path.join(BASE_DIR, 'deterministic_build_blacklist.json')) as f:
|
| - blacklist = frozenset(json.load(f))
|
| - whitelist = WHITELIST[target_platform]
|
| -
|
| - # The two directories.
|
| - first_list = get_files_to_compare(first_dir, recursive) - blacklist
|
| - second_list = get_files_to_compare(second_dir, recursive) - blacklist
|
| -
|
| - equals = []
|
| - expected_diffs = []
|
| - unexpected_diffs = []
|
| - unexpected_equals = []
|
| - all_files = sorted(first_list & second_list)
|
| - missing_files = sorted(first_list.symmetric_difference(second_list))
|
| - if missing_files:
|
| - print >> sys.stderr, 'Different list of files in both directories:'
|
| - print >> sys.stderr, '\n'.join(' ' + i for i in missing_files)
|
| - unexpected_diffs.extend(missing_files)
|
| -
|
| - max_filepath_len = max(len(n) for n in all_files)
|
| - for f in all_files:
|
| - first_file = os.path.join(first_dir, f)
|
| - second_file = os.path.join(second_dir, f)
|
| - result = compare_files(first_file, second_file)
|
| - if not result:
|
| - tag = 'equal'
|
| - equals.append(f)
|
| - if f in whitelist:
|
| - unexpected_equals.append(f)
|
| - else:
|
| - if f in whitelist:
|
| - expected_diffs.append(f)
|
| - tag = 'expected'
|
| - else:
|
| - unexpected_diffs.append(f)
|
| - tag = 'unexpected'
|
| - result = 'DIFFERENT (%s): %s' % (tag, result)
|
| - print('%-*s: %s' % (max_filepath_len, f, result))
|
| - unexpected_diffs.sort()
|
| -
|
| - print('Equals: %d' % len(equals))
|
| - print('Expected diffs: %d' % len(expected_diffs))
|
| - print('Unexpected diffs: %d' % len(unexpected_diffs))
|
| - if unexpected_diffs:
|
| - print('Unexpected files with diffs:\n')
|
| - for u in unexpected_diffs:
|
| - print(' %s' % u)
|
| - if unexpected_equals:
|
| - print('Unexpected files with no diffs:\n')
|
| - for u in unexpected_equals:
|
| - print(' %s' % u)
|
| -
|
| - return int(bool(unexpected_diffs))
|
| -
|
| -
|
| -def main():
|
| - parser = optparse.OptionParser(usage='%prog [options]')
|
| - parser.add_option(
|
| - '-f', '--first-build-dir', help='The first build directory.')
|
| - parser.add_option(
|
| - '-s', '--second-build-dir', help='The second build directory.')
|
| - parser.add_option('-r', '--recursive', action='store_true', default=False,
|
| - help='Indicates if the comparison should be recursive.')
|
| - target = {
|
| - 'darwin': 'mac', 'linux2': 'linux', 'win32': 'win'
|
| - }.get(sys.platform, sys.platform)
|
| - parser.add_option('-t', '--target-platform', help='The target platform.'
|
| - default=target, choices=('android', 'mac', 'linux', 'win'))
|
| - options, _ = parser.parse_args()
|
| -
|
| - if not options.first_build_dir:
|
| - parser.error('--first-build-dir is required')
|
| - if not options.second_build_dir:
|
| - parser.error('--second-build-dir is required')
|
| - if not options.target_platform:
|
| - parser.error('--target-platform is required')
|
| -
|
| - return compare_build_artifacts(os.path.abspath(options.first_build_dir),
|
| - os.path.abspath(options.second_build_dir),
|
| - options.target_platform,
|
| - options.recursive)
|
| -
|
| -
|
| -if __name__ == '__main__':
|
| - sys.exit(main())
|
|
|