nodejs/deps/v8/tools/dev/clean-up-feature-flags-in-tests.py
Michaël Zasso 918fe04351
deps: update V8 to 13.6.233.8
PR-URL: https://github.com/nodejs/node/pull/58070
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Darshan Sen <raisinten@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
2025-05-02 15:06:53 +02:00

151 lines
5.1 KiB
Python
Executable File

#!/usr/bin/env python3
# Copyright 2025 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can
# be found in the LICENSE file.
import argparse
import json
import os
from pathlib import Path
import re
import subprocess
import sys
TEST_ROOT = Path(__file__).absolute().parent.parent.parent / 'test'
TEST_SUITES = [
'mjsunit', 'debugger', 'inspector', 'message', 'js-perf-test', 'webkit'
]
TEST_EXTENSIONS = ('.js', '.mjs')
HAS_FLAGS_RE = re.compile("//\\s*Flags:.*\n")
EXTRACT_FLAGS_RE = re.compile("//\\s*Flags:\\s+((--[A-z0-9-_=]+\\s*)+).*")
FEATURE_FLAG_PREFIXES = {
'js': ('--js-', '--js_'),
'harmony': ('--harmony-', '--harmony_'),
'wasm': ('--experimental-wasm-', '--experimental_wasm_')
}
NEG_FEATURE_FLAG_PREFIXES = {
'js': ('--no-js-', '--no_js_'),
'harmony': ('--no-harmony-', '--no_harmony_'),
'wasm': ('--no-experimental-wasm-', '--no_experimental_wasm_')
}
STAGING_FLAGS = {
'js': '--js-staging',
'harmony': '--harmony',
'wasm': '--wasm-staging'
}
SHIPPING_FLAGS = {
'js': '--js-shipping',
'harmony': '--harmony-shipping',
'wasm': '' # Wasm doesn't have a shipping flag
}
parser = argparse.ArgumentParser()
parser.add_argument(
'--outdir', required=True, type=Path, help='build directory with d8')
args = parser.parse_args()
D8 = os.path.join(args.outdir, 'd8')
def raw_flags_to_cli_flags(raw_flags_for_lang):
return {
kind:
set([f'--{flag}' for flag in raw_flags] +
[f"--{flag.replace('_', '-')}" for flag in raw_flags])
for kind, raw_flags in raw_flags_for_lang.items()
}
def get_feature_flags():
p = subprocess.run([D8, '--print-feature-flags-json'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
raw_flags = json.loads(p.stdout)
return {key: raw_flags_to_cli_flags(val) for key, val in raw_flags.items()}
def clean_up_feature_flags(contents, all_flags_by_lang):
# Returns a (bool, string) pair, where the bool says whether the contents
# changed due to a flag being cleaned up.
if not re.search(HAS_FLAGS_RE, contents):
return (False, contents)
dirty = False
cleaned_contents = []
emitted_staging_flags = set()
for line in contents.splitlines():
match = re.search(EXTRACT_FLAGS_RE, line)
if match:
inprogress_flags = set(match.group(1).split())
original_flags = inprogress_flags.copy()
for (lang, lang_flags) in all_flags_by_lang.items():
# Remove staged flags.
inprogress_flags_no_staged = inprogress_flags - lang_flags['staged']
# If any staged flags were removed, emit the staging flag instead. Only
# do so once per file.
if (inprogress_flags_no_staged
!= inprogress_flags) and (lang not in emitted_staging_flags):
inprogress_flags_no_staged.add(STAGING_FLAGS[lang])
emitted_staging_flags.add(lang)
inprogress_flags = inprogress_flags_no_staged
# Remove flags that are shipping.
inprogress_flags -= lang_flags['shipping']
# Heuristically remove flags that look like feature flags (prefixed by
# one of the known prefixes) that don't exist anymore.
for flag in inprogress_flags.copy():
if flag == STAGING_FLAGS[lang] or flag == SHIPPING_FLAGS[lang]:
continue
if flag.startswith(FEATURE_FLAG_PREFIXES[lang]) and (
flag not in lang_flags['in-progress']):
inprogress_flags.remove(flag)
elif flag.startswith(NEG_FEATURE_FLAG_PREFIXES[lang]) and (
f"--{flag[5:]}" not in lang_flags['in-progress']):
inprogress_flags.remove(flag)
if inprogress_flags != original_flags:
dirty = True
if len(inprogress_flags) > 0:
cleaned_contents.append(f"// Flags: {' '.join(inprogress_flags)}")
else:
cleaned_contents.append(line)
else:
cleaned_contents.append(line)
if not dirty:
return (False, contents)
else:
return (True, "\n".join(cleaned_contents) + "\n")
if __name__ == '__main__':
flags = get_feature_flags()
# Walk test files.
for suite_dir in TEST_SUITES:
suite_path = TEST_ROOT / suite_dir
for dirname, dirs, files in os.walk(suite_path, followlinks=True):
for filename in files:
if not filename.endswith(TEST_EXTENSIONS):
continue
abspath = Path(dirname) / filename
encoding = 'utf-8'
with open(abspath, 'rb') as fh:
# We still have some test files that aren't valid UTF-8. But we also
# can't unconditionally use ISO-8859-1, because we also have tests
# that can only be encoded in UTF-8.
try:
contents = fh.read().decode(encoding)
except:
encoding = 'ISO-8859-1'
contents = fh.read().decode(encoding)
contents_changed, contents = clean_up_feature_flags(contents, flags)
if contents_changed:
with open(abspath, 'w', encoding=encoding) as fh:
fh.write(contents)
print(f"Changed flags in {abspath}")
sys.exit(0)