Skip to content

Commit 2328592

Browse files
jimmodpgeorge
authored andcommitted
tools/codeformat.py: Remove git state detection.
This was added to speed up running codeformat.py when only a small number of files are changed, but it breaks running the tool on the master branch. The pre-commit tool handles this correctly, and it's working well in the main repo, so we can remove the special handling. This makes codeformat.py behave identically to the main repository, but without additional code for handling .c/.h files. This work was funded through GitHub Sponsors. Signed-off-by: Jim Mussared <[email protected]>
1 parent 36e74c1 commit 2328592

File tree

1 file changed

+26
-141
lines changed

1 file changed

+26
-141
lines changed

tools/codeformat.py

+26-141
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
# The MIT License (MIT)
66
#
77
# Copyright (c) 2020 Damien P. George
8-
# Copyright (c) 2020 Jim Mussared
8+
# Copyright (c) 2023 Jim Mussared
99
#
1010
# Permission is hereby granted, free of charge, to any person obtaining a copy
1111
# of this software and associated documentation files (the "Software"), to deal
@@ -25,6 +25,9 @@
2525
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2626
# THE SOFTWARE.
2727

28+
# This is based on tools/codeformat.py from the main micropython/micropython
29+
# repository but without support for .c/.h files.
30+
2831
import argparse
2932
import glob
3033
import itertools
@@ -34,9 +37,6 @@
3437

3538
# Relative to top-level repo dir.
3639
PATHS = [
37-
# C
38-
"**/*.[ch]",
39-
# Python
4040
"**/*.py",
4141
]
4242

@@ -45,19 +45,9 @@
4545
# Path to repo top-level dir.
4646
TOP = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
4747

48-
UNCRUSTIFY_CFG = os.path.join(TOP, "tools/uncrustify.cfg")
49-
50-
C_EXTS = (
51-
".c",
52-
".h",
53-
)
5448
PY_EXTS = (".py",)
5549

5650

57-
MAIN_BRANCH = "master"
58-
BASE_BRANCH = os.environ.get("GITHUB_BASE_REF", MAIN_BRANCH)
59-
60-
6151
def list_files(paths, exclusions=None, prefix=""):
6252
files = set()
6353
for pattern in paths:
@@ -67,128 +57,33 @@ def list_files(paths, exclusions=None, prefix=""):
6757
return sorted(files)
6858

6959

