| #!/usr/bin/env python3 |
| # Copyright 2022 The Chromium Authors |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| """Uses checkstyle to find unused imports and then removes them.""" |
| |
| import os |
| import pathlib |
| import subprocess |
| import sys |
| |
| import checkstyle |
| |
| _STYLE_FILE = os.path.join(os.path.dirname(__file__), 'unused-imports.xml') |
| |
| |
| def _query_for_java_files(): |
| git_root = subprocess.check_output('git rev-parse --show-toplevel', |
| shell=True, |
| encoding='utf8').strip() |
| result = subprocess.run( |
| ('git diff --name-only -M ' |
| '$(git merge-base @{u} HEAD 2>/dev/null || echo HEAD^)'), |
| capture_output=True, |
| check=True, |
| shell=True, |
| encoding='utf8') |
| paths = (os.path.join(git_root, x) for x in result.stdout.splitlines() |
| if x.endswith('.java')) |
| return [p for p in paths if os.path.exists(p)] |
| |
| |
| def _delete_line(path, line): |
| lines = path.read_text().splitlines(keepends=True) |
| lines.pop(line - 1) |
| # Check if removed last import from an import group. |
| if lines[line - 2:line] == ['\n', '\n']: |
| lines.pop(line - 1) |
| |
| path.write_text(''.join(lines)) |
| |
| def _is_cog(): |
| return os.getcwd().startswith('/google/cog/cloud') |
| |
| def main(): |
| if _is_cog(): |
| print( |
| 'command is not supported in non-git environment. Please ' |
| 'use the "Format Modified Lines in All Files (git cl format)" ' |
| 'functionality in the command palette in the editor instead.', |
| file=sys.stderr) |
| sys.exit(1) |
| |
| java_files = _query_for_java_files() |
| if not java_files: |
| print('There are no changed .java files.') |
| sys.exit(1) |
| os.chdir(checkstyle.CHROMIUM_SRC) |
| violations = checkstyle.run_checkstyle(checkstyle.CHROMIUM_SRC, |
| _STYLE_FILE, java_files) |
| processed = set() |
| for v in sorted(violations, key=lambda x: -x.line): |
| # Guard against multiple warnings on the same line. |
| key = (v.file, v.line) |
| if key not in processed: |
| _delete_line(pathlib.Path(v.file), v.line) |
| processed.add(key) |
| count = len(processed) |
| print(f'Removed {count} unused import{"s" if count != 1 else ""}.') |
| |
| |
| if __name__ == '__main__': |
| main() |