blob: 2249a179623d7a96e5984bc66cf6c158a146200e [file] [log] [blame]
#!/usr/bin/env python3
# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
# fix_trailing_whitespace.py script ensures that all files passed into it satisfy
# various requirements in terms of whitespace:
# - There is no leading whitespace in the file.
# - Lines do not have trailing non-newline whitespace and have UNIX-style line endings.
# - The file ends in a single newline.
import argparse
import sys
import subprocess
from pathlib import Path
# This file is $REPO_TOP/util/fix_trailing_newlines.py, so it takes two parent()
# calls to get back to the top.
REPO_TOP = Path(__file__).resolve().parent.parent
def is_ignored(path):
return subprocess.run(['git', 'check-ignore', path]).returncode == 0
def walk_tree(paths=[REPO_TOP]):
for path in paths:
if isinstance(path, str):
path = Path(path)
if path.is_symlink() or is_ignored(path) or 'LICENSE' in path.parts:
continue
if path.is_dir() and 'vendor' not in path.parts:
yield from walk_tree(path.iterdir())
else:
yield path
def main():
parser = argparse.ArgumentParser()
parser.add_argument(
'--dry-run',
action='store_true',
help='report writes which would have happened')
parser.add_argument(
'--recursive', '-r',
action='store_true',
default=False,
help='traverse the entire tree modolo .gitignore'
)
parser.add_argument(
'--verbose', '-v',
action='store_true',
help='verbose output')
parser.add_argument(
'files',
type=str,
nargs='*',
help='files to fix whitespace for')
args = parser.parse_args()
files = args.files
if args.recursive:
files = walk_tree(args.files)
total_fixable = 0
for path in files:
path = Path(path).resolve().relative_to(REPO_TOP)
if not path.is_file() or path.is_symlink():
continue
if 'vendor' in path.parts or path.suffix in ['.patch', '.svg', '.tpl']:
continue
if args.verbose:
print(f'Checking: "{path}"')
try:
old_text = path.read_text()
except UnicodeDecodeError:
print(f'Binary file: "{path}"')
continue
new_text = "\n".join([line.rstrip() for line in old_text.strip().split("\n")]) + "\n"
if old_text != new_text:
print(f'Fixing file: "{path}"', file=sys.stdout)
total_fixable += 1
if not args.dry_run:
path.write_text(new_text)
if total_fixable:
verb = 'Would have fixed' if args.dry_run else 'Fixed'
print(f'{verb} {total_fixable} files.', file=sys.stderr)
# Pass if we fixed everything or there was nothing to fix.
return 1 if total_fixable > 0 else 0
if __name__ == '__main__':
sys.exit(main())