Commit f61ce6b7 authored by Camillo Bruni's avatar Camillo Bruni Committed by V8 LUCI CQ

[tools] Fix deprecation script for mulitple header files

Bug: v8:11165
Change-Id: Ic2c8c6e6b97f279941e8634bc6178511103edbca
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3173676Reviewed-by: 's avatarSathya Gunasekaran  <gsathya@chromium.org>
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/main@{#76988}
parent 9cfab2a7
...@@ -9,6 +9,8 @@ import re ...@@ -9,6 +9,8 @@ import re
import subprocess import subprocess
import sys import sys
from pathlib import Path from pathlib import Path
import logging
from multiprocessing import Pool
RE_GITHASH = re.compile(r"^[0-9a-f]{40}") RE_GITHASH = re.compile(r"^[0-9a-f]{40}")
RE_AUTHOR_TIME = re.compile(r"^author-time (\d+)$") RE_AUTHOR_TIME = re.compile(r"^author-time (\d+)$")
...@@ -18,8 +20,25 @@ VERSION_CACHE = dict() ...@@ -18,8 +20,25 @@ VERSION_CACHE = dict()
RE_VERSION_MAJOR = re.compile(r".*V8_MAJOR_VERSION ([0-9]+)") RE_VERSION_MAJOR = re.compile(r".*V8_MAJOR_VERSION ([0-9]+)")
RE_VERSION_MINOR = re.compile(r".*V8_MINOR_VERSION ([0-9]+)") RE_VERSION_MINOR = re.compile(r".*V8_MINOR_VERSION ([0-9]+)")
RE_MACRO_END = re.compile(r"\);")
RE_DEPRECATE_MACRO = re.compile(r"\(.*?,(.*)\);", re.MULTILINE)
class HeaderFile(object):
def __init__(self, path):
self.path = path
self.blame_list = self.get_blame_list()
def extract_version(hash): @classmethod
def get_api_header_files(clazz, options):
files = subprocess.check_output(
['git', 'ls-tree', '--name-only', '-r', 'HEAD', options.include_dir],
encoding='UTF-8')
files = filter(lambda l: l.endswith('.h'), files.splitlines())
with Pool(processes=24) as pool:
return pool.map(HeaderFile, files)
def extract_version(self, hash):
if hash in VERSION_CACHE: if hash in VERSION_CACHE:
return VERSION_CACHE[hash] return VERSION_CACHE[hash]
if hash == '0000000000000000000000000000000000000000': if hash == '0000000000000000000000000000000000000000':
...@@ -32,10 +51,11 @@ def extract_version(hash): ...@@ -32,10 +51,11 @@ def extract_version(hash):
VERSION_CACHE[hash] = version VERSION_CACHE[hash] = version
return version return version
def get_blame_list(self):
def get_blame(file_path): logging.info(f"blame list for {self.path}")
result = subprocess.check_output( result = subprocess.check_output(
['git', 'blame', '-t', '--line-porcelain', file_path], encoding='UTF-8') ['git', 'blame', '-t', '--line-porcelain', self.path],
encoding='UTF-8')
line_iter = iter(result.splitlines()) line_iter = iter(result.splitlines())
blame_list = list() blame_list = list()
current_blame = None current_blame = None
...@@ -56,8 +76,8 @@ def get_blame(file_path): ...@@ -56,8 +76,8 @@ def get_blame(file_path):
continue continue
match = RE_AUTHOR_TIME.match(line) match = RE_AUTHOR_TIME.match(line)
if match: if match:
current_blame['datetime'] = datetime.fromtimestamp(int( current_blame['datetime'] = datetime.fromtimestamp(
match.groups()[0])) int(match.groups()[0]))
continue continue
match = RE_FILENAME.match(line) match = RE_FILENAME.match(line)
if match: if match:
...@@ -67,23 +87,21 @@ def get_blame(file_path): ...@@ -67,23 +87,21 @@ def get_blame(file_path):
blame_list.append(current_blame) blame_list.append(current_blame)
return blame_list return blame_list
def filter_and_print(self, macro, options):
RE_MACRO_END = re.compile(r"\);")
RE_DEPRECATE_MACRO = re.compile(r"\(.*?,(.*)\);", re.MULTILINE)
def filter_and_print(blame_list, macro, options):
before = options.before before = options.before
index = 0 index = 0
re_macro = re.compile(macro) re_macro = re.compile(macro)
deprecated = list() deprecated = list()
while index < len(blame_list): while index < len(self.blame_list):
blame = blame_list[index] blame = self.blame_list[index]
line = blame['content']
if line.startswith("#") or line.startswith("//"):
index += 1
continue
commit_datetime = blame['datetime'] commit_datetime = blame['datetime']
if commit_datetime >= before: if commit_datetime >= before:
index += 1 index += 1
continue continue
line = blame['content']
commit_hash = blame['hash'] commit_hash = blame['hash']
match = re_macro.search(line) match = re_macro.search(line)
if match: if match:
...@@ -94,7 +112,7 @@ def filter_and_print(blame_list, macro, options): ...@@ -94,7 +112,7 @@ def filter_and_print(blame_list, macro, options):
if pos >= len(line): if pos >= len(line):
# Extend to next line # Extend to next line
index = index + 1 index = index + 1
blame = blame_list[index] blame = self.blame_list[index]
line = line + blame['content'] line = line + blame['content']
if line[pos] == '(': if line[pos] == '(':
parens = parens + 1 parens = parens + 1
...@@ -111,39 +129,47 @@ def filter_and_print(blame_list, macro, options): ...@@ -111,39 +129,47 @@ def filter_and_print(blame_list, macro, options):
content = line[start:pos].strip().replace('""', '') content = line[start:pos].strip().replace('""', '')
deprecated.append((index + 1, commit_datetime, commit_hash, content)) deprecated.append((index + 1, commit_datetime, commit_hash, content))
index = index + 1 index = index + 1
print(f"# Marked as {macro}: {len(deprecated)}") if len(deprecated) == 0: return
for linenumber, commit_datetime, commit_hash, content in deprecated: for linenumber, commit_datetime, commit_hash, content in deprecated:
commit_date = commit_datetime.date() commit_date = commit_datetime.date()
file_position = ( file_position = (f"{self.path}:{linenumber}").rjust(40)
f"{options.v8_header}:{linenumber}").rjust(len(options.v8_header) + 5)
print(f" {file_position}\t{commit_date}\t{commit_hash[:8]}" print(f" {file_position}\t{commit_date}\t{commit_hash[:8]}"
f"\t{extract_version(commit_hash)}\t{content}") f"\t{self.extract_version(commit_hash)}\t{content}")
return len(deprecated) return len(deprecated)
def parse_options(args): def parse_options(args):
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description="Collect deprecation statistics") description="Collect deprecation statistics")
parser.add_argument("v8_header", nargs='?', help="Path to v8.h") parser.add_argument("include_dir", nargs='?', help="Path to includes dir")
parser.add_argument("--before", help="Filter by date") parser.add_argument("--before", help="Filter by date")
parser.add_argument("--verbose",
"-v",
help="Verbose logging",
action="store_true")
options = parser.parse_args(args) options = parser.parse_args(args)
if options.verbose:
logging.basicConfig(level=logging.DEBUG)
if options.before: if options.before:
options.before = datetime.strptime(options.before, '%Y-%m-%d') options.before = datetime.strptime(options.before, '%Y-%m-%d')
else: else:
options.before = datetime.now() options.before = datetime.now()
if options.v8_header is None: if options.include_dir is None:
base_path = Path(__file__).parent.parent base_path = Path(__file__).parent.parent
options.v8_header = str( options.include_dir = str((base_path / 'include').relative_to(base_path))
(base_path / 'include' / 'v8.h').relative_to(base_path))
return options return options
def main(args): def main(args):
options = parse_options(args) options = parse_options(args)
blame_list = get_blame(options.v8_header) header_files = HeaderFile.get_api_header_files(options)
filter_and_print(blame_list, "V8_DEPRECATE_SOON", options) print("V8_DEPRECATE_SOON:")
for header in header_files:
header.filter_and_print("V8_DEPRECATE_SOON", options)
print("\n") print("\n")
filter_and_print(blame_list, "V8_DEPRECATED", options) print("V8_DEPRECATED:")
for header in header_files:
header.filter_and_print("V8_DEPRECATED", options)
if __name__ == "__main__": if __name__ == "__main__":
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment