-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtodo_scanner.py
76 lines (60 loc) · 2.53 KB
/
todo_scanner.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import re
import os
import sys
import argparse
from collections import defaultdict
def export_to_txt(dir, todos):
file_name = os.path.basename(dir)
output_path = os.path.join(os.getcwd(), f"{file_name}.txt")
with open(output_path, "w") as f:
for file_path, todo_list in todos.items():
for todo in todo_list:
f.write(f"{file_path}, {todo}\n")
def print_to_cli(todos):
for file_path, todo_list in todos.items():
for todo in todo_list:
print(f"{file_path}, {todo}")
# TODO: add support for multiline comments.
def is_comment(string):
return string in ["//", "#"]
def get_todos(file_paths):
todos = defaultdict(list)
for file_path in file_paths:
with open(file_path, "r") as file:
for line_num, line in enumerate(file.readlines(), start=1):
line = line.rstrip("\n")
tokens = line.split()
if len(tokens) > 2 and is_comment(tokens[0]):
if "todo" in tokens[1].lower():
todos[file_path].append(f"line {line_num}: {' '.join(tokens[2:])}")
return todos
def get_files(dir, extensions):
res = set()
for root, _, files in os.walk(dir):
for file in files:
if os.path.splitext(file)[1] in extensions:
file_path = os.path.join(root, file)
res.add(file_path)
return res
def create_parser():
default_extensions = [".py", ".h", ".cpp", ".java", ".js"]
parser = argparse.ArgumentParser(description="Scan code files for TODO comments")
parser.add_argument("-d", "--dir", help = "The directory to scan files in. Default: current directory.", required = False, default = os.getcwd())
parser.add_argument("-ext", "--extensions", help = f"File extensions to include in the scan. Default: {default_extensions}", nargs="+", required = False, default = default_extensions)
parser.add_argument("-e", "--export", help = "Export todo comments to a text file. Default: False", required = False, action="store_true", default=False)
return parser
def main(args):
# pattern = re.compile(r"^(#\s*todo):\s*")
parser = create_parser()
parsed_args = parser.parse_args(args[1:])
directory = parsed_args.dir
extensions = parsed_args.extensions
should_export = parsed_args.export
file_paths = get_files(directory, extensions)
todos = get_todos(file_paths)
if should_export:
export_to_txt(directory, todos)
else:
print_to_cli(todos)
if __name__ == "__main__":
main(sys.argv)