浏览代码

Merge branch 'practracker_regen'

Nick Mathewson 5 年之前
父节点
当前提交
300e7d8c99
共有 3 个文件被更改,包括 77 次插入13 次删除
  1. 3 0
      Makefile.am
  2. 70 12
      scripts/maint/practracker/practracker.py
  3. 4 1
      scripts/maint/practracker/problem.py

+ 3 - 0
Makefile.am

@@ -352,6 +352,9 @@ if USEPYTHON
 	$(PYTHON) $(top_srcdir)/scripts/maint/practracker/practracker.py $(top_srcdir)
 endif
 
+practracker-regen:
+	$(PYTHON) $(top_srcdir)/scripts/maint/practracker/practracker.py --regen $(top_srcdir)
+
 check-docs: all
 	$(PERL) $(top_builddir)/scripts/maint/checkOptionDocs.pl
 

+ 70 - 12
scripts/maint/practracker/practracker.py

@@ -13,9 +13,9 @@ practracker.py should be run with its second argument pointing to the Tor
 top-level source directory like this:
   $ python3 ./scripts/maint/practracker/practracker.py .
 
-The exceptions file is meant to be initialized once with the current state of
-the source code and then get saved in the repository for ever after:
-  $ python3 ./scripts/maint/practracker/practracker.py . > ./scripts/maint/practracker/exceptions.txt
+To regenerate the exceptions file so that it allows all current
+problems in the Tor source, use the --regen flag:
+  $ python3 --regen ./scripts/maint/practracker/practracker.py .
 """
 
 from __future__ import print_function
@@ -120,14 +120,59 @@ def consider_metrics_for_file(fname, f):
 
     return found_new_issues
 
-def main():
-    if (len(sys.argv) != 2):
-        print("Usage:\n\t$ practracker.py <tor topdir>\n\t(e.g. $ practracker.py ~/tor/)")
-        return
+HEADER="""\
+# Welcome to the exceptions file for Tor's best-practices tracker!
+#
+# Each line of this file represents a single violation of Tor's best
+# practices -- typically, a violation that we had before practracker.py
+# first existed.
+#
+# There are three kinds of problems that we recognize right now:
+#   function-size -- a function of more than {MAX_FUNCTION_SIZE} lines.
+#   file-size -- a file of more than {MAX_FILE_SIZE} lines.
+#   include-count -- a file with more than {MAX_INCLUDE_COUNT} #includes.
+#
+# Each line below represents a single exception that practracker should
+# _ignore_. Each line has four parts:
+#  1. The word "problem".
+#  2. The kind of problem.
+#  3. The location of the problem: either a filename, or a
+#     filename:functionname pair.
+#  4. The magnitude of the problem to ignore.
+#
+# So for example, consider this line:
+#    problem file-size /src/core/or/connection_or.c 3200
+#
+# It tells practracker to allow the mentioned file to be up to 3200 lines
+# long, even though ordinarily it would warn about any file with more than
+# {MAX_FILE_SIZE} lines.
+#
+# You can either edit this file by hand, or regenerate it completely by
+# running `make practracker-regen`.
+#
+# Remember: It is better to fix the problem than to add a new exception!
+
+""".format(**globals())
+
+def main(argv):
+    import argparse
+
+    progname = argv[0]
+    parser = argparse.ArgumentParser(prog=progname)
+    parser.add_argument("--regen", action="store_true",
+                        help="Regenerate the exceptions file")
+    parser.add_argument("--exceptions",
+                        help="Override the location for the exceptions file")
+    parser.add_argument("topdir", default=".", nargs="?",
+                        help="Top-level directory for the tor source")
+    args = parser.parse_args(argv[1:])
 
     global TOR_TOPDIR
-    TOR_TOPDIR = sys.argv[1]
-    exceptions_file = os.path.join(TOR_TOPDIR, "scripts/maint/practracker", EXCEPTIONS_FNAME)
+    TOR_TOPDIR = args.topdir
+    if args.exceptions:
+        exceptions_file = args.exceptions
+    else:
+        exceptions_file = os.path.join(TOR_TOPDIR, "scripts/maint/practracker", EXCEPTIONS_FNAME)
 
     # 1) Get all the .c files we care about
     files_list = util.get_tor_c_files(TOR_TOPDIR)
@@ -135,13 +180,26 @@ def main():
     # 2) Initialize problem vault and load an optional exceptions file so that
     # we don't warn about the past
     global ProblemVault
-    ProblemVault = problem.ProblemVault(exceptions_file)
+
+    if args.regen:
+        tmpname = exceptions_file + ".tmp"
+        tmpfile = open(tmpname, "w")
+        sys.stdout = tmpfile
+        sys.stdout.write(HEADER)
+        ProblemVault = problem.ProblemVault()
+    else:
+        ProblemVault = problem.ProblemVault(exceptions_file)
 
     # 3) Go through all the files and report problems if they are not exceptions
     found_new_issues = consider_all_metrics(files_list)
 
+    if args.regen:
+        tmpfile.close()
+        os.rename(tmpname, exceptions_file)
+        sys.exit(0)
+
     # If new issues were found, try to give out some advice to the developer on how to resolve it.
-    if (found_new_issues):
+    if found_new_issues and not args.regen:
         new_issues_str = """\
 FAILURE: practracker found new problems in the code: see warnings above.
 
@@ -155,4 +213,4 @@ See doc/HACKING/HelpfulTools.md for more information on using practracker.\
     sys.exit(found_new_issues)
 
 if __name__ == '__main__':
-    main()
+    main(sys.argv)

+ 4 - 1
scripts/maint/practracker/problem.py

@@ -19,10 +19,13 @@ class ProblemVault(object):
     found in the code, and also the old problems we read from the exception
     file.
     """
-    def __init__(self, exception_fname):
+    def __init__(self, exception_fname=None):
         # Exception dictionary: { problem.key() : Problem object }
         self.exceptions = {}
 
+        if exception_fname == None:
+            return
+
         try:
             with open(exception_fname, 'r') as exception_f:
                 self.register_exceptions(exception_f)