Run Sycek C style checker
[ci.git] / hbuild / checkers / sycek.py
blob6c23c74930a5f70c032a002e8a5817b3c51e17f1
1 #!/usr/bin/env python3
4 # Copyright (c) 2018 Vojtech Horky
5 # All rights reserved.
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions
9 # are met:
11 # - Redistributions of source code must retain the above copyright
12 # notice, this list of conditions and the following disclaimer.
13 # - Redistributions in binary form must reproduce the above copyright
14 # notice, this list of conditions and the following disclaimer in the
15 # documentation and/or other materials provided with the distribution.
16 # - The name of the author may not be used to endorse or promote products
17 # derived from this software without specific prior written permission.
19 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 from hbuild.scheduler import Task
32 import os
34 class SycekBuildTask(Task):
35 def __init__(self):
36 Task.__init__(self, 'tool-build', tool='sycek')
38 def run(self):
39 my_dir = self.ctl.make_temp_dir('build/sycek')
41 # Clone sycek
42 res = self.ctl.run_command([
43 'git',
44 'clone',
45 '--quiet',
46 '--depth', '1',
47 'https://github.com/jxsvoboda/sycek',
48 my_dir
50 if res['failed']:
51 return False
53 # Build sycek
54 res = self.ctl.run_command([
55 'make',
56 ], cwd=my_dir)
57 if res['failed']:
58 return False
60 ret = {
61 'sycek_bin': my_dir + '/ccheck',
64 return ret
66 class SycekCheckTask(Task):
67 def __init__(self):
68 Task.__init__(self, 'sycek-style-check')
70 def check_one_file(self, sycek, root_dir, filename):
71 res = self.ctl.run_command([ sycek, filename ], cwd=root_dir, needs_output=True)
72 if res['failed']:
73 self.ctl.append_line_to_log_file("%s: unexpected error, see above." % filename)
74 return ( False, 0 )
75 issues_count = len(res['output'])
76 if issues_count == 0:
77 self.ctl.append_line_to_log_file("%s: no error." % filename)
78 return ( True, 0 )
79 else:
80 self.ctl.append_line_to_log_file("%s: there were issues, see above." % filename)
81 return ( True, issues_count )
83 def run(self):
84 root_dir = self.ctl.get_dependency_data('dir')
85 sycek_bin = self.ctl.get_dependency_data('sycek_bin')
87 all_okay = True
89 top_dirs = [ 'abi', 'kernel', 'boot', 'uspace' ]
91 files_total = 0
92 files_okay = 0
93 files_failures = 0
94 files_errors = 0
95 issues_total = 0
98 for top_dir in top_dirs:
99 for path_prefix, dirs_ignored, filenames in os.walk(os.path.join(root_dir, top_dir)):
100 path_prefix = os.path.relpath(path_prefix, root_dir)
101 for filename in filenames:
102 is_c_file = filename.endswith('.h') or filename.endswith('.c')
103 if not is_c_file:
104 continue
106 res = self.check_one_file(sycek_bin, root_dir, os.path.join(path_prefix, filename))
107 all_okay = all_okay and res[0]
109 files_total = files_total + 1
110 if res[0]:
111 if res[1] == 0:
112 files_okay = files_okay + 1
113 else:
114 files_failures = files_failures + 1
115 issues_total = issues_total + res[1]
116 else:
117 files_errors = files_errors + 1
119 self.ctl.append_line_to_log_file("")
120 self.ctl.append_line_to_log_file("Sycek C style checker summary")
121 self.ctl.append_line_to_log_file("Files scanned: %d" % files_total)
122 self.ctl.append_line_to_log_file("Files clean: %d" % files_okay)
123 self.ctl.append_line_to_log_file("Files with issues: %d" % files_failures)
124 self.ctl.append_line_to_log_file("Files with errors: %d" % files_errors)
125 self.ctl.append_line_to_log_file("Total issues found: %d" % issues_total)
127 return all_okay