1*61046927SAndroid Build Coastguard Worker#!/usr/bin/env python3 2*61046927SAndroid Build Coastguard Worker 3*61046927SAndroid Build Coastguard Workerimport argparse 4*61046927SAndroid Build Coastguard Workerimport pathlib 5*61046927SAndroid Build Coastguard Workerimport re 6*61046927SAndroid Build Coastguard Worker 7*61046927SAndroid Build Coastguard Worker 8*61046927SAndroid Build Coastguard Workerdef detect_misleading_indentation( 9*61046927SAndroid Build Coastguard Worker toml_path: str, 10*61046927SAndroid Build Coastguard Worker toml_lines: list[str], 11*61046927SAndroid Build Coastguard Worker) -> bool: 12*61046927SAndroid Build Coastguard Worker issue_detected = False 13*61046927SAndroid Build Coastguard Worker previous_indentation = 0 14*61046927SAndroid Build Coastguard Worker for line_number, line in enumerate(toml_lines, start=1): 15*61046927SAndroid Build Coastguard Worker if match := re.match(r'^(\s*)\S', line): 16*61046927SAndroid Build Coastguard Worker line_indentation = len(match.group(1)) 17*61046927SAndroid Build Coastguard Worker if line_indentation < previous_indentation: 18*61046927SAndroid Build Coastguard Worker # Allow de-indenting when starting a new section (`[`) or 19*61046927SAndroid Build Coastguard Worker # terminating a multi-line list (`]`) 20*61046927SAndroid Build Coastguard Worker if not re.match(r'^\s*(\[|\])', line): 21*61046927SAndroid Build Coastguard Worker print(f'{toml_path}:{line_number}: ' 22*61046927SAndroid Build Coastguard Worker f'Misleading indentation found') 23*61046927SAndroid Build Coastguard Worker issue_detected = True 24*61046927SAndroid Build Coastguard Worker else: 25*61046927SAndroid Build Coastguard Worker line_indentation = 0 26*61046927SAndroid Build Coastguard Worker previous_indentation = line_indentation 27*61046927SAndroid Build Coastguard Worker 28*61046927SAndroid Build Coastguard Worker return issue_detected 29*61046927SAndroid Build Coastguard Worker 30*61046927SAndroid Build Coastguard Worker 31*61046927SAndroid Build Coastguard Workerdef main(): 32*61046927SAndroid Build Coastguard Worker parser = argparse.ArgumentParser() 33*61046927SAndroid Build Coastguard Worker parser.add_argument( 34*61046927SAndroid Build Coastguard Worker 'toml_files', 35*61046927SAndroid Build Coastguard Worker type=pathlib.Path, 36*61046927SAndroid Build Coastguard Worker nargs=argparse.ZERO_OR_MORE, 37*61046927SAndroid Build Coastguard Worker help='*.toml files to lint (default: src/**/ci/*.toml)', 38*61046927SAndroid Build Coastguard Worker ) 39*61046927SAndroid Build Coastguard Worker 40*61046927SAndroid Build Coastguard Worker args = parser.parse_args() 41*61046927SAndroid Build Coastguard Worker 42*61046927SAndroid Build Coastguard Worker if not args.toml_files: 43*61046927SAndroid Build Coastguard Worker args.toml_files = pathlib.Path('src').glob('**/ci/*.toml') 44*61046927SAndroid Build Coastguard Worker 45*61046927SAndroid Build Coastguard Worker error = False 46*61046927SAndroid Build Coastguard Worker 47*61046927SAndroid Build Coastguard Worker for path in args.toml_files: 48*61046927SAndroid Build Coastguard Worker with path.open('r') as toml_file: 49*61046927SAndroid Build Coastguard Worker toml_lines = toml_file.readlines() 50*61046927SAndroid Build Coastguard Worker if detect_misleading_indentation(path.as_posix(), toml_lines): 51*61046927SAndroid Build Coastguard Worker error = True 52*61046927SAndroid Build Coastguard Worker 53*61046927SAndroid Build Coastguard Worker if error: 54*61046927SAndroid Build Coastguard Worker exit(1) 55*61046927SAndroid Build Coastguard Worker 56*61046927SAndroid Build Coastguard Worker 57*61046927SAndroid Build Coastguard Workerif __name__ == '__main__': 58*61046927SAndroid Build Coastguard Worker main() 59