Description: add back contents of third-party/blink/tools that went missing in the source tarball for 66.0.3359.106 Bug: https://bugs.chromium.org/p/chromium/issues/detail?id=832283 --- /dev/null +++ b/third_party/blink/tools/OWNERS @@ -0,0 +1 @@ +file://third_party/WebKit/Tools/OWNERS --- /dev/null +++ b/third_party/blink/tools/blinkpy/__init__.py @@ -0,0 +1,3 @@ +# Copyright 2017 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. --- /dev/null +++ b/third_party/blink/tools/blinkpy/common/__init__.py @@ -0,0 +1,3 @@ +# Copyright 2017 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. --- /dev/null +++ b/third_party/blink/tools/blinkpy/common/name_style_converter.py @@ -0,0 +1,128 @@ +# Copyright 2017 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. + +# pylint: disable=import-error,print-statement,relative-import + +import re + +SPECIAL_TOKENS = [ + # This list should be sorted by length. + 'CString', + 'Float32', + 'Float64', + 'Base64', + 'IFrame', + 'Latin1', + 'PlugIn', + 'SQLite', + 'Uint16', + 'Uint32', + 'WebGL2', + 'ASCII', + 'CType', + 'DList', + 'Int16', + 'Int32', + 'MPath', + 'OList', + 'TSpan', + 'UList', + 'UTF16', + 'Uint8', + 'WebGL', + 'XPath', + 'ETC1', + 'HTML', + 'Int8', + 'S3TC', + 'SPv2', + 'UTF8', + 'API', + 'CSS', + 'DOM', + 'EXT', + 'RTC', + 'SVG', + '2D', + 'AX', + 'V0', + 'V8', +] + +MATCHING_EXPRESSION = '((?:[A-Z][a-z]+)|[0-9]D?$)' + + +class SmartTokenizer(object): + """Detects special cases that are not easily discernible without additional + knowledge, such as recognizing that in SVGSVGElement, the first two SVGs + are separate tokens, but WebGL is one token.""" + + def __init__(self, name): + self.remaining = name + + def tokenize(self): + name = self.remaining + tokens = [] + while len(name) > 0: + matched_token = None + for token in SPECIAL_TOKENS: + if name.startswith(token): + matched_token = token + break + if not matched_token: + match = re.search(MATCHING_EXPRESSION, name) + if not match: + matched_token = name + elif match.start(0) != 0: + matched_token = name[:match.start(0)] + else: + matched_token = match.group(0) + tokens.append(name[:len(matched_token)]) + name = name[len(matched_token):] + return tokens + + +class NameStyleConverter(object): + """Converts names from camelCase to various other styles. + """ + + def __init__(self, name): + self.tokens = self.tokenize(name) + + def tokenize(self, name): + tokenizer = SmartTokenizer(name) + return tokenizer.tokenize() + + def to_snake_case(self): + """Snake case is the file and variable name style per Google C++ Style + Guide: + https://google.github.io/styleguide/cppguide.html#Variable_Names + + Also known as the hacker case. + https://en.wikipedia.org/wiki/Snake_case + """ + return '_'.join([token.lower() for token in self.tokens]) + + def to_upper_camel_case(self): + """Upper-camel case is the class and function name style per + Google C++ Style Guide: + https://google.github.io/styleguide/cppguide.html#Function_Names + + Also known as the PascalCase. + https://en.wikipedia.org/wiki/Camel_case. + """ + return ''.join([token[0].upper() + token[1:] for token in self.tokens]) + + def to_macro_case(self): + """Macro case is the macro name style per Google C++ Style Guide: + https://google.github.io/styleguide/cppguide.html#Macro_Names + """ + return '_'.join([token.upper() for token in self.tokens]) + + def to_all_cases(self): + return { + 'snake_case': self.to_snake_case(), + 'upper_camel_case': self.to_upper_camel_case(), + 'macro_case': self.to_macro_case(), + } --- /dev/null +++ b/third_party/blink/tools/blinkpy/common/name_style_converter_test.py @@ -0,0 +1,178 @@ +# Copyright 2017 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. + +# pylint: disable=import-error,print-statement,relative-import,protected-access + +"""Unit tests for name_style_converter.py.""" + +import unittest + +from name_style_converter import NameStyleConverter +from name_style_converter import SmartTokenizer + + +class SmartTokenizerTest(unittest.TestCase): + def test_simple_cases(self): + tokenizer = SmartTokenizer('foo') + self.assertEqual(tokenizer.tokenize(), ['foo']) + + tokenizer = SmartTokenizer('fooBar') + self.assertEqual(tokenizer.tokenize(), ['foo', 'Bar']) + + tokenizer = SmartTokenizer('fooBarBaz') + self.assertEqual(tokenizer.tokenize(), ['foo', 'Bar', 'Baz']) + + tokenizer = SmartTokenizer('Baz') + self.assertEqual(tokenizer.tokenize(), ['Baz']) + + tokenizer = SmartTokenizer('') + self.assertEqual(tokenizer.tokenize(), []) + + tokenizer = SmartTokenizer('FOO') + self.assertEqual(tokenizer.tokenize(), ['FOO']) + + tokenizer = SmartTokenizer('foo2') + self.assertEqual(tokenizer.tokenize(), ['foo', '2']) + + def test_tricky_cases(self): + tokenizer = SmartTokenizer('XMLHttpRequest') + self.assertEqual(tokenizer.tokenize(), ['XML', 'Http', 'Request']) + + tokenizer = SmartTokenizer('HTMLElement') + self.assertEqual(tokenizer.tokenize(), ['HTML', 'Element']) + + tokenizer = SmartTokenizer('WebGLRenderingContext') + self.assertEqual(tokenizer.tokenize(), + ['WebGL', 'Rendering', 'Context']) + + tokenizer = SmartTokenizer('CanvasRenderingContext2D') + self.assertEqual(tokenizer.tokenize(), + ['Canvas', 'Rendering', 'Context', '2D']) + tokenizer = SmartTokenizer('CanvasRenderingContext2DAPITest') + self.assertEqual(tokenizer.tokenize(), + ['Canvas', 'Rendering', 'Context', '2D', 'API', 'Test']) + + tokenizer = SmartTokenizer('SVGSVGElement') + self.assertEqual(tokenizer.tokenize(), ['SVG', 'SVG', 'Element']) + + tokenizer = SmartTokenizer('CanvasRenderingContext2D') + self.assertEqual(tokenizer.tokenize(), ['Canvas', 'Rendering', 'Context', '2D']) + + tokenizer = SmartTokenizer('CSSURLImageValue') + self.assertEqual(tokenizer.tokenize(), ['CSS', 'URL', 'Image', 'Value']) + tokenizer = SmartTokenizer('CSSPropertyAPID') + self.assertEqual(tokenizer.tokenize(), ['CSS', 'Property', 'API', 'D']) + tokenizer = SmartTokenizer('AXARIAGridCell') + self.assertEqual(tokenizer.tokenize(), ['AX', 'ARIA', 'Grid', 'Cell']) + + tokenizer = SmartTokenizer('CDATASection') + self.assertEqual(tokenizer.tokenize(), ['CDATA', 'Section']) + + tokenizer = SmartTokenizer('ASCIICType') + self.assertEqual(tokenizer.tokenize(), ['ASCII', 'CType']) + tokenizer = SmartTokenizer('CString') + self.assertEqual(tokenizer.tokenize(), ['CString']) + + tokenizer = SmartTokenizer('HTMLDListElement') + self.assertEqual(tokenizer.tokenize(), ['HTML', 'DList', 'Element']) + tokenizer = SmartTokenizer('HTMLOListElement') + self.assertEqual(tokenizer.tokenize(), ['HTML', 'OList', 'Element']) + tokenizer = SmartTokenizer('HTMLIFrameElement') + self.assertEqual(tokenizer.tokenize(), ['HTML', 'IFrame', 'Element']) + tokenizer = SmartTokenizer('HTMLPlugInElement') + self.assertEqual(tokenizer.tokenize(), ['HTML', 'PlugIn', 'Element']) + + # No special handling for OptGroup, FieldSet, and TextArea. + tokenizer = SmartTokenizer('HTMLOptGroupElement') + self.assertEqual(tokenizer.tokenize(), ['HTML', 'Opt', 'Group', 'Element']) + tokenizer = SmartTokenizer('HTMLFieldSetElement') + self.assertEqual(tokenizer.tokenize(), ['HTML', 'Field', 'Set', 'Element']) + tokenizer = SmartTokenizer('HTMLTextAreaElement') + self.assertEqual(tokenizer.tokenize(), ['HTML', 'Text', 'Area', 'Element']) + + tokenizer = SmartTokenizer('Path2D') + self.assertEqual(tokenizer.tokenize(), ['Path', '2D']) + tokenizer = SmartTokenizer('Point2D') + self.assertEqual(tokenizer.tokenize(), ['Point', '2D']) + tokenizer = SmartTokenizer('CanvasRenderingContext2DState') + self.assertEqual(tokenizer.tokenize(), ['Canvas', 'Rendering', 'Context', '2D', 'State']) + + tokenizer = SmartTokenizer('RTCDTMFSender') + self.assertEqual(tokenizer.tokenize(), ['RTC', 'DTMF', 'Sender']) + + tokenizer = SmartTokenizer('WebGLCompressedTextureS3TCsRGB') + self.assertEqual(tokenizer.tokenize(), ['WebGL', 'Compressed', 'Texture', 'S3TC', 'sRGB']) + tokenizer = SmartTokenizer('WebGL2CompressedTextureETC1') + self.assertEqual(tokenizer.tokenize(), ['WebGL2', 'Compressed', 'Texture', 'ETC1']) + tokenizer = SmartTokenizer('EXTsRGB') + self.assertEqual(tokenizer.tokenize(), ['EXT', 'sRGB']) + + tokenizer = SmartTokenizer('SVGFEBlendElement') + self.assertEqual(tokenizer.tokenize(), ['SVG', 'FE', 'Blend', 'Element']) + tokenizer = SmartTokenizer('SVGMPathElement') + self.assertEqual(tokenizer.tokenize(), ['SVG', 'MPath', 'Element']) + tokenizer = SmartTokenizer('SVGTSpanElement') + self.assertEqual(tokenizer.tokenize(), ['SVG', 'TSpan', 'Element']) + tokenizer = SmartTokenizer('SVGURIReference') + self.assertEqual(tokenizer.tokenize(), ['SVG', 'URI', 'Reference']) + + tokenizer = SmartTokenizer('UTF16TextIterator') + self.assertEqual(tokenizer.tokenize(), ['UTF16', 'Text', 'Iterator']) + tokenizer = SmartTokenizer('UTF8Decoder') + self.assertEqual(tokenizer.tokenize(), ['UTF8', 'Decoder']) + tokenizer = SmartTokenizer('Uint8Array') + self.assertEqual(tokenizer.tokenize(), ['Uint8', 'Array']) + tokenizer = SmartTokenizer('DOMWindowBase64') + self.assertEqual(tokenizer.tokenize(), ['DOM', 'Window', 'Base64']) + tokenizer = SmartTokenizer('TextCodecLatin1') + self.assertEqual(tokenizer.tokenize(), ['Text', 'Codec', 'Latin1']) + tokenizer = SmartTokenizer('V8BindingForCore') + self.assertEqual(tokenizer.tokenize(), ['V8', 'Binding', 'For', 'Core']) + tokenizer = SmartTokenizer('V8DOMRect') + self.assertEqual(tokenizer.tokenize(), ['V8', 'DOM', 'Rect']) + + tokenizer = SmartTokenizer('V0InsertionPoint') + self.assertEqual(tokenizer.tokenize(), ['V0', 'Insertion', 'Point']) + tokenizer = SmartTokenizer('ShadowDOMV0Test') + self.assertEqual(tokenizer.tokenize(), ['Shadow', 'DOM', 'V0', 'Test']) + tokenizer = SmartTokenizer('ElementShadowV0') + self.assertEqual(tokenizer.tokenize(), ['Element', 'Shadow', 'V0']) + tokenizer = SmartTokenizer('StubChromeClientForSPv2') + self.assertEqual(tokenizer.tokenize(), ['Stub', 'Chrome', 'Client', 'For', 'SPv2']) + + tokenizer = SmartTokenizer('SQLiteAuthorizer') + self.assertEqual(tokenizer.tokenize(), ['SQLite', 'Authorizer']) + tokenizer = SmartTokenizer('XPathEvaluator') + self.assertEqual(tokenizer.tokenize(), ['XPath', 'Evaluator']) + + tokenizer = SmartTokenizer('IsXHTMLDocument') + self.assertEqual(tokenizer.tokenize(), ['Is', 'XHTML', 'Document']) + + tokenizer = SmartTokenizer('Animation.idl') + self.assertEqual(tokenizer.tokenize(), ['Animation', '.idl']) + + +class NameStyleConverterTest(unittest.TestCase): + def test_snake_case(self): + converter = NameStyleConverter('HTMLElement') + self.assertEqual(converter.to_snake_case(), 'html_element') + + def test_upper_camel_case(self): + converter = NameStyleConverter('someSuperThing') + self.assertEqual(converter.to_upper_camel_case(), 'SomeSuperThing') + + converter = NameStyleConverter('SVGElement') + self.assertEqual(converter.to_upper_camel_case(), 'SVGElement') + + def test_macro_case(self): + converter = NameStyleConverter('WebGLBaz2D') + self.assertEqual(converter.to_macro_case(), 'WEBGL_BAZ_2D') + + def test_all_cases(self): + converter = NameStyleConverter('SVGScriptElement') + self.assertEqual(converter.to_all_cases(), { + 'snake_case': 'svg_script_element', + 'upper_camel_case': 'SVGScriptElement', + 'macro_case': 'SVG_SCRIPT_ELEMENT', + }) --- /dev/null +++ b/third_party/blink/tools/compile_devtools_frontend.py @@ -0,0 +1,20 @@ +#!/usr/bin/env vpython +# Copyright 2017 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. + +"""Compile DevTools frontend code with Closure compiler. + +This script wraps devtools/scripts/compile_frontend.py. +DevTools bot kicks this script. +""" + +import os +import sys + +sys.path.append(os.path.join( + os.path.dirname(__file__), '..', '..', 'WebKit', 'Source', 'devtools', 'scripts')) +import compile_frontend + +if __name__ == '__main__': + sys.exit(compile_frontend.main()) --- /dev/null +++ b/third_party/blink/tools/move_blink_source.py @@ -0,0 +1,615 @@ +#!/usr/bin/env vpython +# Copyright 2017 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. + +"""Tool to move Blink source from third_party/WebKit to third_party/blink. + +See https://docs.google.com/document/d/1l3aPv1Wx__SpRkdOhvJz8ciEGigNT3wFKv78XiuW0Tw/edit?usp=sharing#heading=h.o225wrxp242h +for the details. +""" + +import argparse +import logging +import os +import re +import sys +from functools import partial + +# Without abspath(), PathFinder can't find chromium_base correctly. +sys.path.append(os.path.abspath( + os.path.join(os.path.dirname(__file__), '..', '..', '..', + 'third_party', 'WebKit', 'Tools', 'Scripts'))) +from blinkpy.common.name_style_converter import NameStyleConverter +from plan_blink_move import plan_blink_move +from plan_blink_move import relative_dest +from webkitpy.common.checkout.git import Git +from webkitpy.common.path_finder import get_chromium_src_dir +from webkitpy.common.path_finder import get_scripts_dir +from webkitpy.common.system.executive import Executive +from webkitpy.common.system.executive import ScriptError +from webkitpy.common.system.filesystem import FileSystem + +_log = logging.getLogger('move_blink_source') + + +class FileType(object): + NONE = 0 + BUILD = 1 + BLINK_BUILD = 2 + OWNERS = 3 + DEPS = 4 + MOJOM = 5 + TYPEMAP = 6 + BLINK_BUILD_PY = 7 + LAYOUT_TESTS_WITH_MOJOM = 8 + + @staticmethod + def detect(path): + slash_dir, basename = os.path.split(path) + slash_dir = slash_dir.replace(os.path.sep, '/') + if basename == 'DEPS': + return FileType.DEPS + if basename == 'OWNERS': + return FileType.OWNERS + if basename.endswith('.mojom'): + return FileType.MOJOM + if basename.endswith('.typemap'): + return FileType.TYPEMAP + if basename.endswith('.py') and 'third_party/WebKit/Source/build' in slash_dir: + return FileType.BLINK_BUILD_PY + if basename.endswith(('.gn', '.gni')): + if 'third_party/WebKit' in path or 'third_party/blink' in slash_dir: + return FileType.BLINK_BUILD + if 'third_party' in slash_dir: + return FileType.NONE + return FileType.BUILD + if basename.endswith('.html') and re.search( + r'third_party/WebKit/LayoutTests/(geolocation-api|installedapp|' + + r'media/mediasession|payments|presentation|webshare)', slash_dir): + return FileType.LAYOUT_TESTS_WITH_MOJOM + return FileType.NONE + + +class MoveBlinkSource(object): + + def __init__(self, fs, options, repo_root): + self._fs = fs + self._options = options + _log.debug(options) + self._repo_root = repo_root + + # The following fields are initialized in _create_basename_maps. + self._basename_map = None + self._basename_re = None + self._idl_generated_impl_headers = None + # _checked_in_header_re is used to distinguish checked-in header files + # and generated header files. + self._checked_in_header_re = None + + self._updated_files = [] + + def update(self, apply_only=None): + """Updates contents of files affected by Blink source move. + + Args: + apply_only: If it's None, updates all affected files. Otherwise, + it should be a set of file paths and this function updates + only the files in |apply_only|. + """ + _log.info('Planning renaming ...') + file_pairs = plan_blink_move(self._fs, []) + _log.info('Will move %d files', len(file_pairs)) + + self._create_basename_maps(file_pairs) + dirs = self._update_file_content(apply_only) + + # Updates #includes in files in directories with updated DEPS + + # third_party/WebKit/{Source,common,public}. + self._append_unless_upper_dir_exists(dirs, self._fs.join(self._repo_root, 'third_party', 'WebKit', 'Source')) + self._append_unless_upper_dir_exists(dirs, self._fs.join(self._repo_root, 'third_party', 'WebKit', 'common')) + self._append_unless_upper_dir_exists(dirs, self._fs.join(self._repo_root, 'third_party', 'WebKit', 'public')) + self._append_unless_upper_dir_exists(dirs, self._fs.join(self._repo_root, 'mojo', 'public', 'tools', + 'bindings', 'generators', 'cpp_templates')) + self._update_cpp_includes_in_directories(dirs, apply_only) + + # Content update for individual files. + # The following is a list of tuples. + # Tuple: (, [replacement commands]) + # Command: a callable object, or + # a tuple of (, ). + file_replacement_list = [ + ('DEPS', + [('src/third_party/WebKit/Source/devtools', + 'src/third_party/blink/renderer/devtools')]), + ('WATCHLISTS', + [('third_party/WebKit/Source', 'third_party/blink/renderer'), + ('third_party/WebKit/public', 'third_party/blink/renderer/public')]), + ('build/check_gn_headers_whitelist.txt', + [('third_party/WebKit/Source', 'third_party/blink/renderer'), + ('third_party/WebKit/public', 'third_party/blink/renderer/public'), + self._update_basename]), + ('testing/buildbot/gn_isolate_map.pyl', + [('third_party/WebKit/Source', 'third_party/blink/renderer')]), + ('third_party/WebKit/Source/BUILD.gn', + [('$root_gen_dir/third_party/WebKit', + '$root_gen_dir/third_party/blink/renderer')]), + ('third_party/WebKit/Source/config.gni', + [('snake_case_source_files = false', + 'snake_case_source_files = true')]), + ('third_party/WebKit/Source/core/css/CSSProperties.json5', + [self._update_basename]), + ('third_party/WebKit/Source/core/css/ComputedStyleExtraFields.json5', + [self._update_basename]), + ('third_party/WebKit/Source/core/css/ComputedStyleFieldAliases.json5', + [self._update_basename]), + ('third_party/WebKit/Source/core/html/parser/create-html-entity-table', + [self._update_basename]), + ('third_party/WebKit/Source/core/inspector/inspector_protocol_config.json', + [self._update_basename]), + ('third_party/WebKit/Source/core/probe/CoreProbes.json5', + [self._update_basename]), + ('third_party/WebKit/Source/core/testing/InternalSettings.h', + [('InternalSettingsGenerated.h', 'internal_settings_generated.h')]), + ('third_party/WebKit/Source/core/testing/Internals.cpp', + [('InternalRuntimeFlags.h', 'internal_runtime_flags.h')]), + ('third_party/WebKit/Source/platform/probe/PlatformProbes.json5', + [self._update_basename]), + ('third_party/WebKit/public/BUILD.gn', + [('$root_gen_dir/third_party/WebKit', + '$root_gen_dir/third_party/blink/renderer')]), + ('third_party/WebKit/public/blink_resources.grd', + [('../Source/', '../')]), + ('tools/android/eclipse/.classpath', + [('third_party/WebKit/public', 'third_party/blink/renderer/public')]), + ('tools/android/loading/cloud/backend/deploy.sh', + [('third_party/WebKit/Source', 'third_party/blink/renderer')]), + ('tools/android/loading/emulation_unittest.py', + [('third_party/WebKit/Source', 'third_party/blink/renderer')]), + ('tools/android/loading/options.py', + [('third_party/WebKit/Source', 'third_party/blink/renderer')]), + ('tools/android/loading/request_track.py', + [('third_party/WebKit/Source', 'third_party/blink/renderer')]), + ('tools/gritsettings/resource_ids', + [('third_party/WebKit/public', 'third_party/blink/renderer/public'), + ('third_party/WebKit/Source', 'third_party/blink/renderer')]), + ('tools/metrics/actions/extract_actions.py', + [('third_party/WebKit/Source', 'third_party/blink/renderer')]), + ('tools/metrics/histograms/update_editor_commands.py', + [('third_party/WebKit/Source/core/editing/EditorCommand.cpp', + 'third_party/blink/renderer/core/editing/editor_command.cc')]), + ('tools/metrics/histograms/update_use_counter_css.py', + [('third_party/WebKit/Source/core/frame/UseCounter.cpp', + 'third_party/blink/renderer/core/frame/use_counter.cc')]), + ('tools/metrics/histograms/update_use_counter_feature_enum.py', + [('third_party/WebKit/public', 'third_party/blink/renderer/public')]), + ] + for file_path, replacement_list in file_replacement_list: + if not apply_only or file_path in apply_only: + self._update_single_file_content(file_path, replacement_list, should_write=self._options.run) + + if self._options.run: + _log.info('Formatting updated %d files ...', len(self._updated_files)) + git = Git(cwd=self._repo_root) + # |git cl format| can't handle too many files at once. + while len(self._updated_files) > 0: + end_index = 100 + if end_index > len(self._updated_files): + end_index = len(self._updated_files) + git.run(['cl', 'format'] + self._updated_files[:end_index]) + self._updated_files = self._updated_files[end_index:] + + if not apply_only: + _log.info('Make a local commit ...') + git.commit_locally_with_message("""The Great Blink mv for source files, part 1. + +Update file contents without moving files. + +NOAUTOREVERT=true +Bug: 768828 +""") + + def move(self, apply_only=None): + """Move Blink source files. + + Args: + apply_only: If it's None, move all affected files. Otherwise, + it should be a set of file paths and this function moves + only the files in |apply_only|. + """ + _log.info('Planning renaming ...') + file_pairs = plan_blink_move(self._fs, []) + + if apply_only: + file_pairs = [(src, dest) for (src, dest) in file_pairs + if 'third_party/WebKit/' + src.replace('\\', '/') in apply_only] + print 'Update file_pairs = ', file_pairs + _log.info('Will move %d files', len(file_pairs)) + + git = Git(cwd=self._repo_root) + files_set = self._get_checked_in_files(git) + for i, (src, dest) in enumerate(file_pairs): + src_from_repo = self._fs.join('third_party', 'WebKit', src) + if src_from_repo.replace('\\', '/') not in files_set: + _log.info('%s is not in the repository', src) + continue + dest_from_repo = self._fs.join('third_party', 'blink', dest) + self._fs.maybe_make_directory(self._repo_root, 'third_party', 'blink', self._fs.dirname(dest)) + if self._options.run_git: + git.move(src_from_repo, dest_from_repo) + _log.info('[%d/%d] Git moved %s', i + 1, len(file_pairs), src) + else: + self._fs.move(self._fs.join(self._repo_root, src_from_repo), + self._fs.join(self._repo_root, dest_from_repo)) + _log.info('[%d/%d] Moved %s', i + 1, len(file_pairs), src) + if apply_only: + return + + self._update_single_file_content( + 'build/get_landmines.py', + [('\ndef main', ' print \'The Great Blink mv for source files (crbug.com/768828)\'\n\ndef main')]) + + _log.info('Run run-bindings-tests ...') + Executive().run_command(['python', + self._fs.join(get_scripts_dir(), 'run-bindings-tests'), + '--reset-results'], + cwd=self._repo_root) + + if self._options.run_git: + _log.info('Make a local commit ...') + git.commit_locally_with_message("""The Great Blink mv for source files, part 2. + +Move and rename files. + +NOAUTOREVERT=true +Bug: 768828 +""") + + def fix_branch(self): + git = Git(cwd=self._repo_root) + status = self._get_local_change_status(git) + if len(status) == 0: + _log.info('No local changes.') + return + modified_files = {f for (s, f) in status if s != 'D'} + deleted_files = {f for (s, f) in status if s == 'D'} + + self.update(apply_only=modified_files) + self.move(apply_only=modified_files) + try: + git.commit_locally_with_message('This commit should be squashed.') + except ScriptError: + _log.info('move_blink_source.py modified nothing.') + + # TODO(tkent): Show a message about deleted_files. + + def _get_local_change_status(self, git): + """Returns a list of tuples representing local change summary. + + Each tuple contains two strings. The first one is file change status + such as "M", "D". See --diff-filter section of git-diff manual page. + The second one is file name relative to the repository top. + """ + + base_commit = git.run(['show-branch', '--merge-base', 'master', 'HEAD']).strip() + # Note that file names in the following command result are always + # slash-separated, even on Windows. + status_lines = git.run(['diff', '--name-status', '--no-renames', base_commit]).split('\n') + status_tuple_list = [] + for l in status_lines: + items = l.split('\t') + if len(items) == 2: + status_tuple_list.append(tuple(items)) + elif len(l) > 0: + _log.warning('Unrecognized diff output: "%s"', l) + return status_tuple_list + + def _get_checked_in_files(self, git): + files_text = git.run(['ls-files', + 'third_party/WebKit/Source', + 'third_party/WebKit/common', + 'third_party/WebKit/public']) + return set(files_text.split('\n')) + + def _create_basename_maps(self, file_pairs): + basename_map = {} + # Generated inspector/protocol/* contains a lot of names duplicated with + # checked-in core files. We don't want to rename them, and don't want to + # replace them in BUILD.gn and #include accidentally. + pattern = r'(? => ' + for pair in file_pairs: + print '%s\t=>\t%s' % pair + + +if __name__ == '__main__': + main()