Skip to content

Commit a244f8a

Browse files
committed
lint, autogen, format: Improve and unify UX
- This commit is ported from: - mlkem-native, commit: 1f40536 - `autogen` prints high-level status updates in addition to the low-level per-file status updates - `autogen` uses color coding like `format` does - `lint` omits GH summary content if GITHUB_STEP_SUMMARY is not set. - format uses color-coded error messages - The color definitions across the scripts have been harmonized Note: We did not port the functional changes from commit 1f40536 due to the divergence between the two project repositories. However, if `synchronize_backends`, `gen_citations_for` or other functions are introduced in the future, we will consider incorporating those changes into mldsa-native. Signed-off-by: willieyz <[email protected]>
1 parent a7c9c15 commit a244f8a

File tree

3 files changed

+178
-49
lines changed

3 files changed

+178
-49
lines changed

scripts/autogen

Lines changed: 59 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,44 @@ montgomery_factor = pow(2, 32, modulus)
2626
# - header guards
2727

2828

29+
# Standard color definitions
30+
GREEN = "\033[32m"
31+
RED = "\033[31m"
32+
BLUE = "\033[94m"
33+
BOLD = "\033[1m"
34+
NORMAL = "\033[0m"
35+
36+
37+
def clear_status_line():
38+
"""Clear any existing status line by overwriting with spaces and returning to start of line"""
39+
print(f"\r{' ' * 160}", end="", flush=True)
40+
41+
2942
def status_update(task, msg):
30-
print(f"\r{'':<140}", end="", flush=True)
31-
print(f"\r[{task}]: {msg} ...", end="", flush=True)
43+
clear_status_line()
44+
print(f"\r{BLUE}[{task}]{NORMAL}: {msg} ...", end="", flush=True)
45+
46+
47+
def high_level_status(msg):
48+
clear_status_line()
49+
print(
50+
f"\r{GREEN}{NORMAL} {msg}"
51+
) # This will end with a newline, clearing the status line
52+
53+
54+
def info(msg):
55+
clear_status_line()
56+
print(f"\r{GREEN}info{NORMAL} {msg}")
57+
58+
59+
def error(msg):
60+
clear_status_line()
61+
print(f"\r{RED}error{NORMAL} {msg}")
62+
63+
64+
def file_updated(filename):
65+
clear_status_line()
66+
print(f"\r{BOLD}updated {filename}{NORMAL}")
3267

3368

3469
def gen_header():
@@ -237,7 +272,7 @@ class CondParser:
237272
return CondParser.print_exp(self.parse_condition(filename, exp))
238273

239274

240-
def adjust_preprocessor_comments_for_filename(content, source_file):
275+
def adjust_preprocessor_comments_for_filename(content, source_file, show_status=False):
241276
"""Automatically add comments to large `#if ... #else ... #endif`
242277
blocks indicating the guarding conditions.
243278
@@ -267,7 +302,8 @@ def adjust_preprocessor_comments_for_filename(content, source_file):
267302
268303
```
269304
"""
270-
status_update("if-else", source_file)
305+
if show_status:
306+
status_update("if-else", source_file)
271307

272308
content = content.split("\n")
273309
new_content = []
@@ -387,7 +423,9 @@ def adjust_preprocessor_comments_for_filename(content, source_file):
387423
def gen_preprocessor_comments_for(source_file, dry_run=False):
388424
with open(source_file, "r") as f:
389425
content = f.read()
390-
new_content = adjust_preprocessor_comments_for_filename(content, source_file)
426+
new_content = adjust_preprocessor_comments_for_filename(
427+
content, source_file, show_status=True
428+
)
391429
update_file(source_file, new_content, dry_run=dry_run)
392430

393431

@@ -399,13 +437,20 @@ def gen_preprocessor_comments(dry_run=False):
399437
)
400438

401439

402-
def update_file(filename, content, dry_run=False, force_format=False):
403-
440+
def update_file(
441+
filename,
442+
content,
443+
dry_run=False,
444+
force_format=False,
445+
skip_preprocessor_comments=False,
446+
):
404447
if force_format is True or filename.endswith((".c", ".h", ".i")):
405-
content = adjust_preprocessor_comments_for_filename(content, filename)
448+
if skip_preprocessor_comments is False:
449+
content = adjust_preprocessor_comments_for_filename(content, filename)
406450
content = format_content(content)
407451

