utils: checkstyle.py: Show location of coding style issue within line
The issue checkers display the line number and line content of each offending line, but don't show the location of the issue within a line. Improve checkstyle by adding a marker that points to the exact location. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
parent
4a7c9ce467
commit
aad5837d70
1 changed files with 26 additions and 14 deletions
|
@ -556,8 +556,9 @@ class StyleChecker(metaclass=ClassRegistry):
|
||||||
|
|
||||||
|
|
||||||
class StyleIssue(object):
|
class StyleIssue(object):
|
||||||
def __init__(self, line_number, line, msg):
|
def __init__(self, line_number, position, line, msg):
|
||||||
self.line_number = line_number
|
self.line_number = line_number
|
||||||
|
self.position = position
|
||||||
self.line = line
|
self.line = line
|
||||||
self.msg = msg
|
self.msg = msg
|
||||||
|
|
||||||
|
@ -584,7 +585,7 @@ class HexValueChecker(StyleChecker):
|
||||||
if value == value.lower():
|
if value == value.lower():
|
||||||
continue
|
continue
|
||||||
|
|
||||||
issues.append(StyleIssue(line_number, line,
|
issues.append(StyleIssue(line_number, match.span(0), line,
|
||||||
f'Use lowercase hex constant {value.lower()}'))
|
f'Use lowercase hex constant {value.lower()}'))
|
||||||
|
|
||||||
return issues
|
return issues
|
||||||
|
@ -623,7 +624,7 @@ class IncludeChecker(StyleChecker):
|
||||||
header_type = 'C compatibility'
|
header_type = 'C compatibility'
|
||||||
header = header[1:] + '.h'
|
header = header[1:] + '.h'
|
||||||
|
|
||||||
issues.append(StyleIssue(line_number, line,
|
issues.append(StyleIssue(line_number, match.span(1), line,
|
||||||
f'{header_type} header <{header}> is preferred'))
|
f'{header_type} header <{header}> is preferred'))
|
||||||
|
|
||||||
return issues
|
return issues
|
||||||
|
@ -641,10 +642,12 @@ class LogCategoryChecker(StyleChecker):
|
||||||
issues = []
|
issues = []
|
||||||
for line_number in line_numbers:
|
for line_number in line_numbers:
|
||||||
line = self.__content[line_number-1]
|
line = self.__content[line_number-1]
|
||||||
if not LogCategoryChecker.log_regex.search(line):
|
match = LogCategoryChecker.log_regex.search(line)
|
||||||
|
if not match:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
issues.append(StyleIssue(line_number, line, 'LOG() should use categories'))
|
issues.append(StyleIssue(line_number, match.span(1), line,
|
||||||
|
'LOG() should use categories'))
|
||||||
|
|
||||||
return issues
|
return issues
|
||||||
|
|
||||||
|
@ -660,8 +663,10 @@ class MesonChecker(StyleChecker):
|
||||||
issues = []
|
issues = []
|
||||||
for line_number in line_numbers:
|
for line_number in line_numbers:
|
||||||
line = self.__content[line_number-1]
|
line = self.__content[line_number-1]
|
||||||
if line.find('\t') != -1:
|
pos = line.find('\t')
|
||||||
issues.append(StyleIssue(line_number, line, 'meson.build should use spaces for indentation'))
|
if pos != -1:
|
||||||
|
issues.append(StyleIssue(line_number, [pos, pos], line,
|
||||||
|
'meson.build should use spaces for indentation'))
|
||||||
return issues
|
return issues
|
||||||
|
|
||||||
|
|
||||||
|
@ -681,7 +686,7 @@ class Pep8Checker(StyleChecker):
|
||||||
ret = subprocess.run(['pycodestyle', '--ignore=E501', '-'],
|
ret = subprocess.run(['pycodestyle', '--ignore=E501', '-'],
|
||||||
input=data, stdout=subprocess.PIPE)
|
input=data, stdout=subprocess.PIPE)
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
issues.append(StyleIssue(0, None, 'Please install pycodestyle to validate python additions'))
|
issues.append(StyleIssue(0, None, None, 'Please install pycodestyle to validate python additions'))
|
||||||
return issues
|
return issues
|
||||||
|
|
||||||
results = ret.stdout.decode('utf-8').splitlines()
|
results = ret.stdout.decode('utf-8').splitlines()
|
||||||
|
@ -693,7 +698,7 @@ class Pep8Checker(StyleChecker):
|
||||||
|
|
||||||
if line_number in line_numbers:
|
if line_number in line_numbers:
|
||||||
line = self.__content[line_number - 1]
|
line = self.__content[line_number - 1]
|
||||||
issues.append(StyleIssue(line_number, line, msg))
|
issues.append(StyleIssue(line_number, None, line, msg))
|
||||||
|
|
||||||
return issues
|
return issues
|
||||||
|
|
||||||
|
@ -714,7 +719,7 @@ class ShellChecker(StyleChecker):
|
||||||
ret = subprocess.run(['shellcheck', '-Cnever', '-'],
|
ret = subprocess.run(['shellcheck', '-Cnever', '-'],
|
||||||
input=data, stdout=subprocess.PIPE)
|
input=data, stdout=subprocess.PIPE)
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
issues.append(StyleIssue(0, None, 'Please install shellcheck to validate shell script additions'))
|
issues.append(StyleIssue(0, None, None, 'Please install shellcheck to validate shell script additions'))
|
||||||
return issues
|
return issues
|
||||||
|
|
||||||
results = ret.stdout.decode('utf-8').splitlines()
|
results = ret.stdout.decode('utf-8').splitlines()
|
||||||
|
@ -727,11 +732,8 @@ class ShellChecker(StyleChecker):
|
||||||
line = results[nr + 1]
|
line = results[nr + 1]
|
||||||
msg = results[nr + 2]
|
msg = results[nr + 2]
|
||||||
|
|
||||||
# Determined, but not yet used
|
|
||||||
position = msg.find('^') + 1
|
|
||||||
|
|
||||||
if line_number in line_numbers:
|
if line_number in line_numbers:
|
||||||
issues.append(StyleIssue(line_number, line, msg))
|
issues.append(StyleIssue(line_number, None, line, msg))
|
||||||
|
|
||||||
return issues
|
return issues
|
||||||
|
|
||||||
|
@ -973,6 +975,16 @@ def check_file(top_level, commit, filename, checkers):
|
||||||
print('%s+%s%s' % (Colours.fg(Colours.Yellow), issue.line.rstrip(),
|
print('%s+%s%s' % (Colours.fg(Colours.Yellow), issue.line.rstrip(),
|
||||||
Colours.reset()))
|
Colours.reset()))
|
||||||
|
|
||||||
|
if issue.position is not None:
|
||||||
|
# Align the position marker by using the original line with
|
||||||
|
# all characters except for tabs replaced with spaces. This
|
||||||
|
# ensures proper alignment regardless of how the code is
|
||||||
|
# indented.
|
||||||
|
start = issue.position[0]
|
||||||
|
prefix = ''.join([c if c == '\t' else ' ' for c in issue.line[:start]])
|
||||||
|
length = issue.position[1] - start - 1
|
||||||
|
print(' ' + prefix + '^' + '~' * length)
|
||||||
|
|
||||||
return len(formatted_diff) + len(issues)
|
return len(formatted_diff) + len(issues)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue