1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
|
# Copyright 2014 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Presubmit script for files in chrome/browser/resources.
See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
for more details about the presubmit API built into depot_tools.
"""
ACTION_XML_PATH = '../../../tools/metrics/actions/actions.xml'
PRESUBMIT_VERSION = '2.0.0'
def InternalCheckUserActionUpdate(input_api, output_api, action_xml_path):
"""Checks if any new user action has been added."""
if any('actions.xml' == input_api.os_path.basename(f) for f in
input_api.change.LocalPaths()):
# If actions.xml is already included in the changelist, the PRESUBMIT
# for actions.xml will do a more complete presubmit check.
return []
file_filter = lambda f: f.LocalPath().endswith('.html')
action_re = r'(^|\s+)metric\s*=\s*"([^ ]*)"'
current_actions = None
for f in input_api.AffectedFiles(file_filter=file_filter):
for line_num, line in f.ChangedContents():
match = input_api.re.search(action_re, line)
if match:
# Loads contents in tools/metrics/actions/actions.xml to memory. It's
# loaded only once.
if not current_actions:
with open(action_xml_path, encoding='utf-8') as actions_f:
current_actions = actions_f.read()
metric_name = match.group(2)
is_boolean = IsBoolean(f.NewContents(), metric_name, input_api)
# Search for the matched user action name in |current_actions|.
if not IsActionPresent(current_actions, metric_name, is_boolean):
return [output_api.PresubmitPromptWarning(
'File %s line %d: %s is missing in '
'tools/metrics/actions/actions.xml. Please run '
'tools/metrics/actions/extract_actions.py to update.'
% (f.LocalPath(), line_num, metric_name), [])]
return []
def CheckUserActionUpdate(input_api, output_api):
return InternalCheckUserActionUpdate(input_api, output_api, ACTION_XML_PATH)
def IsActionPresent(current_actions, metric_name, is_boolean):
"""Checks if metric_name is defined in the actions file.
Checks whether there's matching entries in an actions.xml file for the given
|metric_name|, depending on whether it is a boolean action.
Args:
current_actions: The content of the actions.xml file.
metric_name: The name for which the check should be done.
is_boolean: Whether the action comes from a boolean control.
"""
if not is_boolean:
action = 'name="{0}"'.format(metric_name)
return action in current_actions
action_disabled = 'name="{0}_Disable"'.format(metric_name)
action_enabled = 'name="{0}_Enable"'.format(metric_name)
return (action_disabled in current_actions and
action_enabled in current_actions)
def IsBoolean(new_content_lines, metric_name, input_api):
"""Check whether action defined in the changed code is boolean or not.
Checks whether the action comes from boolean control based on the HTML
elements attributes.
Args:
new_content_lines: List of changed lines.
metric_name: The name for which the check should be done.
"""
new_content = '\n'.join(new_content_lines)
html_element_re = r'<(.*?)(^|\s+)metric\s*=\s*"%s"(.*?)>' % (metric_name)
type_re = (r'datatype\s*=\s*"boolean"|type\s*=\s*"checkbox"|'
r'type\s*=\s*"radio".*?value\s*=\s*("true"|"false")')
match = input_api.re.search(html_element_re, new_content, input_api.re.DOTALL)
return (match and
any(input_api.re.search(type_re, match.group(i)) for i in (1, 3)))
def CheckHtml(input_api, output_api):
return input_api.canned_checks.CheckLongLines(
input_api, output_api, 80, lambda x: x.LocalPath().endswith('.html'))
def CheckSvgsOptimized(input_api, output_api):
results = []
try:
import sys
old_sys_path = sys.path[:]
cwd = input_api.PresubmitLocalPath()
sys.path += [input_api.os_path.join(cwd, '..', '..', '..', 'tools')]
from resources import svgo_presubmit
results += svgo_presubmit.CheckOptimized(input_api, output_api)
finally:
sys.path = old_sys_path
return results
def _ImportWebDevStyle(input_api):
try:
import sys
old_sys_path = sys.path[:]
cwd = input_api.PresubmitLocalPath()
sys.path += [input_api.os_path.join(cwd, '..', '..', '..', 'tools')]
from web_dev_style import presubmit_support
finally:
sys.path = old_sys_path
return presubmit_support
def CheckWebDevStyle(input_api, output_api):
presubmit_support = _ImportWebDevStyle(input_api)
return presubmit_support.CheckStyle(input_api, output_api)
def CheckNoNewJs(input_api, output_api):
EXCLUDED_PATHS = [
'chrome/browser/resources/bluetooth_internals/',
'chrome/browser/resources/chromeos/',
'chrome/browser/resources/device_log/',
# TODO(crbug.com/403113291): Migrate incognito_navigation_blocked_page to
# TypeScript and remove exception.
'chrome/browser/resources/enterprise/incognito_navigation_blocked_page/',
'chrome/browser/resources/gaia_auth_host/',
'chrome/browser/resources/hangout_services/',
'chrome/browser/resources/inspect/',
'chrome/browser/resources/net_internals/',
'chrome/browser/resources/network_speech_synthesis/',
'chrome/browser/resources/new_tab_page_incognito_guest/',
'chrome/browser/resources/reading_mode_gdocs_helper/',
]
normalized_excluded_paths = []
for path in EXCLUDED_PATHS:
normalized_excluded_paths.append(input_api.os_path.normpath(path))
def excluded_path(f):
for path in normalized_excluded_paths:
if f.LocalPath().startswith(path) or '.eslintrc.js' in f.LocalPath():
return True
return False
presubmit_support = _ImportWebDevStyle(input_api)
return presubmit_support.DisallowNewJsFiles(input_api, output_api,
lambda f: not excluded_path(f))
def CheckNoNewPolymer(input_api, output_api):
EXCLUDED_PATHS = [
'chrome/browser/resources/ash/',
'chrome/browser/resources/certificate_manager/',
'chrome/browser/resources/chromeos/',
'chrome/browser/resources/password_manager/',
'chrome/browser/resources/settings/',
]
normalized_excluded_paths = []
for path in EXCLUDED_PATHS:
normalized_excluded_paths.append(input_api.os_path.normpath(path))
def excluded_path(f):
for path in normalized_excluded_paths:
if f.LocalPath().startswith(path):
return True
return False
presubmit_support = _ImportWebDevStyle(input_api)
return presubmit_support.DisallowNewPolymerElements(
input_api, output_api, lambda f: not excluded_path(f))
def CheckPatchFormatted(input_api, output_api):
results = input_api.canned_checks.CheckPatchFormatted(input_api, output_api,
check_js=True)
return results
|