Skip to content
This repository was archived by the owner on Apr 6, 2022. It is now read-only.

Commit 187a2fc

Browse files
ulfalizernashif
authored andcommitted
check_compliance.py: Remove prepare(), add 'path' class variable, misc.
Simplify check_compliance.py a bit to make it easier to follow, and to make it easier to add new tests: - Store the path printed for each test in a ComplianceTest.path_hint class variable instead of passing it to ComplianceTest.prepare(). Print the "Running <test name> in <path> ..." message in main() instead of in prepare(). Remove ComplianceTest.prepare() and all the calls to it, as it's no longer needed. - Store the commit range in a global COMMIT_RANGE variable, set in main(), instead of passing it to ComplianceTest.prepare() This simplifies ComplianceTest.__init__() to take no args. Use __init__() to initialize ComplianceTest.case, instead of doing it in ComplianceTest.prepare(). - Remove some unused stuff too: * The class variables on the ComplianceTest class itself. Instead, document what class variables subclasses need to set. * The empty ComplianceTest.run(). Document that subclasses need it instead. * The unused ComplianceTest._title variable * The unused 'suite' argument to ComplianceTest.__init__(), which was used to set an unused ComplianceTest.suite variable - Remove the _'s in front of class variables. No other things are marked private, and they're used outside the class. Signed-off-by: Ulf Magnusson <[email protected]>
1 parent 081d80d commit 187a2fc

File tree

1 file changed

+72
-83
lines changed

1 file changed

+72
-83
lines changed

scripts/check_compliance.py

Lines changed: 72 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -87,34 +87,22 @@ class MyCase(TestCase):
8787

8888
class ComplianceTest:
8989
"""
90-
Main Test class
90+
Base class for tests. Inheriting classes should have a run() method and set
91+
these class variables:
9192
92-
"""
93-
94-
_name = ""
95-
_title = ""
96-
_doc = "https://docs.zephyrproject.org/latest/contribute/"
93+
name:
94+
Test name
9795
98-
def __init__(self, suite, commit_range):
99-
self.case = None
100-
self.suite = suite
101-
self.commit_range = commit_range
102-
# get() defaults to None if not present
96+
doc:
97+
Link to documentation related to what's being tested
10398
104-
def prepare(self, where):
105-
"""
106-
Prepare test case
107-
:return:
108-
"""
109-
self.case = MyCase(self._name)
99+
path_hint:
100+
The path the test runs itself in. This is just informative and used in
101+
the message that gets printed when running the test.
102+
"""
103+
def __init__(self):
104+
self.case = MyCase(self.name)
110105
self.case.classname = "Guidelines"
111-
print("Running {:16} tests in {} ...".format(self._name, where))
112-
113-
def run(self):
114-
"""
115-
Run testcase
116-
:return:
117-
"""
118106

119107
def error(self, msg):
120108
"""
@@ -159,7 +147,7 @@ def add_failure(self, msg):
159147
"""
160148
if not self.case.result:
161149
# First reported failure
162-
self.case.result = Failure(self._name + " issues", "failure")
150+
self.case.result = Failure(self.name + " issues", "failure")
163151
self.case.result._elem.text = msg.rstrip()
164152
else:
165153
# If there are multiple Failures, concatenate their messages
@@ -201,19 +189,19 @@ class CheckPatch(ComplianceTest):
201189
Runs checkpatch and reports found issues
202190
203191
"""
204-
_name = "checkpatch"
205-
_doc = "https://docs.zephyrproject.org/latest/contribute/#coding-style"
192+
name = "checkpatch"
193+
doc = "https://docs.zephyrproject.org/latest/contribute/#coding-style"
194+
path_hint = GIT_TOP
206195

207196
def run(self):
208-
self.prepare(GIT_TOP)
209197
# Default to Zephyr's checkpatch if ZEPHYR_BASE is set
210198
checkpatch = os.path.join(ZEPHYR_BASE or GIT_TOP, 'scripts',
211199
'checkpatch.pl')
212200
if not os.path.exists(checkpatch):
213201
self.skip(checkpatch + " not found")
214202

