From 56193efea282b72912934160fd8eb97df775de61 Mon Sep 17 00:00:00 2001 From: Martin Taibr Date: Tue, 19 Sep 2017 23:18:51 +0200 Subject: [PATCH] script to uncrustify files not modified on branches --- qcsrc/tools/uncrustify-unmodified.py | 80 ++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100755 qcsrc/tools/uncrustify-unmodified.py diff --git a/qcsrc/tools/uncrustify-unmodified.py b/qcsrc/tools/uncrustify-unmodified.py new file mode 100755 index 000000000..91179f4f1 --- /dev/null +++ b/qcsrc/tools/uncrustify-unmodified.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python3 + +# Finds files that are not modified on any branch and formats them. + +# You should be on master or a branch that just merged master since we want to avoid conflicts when merging other branches into master. + +# If you're on Windows, you probably wanna fix path separators and maybe other tihngs, I am not touching that. + +import glob +import os.path +import shlex +import subprocess + +def main(): + if not os.path.exists("qcsrc"): + # otherwise the files reported by different commands would have different prefixes + print("Must be run in data repo root (xonotic-data.pk3dir)") + return + + # get the latest changes on all branches + run('git fetch') + + # get all remote branches - those would potentially get merge conflicts if we formatted everything + branches = run('git branch --list --remotes') + branches = [b.strip() for b in branches] + branches.remove('origin/HEAD -> origin/master') + branches.remove('origin/master') + + all_files = set(glob.glob("**/*.qc", recursive=True) + glob.glob("**/*.qh", recursive=True)) + all_files = {f for f in all_files if not f.startswith('qcsrc/dpdefs')} + modified_files = set() + + for branch in branches: + print(branch) + + # If some complex branching and merging happens, there can be multiple merge bases. + # The diff between each of them and the tip of the branch can contain changes that are not in master + # and could cause conflicts. + merge_bases = run('git merge-base --all origin/master {}'.format(branch)) + for base in merge_bases: + print("\t", base) + + # with --name-only it shows only the new name when renaming so the order matters + # i guess diff from branch to base should be enough but let's be sure + files1 = set(run('git diff --name-only {} {}'.format(base, branch))) + files2 = set(run('git diff --name-only {} {}'.format(branch, base))) + files = {f for f in files1.union(files2) if f.endswith(".qc") or f.endswith(".qh")} + + for f in sorted(files): + print("\t\t", f) + + modified_files = modified_files.union(files) + + # modified files contain newly added files so the number of remaining files will be larger than all - modified + remaining_files = all_files - modified_files + nonexistent_files = modified_files - all_files + + print("all on master ({}):".format(len(all_files))) + for f in sorted(all_files): + print("\t", f) + + print("modified on branches ({}):".format(len(modified_files))) + for f in sorted(modified_files): + print("\t", f) + + print("modified files that don't exist on master ({}):".format(len(nonexistent_files))) + for f in sorted(nonexistent_files): + print("\t", f) + + print("formatting on master ({}):".format(len(remaining_files))) + for f in sorted(remaining_files): + print("\t", f) + run("bash qcsrc/tools/uncrustify.sh {}".format(shlex.quote(f))) + +def run(cmd: str) -> [str]: + process = subprocess.Popen(shlex.split(cmd), stdin=subprocess.PIPE, stdout=subprocess.PIPE) + stdout, stderr = process.communicate() + return stdout.decode().splitlines() + +main() -- 2.39.2