70-
def fixup_c(filename):
71-
# Read file.
72-
with open(filename) as f:
73-
lines = f.readlines()
74-
75-
# Write out file with fixups.
76-
with open(filename, "w", newline="") as f:
77-
dedent_stack = []
78-
while lines:
79-
# Get next line.
80-
l = lines.pop(0)
81-
82-
# Dedent #'s to match indent of following line (not previous line).
83-
m = re.match(r"( +)#(if |ifdef |ifndef |elif |else|endif)", l)
84-
if m:
85-
indent = len(m.group(1))
86-
directive = m.group(2)
87-
if directive in ("if ", "ifdef ", "ifndef "):
88-
l_next = lines[0]
89-
indent_next = len(re.match(r"( *)", l_next).group(1))
90-
if indent - 4 == indent_next and re.match(r" +(} else |case )", l_next):
91-
# This #-line (and all associated ones) needs dedenting by 4 spaces.
92-
l = l[4:]
93-
dedent_stack.append(indent - 4)
94-
else:
95-
# This #-line does not need dedenting.
96-
dedent_stack.append(-1)
97-
else:
98-
if dedent_stack[-1] >= 0:
99-
# This associated #-line needs dedenting to match the #if.
100-
indent_diff = indent - dedent_stack[-1]
101-
assert indent_diff >= 0
102-
l = l[indent_diff:]
103-
if directive == "endif":
104-
dedent_stack.pop()
105-
106-
# Write out line.
107-
f.write(l)
108-
109-
assert not dedent_stack, filename
110-
111-
112-
def query_git_files(verbose):
113-
def cmd_result_set(cmd):
114-
ret = subprocess.run(cmd, capture_output=True).stdout.strip().decode()
115-
if not ret:
116-
return set()
117-
return {f.strip() for f in ret.split("\n")}
118-
119-
def rel_paths(files, root):
120-
return {os.path.relpath(os.path.join(root, f.strip()), ".") for f in files}
121-
122-
try:
123-
ret = set()
124-
125-
# get path to root of repository
126-
root_dir = (
127-
subprocess.run(["git", "rev-parse", "--show-toplevel"], capture_output=True)
128-
.stdout.strip()
129-
.decode()
130-
)
131-
132-
# Check locally modified files
133-
status = cmd_result_set(["git", "status", "--porcelain"])
134-
dirty_files = rel_paths({line.split(" ", 1)[-1] for line in status}, root_dir)
135-
ret |= dirty_files
136-
137-
# Current commit and branch
138-
current_commit = (
139-
subprocess.run(["git", "rev-parse", "HEAD"], capture_output=True)
140-
.stdout.strip()
141-
.decode()
142-
)
143-
current_branches = cmd_result_set(["git", "branch", "--contains", current_commit])
144-
if MAIN_BRANCH in current_branches:
145-
if ret:
146-
if verbose:
147-
print("Local changes detected, only scanning them.")
148-
return ret
149-
150-
# We're on clean master, run on entire repo
151-
if verbose:
152-
print("Scanning whole repository")
153-
return None
154-
155-
# List the files modified on current branch
156-
if verbose:
157-
print("Scanning changes from current branch and any local changes")
158-
files_on_branch = rel_paths(
159-
cmd_result_set(["git", "diff", "--name-only", BASE_BRANCH]), root_dir
160-
)
161-
ret |= files_on_branch
162-
return ret
163-
except:
164-
# Git not available, run on entire repo
165-
return None
166-
167-
16860
def main():
169-
cmd_parser = argparse.ArgumentParser(description="Auto-format C and Python files.")
170-
cmd_parser.add_argument("-c", action="store_true", help="Format C code only")
171-
cmd_parser.add_argument("-p", action="store_true", help="Format Python code only")
61+
cmd_parser = argparse.ArgumentParser(description="Auto-format Python files.")
17262
cmd_parser.add_argument("-v", action="store_true", help="Enable verbose output")
17363
cmd_parser.add_argument(
174-
"files",
175-
nargs="*",
176-
help="Run on specific globs. If not specied current branch changes will be used",
64+
"-f",
65+
action="store_true",
66+
help="Filter files provided on the command line against the default list of files to check.",
17767
)
68+
cmd_parser.add_argument("files", nargs="*", help="Run on specific globs")
17869
args = cmd_parser.parse_args()
17970

180-
# Setting only one of -c or -p disables the other. If both or neither are set, then do both.
181-
format_c = args.c or not args.p
182-
format_py = args.p or not args.c
183-
18471
# Expand the globs passed on the command line, or use the default globs above.
18572
files = []
18673
if args.files:
18774
files = list_files(args.files)
75+
if args.f:
76+
# Filter against the default list of files. This is a little fiddly
77+
# because we need to apply both the inclusion globs given in PATHS
78+
# as well as the EXCLUSIONS, and use absolute paths
79+
files = set(os.path.abspath(f) for f in files)
80+
all_files = set(list_files(PATHS, EXCLUSIONS, TOP))
81+
if args.v: # In verbose mode, log any files we're skipping
82+
for f in files - all_files:
83+
print("Not checking: {}".format(f))
84+
files = list(files & all_files)
18885
else:
189-
files = query_git_files(verbose=args.v)
190-
if not files:
191-
files = list_files(PATHS, EXCLUSIONS, TOP)
86+
files = list_files(PATHS, EXCLUSIONS, TOP)
19287

19388
# Extract files matching a specific language.
19489
def lang_files(exts):
@@ -204,23 +99,13 @@ def batch(cmd, files, N=200):
20499
break
205100
subprocess.check_call(cmd + file_args)
206101

207-
# Format C files with uncrustify.
208-
if format_c:
209-
command = ["uncrustify", "-c", UNCRUSTIFY_CFG, "-lC", "--no-backup"]
210-
if not args.v:
211-
command.append("-q")
212-
batch(command, lang_files(C_EXTS))
213-
for file in lang_files(C_EXTS):
214-
fixup_c(file)
215-
216102
# Format Python files with black.
217-
if format_py:
218-
command = ["black", "--fast", "--line-length=99"]
219-
if args.v:
220-
command.append("-v")
221-
else:
222-
command.append("-q")
223-
batch(command, lang_files(PY_EXTS))
103+
command = ["black", "--fast", "--line-length=99"]
104+
if args.v:
105+
command.append("-v")
106+
else:
107+
command.append("-q")
108+
batch(command, lang_files(PY_EXTS))
224109

225110

226111
if __name__ == "__main__":

0 commit comments

Comments
 (0)