blob: 78e764c9d0a7b86e97c2577ddca49176c80befc3 [file] [log] [blame]
#!/usr/bin/env python3
# Copyright 2021 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Checks that all TODOs refer to a valid bug"""
import sys
import os
# Ensure that this file can import from cobalt root even if run as a script.
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import re
from tools import get_files
# Find the root directory of the cobalt core repository (One directory up from the tools/ directory)
cobalt_root = os.path.abspath(
os.path.join(os.path.join(os.path.dirname(__file__), '..')))
VALID_FORMATS = 'TODO(fxbug.dev/12345): With a colon if a message is present'
SKIP_VALIDATION = [
# TODO(fxbug.dev/93229): Remove statusor symlink files once StatusOr move is done.
'src/lib/statusor/statusor.h', # Symlink to file in src/public/lib/statusor/
'src/lib/statusor/status_macros.h', # Symlink to file in src/public/lib/statusor/
'src/lib/statusor/statusor_internals.h', # Symlink to file in src/public/lib/statusor/
'src/public/lib/statusor/statusor.h', # Copied from external source
'src/pb/report_row.proto', # Copied from external source
]
todo = re.compile(r'TODO\((.*)\)')
valid = re.compile(r'TODO\(((https?://)?(fxb)(ug.dev)?/\d+)\)(: .+|)')
deprecated = re.compile(r'TODO\((https?://fxbug.dev|fxb)/\d+\)')
BOLD = '\033[1m'
END = '\033[0m'
CYAN = '\033[36m'
RED = '\033[91m'
YELLOW = '\033[93m'
def main(should_error=True, strict=True):
source_files = [
os.path.relpath(f, cobalt_root) for f in get_files.files_to_lint(
('.h', '.cc', '.go', '.rs', '.py', '.proto', '.gn', '.gni'),
only_directories=['src', 'keys', 'tools'],
all_files=True)
]
errors = 0
for file in source_files:
if file in SKIP_VALIDATION:
continue
with open(file, 'r') as f:
for i, line in enumerate(f.readlines()):
line = line.strip().replace('\t', ' ')
if match := todo.search(line):
if not valid.search(line):
print(f'{file}:{i+1}')
print(f'{CYAN}{line}{END}')
print(
f"{' ' * match.start(0)}^ {BOLD}{RED}ERROR: TODO must use the format {VALID_FORMATS}.{END}"
)
print()
if should_error:
errors += 1
if deprecated.search(line):
print(f'{file}:{i+1}')
print(f'{CYAN}{line}{END}')
print(
f"{' ' * match.start(0)}^ {BOLD}{YELLOW}WARNING: Using deprecated TODO format. Please use {VALID_FORMATS}.{END}"
)
print()
if strict:
errors += 1
return errors
if __name__ == '__main__':
exit(main())