3 from __future__
import print_function
4 from __future__
import with_statement
19 "New system requirements",
22 "Code simplification and refactoring",
24 "Deprecated features",
25 "Directory authority changes"])
27 NEEDS_SUBCATEGORIES
= set([
44 print("{}:".format(fname
))
45 print("\t{}".format(s
))
47 m
= re
.search(r
'(\d{3,})', os
.path
.basename(fname
))
53 with
open(fname
) as f
:
56 if bugnum
and bugnum
not in contents
:
57 warn("bug number {} does not appear".format(bugnum
))
59 m
= re
.match(r
'^[ ]{2}o ([^\(:]*)([^:]*):', contents
)
61 warn("Header not in format expected. (' o Foo:' or ' o Foo (Bar):')")
62 elif m
.group(1).strip() not in KNOWN_GROUPS
:
63 warn("Unrecognized header: %r" % m
.group(1))
64 elif (m
.group(1) in NEEDS_SUBCATEGORIES
and '(' not in m
.group(2)):
65 warn("Missing subcategory on %r" % m
.group(1))
68 isBug
= ("bug" in m
.group(1).lower() or "fix" in m
.group(1).lower())
72 contents
= " ".join(contents
.split())
74 if re
.search(r
'\#\d{2,}', contents
):
75 warn("Don't use a # before ticket numbers. ('bug 1234' not '#1234')")
77 if isBug
and not re
.search(r
'(\d+)', contents
):
78 warn("Ticket marked as bugfix, but does not mention a number.")
79 elif isBug
and not re
.search(r
'Fixes ([a-z ]*)bugs? (\d+)', contents
):
80 warn("Ticket marked as bugfix, but does not say 'Fixes bug XXX'")
82 if re
.search(r
'[bB]ug (\d+)', contents
):
83 if not re
.search(r
'[Bb]ugfix on ', contents
):
84 warn("Bugfix does not say 'bugfix on X.Y.Z'")
85 elif not re
.search('[fF]ixes ([a-z ]*)bugs? (\d+)((, \d+)* and \d+)?; bugfix on ',
87 warn("Bugfix does not say 'Fixes bug X; bugfix on Y'")
88 elif re
.search('tor-([0-9]+)', contents
):
89 warn("Do not prefix versions with 'tor-'. ('0.1.2', not 'tor-0.1.2'.)")
91 return have_warned
!= []
94 """Walk through the arguments: for directories, yield their contents;
95 for files, just yield the files. Only search one level deep, because
96 that's how the changes directory is laid out."""
99 for item
in os
.listdir(f
):
100 if item
.startswith("."): #ignore dotfiles
102 yield os
.path
.join(f
, item
)
106 if __name__
== '__main__':
108 for fname
in files(sys
.argv
[1:]):
109 if fname
.endswith("~"):