408452
if dry_run is False:
453+
file_updated(filename)
409454
with open(filename, "w+") as f:
410455
f.write(content)
411456
else:
@@ -416,11 +461,10 @@ def update_file(filename, content, dry_run=False, force_format=False):
416461
current_content = f.read()
417462
if current_content != content:
418463
filename_new = f"{filename}.new"
419-
print(
420-
f"Autogenerated file {filename} needs updating. Have you called scripts/autogen?",
421-
file=sys.stderr,
464+
error(
465+
f"Autogenerated file {filename} needs updating. Have you called scripts/autogen?"
422466
)
423-
print(f"Writing new version to {filename_new}", file=sys.stderr)
467+
info(f"Writing new version to {filename_new}")
424468
with open(filename_new, "w") as f:
425469
f.write(content)
426470
subprocess.run(["diff", filename, filename_new])
@@ -1035,10 +1079,11 @@ def _main():
10351079
gen_aarch64_rej_uniform_eta_table(args.dry_run)
10361080
gen_avx2_zeta_file(args.dry_run)
10371081
gen_avx2_rej_uniform_table(args.dry_run)
1082+
high_level_status("Generated zeta and lookup tables")
10381083
gen_header_guards(args.dry_run)
1084+
high_level_status("Generated header guards")
10391085
gen_preprocessor_comments(args.dry_run)
1040-
1041-
print()
1086+
high_level_status("Generated preprocessor comments")
10421087

10431088

10441089
if __name__ == "__main__":

scripts/format

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,40 +10,49 @@ set -o pipefail
1010
# consts
1111
ROOT="$(realpath "$(dirname "$0")"/../)"
1212

13-
GREEN="$(tput setaf 2)"
14-
NORMAL="$(tput sgr0)"
13+
# Standard color definitions
14+
GREEN="\033[32m"
15+
RED="\033[31m"
16+
BLUE="\033[94m"
17+
BOLD="\033[1m"
18+
NORMAL="\033[0m"
1519

1620
# utility
1721
info()
1822
{
19-
printf "%s %b\n" "${GREEN}info" "${NORMAL}${*}"
23+
printf "%b %b\n" "${GREEN}info" "${NORMAL}${*}"
24+
}
25+
26+
error()
27+
{
28+
printf "%b %b\n" "${RED}error" "${NORMAL}${*}"
2029
}
2130

2231
info "Formatting nix files"
2332
if ! command -v nixpkgs-fmt 2>&1 >/dev/null; then
24-
echo "nixpkgs-fmt not found. Are you running in a nix shell? See BUILDING.md."
33+
error "nixpkgs-fmt not found. Are you running in a nix shell? See BUILDING.md."
2534
exit 1
2635
fi
2736

2837
nixpkgs-fmt "$ROOT"
2938

3039
info "Formatting shell scripts"
3140
if ! command -v shfmt 2>&1 >/dev/null; then
32-
echo "shfmt not found. Are you running in a nix shell? See BUILDING.md."
41+
error "shfmt not found. Are you running in a nix shell? See BUILDING.md."
3342
exit 1
3443
fi
3544
shfmt -s -w -l -i 2 -ci -fn $(shfmt -f $(git grep -l '' :/))
3645

3746
info "Formatting python scripts"
3847
if ! command -v black 2>&1 >/dev/null; then
39-
echo "black not found. Are you running in a nix shell? See BUILDING.md."
48+
error "black not found. Are you running in a nix shell? See BUILDING.md."
4049
exit 1
4150
fi
4251
black --include "(scripts/tests|scripts/simpasm|scripts/autogen|scripts/check-namespace|\.py$)" "$ROOT"
4352

4453
info "Formatting c files"
4554
if ! command -v clang-format 2>&1 >/dev/null; then
46-
echo "clang-format not found. Are you running in a nix shell? See BUILDING.md."
55+
error "clang-format not found. Are you running in a nix shell? See BUILDING.md."
4756
exit 1
4857
fi
4958

scripts/lint

Lines changed: 103 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,29 @@ set -o pipefail
1111
ROOT="$(realpath "$(dirname "$0")"/../)"
1212
GITHUB_STEP_SUMMARY=${GITHUB_STEP_SUMMARY:-/dev/stdout}
1313

14+
# Check if we're in GitHub context
15+
IN_GITHUB_CONTEXT=false
16+
if [[ $GITHUB_STEP_SUMMARY != "/dev/stdout" ]]; then
17+
IN_GITHUB_CONTEXT=true
18+
fi
19+
20+
# Standard color definitions
21+
GREEN="\033[32m"
22+
RED="\033[31m"
23+
BLUE="\033[94m"
24+
BOLD="\033[1m"
25+
NORMAL="\033[0m"
26+
27+
info()
28+
{
29+
printf "%b %b\n" "${GREEN}" "${NORMAL}${*}"
30+
}
31+
32+
error()
33+
{
34+
printf "%b %b\n" "${RED}" "${NORMAL}${*}"
35+
}
36+
1437
checkerr()
1538
{
1639
local code=$?
@@ -22,44 +45,92 @@ checkerr()
2245
fi
2346

2447
if [[ ${#out} != 0 ]]; then
25-
echo "$out" | while read -r file line; do
26-
echo "::error file=$file,line=${line:-1},title=Format error::$file require to be formatted"
27-
done
48+
if $IN_GITHUB_CONTEXT; then
49+
echo "$out" | while read -r file line; do
50+
echo "::error file=$file,line=${line:-1},title=Format error::$file require to be formatted"
51+
done
52+
fi
2853
success=false
2954
fi
3055

3156
if $success; then
32-
echo ":white_check_mark: $title" >>"$GITHUB_STEP_SUMMARY"
57+
info "$title"
58+
gh_summary_success "$title"
3359
else
60+
error "$title"
3461
SUCCESS=false
35-
echo ":x: $title" >>"$GITHUB_STEP_SUMMARY"
62+
gh_summary_failure "$title"
63+
fi
64+
}
65+
66+
gh_group_start()
67+
{
68+
if $IN_GITHUB_CONTEXT; then
69+
echo "::group::$1"
70+
fi
71+
}
72+
73+
gh_group_end()
74+
{
75+
if $IN_GITHUB_CONTEXT; then
76+
echo "::endgroup::"
77+
fi
78+
}
79+
80+
gh_summary_success()
81+
{
82+
if $IN_GITHUB_CONTEXT; then
83+
echo ":white_check_mark: $1" >>"$GITHUB_STEP_SUMMARY"
84+
fi
85+
}
86+
87+
gh_summary_failure()
88+
{
89+
if $IN_GITHUB_CONTEXT; then
90+
echo ":x: $1" >>"$GITHUB_STEP_SUMMARY"
91+
fi
92+
}
93+
94+
gh_error()
95+
{
96+
if $IN_GITHUB_CONTEXT; then
97+
echo "::error file=$1,line=${2:-1},title=$3::$4"
98+
fi
99+
}
100+
101+
gh_error_simple()
102+
{
103+
if $IN_GITHUB_CONTEXT; then
104+
echo "::error title=$1::$2"
36105
fi
37106
}
38107

39108
# Formatting
40109
SUCCESS=true
41110

42-
echo "::group::Linting nix files with nixpkgs-fmt"
111+
gh_group_start "Linting nix files with nixpkgs-fmt"
43112
checkerr "Lint nix" "$(nixpkgs-fmt --check "$ROOT")"
44-
echo "::endgroup::"
113+
gh_group_end
45114

46-
#echo "::group::Linting shell scripts with shfmt"
115+
#gh_group_start "Linting shell scripts with shfmt"
47116
#checkerr "Lint shell" "$(shfmt -s -l -i 2 -ci -fn $(shfmt -f $(git grep -l '' :/)))"
48-
#echo "::endgroup::"
117+
#gh_group_end
49118

50-
echo "::group::Linting python scripts with black"
119+
gh_group_start "Linting python scripts with black"
51120
if ! diff=$(black --check --diff -q --include "(scripts/tests|scripts/simpasm|scripts/autogen|scripts/check-namespace|\.py$)" "$ROOT"); then
52-
echo "::error title=Format error::$diff"
121+
gh_error_simple "Format error" "$diff"
122+
error "Lint python"
53123
SUCCESS=false
54-
echo ":x: Lint python" >>"$GITHUB_STEP_SUMMARY"
124+
gh_summary_failure "Lint python"
55125
else
56-
echo ":white_check_mark: Lint Python" >>"$GITHUB_STEP_SUMMARY"
126+
info "Lint Python"
127+
gh_summary_success "Lint Python"
57128
fi
58-
echo "::endgroup::"
129+
gh_group_end
59130

60-
echo "::group::Linting c files with clang-format"
131+
gh_group_start "Linting c files with clang-format"
61132
checkerr "Lint C" "$(clang-format $(git ls-files ":/*.c" ":/*.h") --Werror --dry-run 2>&1 | grep "error:" | cut -d ':' -f 1,2 | tr ':' ' ')"
62-
echo "::endgroup::"
133+
gh_group_end
63134

64135
check-eol-dry-run()
65136
{
@@ -71,52 +142,56 @@ check-eol-dry-run()
71142
fi
72143
done
73144
}
74-
echo "::group::Checking eol"
145+
gh_group_start "Checking eol"
75146
checkerr "Check eol" "$(check-eol-dry-run)"
76-
echo "::endgroup::"
147+
gh_group_end
77148

78149
check-spdx()
79150
{
80151
local success=true
81152
for file in $(git ls-files -- ":/" ":/!:*.json" ":/!:*.png" ":/!:*LICENSE*" ":/!:.git*" ":/!:flake.lock"); do
82153
# Ignore symlinks
83154
if [[ ! -L $file && $(grep "SPDX-License-Identifier:" $file | wc -l) == 0 ]]; then
84-
echo "::error file=$file,line=${line:-1},title=Missing license header error::$file is missing SPDX License header"
155+
gh_error "$file" "${line:-1}" "Missing license header error" "$file is missing SPDX License header"
85156
success=false
86157
fi
87158
done
88159
for file in $(git ls-files -- "*.[chsS]" "*.py" ":/!proofs/cbmc/*.py"); do
89160
# Ignore symlinks
90161
if [[ ! -L $file && $(grep "Copyright (c) The mldsa-native project authors" $file | wc -l) == 0 ]]; then
91-
echo "::error file=$file,line=${line:-1},title=Missing copyright header error::$file is missing copyright header"
162+
gh_error "$file" "${line:-1}" "Missing copyright header error" "$file is missing copyright header"
92163
success=false
93164
fi
94165
done
95166

96167
if $success; then
97-
echo ":white_check_mark: Check SPDX + Copyright" >>"$GITHUB_STEP_SUMMARY"
168+
info "Check SPDX + Copyright"
169+
gh_summary_success "Check SPDX + Copyright"
98170
else
171+
error "Check SPDX + Copyright"
99172
SUCCESS=false
100-
echo ":x: Check SPDX + Copyright" >>"$GITHUB_STEP_SUMMARY"
173+
gh_summary_failure "Check SPDX + Copyright"
101174
fi
102175
}
103-
echo "::group::Checking SPDX + Copyright headers"
176+
gh_group_start "Checking SPDX + Copyright headers"
104177
check-spdx
105-
echo "::endgroup::"
178+
gh_group_end
106179

107180
check-autogenerated-files()
108181
{
109182
if python3 $ROOT/scripts/autogen --dry-run; then
110-
echo ":white_check_mark: Check native auto-generated files" >>"$GITHUB_STEP_SUMMARY"
183+
info "Check native auto-generated files"
184+
gh_summary_success "Check native auto-generated files"
111185
else
112-
echo ":x: Check native auto-generated files" >>"$GITHUB_STEP_SUMMARY"
186+
error "Check native auto-generated files"
187+
gh_summary_failure "Check native auto-generated files"
113188
SUCCESS=false
114189
fi
115190
}
116191

117-
echo "::group::Check native auto-generated files"
192+
gh_group_start "Check native auto-generated files"
118193
check-autogenerated-files
119-
echo "::endgroup::"
194+
gh_group_end
120195

121196
if ! $SUCCESS; then
122197
exit 1

0 commit comments

Comments
 (0)