215203
# git diff's output doesn't depend on the current (sub)directory
216-
diff = subprocess.Popen(('git', 'diff', '%s' % (self.commit_range)),
204+
diff = subprocess.Popen(('git', 'diff', COMMIT_RANGE),
217205
stdout=subprocess.PIPE)
218206
try:
219207
subprocess.check_output((checkpatch, '--mailback', '--no-tree', '-'),
@@ -235,12 +223,11 @@ class KconfigCheck(ComplianceTest):
235223
Checks is we are introducing any new warnings/errors with Kconfig,
236224
for example using undefiend Kconfig variables.
237225
"""
238-
_name = "Kconfig"
239-
_doc = "https://docs.zephyrproject.org/latest/guides/kconfig/index.html"
226+
name = "Kconfig"
227+
doc = "https://docs.zephyrproject.org/latest/guides/kconfig/index.html"
228+
path_hint = ZEPHYR_BASE
240229

241230
def run(self):
242-
self.prepare(ZEPHYR_BASE)
243-
244231
kconf = self.parse_kconfig()
245232

246233
self.check_top_menu_not_too_long(kconf)
@@ -500,11 +487,11 @@ class DeviceTreeCheck(ComplianceTest):
500487
"""
501488
Runs the dtlib and edtlib test suites in scripts/dts/.
502489
"""
503-
_name = "Device tree"
504-
_doc = "https://docs.zephyrproject.org/latest/guides/dts/index.html"
490+
name = "Device tree"
491+
doc = "https://docs.zephyrproject.org/latest/guides/dts/index.html"
492+
path_hint = ZEPHYR_BASE
505493

506494
def run(self):
507-
self.prepare(ZEPHYR_BASE)
508495
if not ZEPHYR_BASE:
509496
self.skip("Not a Zephyr tree (ZEPHYR_BASE unset)")
510497

@@ -542,8 +529,9 @@ class Codeowners(ComplianceTest):
542529
"""
543530
Check if added files have an owner.
544531
"""
545-
_name = "Codeowners"
546-
_doc = "https://help.github.com/articles/about-code-owners/"
532+
name = "Codeowners"
533+
doc = "https://help.github.com/articles/about-code-owners/"
534+
path_hint = GIT_TOP
547535

548536
def ls_owned_files(self, codeowners):
549537
"""Returns an OrderedDict mapping git patterns from the CODEOWNERS file
@@ -610,7 +598,6 @@ def git_pattern_to_glob(self, git_pattern):
610598
return ret
611599

612600
def run(self):
613-
self.prepare(GIT_TOP)
614601
# TODO: testing an old self.commit range that doesn't end
615602
# with HEAD is most likely a mistake. Should warn, see
616603
# https://github.com/zephyrproject-rtos/ci-tools/pull/24
@@ -619,9 +606,9 @@ def run(self):
619606
self.skip("CODEOWNERS not available in this repo")
620607

621608
name_changes = git("diff", "--name-only", "--diff-filter=ARCD",
622-
self.commit_range)
609+
COMMIT_RANGE)
623610

624-
owners_changes = git("diff", "--name-only", self.commit_range,
611+
owners_changes = git("diff", "--name-only", COMMIT_RANGE,
625612
"--", codeowners)
626613

627614
if not name_changes and not owners_changes:
@@ -637,7 +624,7 @@ def run(self):
637624
# however if one is missed then it will always be reported as an
638625
# Addition instead.
639626
new_files = git("diff", "--name-only", "--diff-filter=ARC",
640-
self.commit_range).splitlines()
627+
COMMIT_RANGE).splitlines()
641628
logging.debug("New files %s", new_files)
642629

643630
# Convert to pathlib.Path string representation (e.g.,
@@ -674,14 +661,13 @@ class Documentation(ComplianceTest):
674661
Checks if documentation build has generated any new warnings.
675662
676663
"""
677-
_name = "Documentation"
678-
_doc = "https://docs.zephyrproject.org/latest/guides/documentation/index.html"
664+
name = "Documentation"
665+
doc = "https://docs.zephyrproject.org/latest/guides/documentation/index.html"
666+
path_hint = os.getcwd()
679667

680668
DOCS_WARNING_FILE = "doc.warnings"
681669

682670
def run(self):
683-
self.prepare(os.getcwd())
684-
685671
if os.path.exists(self.DOCS_WARNING_FILE) and os.path.getsize(self.DOCS_WARNING_FILE) > 0:
686672
with open(self.DOCS_WARNING_FILE, "rb") as docs_warning:
687673
self.add_failure(docs_warning.read().decode("utf-8"))
@@ -692,15 +678,14 @@ class GitLint(ComplianceTest):
692678
Runs gitlint on the commits and finds issues with style and syntax
693679
694680
"""
695-
_name = "Gitlint"
696-
_doc = "https://docs.zephyrproject.org/latest/contribute/#commit-guidelines"
681+
name = "Gitlint"
682+
doc = "https://docs.zephyrproject.org/latest/contribute/#commit-guidelines"
683+
path_hint = GIT_TOP
697684

698685
def run(self):
699-
self.prepare(GIT_TOP)
700-
701686
# By default gitlint looks for .gitlint configuration only in
702687
# the current directory
703-
proc = subprocess.Popen('gitlint --commits %s' % (self.commit_range),
688+
proc = subprocess.Popen('gitlint --commits ' + COMMIT_RANGE,
704689
stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
705690
shell=True, cwd=GIT_TOP)
706691

@@ -717,18 +702,17 @@ class PyLint(ComplianceTest):
717702
Runs pylint on all .py files, with a limited set of checks enabled. The
718703
configuration is in the pylintrc file.
719704
"""
720-
_name = "pylint"
721-
_doc = "https://www.pylint.org/"
705+
name = "pylint"
706+
doc = "https://www.pylint.org/"
707+
path_hint = GIT_TOP
722708

723709
def run(self):
724-
self.prepare(GIT_TOP)
725-
726710
# Path to pylint configuration file
727711
pylintrc = os.path.join(os.path.dirname(__file__), "pylintrc")
728712

729713
# List of files added/modified by the commit(s).
730714
files = git(
731-
"diff", "--name-only", "--diff-filter=d", self.commit_range, "--",
715+
"diff", "--name-only", "--diff-filter=d", COMMIT_RANGE, "--",
732716
# Skip to work around crash in pylint 2.2.2:
733717
# https://github.com/PyCQA/pylint/issues/2906
734718
":!boards/xtensa/intel_s1000_crb/support/create_board_img.py") \
@@ -780,21 +764,20 @@ class License(ComplianceTest):
780764
Checks for licenses in new files added by the Pull request
781765
782766
"""
783-
_name = "License"
784-
_doc = "https://docs.zephyrproject.org/latest/contribute/#licensing"
767+
name = "License"
768+
doc = "https://docs.zephyrproject.org/latest/contribute/#licensing"
769+
# copyfile() below likely requires that getcwd()==GIT_TOP
770+
path_hint = os.getcwd()
785771

786772
def run(self):
787-
# copyfile() below likely requires that getcwd()==GIT_TOP
788-
self.prepare(os.getcwd())
789-
790773
scancode = "/opt/scancode-toolkit/scancode"
791774
if not os.path.exists(scancode):
792775
self.skip("scancode-toolkit not installed")
793776

794777
os.makedirs("scancode-files", exist_ok=True)
795778
# git diff's output doesn't depend on the current (sub)directory
796779
new_files = git("diff", "--name-only", "--diff-filter=A",
797-
self.commit_range).splitlines()
780+
COMMIT_RANGE).splitlines()
798781

799782
if not new_files:
800783
return
@@ -881,15 +864,14 @@ class Identity(ComplianceTest):
881864
"""
882865
Checks if Emails of author and signed-off messages are consistent.
883866
"""
884-
_name = "Identity/Emails"
885-
_doc = "https://docs.zephyrproject.org/latest/contribute/#commit-guidelines"
867+
name = "Identity/Emails"
868+
doc = "https://docs.zephyrproject.org/latest/contribute/#commit-guidelines"
869+
# git rev-list and git log don't depend on the current (sub)directory
870+
# unless explicited
871+
path_hint = GIT_TOP
886872

887873
def run(self):
888-
# git rev-list and git log don't depend on the current
889-
# (sub)directory unless explicited.
890-
self.prepare(GIT_TOP)
891-
892-
for shaidx in get_shas(self.commit_range):
874+
for shaidx in get_shas(COMMIT_RANGE):
893875
commit = git("log", "--decorate=short", "-n 1", shaidx)
894876
signed = []
895877
author = ""
@@ -951,11 +933,11 @@ def set_pending():
951933
# Sets 'pending' status for all tests for the commit given by --sha
952934

953935
for testcase in ComplianceTest.__subclasses__():
954-
print("Creating pending status for " + testcase._name)
936+
print("Creating pending status for " + testcase.name)
955937
github_commit.create_status(
956-
'pending', testcase._doc,
938+
'pending', testcase.doc,
957939
'Run in progress (build no. {})'.format(build_number),
958-
testcase._name)
940+
testcase.name)
959941

