diff --git a/util/metrics.py b/util/metrics.py index a8a1d85e..55b1612a 100755 --- a/util/metrics.py +++ b/util/metrics.py @@ -1,5 +1,7 @@ #!/usr/bin/env python +from __future__ import print_function + import glob import fnmatch import itertools @@ -10,6 +12,9 @@ TODO_PATTERN = re.compile(r'\s*// TODO:') DOC_PATTERN = re.compile(r'\s*//') EXPECT_PATTERN = re.compile(r'// expect') +C_FORMAT_LINE = "{0:<10} {1:>7} {2:>7} {3:>7} {4:>7} {5:>7} {6:>7} {7:>7}" +WREN_FORMAT_LINE = "{0:<10} {1:>7} {2:>7} {3:>7} {4:>7} {5:>7} {6:>7}" + num_files = 0 num_docs = 0 num_code = 0 @@ -26,64 +31,94 @@ num_benchmark_todos = 0 num_benchmark_empty = 0 num_benchmark = 0 -files = itertools.chain(glob.iglob("src/vm/*.[ch]"), - glob.iglob("src/include/*.[ch]")) -for source_path in files: - num_files += 1 - with open(source_path, "r") as input: - for line in input: - num_semicolons += line.count(';') - match = TODO_PATTERN.match(line) - if match: - num_todos += 1 - continue +def c_metrics(label, directories): + """Reports the metrics of one or more directories of C code.""" + num_files = 0 + num_semicolons = 0 + num_todos = 0 + num_code = 0 + num_docs = 0 + num_empty = 0 - match = DOC_PATTERN.match(line) - if match: - num_docs += 1 - continue + for directory in directories: + files = glob.iglob(directory + "/*.[ch]") + for source_path in files: + num_files += 1 - stripped = line.strip() - # Don't count { or } lines since Wren's coding style puts them on their - # own lines but they don't add anything meaningful to the length of the - # program. - if (stripped == "" or stripped == "{" or stripped == "}"): - num_empty += 1 - continue + with open(source_path, "r") as input: + for line in input: + num_semicolons += line.count(';') + match = TODO_PATTERN.match(line) + if match: + num_todos += 1 + continue - num_code += 1 + match = DOC_PATTERN.match(line) + if match: + num_docs += 1 + continue -for dir_path, dir_names, file_names in os.walk("test"): - for file_name in fnmatch.filter(file_names, "*.wren"): - num_test_files += 1 - with open(os.path.join(dir_path, file_name), "r") as input: - for line in input: - if (line.strip() == ""): - num_test_empty += 1 - else: - num_test += 1 + stripped = line.strip() + # Don't count { or } lines since Wren's coding style puts them on + # their own lines but they don't add anything meaningful to the + # length of the program. + if stripped == "" or stripped == "{" or stripped == "}": + num_empty += 1 + continue - match = TODO_PATTERN.match(line) - if match: - num_test_todos += 1 - continue + num_code += 1 - match = EXPECT_PATTERN.search(line) - if match: - num_expects += 1 - continue + print(C_FORMAT_LINE.format( + label, num_files, num_semicolons, num_todos, num_code, num_docs, + num_empty, num_todos + num_docs + num_empty + num_code)) -print("source:") -print(" files " + str(num_files)) -print(" semicolons " + str(num_semicolons)) -print(" TODOs " + str(num_todos)) -print(" comment lines " + str(num_docs)) -print(" code lines " + str(num_code)) -print(" empty lines " + str(num_empty)) -print("\n") -print("test:") -print(" files " + str(num_test_files)) -print(" TODOs " + str(num_test_todos)) -print(" expectations " + str(num_expects)) -print(" non-empty lines " + str(num_test)) -print(" empty lines " + str(num_test_empty)) + +def wren_metrics(label, directories): + """Reports the metrics of one or more directories of Wren code.""" + num_files = 0 + num_empty = 0 + num_code = 0 + num_todos = 0 + num_expects = 0 + + for directory in directories: + for dir_path, dir_names, file_names in os.walk(directory): + for file_name in fnmatch.filter(file_names, "*.wren"): + num_files += 1 + + with open(os.path.join(dir_path, file_name), "r") as input: + for line in input: + if line.strip() == "": + num_empty += 1 + continue + + match = TODO_PATTERN.match(line) + if match: + num_todos += 1 + continue + + match = EXPECT_PATTERN.search(line) + if match: + num_expects += 1 + continue + + num_code += 1 + + print(WREN_FORMAT_LINE.format( + label, num_files, num_todos, num_code, num_expects, num_empty, + num_todos + num_code + num_expects + num_empty)) + + +print(C_FORMAT_LINE.format( + "", "files", "';'", "todos", "code", "comment", "empty", "total")) +c_metrics("vm", ["src/vm", "src/include"]) +c_metrics("optional", ["src/optional"]) +c_metrics("cli", ["src/cli", "src/module"]) + +print() +print(WREN_FORMAT_LINE.format( + "", "files", "todos", "code", "expects", "empty", "total")) +wren_metrics("core", ["src/vm"]) +wren_metrics("optional", ["src/optional"]) +wren_metrics("cli", ["src/module"]) +wren_metrics("test", ["test"])