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
|
# Copyright (c) 2012 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.
"""Presubmit script for changes affecting extensions.
See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
for more details about the presubmit API built into gcl.
"""
import fnmatch
import os
import re
EXTENSIONS_PATH = os.path.join('chrome', 'common', 'extensions')
DOCS_PATH = os.path.join(EXTENSIONS_PATH, 'docs')
SERVER2_PATH = os.path.join(DOCS_PATH, 'server2')
API_PATH = os.path.join(EXTENSIONS_PATH, 'api')
TEMPLATES_PATH = os.path.join(DOCS_PATH, 'templates')
PRIVATE_TEMPLATES_PATH = os.path.join(TEMPLATES_PATH, 'private')
PUBLIC_TEMPLATES_PATH = os.path.join(TEMPLATES_PATH, 'public')
INTROS_PATH = os.path.join(TEMPLATES_PATH, 'intros')
ARTICLES_PATH = os.path.join(TEMPLATES_PATH, 'articles')
LOCAL_PUBLIC_TEMPLATES_PATH = os.path.join('docs',
'templates',
'public')
def _ReadFile(filename):
with open(filename) as f:
return f.read()
def _ListFilesInPublic():
all_files = []
for path, dirs, files in os.walk(LOCAL_PUBLIC_TEMPLATES_PATH):
all_files.extend(
os.path.join(path, filename)[len(LOCAL_PUBLIC_TEMPLATES_PATH + os.sep):]
for filename in files)
return all_files
def _UnixName(name):
name = os.path.splitext(name)[0]
s1 = re.sub('([a-z])([A-Z])', r'\1_\2', name)
s2 = re.sub('([A-Z]+)([A-Z][a-z])', r'\1_\2', s1)
return s2.replace('.', '_').lower()
def _FindMatchingTemplates(template_name, template_path_list):
matches = []
unix_name = _UnixName(template_name)
for template in template_path_list:
if unix_name == _UnixName(template.split(os.sep)[-1]):
matches.append(template)
return matches
def _SanitizeAPIName(name, api_path):
if not api_path.endswith(os.sep):
api_path += os.sep
filename = os.path.splitext(name)[0][len(api_path):].replace(os.sep, '_')
if 'experimental' in filename:
filename = 'experimental_' + filename.replace('experimental_', '')
return filename
def _CreateIntegrationTestArgs(affected_files):
if (any(fnmatch.fnmatch(name, '%s*.py' % SERVER2_PATH)
for name in affected_files) or
any(fnmatch.fnmatch(name, '%s*' % PRIVATE_TEMPLATES_PATH)
for name in affected_files)):
return ['-a']
args = []
for name in affected_files:
if (fnmatch.fnmatch(name, '%s*' % PUBLIC_TEMPLATES_PATH) or
fnmatch.fnmatch(name, '%s*' % INTROS_PATH) or
fnmatch.fnmatch(name, '%s*' % ARTICLES_PATH)):
args.extend(_FindMatchingTemplates(name.split(os.sep)[-1],
_ListFilesInPublic()))
if fnmatch.fnmatch(name, '%s*' % API_PATH):
args.extend(_FindMatchingTemplates(_SanitizeAPIName(name, API_PATH),
_ListFilesInPublic()))
return args
def _CheckHeadingIDs(input_api):
ids_re = re.compile('<h[23].*id=.*?>')
headings_re = re.compile('<h[23].*?>')
bad_files = []
for name in input_api.AbsoluteLocalPaths():
if not os.path.exists(name):
continue
if (fnmatch.fnmatch(name, '*%s*' % INTROS_PATH) or
fnmatch.fnmatch(name, '*%s*' % ARTICLES_PATH)):
contents = input_api.ReadFile(name)
if (len(re.findall(headings_re, contents)) !=
len(re.findall(ids_re, contents))):
bad_files.append(name)
return bad_files
def _CheckLinks(input_api, output_api, results):
for affected_file in input_api.AffectedFiles():
name = affected_file.LocalPath()
absolute_path = affected_file.AbsoluteLocalPath()
if not os.path.exists(absolute_path):
continue
if (fnmatch.fnmatch(name, '%s*' % PUBLIC_TEMPLATES_PATH) or
fnmatch.fnmatch(name, '%s*' % INTROS_PATH) or
fnmatch.fnmatch(name, '%s*' % ARTICLES_PATH) or
fnmatch.fnmatch(name, '%s*' % API_PATH)):
contents = _ReadFile(absolute_path)
args = []
if input_api.platform == 'win32':
args = [input_api.python_executable]
args.extend([os.path.join('docs', 'server2', 'link_converter.py'),
'-o',
'-f',
absolute_path])
output = input_api.subprocess.check_output(
args,
cwd=input_api.PresubmitLocalPath(),
universal_newlines=True)
if output != contents:
changes = ''
for i, (line1, line2) in enumerate(
zip(contents.split('\n'), output.split('\n'))):
if line1 != line2:
changes = ('%s\nLine %d:\n-%s\n+%s\n' %
(changes, i + 1, line1, line2))
if changes:
results.append(output_api.PresubmitPromptWarning(
'File %s may have an old-style <a> link to an API page. Please '
'run docs/server2/link_converter.py to convert the link[s], or '
'convert them manually.\n\nSuggested changes are: %s' %
(name, changes)))
def _CheckChange(input_api, output_api):
results = [
output_api.PresubmitError('File %s needs an id for each heading.' % name)
for name in _CheckHeadingIDs(input_api)]
try:
integration_test = []
# From depot_tools/presubmit_canned_checks.py:529
if input_api.platform == 'win32':
integration_test = [input_api.python_executable]
integration_test.append(
os.path.join('docs', 'server2', 'integration_test.py'))
integration_test.extend(_CreateIntegrationTestArgs(input_api.LocalPaths()))
input_api.subprocess.check_call(integration_test,
cwd=input_api.PresubmitLocalPath())
except input_api.subprocess.CalledProcessError:
results.append(output_api.PresubmitError('IntegrationTest failed!'))
_CheckLinks(input_api, output_api, results)
return results
def CheckChangeOnUpload(input_api, output_api):
return _CheckChange(input_api, output_api)
def CheckChangeOnCommit(input_api, output_api):
return _CheckChange(input_api, output_api)
|