зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1329201 - Remove check-moz-style from m-c r=Ms2ger
MozReview-Commit-ID: 4uG6uEyMN7w --HG-- extra : rebase_source : 0edf02bb458c687c696508b7d2df39ada51f73d4
This commit is contained in:
Родитель
f64146d9d7
Коммит
33bf059a2e
|
@ -1,172 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
#
|
||||
# Copyright (C) 2009 Google Inc. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following disclaimer
|
||||
# in the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Google Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
"""Script to run the linter for source code of WebKit."""
|
||||
|
||||
import os
|
||||
import os.path
|
||||
import re
|
||||
import sys
|
||||
|
||||
import modules.cpplint as cpplint
|
||||
from modules.diff_parser import DiffParser
|
||||
from modules.scm import detect_scm_system
|
||||
|
||||
|
||||
# Override the usage of the lint tool.
|
||||
cpplint._USAGE = """
|
||||
Syntax: %(program_name)s [--verbose=#] [--git-commit=<COMMITISH>] [--output=vs7] [--filter=-x,+y,...]
|
||||
|
||||
The style guidelines this tries to follow are those in
|
||||
http://webkit.org/coding/coding-style.html
|
||||
|
||||
Every problem is given a confidence score from 1-5, with 5 meaning we are
|
||||
certain of the problem, and 1 meaning it could be a legitimate construct.
|
||||
This will miss some errors, and is not a substitute for a code review.
|
||||
|
||||
To prevent specific lines from being linted, add a '// NOLINT' comment to the
|
||||
end of the line.
|
||||
|
||||
Linted extensions are .cpp, .c and .h. Other file types will be ignored.
|
||||
|
||||
Flags:
|
||||
|
||||
verbose=#
|
||||
Specify a number 0-5 to restrict errors to certain verbosity levels.
|
||||
|
||||
git-commit=<COMMITISH>
|
||||
Check style for a specified git commit.
|
||||
Note that the program checks style based on current local file
|
||||
instead of actual diff of the git commit. So, if the files are
|
||||
updated after the specified git commit, the information of line
|
||||
number may be wrong.
|
||||
|
||||
output=vs7
|
||||
By default, the output is formatted to ease emacs parsing. Visual Studio
|
||||
compatible output (vs7) may also be used. Other formats are unsupported.
|
||||
|
||||
filter=-x,+y,...
|
||||
Specify a comma-separated list of category-filters to apply: only
|
||||
error messages whose category names pass the filters will be printed.
|
||||
(Category names are printed with the message and look like
|
||||
"[whitespace/indent]".) Filters are evaluated left to right.
|
||||
"-FOO" and "FOO" means "do not print categories that start with FOO".
|
||||
"+FOO" means "do print categories that start with FOO".
|
||||
|
||||
Examples: --filter=-whitespace,+whitespace/braces
|
||||
--filter=whitespace,runtime/printf,+runtime/printf_format
|
||||
--filter=-,+build/include_what_you_use
|
||||
|
||||
To see a list of all the categories used in %(program_name)s, pass no arg:
|
||||
--filter=
|
||||
""" % {'program_name': sys.argv[0]}
|
||||
|
||||
def process_patch(patch_string, root, cwd, scm):
|
||||
"""Does lint on a single patch.
|
||||
|
||||
Args:
|
||||
patch_string: A string of a patch.
|
||||
"""
|
||||
patch = DiffParser(patch_string.splitlines())
|
||||
|
||||
if not len(patch.files):
|
||||
cpplint.error("patch", 0, "patch/notempty", 3,
|
||||
"Patch does not appear to diff against any file.")
|
||||
return
|
||||
|
||||
if not patch.status_line:
|
||||
cpplint.error("patch", 0, "patch/nosummary", 3,
|
||||
"Patch does not have a summary.")
|
||||
else:
|
||||
proper_format = re.match(r"^Bug [0-9]+ - ", patch.status_line)
|
||||
if not proper_format:
|
||||
proper_format = re.match(r"^No bug - ", patch.status_line)
|
||||
cpplint.error("patch", 0, "patch/bugnumber", 3,
|
||||
"Patch summary should begin with 'Bug XXXXX - ' " +
|
||||
"or 'No bug -'.")
|
||||
|
||||
if not patch.patch_description:
|
||||
cpplint.error("patch", 0, "patch/nodescription", 3,
|
||||
"Patch does not have a description.")
|
||||
|
||||
for filename, diff in patch.files.iteritems():
|
||||
file_extension = os.path.splitext(filename)[1]
|
||||
|
||||
if file_extension in ['.cpp', '.c', '.h']:
|
||||
line_numbers = set()
|
||||
orig_filename = filename
|
||||
|
||||
def error_for_patch(filename, line_number, category, confidence,
|
||||
message):
|
||||
"""Wrapper function of cpplint.error for patches.
|
||||
|
||||
This function outputs errors only if the line number
|
||||
corresponds to lines which are modified or added.
|
||||
"""
|
||||
if not line_numbers:
|
||||
for line in diff.lines:
|
||||
# When deleted line is not set, it means that
|
||||
# the line is newly added.
|
||||
if not line[0]:
|
||||
line_numbers.add(line[1])
|
||||
|
||||
if line_number in line_numbers:
|
||||
cpplint.error(orig_filename, line_number,
|
||||
category, confidence, message)
|
||||
|
||||
cpplint.process_file(os.path.join(root, filename),
|
||||
relative_name=orig_filename,
|
||||
error=error_for_patch)
|
||||
|
||||
|
||||
def main():
|
||||
cpplint.use_mozilla_styles()
|
||||
|
||||
(args, flags) = cpplint.parse_arguments(sys.argv[1:], ["git-commit="])
|
||||
if args:
|
||||
sys.stderr.write("ERROR: We don't support files as arguments for " +
|
||||
"now.\n" + cpplint._USAGE)
|
||||
sys.exit(1)
|
||||
|
||||
cwd = os.path.abspath('.')
|
||||
scm = detect_scm_system(cwd)
|
||||
root = scm.find_checkout_root(cwd)
|
||||
|
||||
if "--git-commit" in flags:
|
||||
process_patch(scm.create_patch_from_local_commit(flags["--git-commit"]), root, cwd, scm)
|
||||
else:
|
||||
process_patch(scm.create_patch(), root, cwd, scm)
|
||||
|
||||
sys.stderr.write('Total errors found: %d\n' % cpplint.error_count())
|
||||
sys.exit(cpplint.error_count() > 0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -1,162 +0,0 @@
|
|||
# Copyright (C) 2009 Google Inc. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following disclaimer
|
||||
# in the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Google Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
"""WebKit's Python module for interacting with patches."""
|
||||
|
||||
import logging
|
||||
import re
|
||||
|
||||
|
||||
_regexp_compile_cache = {}
|
||||
|
||||
|
||||
def match(pattern, string):
|
||||
"""Matches the string with the pattern, caching the compiled regexp."""
|
||||
if not pattern in _regexp_compile_cache:
|
||||
_regexp_compile_cache[pattern] = re.compile(pattern)
|
||||
return _regexp_compile_cache[pattern].match(string)
|
||||
|
||||
|
||||
def git_diff_to_svn_diff(line):
|
||||
"""Converts a git formatted diff line to a svn formatted line.
|
||||
|
||||
Args:
|
||||
line: A string representing a line of the diff.
|
||||
"""
|
||||
conversion_patterns = (("^diff --git a/(.+) b/(?P<FilePath>.+)", lambda matched: "Index: " + matched.group('FilePath') + "\n"),
|
||||
("^new file.*", lambda matched: "\n"),
|
||||
("^index [0-9a-f]{7}\.\.[0-9a-f]{7} [0-9]{6}", lambda matched: "===================================================================\n"),
|
||||
("^--- a/(?P<FilePath>.+)", lambda matched: "--- " + matched.group('FilePath') + "\n"),
|
||||
("^\+\+\+ b/(?P<FilePath>.+)", lambda matched: "+++ " + matched.group('FilePath') + "\n"))
|
||||
|
||||
for pattern, conversion in conversion_patterns:
|
||||
matched = match(pattern, line)
|
||||
if matched:
|
||||
return conversion(matched)
|
||||
return line
|
||||
|
||||
|
||||
def get_diff_converter(first_diff_line):
|
||||
"""Gets a converter function of diff lines.
|
||||
|
||||
Args:
|
||||
first_diff_line: The first filename line of a diff file.
|
||||
If this line is git formatted, we'll return a
|
||||
converter from git to SVN.
|
||||
"""
|
||||
if match(r"^diff --git a/", first_diff_line):
|
||||
return git_diff_to_svn_diff
|
||||
return lambda input: input
|
||||
|
||||
|
||||
_INITIAL_STATE = 1
|
||||
_DECLARED_FILE_PATH = 2
|
||||
_PROCESSING_CHUNK = 3
|
||||
|
||||
|
||||
class DiffFile:
|
||||
"""Contains the information for one file in a patch.
|
||||
|
||||
The field "lines" is a list which contains tuples in this format:
|
||||
(deleted_line_number, new_line_number, line_string)
|
||||
If deleted_line_number is zero, it means this line is newly added.
|
||||
If new_line_number is zero, it means this line is deleted.
|
||||
"""
|
||||
|
||||
def __init__(self, filename):
|
||||
self.filename = filename
|
||||
self.lines = []
|
||||
|
||||
def add_new_line(self, line_number, line):
|
||||
self.lines.append((0, line_number, line))
|
||||
|
||||
def add_deleted_line(self, line_number, line):
|
||||
self.lines.append((line_number, 0, line))
|
||||
|
||||
def add_unchanged_line(self, deleted_line_number, new_line_number, line):
|
||||
self.lines.append((deleted_line_number, new_line_number, line))
|
||||
|
||||
|
||||
class DiffParser:
|
||||
"""A parser for a patch file.
|
||||
|
||||
The field "files" is a dict whose key is the filename and value is
|
||||
a DiffFile object.
|
||||
"""
|
||||
|
||||
def __init__(self, diff_input):
|
||||
"""Parses a diff.
|
||||
|
||||
Args:
|
||||
diff_input: An iterable object.
|
||||
"""
|
||||
state = _INITIAL_STATE
|
||||
|
||||
self.files = {}
|
||||
current_file = None
|
||||
old_diff_line = None
|
||||
new_diff_line = None
|
||||
for line in diff_input:
|
||||
line = line.rstrip("\n")
|
||||
if state == _INITIAL_STATE:
|
||||
transform_line = get_diff_converter(line)
|
||||
line = transform_line(line)
|
||||
|
||||
file_declaration = match(r"^Index: (?P<FilePath>.+)", line)
|
||||
if file_declaration:
|
||||
filename = file_declaration.group('FilePath')
|
||||
current_file = DiffFile(filename)
|
||||
self.files[filename] = current_file
|
||||
state = _DECLARED_FILE_PATH
|
||||
continue
|
||||
|
||||
lines_changed = match(r"^@@ -(?P<OldStartLine>\d+)(,\d+)? \+(?P<NewStartLine>\d+)(,\d+)? @@", line)
|
||||
if lines_changed:
|
||||
if state != _DECLARED_FILE_PATH and state != _PROCESSING_CHUNK:
|
||||
logging.error('Unexpected line change without file path declaration: %r' % line)
|
||||
old_diff_line = int(lines_changed.group('OldStartLine'))
|
||||
new_diff_line = int(lines_changed.group('NewStartLine'))
|
||||
state = _PROCESSING_CHUNK
|
||||
continue
|
||||
|
||||
if state == _PROCESSING_CHUNK:
|
||||
if line.startswith('+'):
|
||||
current_file.add_new_line(new_diff_line, line[1:])
|
||||
new_diff_line += 1
|
||||
elif line.startswith('-'):
|
||||
current_file.add_deleted_line(old_diff_line, line[1:])
|
||||
old_diff_line += 1
|
||||
elif line.startswith(' '):
|
||||
current_file.add_unchanged_line(old_diff_line, new_diff_line, line[1:])
|
||||
old_diff_line += 1
|
||||
new_diff_line += 1
|
||||
elif line == '\\ No newline at end of file':
|
||||
# Nothing to do. We may still have some added lines.
|
||||
pass
|
||||
else:
|
||||
logging.error('Unexpected diff format when parsing a chunk: %r' % line)
|
|
@ -1 +0,0 @@
|
|||
# Required for Python to search this directory for module files
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,180 +0,0 @@
|
|||
# Copyright (C) 2009 Google Inc. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following disclaimer
|
||||
# in the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Google Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
"""WebKit's Python module for interacting with patches."""
|
||||
|
||||
import logging
|
||||
import re
|
||||
|
||||
|
||||
_regexp_compile_cache = {}
|
||||
|
||||
|
||||
def match(pattern, string):
|
||||
"""Matches the string with the pattern, caching the compiled regexp."""
|
||||
if not pattern in _regexp_compile_cache:
|
||||
_regexp_compile_cache[pattern] = re.compile(pattern)
|
||||
return _regexp_compile_cache[pattern].match(string)
|
||||
|
||||
|
||||
def git_diff_to_svn_diff(line):
|
||||
"""Converts a git formatted diff line to a svn formatted line.
|
||||
|
||||
Args:
|
||||
line: A string representing a line of the diff.
|
||||
"""
|
||||
conversion_patterns = (("^diff --git a/(.+) b/(?P<FilePath>.+)", lambda matched: "Index: " + matched.group('FilePath') + "\n"),
|
||||
("^new file.*", lambda matched: "\n"),
|
||||
("^index [0-9a-f]{7}\.\.[0-9a-f]{7} [0-9]{6}", lambda matched: "===================================================================\n"),
|
||||
("^--- a/(?P<FilePath>.+)", lambda matched: "--- " + matched.group('FilePath') + "\n"),
|
||||
("^\+\+\+ b/(?P<FilePath>.+)", lambda matched: "+++ " + matched.group('FilePath') + "\n"))
|
||||
|
||||
for pattern, conversion in conversion_patterns:
|
||||
matched = match(pattern, line)
|
||||
if matched:
|
||||
return conversion(matched)
|
||||
return line
|
||||
|
||||
|
||||
def get_diff_converter(first_diff_line):
|
||||
"""Gets a converter function of diff lines.
|
||||
|
||||
Args:
|
||||
first_diff_line: The first filename line of a diff file.
|
||||
If this line is git formatted, we'll return a
|
||||
converter from git to SVN.
|
||||
"""
|
||||
if match(r"^diff --git a/", first_diff_line):
|
||||
return git_diff_to_svn_diff
|
||||
return lambda input: input
|
||||
|
||||
|
||||
_INITIAL_STATE = 1
|
||||
_DECLARED_FILE_PATH = 2
|
||||
_PROCESSING_CHUNK = 3
|
||||
|
||||
|
||||
class DiffFile:
|
||||
"""Contains the information for one file in a patch.
|
||||
|
||||
The field "lines" is a list which contains tuples in this format:
|
||||
(deleted_line_number, new_line_number, line_string)
|
||||
If deleted_line_number is zero, it means this line is newly added.
|
||||
If new_line_number is zero, it means this line is deleted.
|
||||
"""
|
||||
|
||||
def __init__(self, filename):
|
||||
self.filename = filename
|
||||
self.lines = []
|
||||
|
||||
def add_new_line(self, line_number, line):
|
||||
self.lines.append((0, line_number, line))
|
||||
|
||||
def add_deleted_line(self, line_number, line):
|
||||
self.lines.append((line_number, 0, line))
|
||||
|
||||
def add_unchanged_line(self, deleted_line_number, new_line_number, line):
|
||||
self.lines.append((deleted_line_number, new_line_number, line))
|
||||
|
||||
|
||||
class DiffParser:
|
||||
"""A parser for a patch file.
|
||||
|
||||
The field "files" is a dict whose key is the filename and value is
|
||||
a DiffFile object.
|
||||
"""
|
||||
|
||||
def __init__(self, diff_input):
|
||||
"""Parses a diff.
|
||||
|
||||
Args:
|
||||
diff_input: An iterable object.
|
||||
"""
|
||||
state = _INITIAL_STATE
|
||||
|
||||
self.files = {}
|
||||
self.status_line = None
|
||||
self.patch_description = None
|
||||
current_file = None
|
||||
old_diff_line = None
|
||||
new_diff_line = None
|
||||
for line in diff_input:
|
||||
line = line.rstrip("\n")
|
||||
if state == _INITIAL_STATE:
|
||||
transform_line = get_diff_converter(line)
|
||||
line = transform_line(line)
|
||||
|
||||
comment_line = match(r"^\#", line)
|
||||
if comment_line:
|
||||
continue
|
||||
|
||||
file_declaration = match(r"^Index: (?P<FilePath>.+)", line)
|
||||
if file_declaration:
|
||||
filename = file_declaration.group('FilePath')
|
||||
current_file = DiffFile(filename)
|
||||
self.files[filename] = current_file
|
||||
state = _DECLARED_FILE_PATH
|
||||
continue
|
||||
|
||||
lines_changed = match(r"^@@ -(?P<OldStartLine>\d+)(,\d+)? \+(?P<NewStartLine>\d+)(,\d+)? @@", line)
|
||||
if lines_changed:
|
||||
if state != _DECLARED_FILE_PATH and state != _PROCESSING_CHUNK:
|
||||
logging.error('Unexpected line change without file path declaration: %r' % line)
|
||||
old_diff_line = int(lines_changed.group('OldStartLine'))
|
||||
new_diff_line = int(lines_changed.group('NewStartLine'))
|
||||
state = _PROCESSING_CHUNK
|
||||
continue
|
||||
|
||||
if state == _PROCESSING_CHUNK:
|
||||
if line.startswith('+'):
|
||||
current_file.add_new_line(new_diff_line, line[1:])
|
||||
new_diff_line += 1
|
||||
elif line.startswith('-'):
|
||||
current_file.add_deleted_line(old_diff_line, line[1:])
|
||||
old_diff_line += 1
|
||||
elif line.startswith(' '):
|
||||
current_file.add_unchanged_line(old_diff_line, new_diff_line, line[1:])
|
||||
old_diff_line += 1
|
||||
new_diff_line += 1
|
||||
elif line == '\\ No newline at end of file':
|
||||
# Nothing to do. We may still have some added lines.
|
||||
pass
|
||||
else:
|
||||
logging.error('Unexpected diff format when parsing a chunk: %r' % line)
|
||||
|
||||
# Patch description
|
||||
if state == _INITIAL_STATE:
|
||||
if not self.status_line:
|
||||
self.status_line = line
|
||||
else:
|
||||
if not self.patch_description:
|
||||
# Skip the first blank line after the patch description
|
||||
if line != "":
|
||||
self.patch_description = line
|
||||
else:
|
||||
self.patch_description = self.patch_description + "\n" + line
|
|
@ -1,39 +0,0 @@
|
|||
# Copyright (c) 2009, Google Inc. All rights reserved.
|
||||
# Copyright (c) 2009 Apple Inc. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following disclaimer
|
||||
# in the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Google Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# WebKit's Python module for logging
|
||||
|
||||
import sys
|
||||
|
||||
def log(string):
|
||||
print >> sys.stderr, string
|
||||
|
||||
def error(string):
|
||||
log("ERROR: " + string)
|
||||
exit(1)
|
|
@ -1,420 +0,0 @@
|
|||
# Copyright (c) 2009, Google Inc. All rights reserved.
|
||||
# Copyright (c) 2009 Apple Inc. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following disclaimer
|
||||
# in the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Google Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# Python module for interacting with an SCM system (like SVN or Git)
|
||||
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
# Import WebKit-specific modules.
|
||||
from modules.logging import error, log
|
||||
|
||||
def detect_scm_system(path):
|
||||
if HG.in_working_directory(path):
|
||||
return HG(cwd=path)
|
||||
|
||||
if SVN.in_working_directory(path):
|
||||
return SVN(cwd=path)
|
||||
|
||||
if Git.in_working_directory(path):
|
||||
return Git(cwd=path)
|
||||
|
||||
raise ScriptError("working directory is not a HG/SVN/Git repo")
|
||||
|
||||
def first_non_empty_line_after_index(lines, index=0):
|
||||
first_non_empty_line = index
|
||||
for line in lines[index:]:
|
||||
if re.match("^\s*$", line):
|
||||
first_non_empty_line += 1
|
||||
else:
|
||||
break
|
||||
return first_non_empty_line
|
||||
|
||||
|
||||
class CommitMessage:
|
||||
def __init__(self, message):
|
||||
self.message_lines = message[first_non_empty_line_after_index(message, 0):]
|
||||
|
||||
def body(self, lstrip=False):
|
||||
lines = self.message_lines[first_non_empty_line_after_index(self.message_lines, 1):]
|
||||
if lstrip:
|
||||
lines = [line.lstrip() for line in lines]
|
||||
return "\n".join(lines) + "\n"
|
||||
|
||||
def description(self, lstrip=False, strip_url=False):
|
||||
line = self.message_lines[0]
|
||||
if lstrip:
|
||||
line = line.lstrip()
|
||||
if strip_url:
|
||||
line = re.sub("^(\s*)<.+> ", "\1", line)
|
||||
return line
|
||||
|
||||
def message(self):
|
||||
return "\n".join(self.message_lines) + "\n"
|
||||
|
||||
def parse_bug_id(self):
|
||||
for line in self.message_lines:
|
||||
match = re.search("http\://webkit\.org/b/(?P<bug_id>\d+)", line)
|
||||
if match:
|
||||
return match.group('bug_id')
|
||||
match = re.search(Bugzilla.bug_server_regex + "show_bug\.cgi\?id=(?P<bug_id>\d+)", line)
|
||||
if match:
|
||||
return match.group('bug_id')
|
||||
return None
|
||||
|
||||
|
||||
class ScriptError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class SCM:
|
||||
def __init__(self, cwd, dryrun=False):
|
||||
self.cwd = cwd
|
||||
self.checkout_root = self.find_checkout_root(self.cwd)
|
||||
self.dryrun = dryrun
|
||||
|
||||
@staticmethod
|
||||
def run_command(args, cwd=None, input=None, raise_on_failure=True, return_exit_code=False):
|
||||
stdin = subprocess.PIPE if input else None
|
||||
process = subprocess.Popen(args, stdout=subprocess.PIPE, stdin=stdin, cwd=cwd)
|
||||
output = process.communicate(input)[0].rstrip()
|
||||
exit_code = process.wait()
|
||||
if raise_on_failure and exit_code:
|
||||
raise ScriptError('Failed to run "%s" exit_code: %d cwd: %s' % (args, exit_code, cwd))
|
||||
if return_exit_code:
|
||||
return exit_code
|
||||
return output
|
||||
|
||||
def script_path(self, script_name):
|
||||
return os.path.join(self.checkout_root, "WebKitTools", "Scripts", script_name)
|
||||
|
||||
def ensure_clean_working_directory(self, force):
|
||||
if not force and not self.working_directory_is_clean():
|
||||
print self.run_command(self.status_command(), raise_on_failure=False)
|
||||
error("Working directory has modifications, pass --force-clean or --no-clean to continue.")
|
||||
|
||||
log("Cleaning working directory")
|
||||
self.clean_working_directory()
|
||||
|
||||
def ensure_no_local_commits(self, force):
|
||||
if not self.supports_local_commits():
|
||||
return
|
||||
commits = self.local_commits()
|
||||
if not len(commits):
|
||||
return
|
||||
if not force:
|
||||
error("Working directory has local commits, pass --force-clean to continue.")
|
||||
self.discard_local_commits()
|
||||
|
||||
def apply_patch(self, patch):
|
||||
# It's possible that the patch was not made from the root directory.
|
||||
# We should detect and handle that case.
|
||||
curl_process = subprocess.Popen(['curl', patch['url']], stdout=subprocess.PIPE)
|
||||
patch_apply_process = subprocess.Popen([self.script_path('svn-apply'), '--reviewer', patch['reviewer']], stdin=curl_process.stdout)
|
||||
|
||||
return_code = patch_apply_process.wait()
|
||||
if return_code:
|
||||
raise ScriptError("Patch %s from bug %s failed to download and apply." % (patch['url'], patch['bug_id']))
|
||||
|
||||
def run_status_and_extract_filenames(self, status_command, status_regexp):
|
||||
filenames = []
|
||||
for line in self.run_command(status_command).splitlines():
|
||||
match = re.search(status_regexp, line)
|
||||
if not match:
|
||||
continue
|
||||
# status = match.group('status')
|
||||
filename = match.group('filename')
|
||||
filenames.append(filename)
|
||||
return filenames
|
||||
|
||||
@staticmethod
|
||||
def in_working_directory(path):
|
||||
raise NotImplementedError, "subclasses must implement"
|
||||
|
||||
@staticmethod
|
||||
def find_checkout_root(path):
|
||||
raise NotImplementedError, "subclasses must implement"
|
||||
|
||||
@staticmethod
|
||||
def commit_success_regexp():
|
||||
raise NotImplementedError, "subclasses must implement"
|
||||
|
||||
def working_directory_is_clean(self):
|
||||
raise NotImplementedError, "subclasses must implement"
|
||||
|
||||
def clean_working_directory(self):
|
||||
raise NotImplementedError, "subclasses must implement"
|
||||
|
||||
def update_webkit(self):
|
||||
raise NotImplementedError, "subclasses must implement"
|
||||
|
||||
def status_command(self):
|
||||
raise NotImplementedError, "subclasses must implement"
|
||||
|
||||
def changed_files(self):
|
||||
raise NotImplementedError, "subclasses must implement"
|
||||
|
||||
def display_name(self):
|
||||
raise NotImplementedError, "subclasses must implement"
|
||||
|
||||
def create_patch(self):
|
||||
raise NotImplementedError, "subclasses must implement"
|
||||
|
||||
def commit_with_message(self, message):
|
||||
raise NotImplementedError, "subclasses must implement"
|
||||
|
||||
# Subclasses must indicate if they support local commits,
|
||||
# but the SCM baseclass will only call local_commits methods when this is true.
|
||||
@staticmethod
|
||||
def supports_local_commits():
|
||||
raise NotImplementedError, "subclasses must implement"
|
||||
|
||||
def create_patch_from_local_commit(self, commit_id):
|
||||
pass
|
||||
|
||||
def commit_locally_with_message(self, message):
|
||||
pass
|
||||
|
||||
def discard_local_commits(self):
|
||||
pass
|
||||
|
||||
def local_commits(self):
|
||||
return []
|
||||
|
||||
|
||||
class SVN(SCM):
|
||||
def __init__(self, cwd, dryrun=False):
|
||||
SCM.__init__(self, cwd, dryrun)
|
||||
self.cached_version = None
|
||||
|
||||
@staticmethod
|
||||
def in_working_directory(path):
|
||||
return os.path.isdir(os.path.join(path, '.svn'))
|
||||
|
||||
@staticmethod
|
||||
def find_uuid(path):
|
||||
if not SVN.in_working_directory(path):
|
||||
return None
|
||||
info = SVN.run_command(['svn', 'info', path])
|
||||
match = re.search("^Repository UUID: (?P<uuid>.+)$", info, re.MULTILINE)
|
||||
if not match:
|
||||
raise ScriptError('svn info did not contain a UUID.')
|
||||
return match.group('uuid')
|
||||
|
||||
@staticmethod
|
||||
def find_checkout_root(path):
|
||||
uuid = SVN.find_uuid(path)
|
||||
# If |path| is not in a working directory, we're supposed to return |path|.
|
||||
if not uuid:
|
||||
return path
|
||||
# Search up the directory hierarchy until we find a different UUID.
|
||||
last_path = None
|
||||
while True:
|
||||
if uuid != SVN.find_uuid(path):
|
||||
return last_path
|
||||
last_path = path
|
||||
(path, last_component) = os.path.split(path)
|
||||
if last_path == path:
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def commit_success_regexp():
|
||||
return "^Committed revision (?P<svn_revision>\d+)\.$"
|
||||
|
||||
def svn_version(self):
|
||||
if not self.cached_version:
|
||||
self.cached_version = self.run_command(['svn', '--version', '--quiet'])
|
||||
|
||||
return self.cached_version
|
||||
|
||||
def working_directory_is_clean(self):
|
||||
return self.run_command(['svn', 'diff']) == ""
|
||||
|
||||
def clean_working_directory(self):
|
||||
self.run_command(['svn', 'revert', '-R', '.'])
|
||||
|
||||
def update_webkit(self):
|
||||
self.run_command(self.script_path("update-webkit"))
|
||||
|
||||
def status_command(self):
|
||||
return ['svn', 'status']
|
||||
|
||||
def changed_files(self):
|
||||
if self.svn_version() > "1.6":
|
||||
status_regexp = "^(?P<status>[ACDMR]).{6} (?P<filename>.+)$"
|
||||
else:
|
||||
status_regexp = "^(?P<status>[ACDMR]).{5} (?P<filename>.+)$"
|
||||
return self.run_status_and_extract_filenames(self.status_command(), status_regexp)
|
||||
|
||||
@staticmethod
|
||||
def supports_local_commits():
|
||||
return False
|
||||
|
||||
def display_name(self):
|
||||
return "svn"
|
||||
|
||||
def create_patch(self):
|
||||
return self.run_command(self.script_path("svn-create-patch"))
|
||||
|
||||
def commit_with_message(self, message):
|
||||
if self.dryrun:
|
||||
return "Dry run, no remote commit."
|
||||
return self.run_command(['svn', 'commit', '-m', message])
|
||||
|
||||
|
||||
# All git-specific logic should go here.
|
||||
class Git(SCM):
|
||||
def __init__(self, cwd, dryrun=False):
|
||||
SCM.__init__(self, cwd, dryrun)
|
||||
|
||||
@classmethod
|
||||
def in_working_directory(cls, path):
|
||||
return cls.run_command(['git', 'rev-parse', '--is-inside-work-tree'], raise_on_failure=False, cwd=path) == "true"
|
||||
|
||||
@classmethod
|
||||
def find_checkout_root(cls, path):
|
||||
# "git rev-parse --show-cdup" would be another way to get to the root
|
||||
(checkout_root, dot_git) = os.path.split(cls.run_command(['git', 'rev-parse', '--git-dir'], cwd=path))
|
||||
# If we were using 2.6 # checkout_root = os.path.relpath(checkout_root, path)
|
||||
if not os.path.isabs(checkout_root): # Sometimes git returns relative paths
|
||||
checkout_root = os.path.join(path, checkout_root)
|
||||
return checkout_root
|
||||
|
||||
@staticmethod
|
||||
def commit_success_regexp():
|
||||
return "^Committed r(?P<svn_revision>\d+)$"
|
||||
|
||||
def discard_local_commits(self):
|
||||
self.run_command(['git', 'reset', '--hard', 'trunk'])
|
||||
|
||||
def local_commits(self):
|
||||
return self.run_command(['git', 'log', '--pretty=oneline', 'HEAD...trunk']).splitlines()
|
||||
|
||||
def working_directory_is_clean(self):
|
||||
return self.run_command(['git', 'diff-index', 'HEAD']) == ""
|
||||
|
||||
def clean_working_directory(self):
|
||||
# Could run git clean here too, but that wouldn't match working_directory_is_clean
|
||||
self.run_command(['git', 'reset', '--hard', 'HEAD'])
|
||||
|
||||
def update_webkit(self):
|
||||
# FIXME: Should probably call update-webkit, no?
|
||||
log("Updating working directory")
|
||||
self.run_command(['git', 'svn', 'rebase'])
|
||||
|
||||
def status_command(self):
|
||||
return ['git', 'status']
|
||||
|
||||
def changed_files(self):
|
||||
status_command = ['git', 'diff', '-r', '--name-status', '-C', '-M', 'HEAD']
|
||||
status_regexp = '^(?P<status>[ADM])\t(?P<filename>.+)$'
|
||||
return self.run_status_and_extract_filenames(status_command, status_regexp)
|
||||
|
||||
@staticmethod
|
||||
def supports_local_commits():
|
||||
return True
|
||||
|
||||
def display_name(self):
|
||||
return "git"
|
||||
|
||||
def create_patch(self):
|
||||
return self.run_command(['git', 'diff', 'HEAD'])
|
||||
|
||||
def commit_with_message(self, message):
|
||||
self.commit_locally_with_message(message)
|
||||
return self.push_local_commits_to_server()
|
||||
|
||||
# Git-specific methods:
|
||||
|
||||
def create_patch_from_local_commit(self, commit_id):
|
||||
return self.run_command(['git', 'diff', commit_id + "^.." + commit_id])
|
||||
|
||||
def commit_locally_with_message(self, message):
|
||||
self.run_command(['git', 'commit', '--all', '-F', '-'], input=message)
|
||||
|
||||
def push_local_commits_to_server(self):
|
||||
if self.dryrun:
|
||||
return "Dry run, no remote commit."
|
||||
return self.run_command(['git', 'svn', 'dcommit'])
|
||||
|
||||
def commit_ids_from_range_arguments(self, args, cherry_pick=False):
|
||||
# First get the commit-ids for the passed in revisions.
|
||||
revisions = self.run_command(['git', 'rev-parse', '--revs-only'] + args).splitlines()
|
||||
|
||||
if cherry_pick:
|
||||
return revisions
|
||||
|
||||
# If we're not cherry picking and were only passed one revision, assume "^revision head" aka "revision..head".
|
||||
if len(revisions) < 2:
|
||||
revisions[0] = "^" + revisions[0]
|
||||
revisions.append("HEAD")
|
||||
|
||||
return self.run_command(['git', 'rev-list'] + revisions).splitlines()
|
||||
|
||||
def commit_message_for_local_commit(self, commit_id):
|
||||
commit_lines = self.run_command(['git', 'cat-file', 'commit', commit_id]).splitlines()
|
||||
|
||||
# Skip the git headers.
|
||||
first_line_after_headers = 0
|
||||
for line in commit_lines:
|
||||
first_line_after_headers += 1
|
||||
if line == "":
|
||||
break
|
||||
return CommitMessage(commit_lines[first_line_after_headers:])
|
||||
|
||||
def files_changed_summary_for_commit(self, commit_id):
|
||||
return self.run_command(['git', 'diff-tree', '--shortstat', '--no-commit-id', commit_id])
|
||||
|
||||
|
||||
# All hg-specific logic should go here.
|
||||
class HG(SCM):
|
||||
def __init__(self, cwd, dryrun=False):
|
||||
SCM.__init__(self, cwd, dryrun)
|
||||
|
||||
@classmethod
|
||||
def in_working_directory(cls, path):
|
||||
return cls.run_command(['hg', 'status'], cwd=path, return_exit_code=True) == 0
|
||||
|
||||
@classmethod
|
||||
def find_checkout_root(cls, path):
|
||||
checkout_root = cls.run_command(['hg', 'root'], cwd=path)
|
||||
return checkout_root
|
||||
|
||||
def status_command(self):
|
||||
return ['hg', 'status']
|
||||
|
||||
def display_name(self):
|
||||
return "hg"
|
||||
|
||||
def create_patch(self):
|
||||
if self.run_command(['hg', 'diff']) != "":
|
||||
sys.stderr.write("Warning: outstanding changes not include in style check.\n")
|
||||
return self.run_command(['hg', 'export', 'tip'])
|
|
@ -1,78 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
#
|
||||
# Any copyright is dedicated to the Public Domain.
|
||||
# http://creativecommons.org/publicdomain/zero/1.0/
|
||||
#
|
||||
|
||||
from __future__ import print_function
|
||||
from modules.scm import detect_scm_system
|
||||
from contextlib import closing
|
||||
import checkmozstyle
|
||||
import os
|
||||
import modules.cpplint as cpplint
|
||||
import StringIO
|
||||
|
||||
TESTS = [
|
||||
# Empty patch
|
||||
{
|
||||
"patch": "tests/test1.patch",
|
||||
"cpp": "tests/test1.cpp",
|
||||
"out": "tests/test1.out"
|
||||
},
|
||||
# Bad header
|
||||
{
|
||||
"patch": "tests/test2.patch",
|
||||
"cpp": "tests/test2.cpp",
|
||||
"out": "tests/test2.out"
|
||||
},
|
||||
# Bad Description
|
||||
{
|
||||
"patch": "tests/test3.patch",
|
||||
"cpp": "tests/test3.cpp",
|
||||
"out": "tests/test3.out"
|
||||
},
|
||||
# readability tests
|
||||
{
|
||||
"patch": "tests/test4.patch",
|
||||
"cpp": "tests/test4.cpp",
|
||||
"out": "tests/test4.out"
|
||||
},
|
||||
# runtime tests
|
||||
{
|
||||
"patch": "tests/test5.patch",
|
||||
"cpp": "tests/test5.cpp",
|
||||
"out": "tests/test5.out"
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
def main():
|
||||
cwd = os.path.abspath('.')
|
||||
scm = detect_scm_system(cwd)
|
||||
cpplint.use_mozilla_styles()
|
||||
(args, flags) = cpplint.parse_arguments([])
|
||||
|
||||
for test in TESTS:
|
||||
with open(test["patch"]) as fh:
|
||||
patch = fh.read()
|
||||
|
||||
with closing(StringIO.StringIO()) as output:
|
||||
cpplint.set_stream(output)
|
||||
checkmozstyle.process_patch(patch, cwd, cwd, scm)
|
||||
result = output.getvalue()
|
||||
|
||||
with open(test["out"]) as fh:
|
||||
expected_output = fh.read()
|
||||
|
||||
test_status = "PASSED"
|
||||
if result != expected_output:
|
||||
test_status = "FAILED"
|
||||
print("TEST " + test["patch"] + " " + test_status)
|
||||
print("Got result:\n" + result + "Expected:\n" + expected_output)
|
||||
else:
|
||||
print("TEST " + test["patch"] + " " + test_status)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -1 +0,0 @@
|
|||
patch:0: Patch does not appear to diff against any file. [patch/notempty] [3]
|
|
@ -1 +0,0 @@
|
|||
Bad patch that doesn't diff any files
|
|
@ -1,3 +0,0 @@
|
|||
int main() {
|
||||
return 0;
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
patch:0: Patch does not have a summary. [patch/nosummary] [3]
|
||||
patch:0: Patch does not have a description. [patch/nodescription] [3]
|
||||
tests/test2.cpp:1: No copyright message found. [legal/copyright] [3]
|
||||
Done processing tests/test2.cpp
|
|
@ -1,9 +0,0 @@
|
|||
# Test
|
||||
diff --git a/tests/test2.cpp b/tests/test2.cpp
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/tests/test2.cpp
|
||||
@@ -0,0 +1,3 @@
|
||||
+int main() {
|
||||
+ return 0;
|
||||
+}
|
|
@ -1,3 +0,0 @@
|
|||
patch:0: Patch summary should begin with 'Bug XXXXX - ' or 'No bug -'. [patch/bugnumber] [3]
|
||||
tests/test2.cpp:1: No copyright message found. [legal/copyright] [3]
|
||||
Done processing tests/test2.cpp
|
|
@ -1,12 +0,0 @@
|
|||
# Test
|
||||
patch summary with no bug number
|
||||
|
||||
Some bogus patch description
|
||||
diff --git a/tests/test2.cpp b/tests/test2.cpp
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/tests/test2.cpp
|
||||
@@ -0,0 +1,3 @@
|
||||
+int main() {
|
||||
+ return 0;
|
||||
+}
|
|
@ -1,40 +0,0 @@
|
|||
class ShouldUseExplicit {
|
||||
// runtime/explicit
|
||||
ShouldUseExplicit(int i);
|
||||
};
|
||||
|
||||
// readability/function
|
||||
int foo(int) {
|
||||
}
|
||||
|
||||
int main() {
|
||||
int i = 0;
|
||||
|
||||
// readability/control_flow
|
||||
// XXX This doesn't trigger it. It needs to be fixed.
|
||||
if (i) {
|
||||
return;
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
|
||||
// whitespace/parens
|
||||
if(i){}
|
||||
|
||||
// readability/casting
|
||||
void* bad = (void*)i;
|
||||
|
||||
// readability/comparison_to_zero
|
||||
if (i == true) {}
|
||||
if (i == false) {}
|
||||
if (i != true) {}
|
||||
if (i != false) {}
|
||||
if (i == NULL) {}
|
||||
if (i != NULL) {}
|
||||
if (i == nullptr) {}
|
||||
if (i != nullptr) {}
|
||||
if (i) {}
|
||||
if (!i) {}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
tests/test4.cpp:1: No copyright message found. [legal/copyright] [3]
|
||||
tests/test4.cpp:3: Single-argument constructors should be marked explicit. [runtime/explicit] [5]
|
||||
tests/test4.cpp:7: All parameters should be named in a function [readability/function] [3]
|
||||
tests/test4.cpp:22: Missing space before ( in if( [whitespace/parens] [5]
|
||||
tests/test4.cpp:22: Missing space before { [whitespace/braces] [5]
|
||||
tests/test4.cpp:25: Using C-style cast. Use reinterpret_cast<void*>(...) instead [readability/casting] [4]
|
||||
tests/test4.cpp:28: Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons. [readability/comparison_to_zero] [5]
|
||||
tests/test4.cpp:29: Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons. [readability/comparison_to_zero] [5]
|
||||
tests/test4.cpp:30: Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons. [readability/comparison_to_zero] [5]
|
||||
tests/test4.cpp:31: Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons. [readability/comparison_to_zero] [5]
|
||||
tests/test4.cpp:32: Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons. [readability/comparison_to_zero] [5]
|
||||
tests/test4.cpp:33: Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons. [readability/comparison_to_zero] [5]
|
||||
Done processing tests/test4.cpp
|
|
@ -1,49 +0,0 @@
|
|||
# Test
|
||||
Bug 12 - patch summary with no bug number
|
||||
|
||||
Some bogus patch description
|
||||
diff --git a/tests/test4.cpp b/tests/test4.cpp
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/tests/test4.cpp
|
||||
@@ -0,0 +1,49 @@
|
||||
+class ShouldUseExplicit {
|
||||
+ // runtime/explicit
|
||||
+ ShouldUseExplicit(int i);
|
||||
+};
|
||||
+
|
||||
+// readability/function
|
||||
+int foo(int) {
|
||||
+}
|
||||
+
|
||||
+int main() {
|
||||
+ int i = 0;
|
||||
+
|
||||
+ // readability/control_flow
|
||||
+ // XXX This doesn't trigger it. It needs to be fixed.
|
||||
+ if (i) {
|
||||
+ return;
|
||||
+ } else {
|
||||
+ i++;
|
||||
+ }
|
||||
+
|
||||
+ // whitespace/parens
|
||||
+ if(i){}
|
||||
+
|
||||
+ // readability/casting
|
||||
+ void* bad = (void*)i;
|
||||
+
|
||||
+ // readability/comparison_to_zero
|
||||
+ if (i == true) {}
|
||||
+ if (i == false) {}
|
||||
+ if (i != true) {}
|
||||
+ if (i != false) {}
|
||||
+ if (i == NULL) {}
|
||||
+ if (i != NULL) {}
|
||||
+ if (i == nullptr) {}
|
||||
+ if (i != nullptr) {}
|
||||
+ if (i) {}
|
||||
+ if (!i) {}
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
|
@ -1,24 +0,0 @@
|
|||
// License bogus
|
||||
|
||||
// runtime/virtual
|
||||
class ShouldHaveVirtualDes {
|
||||
virtual foo();
|
||||
};
|
||||
|
||||
int main() {
|
||||
// runtime/memset
|
||||
memset(blah, sizeof(blah), 0);
|
||||
|
||||
// runtime/rtti
|
||||
dynamic_cast<Derived*>(obj);
|
||||
|
||||
// runtime/sizeof
|
||||
int varname = 0;
|
||||
int mySize = sizeof(int);
|
||||
|
||||
// runtime/threadsafe_fn
|
||||
getpwuid();
|
||||
strtok();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
tests/test5.cpp:4: The class ShouldHaveVirtualDes probably needs a virtual destructor due to having virtual method(s), one declared at line 5. [runtime/virtual] [4]
|
||||
tests/test5.cpp:10: Did you mean "memset(blah, 0, sizeof(blah))"? [runtime/memset] [4]
|
||||
tests/test5.cpp:13: Do not use dynamic_cast<>. If you need to cast within a class hierarchy, use static_cast<> to upcast. Mozilla doesn't support RTTI. [runtime/rtti] [5]
|
||||
tests/test5.cpp:17: Using sizeof(type). Use sizeof(varname) instead if possible [runtime/sizeof] [1]
|
||||
tests/test5.cpp:20: Consider using getpwuid_r(...) instead of getpwuid(...) for improved thread safety. [runtime/threadsafe_fn] [2]
|
||||
tests/test5.cpp:21: Consider using strtok_r(...) instead of strtok(...) for improved thread safety. [runtime/threadsafe_fn] [2]
|
||||
Done processing tests/test5.cpp
|
|
@ -1,33 +0,0 @@
|
|||
# Test
|
||||
Bug 12 - patch summary with no bug number
|
||||
|
||||
Some bogus patch description
|
||||
diff --git a/tests/test5.cpp b/tests/test5.cpp
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/tests/test5.cpp
|
||||
@@ -0,0 +1,24 @@
|
||||
+// License bogus
|
||||
+
|
||||
+// runtime/virtual
|
||||
+class ShouldHaveVirtualDes {
|
||||
+ virtual foo();
|
||||
+};
|
||||
+
|
||||
+int main() {
|
||||
+ // runtime/memset
|
||||
+ memset(blah, sizeof(blah), 0);
|
||||
+
|
||||
+ // runtime/rtti
|
||||
+ dynamic_cast<Derived*>(obj);
|
||||
+
|
||||
+ // runtime/sizeof
|
||||
+ int varname = 0;
|
||||
+ int mySize = sizeof(int);
|
||||
+
|
||||
+ // runtime/threadsafe_fn
|
||||
+ getpwuid();
|
||||
+ strtok();
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
Загрузка…
Ссылка в новой задаче