960942
def report_test_results_to_github(suite):
961943
# Reports test results to Github.
@@ -964,7 +946,7 @@ def report_test_results_to_github(suite):
964946

965947
print("reporting results to GitHub")
966948

967-
name2doc = {testcase._name: testcase._doc
949+
name2doc = {testcase.name: testcase.doc
968950
for testcase in ComplianceTest.__subclasses__()}
969951

970952
n_failures = 0
@@ -1170,20 +1152,21 @@ def _main(args):
11701152
# The "real" main(), which is wrapped to catch exceptions and report them
11711153
# to GitHub. Returns the number of test failures.
11721154

1155+
# The commit range passed in --commit, e.g. "HEAD~3"
1156+
global COMMIT_RANGE
1157+
COMMIT_RANGE = args.commits
1158+
11731159
init_logs(args.loglevel)
11741160

11751161
if args.list:
11761162
for testcase in ComplianceTest.__subclasses__():
1177-
print(testcase._name)
1163+
print(testcase.name)
11781164
return 0
11791165

11801166
if args.status:
11811167
set_pending()
11821168
return 0
11831169

1184-
if not args.commits:
1185-
err("No commit range given")
1186-
11871170
# Load saved test results from an earlier run, if requested
11881171
if args.previous_run:
11891172
if not os.path.exists(args.previous_run):
@@ -1204,15 +1187,21 @@ def _main(args):
12041187
suite = TestSuite("Compliance")
12051188

12061189
for testcase in ComplianceTest.__subclasses__():
1207-
test = testcase(suite, args.commits)
1208-
if args.module:
1209-
if test._name not in args.module:
1210-
continue
1211-
elif test._name in args.exclude_module:
1212-
print("Skipping " + test._name)
1190+
# "Modules" and "testcases" are the same thing. Better flags would have
1191+
# been --tests and --exclude-tests or the like, but it's awkward to
1192+
# change now.
1193+
1194+
if args.module and testcase.name not in args.module:
1195+
continue
1196+
1197+
if testcase.name in args.exclude_module:
1198+
print("Skipping " + testcase.name)
12131199
continue
12141200

1201+
test = testcase()
12151202
try:
1203+
print("Running {:16} tests in {} ..."
1204+
.format(test.name, test.path_hint))
12161205
test.run()
12171206
except EndTest:
12181207
pass

0 commit comments

Comments
 (0)