| #!/usr/bin/env python3 |
| # Copyright 2021 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| """Linter for *.mojom files.""" |
| |
| import json |
| import os |
| import sys |
| |
| TOP_DIR = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) |
| |
| # Find chromite! |
| sys.path.insert(0, os.path.join(TOP_DIR, '..', '..')) |
| |
| # pylint: disable=wrong-import-position |
| from chromite.lib import commandline |
| from chromite.lib import constants |
| from chromite.lib import cros_build_lib |
| from chromite.lib import git |
| # pylint: enable=wrong-import-position |
| |
| CHECK_STABLE_MOJOM_COMPATIBILITY = os.path.join( |
| constants.SOURCE_ROOT, 'src', 'aosp', 'external', 'libchrome', 'mojo', |
| 'public', 'tools', 'mojom', 'check_stable_mojom_compatibility.py') |
| |
| |
| def GetDiffFiles(from_commit, to_commit): |
| """Returns the changed file list.""" |
| cmd = ['diff', '--name-only', from_commit, to_commit] |
| res = git.RunGit(TOP_DIR, cmd) |
| return res.stdout.splitlines() |
| |
| |
| def GetRenameMap(from_commit, to_commit): |
| """Returns a new name to old name mapping for renamed files.""" |
| cmd = ['diff', '--name-status', '--diff-filter=R', from_commit, to_commit] |
| res = git.RunGit(TOP_DIR, cmd) |
| rename_map = {} |
| for line in res.stdout.splitlines(): |
| tokens = line.split('\t') |
| rename_map[tokens[2]] = tokens[1] |
| return rename_map |
| |
| |
| def GetFileContent(commit, file): |
| """Returns the content of a file in a commit.""" |
| cmd = ['show', f'{commit}:{file}'] |
| res = git.RunGit(TOP_DIR, cmd, check=False) |
| return '' if res.returncode else res.stdout |
| |
| |
| def CheckMojoStable(commit): |
| """Checks if the mojom files follow the stable rules.""" |
| last_commit = f'{commit}^' |
| rename_map = GetRenameMap(last_commit, commit) |
| delta = [] |
| for file in GetDiffFiles(last_commit, commit): |
| if not file.endswith('.mojom'): |
| continue |
| old_file = rename_map.get(file, file) |
| delta.append({ |
| 'filename': file, |
| 'old': GetFileContent(last_commit, old_file), |
| 'new': GetFileContent(commit, file), |
| }) |
| cmd = [CHECK_STABLE_MOJOM_COMPATIBILITY, '--src-root', TOP_DIR] |
| res = cros_build_lib.run(cmd, input=json.dumps(delta), check=False) |
| if res.returncode: |
| cros_build_lib.Die('Please fix the mojom error.') |
| |
| |
| def GetParser(): |
| """Returns an argument parser.""" |
| parser = commandline.ArgumentParser(description=__doc__) |
| parser.add_argument('--commit', |
| required=True, |
| help='The git commit to be checked. ' |
| 'Pass "pre-submit" for the pre-submit check.') |
| return parser |
| |
| |
| def main(argv): |
| parser = GetParser() |
| opts = parser.parse_args(argv) |
| opts.Freeze() |
| |
| # If we are running a pre-submit check, check the HEAD. |
| commit = opts.commit if opts.commit != 'pre-submit' else 'HEAD' |
| return CheckMojoStable(commit) |
| |
| |
| if __name__ == '__main__': |
| commandline.ScriptWrapperMain(lambda _: main) |