]>
git.proxmox.com Git - rustc.git/blob - src/etc/tidy.py
1 # Copyright 2010-2014 The Rust Project Developers. See the COPYRIGHT
2 # file at the top-level directory of this distribution and at
3 # http://rust-lang.org/COPYRIGHT.
5 # Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 # http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 # <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 # option. This file may not be copied, modified, or distributed
9 # except according to those terms.
16 from licenseck
import check_license
21 cr_flag
= "ignore-tidy-cr"
22 tab_flag
= "ignore-tidy-tab"
23 linelength_flag
= "ignore-tidy-linelength"
25 interesting_files
= ['.rs', '.py', '.js', '.sh', '.c', '.h']
26 uninteresting_files
= ['miniz.c', 'jquery', 'rust_android_dummy']
30 'src/libcollectionstest',
34 'src/rustc/test_shim',
39 def report_error_name_no(name
, no
, s
):
41 print("%s:%d: %s" % (name
, no
, s
))
46 report_error_name_no(fileinput
.filename(), fileinput
.filelineno(), s
)
50 print("%s:%d: %s" % (fileinput
.filename(),
51 fileinput
.filelineno(),
55 def do_license_check(name
, contents
):
56 if not check_license(name
, contents
):
57 report_error_name_no(name
, 1, "incorrect license")
60 def update_counts(current_name
):
62 global count_other_linted_files
64 _
, ext
= os
.path
.splitext(current_name
)
66 if ext
in interesting_files
:
69 count_other_linted_files
+= 1
72 def interesting_file(f
):
73 if any(x
in f
for x
in uninteresting_files
):
76 return any(os
.path
.splitext(f
)[1] == ext
for ext
in interesting_files
)
79 # Be careful to support Python 2.4, 2.6, and 3.x here!
80 config_proc
= subprocess
.Popen(["git", "config", "core.autocrlf"],
81 stdout
=subprocess
.PIPE
)
82 result
= config_proc
.communicate()[0]
84 true
= "true".encode('utf8')
85 autocrlf
= result
.strip() == true
if result
is not None else False
91 check_linelength
= True
94 print("usage: tidy.py <src-dir>")
100 count_non_blank_lines
= 0
101 count_other_linted_files
= 0
103 file_counts
= {ext
: 0 for ext
in interesting_files
}
106 needs_unstable_attr
= set()
109 for (dirpath
, dirnames
, filenames
) in os
.walk(src_dir
):
110 # Skip some third-party directories
122 'src/rust-installer',
126 dirpath
= os
.path
.normpath(dirpath
)
127 if any(os
.path
.normpath(d
) in dirpath
for d
in skippable_dirs
):
130 file_names
= [os
.path
.join(dirpath
, f
) for f
in filenames
131 if interesting_file(f
)
132 and not f
.endswith("_gen.rs")
138 for line
in fileinput
.input(file_names
,
139 openhook
=fileinput
.hook_encoded("utf-8")):
141 filename
= fileinput
.filename()
143 if "tidy.py" not in filename
:
145 report_err("TODO is deprecated; use FIXME")
146 match
= re
.match(r
'^.*/(\*|/!?)\s*XXX', line
)
148 report_err("XXX is no longer necessary, use FIXME")
149 match
= re
.match(r
'^.*//\s*(NOTE.*)$', line
)
150 if match
and "TRAVIS" not in os
.environ
:
152 if "snap" in m
.lower():
153 report_warn(match
.group(1))
154 match
= re
.match(r
'^.*//\s*SNAP\s+(\w+)', line
)
157 date
, rev
= snapshot
.curr_snapshot_rev()
158 if not hsh
.startswith(rev
):
159 report_err("snapshot out of date (" + date
163 report_warn("unmatched SNAP line: " + line
)
164 search
= re
.search(r
'^#!\[unstable', line
)
166 needs_unstable_attr
.discard(filename
)
172 if linelength_flag
in line
:
173 check_linelength
= False
175 if check_tab
and ('\t' in line
and
176 "Makefile" not in filename
):
177 report_err("tab character")
178 if check_cr
and not autocrlf
and '\r' in line
:
179 report_err("CR character")
180 if line
.endswith(" \n") or line
.endswith("\t\n"):
181 report_err("trailing whitespace")
182 line_len
= len(line
)-2 if autocrlf
else len(line
)-1
184 if check_linelength
and line_len
> cols
:
185 report_err("line longer than %d chars" % cols
)
187 if fileinput
.isfirstline():
188 # This happens at the end of each file except the last.
189 if current_name
!= "":
190 update_counts(current_name
)
191 assert len(current_contents
) > 0
192 do_license_check(current_name
, current_contents
)
194 current_name
= filename
195 current_contents
= ""
198 check_linelength
= True
199 if all(f
not in filename
for f
in stable_whitelist
) and \
200 re
.search(r
'src/.*/lib\.rs', filename
):
201 needs_unstable_attr
.add(filename
)
203 # Put a reasonable limit on the amount of header data we use for
205 if len(current_contents
) < 1000:
206 current_contents
+= line
210 count_non_blank_lines
+= 1
212 if current_name
!= "":
213 update_counts(current_name
)
214 assert len(current_contents
) > 0
215 do_license_check(current_name
, current_contents
)
216 for f
in needs_unstable_attr
:
217 report_error_name_no(f
, 1, "requires unstable attribute")
219 except UnicodeDecodeError as e
:
220 report_err("UTF-8 decoding error " + str(e
))
223 for ext
in sorted(file_counts
, key
=file_counts
.get
, reverse
=True):
224 print("* linted {} {} files".format(file_counts
[ext
], ext
))
225 print("* linted {} other files".format(count_other_linted_files
))
226 print("* total lines of code: {}".format(count_lines
))
227 print("* total non-blank lines of code: {}".format(count_non_blank_lines
))