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 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
# Copyright 2025 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import os
# Runs PRESUBMIT.py in py3 mode by git cl presubmit.
USE_PYTHON3 = True
DEBUG = False
API_FILE = 'chrome/browser/resources/glic/glic_api/glic_api.ts'
TRIGGERING_FILE_PREFIXES = [
'chrome/browser/resources/glic/glic_api/',
'chrome/browser/resources/glic/presubmit/',
]
def CheckApiChangesAreBackwardsCompatible(input_api, output_api, api_file,
on_upload):
"""
Sets up a temporary directory with a copy of the glic_api.ts before
modification, and a tsconfig.json file to build
chrome/browser/resources/glic/presubmit/check_api_compatibility.ts.
"""
skip_compatibility_check = (
'Bypass-Glic-Api-Compatibility-Check'
in input_api.change.GitFootersFromDescription())
if skip_compatibility_check:
return []
src_root = input_api.os_path.join(os.getcwd(), '../../../../')
tmp_dir = input_api.tempfile.TemporaryDirectory()
tmp_dir_name = tmp_dir.name
# For debugging, use a temporary directory that won't be deleted.
if DEBUG:
tmp_dir_name = input_api.tempfile.mkdtemp()
# If API_FILE was modified, get its old contents. Otherwise, use its current
# contents to confirm any modified checks still pass.
if api_file:
old_contents = '\n'.join(api_file.OldContents())
else:
with open(input_api.os_path.join(src_root, API_FILE), 'r') as f:
old_contents = f.read()
with open(input_api.os_path.join(tmp_dir_name, 'old_glic_api.ts'),
'w') as oldfile:
oldfile.write(old_contents)
tsconfig_path = input_api.os_path.join(tmp_dir_name, 'tsconfig.json')
with open(input_api.os_path.join(tmp_dir_name, 'tsconfig.json'),
'w') as tsconfigfile:
tsconfigfile.write('''{
"extends": "$ROOT/chrome/browser/resources/glic/presubmit/tsconfig.json",
"compilerOptions": {
"baseUrl": "$ROOT",
"paths": {
"@tmp/*": ["$TMP/*"]
}
}
}
'''.replace("$TMP",
tmp_dir_name.replace('\\',
'/')).replace('$ROOT',
src_root.replace('\\', '/')))
message = (
'** Your changelist is a backwards-incompatible Glic API change!\n' +
'** Did you add a non-optional field or function, or change the\n' +
'** type of an existing field or function?\n' +
'** Please fix, or add Bypass-Glic-Api-Compatibility-Check: <reason>' +
' to your changelist description if this is intended. Error:\n ')
tsc_cmd = [
input_api.python_executable,
input_api.os_path.join(src_root, 'third_party/node/node.py'),
input_api.os_path.join(
src_root, 'third_party/node/node_modules/typescript/bin/tsc'),
'--noEmit', '-p', tsconfig_path
]
if DEBUG:
print('Running', ' '.join(tsc_cmd))
try:
input_api.subprocess.check_output(tsc_cmd,
stderr=input_api.subprocess.STDOUT)
except input_api.subprocess.CalledProcessError as e:
message = message + e.output.decode('utf-8')
if on_upload:
return [output_api.PresubmitPromptWarning(message)]
else:
return [output_api.PresubmitError(message)]
return []
def CheckApiChangesAreBackwardsCompatibleIfModified(input_api, output_api,
on_upload):
os_path = input_api.os_path
api_file_affected = None
need_api_check = False
results = []
for f in input_api.AffectedFiles():
if any([
os_path.normcase(f.LocalPath()).startswith(
os_path.normcase(prefix))
for prefix in TRIGGERING_FILE_PREFIXES
]):
need_api_check = True
if f.LocalPath() == API_FILE:
api_file_affected = f
break
if need_api_check:
results.extend(
CheckApiChangesAreBackwardsCompatible(input_api, output_api,
api_file_affected,
on_upload))
return results
def CheckChangeOnUpload(input_api, output_api):
return CheckApiChangesAreBackwardsCompatibleIfModified(
input_api, output_api, True)
def CheckChangeOnCommit(input_api, output_api):
return CheckApiChangesAreBackwardsCompatibleIfModified(
input_api, output_api, False)
|