utils: checkstyle.py: Factor out common code to new CheckerBase class
The CommitChecker, StyleChecker and Formatter classes duplicate code. Create a new CheckerBase class to factor out common code. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
parent
f028b09b7b
commit
5f7bcd93fd
1 changed files with 51 additions and 89 deletions
|
@ -334,37 +334,57 @@ class Amendment(Commit):
|
|||
class ClassRegistry(type):
|
||||
def __new__(cls, clsname, bases, attrs):
|
||||
newclass = super().__new__(cls, clsname, bases, attrs)
|
||||
if bases:
|
||||
bases[0].subclasses.append(newclass)
|
||||
bases[0].subclasses.sort(key=lambda x: getattr(x, 'priority', 0),
|
||||
reverse=True)
|
||||
if bases and bases[0] != CheckerBase:
|
||||
base = bases[0]
|
||||
|
||||
if not hasattr(base, 'subclasses'):
|
||||
base.subclasses = []
|
||||
base.subclasses.append(newclass)
|
||||
base.subclasses.sort(key=lambda x: getattr(x, 'priority', 0),
|
||||
reverse=True)
|
||||
return newclass
|
||||
|
||||
|
||||
class CheckerBase(metaclass=ClassRegistry):
|
||||
#
|
||||
# Class methods
|
||||
#
|
||||
@classmethod
|
||||
def instances(cls, obj, names):
|
||||
for instance in cls.subclasses:
|
||||
if names and instance.__name__ not in names:
|
||||
continue
|
||||
if instance.supports(obj):
|
||||
yield instance
|
||||
|
||||
@classmethod
|
||||
def supports(cls, obj):
|
||||
if hasattr(cls, 'commit_types'):
|
||||
return type(obj) in cls.commit_types
|
||||
|
||||
if hasattr(cls, 'patterns'):
|
||||
for pattern in cls.patterns:
|
||||
if fnmatch.fnmatch(os.path.basename(obj), pattern):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
def all_patterns(cls):
|
||||
patterns = set()
|
||||
for instance in cls.subclasses:
|
||||
if hasattr(instance, 'patterns'):
|
||||
patterns.update(instance.patterns)
|
||||
|
||||
return patterns
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Commit Checkers
|
||||
#
|
||||
|
||||
class CommitChecker(metaclass=ClassRegistry):
|
||||
subclasses = []
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
#
|
||||
# Class methods
|
||||
#
|
||||
@classmethod
|
||||
def checkers(cls, commit, names):
|
||||
for checker in cls.subclasses:
|
||||
if names and checker.__name__ not in names:
|
||||
continue
|
||||
if checker.supports(commit):
|
||||
yield checker
|
||||
|
||||
@classmethod
|
||||
def supports(cls, commit):
|
||||
return type(commit) in cls.commit_types
|
||||
class CommitChecker(CheckerBase):
|
||||
pass
|
||||
|
||||
|
||||
class CommitIssue(object):
|
||||
|
@ -561,37 +581,8 @@ class TrailersChecker(CommitChecker):
|
|||
# Style Checkers
|
||||
#
|
||||
|
||||
class StyleChecker(metaclass=ClassRegistry):
|
||||
subclasses = []
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
#
|
||||
# Class methods
|
||||
#
|
||||
@classmethod
|
||||
def checkers(cls, filename, names):
|
||||
for checker in cls.subclasses:
|
||||
if names and checker.__name__ not in names:
|
||||
continue
|
||||
if checker.supports(filename):
|
||||
yield checker
|
||||
|
||||
@classmethod
|
||||
def supports(cls, filename):
|
||||
for pattern in cls.patterns:
|
||||
if fnmatch.fnmatch(os.path.basename(filename), pattern):
|
||||
return True
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
def all_patterns(cls):
|
||||
patterns = set()
|
||||
for checker in cls.subclasses:
|
||||
patterns.update(checker.patterns)
|
||||
|
||||
return patterns
|
||||
class StyleChecker(CheckerBase):
|
||||
pass
|
||||
|
||||
|
||||
class StyleIssue(object):
|
||||
|
@ -748,37 +739,8 @@ class ShellChecker(StyleChecker):
|
|||
# Formatters
|
||||
#
|
||||
|
||||
class Formatter(metaclass=ClassRegistry):
|
||||
subclasses = []
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
#
|
||||
# Class methods
|
||||
#
|
||||
@classmethod
|
||||
def formatters(cls, filename, names):
|
||||
for formatter in cls.subclasses:
|
||||
if names and formatter.__name__ not in names:
|
||||
continue
|
||||
if formatter.supports(filename):
|
||||
yield formatter
|
||||
|
||||
@classmethod
|
||||
def supports(cls, filename):
|
||||
for pattern in cls.patterns:
|
||||
if fnmatch.fnmatch(os.path.basename(filename), pattern):
|
||||
return True
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
def all_patterns(cls):
|
||||
patterns = set()
|
||||
for formatter in cls.subclasses:
|
||||
patterns.update(formatter.patterns)
|
||||
|
||||
return patterns
|
||||
class Formatter(CheckerBase):
|
||||
pass
|
||||
|
||||
|
||||
class CLangFormatter(Formatter):
|
||||
|
@ -957,7 +919,7 @@ def check_file(top_level, commit, filename, checkers):
|
|||
after = commit.get_file(filename)
|
||||
|
||||
formatted = after
|
||||
for formatter in Formatter.formatters(filename, checkers):
|
||||
for formatter in Formatter.instances(filename, checkers):
|
||||
formatted = formatter.format(filename, formatted)
|
||||
|
||||
after = after.splitlines(True)
|
||||
|
@ -971,7 +933,7 @@ def check_file(top_level, commit, filename, checkers):
|
|||
|
||||
# Check for code issues not related to formatting.
|
||||
issues = []
|
||||
for checker in StyleChecker.checkers(filename, checkers):
|
||||
for checker in StyleChecker.instances(filename, checkers):
|
||||
checker = checker(after)
|
||||
for hunk in commit_diff:
|
||||
issues += checker.check(hunk.side('to').touched)
|
||||
|
@ -1019,7 +981,7 @@ def check_style(top_level, commit, checkers):
|
|||
issues = 0
|
||||
|
||||
# Apply the commit checkers first.
|
||||
for checker in CommitChecker.checkers(commit, checkers):
|
||||
for checker in CommitChecker.instances(commit, checkers):
|
||||
for issue in checker.check(commit, top_level):
|
||||
print('%s%s%s' % (Colours.fg(Colours.Yellow), issue.msg, Colours.reset()))
|
||||
issues += 1
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue