Skip to content

Commit b707b1d

Browse files
fix: remove stray newline from burr/examples symlink target (#748)
* fix: remove stray newline from burr/examples symlink target The burr/examples symlink was committed with target '../examples\n' (12 bytes) instead of '../examples' (11 bytes). Most tools tolerate the trailing newline, but stricter consumers (Java's FileReader via Apache RAT, some Linux extractors of the source tarball) treat '../examples\n' as a literal nonexistent target and fail. Manifested in CI as a RAT crash on the source tarball produced by git-archive: the symlink in the tarball points to '../examples\n', which doesn't resolve, and RAT raises FileNotFoundException trying to read it as a file. Recreate the symlink via 'rm burr/examples && ln -s ../examples burr/examples' to write the correct 11-byte target. * fix: fail license verification when Apache RAT exits non-zero Previously, if RAT crashed partway through scanning (e.g. on the broken burr/examples symlink that motivated this PR), the verify script would print a warning, parse the truncated XML report, find zero unapproved licenses in whatever RAT managed to scan before the crash, and report success. That false green is what hid the symlink corruption when PR #745 merged into main, even though our release-validation workflow technically ran on main. The CI run scanned 14 files (out of ~700), saw RAT exit code 1, swallowed it, and called the build green. Treat any nonzero exit from RAT as a hard failure of license verification. Print the last 25 lines of RAT stderr so the next debug session has the trace immediately. * fix: exclude burr/examples symlink from end-of-file-fixer pre-commit hook end-of-file-fixer mistreats the symlink as a regular text file and appends '\n' to the link target, turning '../examples' (11 bytes) into '../examples\n' (12 bytes). Strict consumers (Apache RAT, Linux tar extractors) then fail to resolve the symlink. This is exactly the bug that motivated PR #748 — without this exclude, the next pre-commit run on a maintainer's machine would silently re-corrupt the symlink. Also exclude trailing-whitespace defensively for the same reason.
1 parent ff76817 commit b707b1d

4 files changed

Lines changed: 22 additions & 5 deletions

File tree

.github/workflows/release-validation.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ permissions:
5252

5353
jobs:
5454
build-artifacts:
55-
name: build-artifacts
55+
name: "Release Validation / build-artifacts"
5656
runs-on: ubuntu-latest
5757
timeout-minutes: 20
5858
outputs:
@@ -133,7 +133,7 @@ jobs:
133133
retention-days: 14
134134

135135
install-and-smoke:
136-
name: install-and-smoke
136+
name: "Release Validation / install-and-smoke"
137137
needs: build-artifacts
138138
runs-on: ubuntu-latest
139139
timeout-minutes: 10

.pre-commit-config.yaml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,17 @@ repos:
3232
rev: v4.5.0
3333
hooks:
3434
- id: trailing-whitespace
35-
# ensures files are either empty or end with a blank line
35+
# burr/examples is a symlink. trailing-whitespace would mangle the
36+
# link target text (treating "../examples" as a "trailing whitespace"
37+
# situation) and break the symlink.
38+
exclude: '^burr/examples$'
39+
# ensures files are either empty or end with a blank line.
40+
# NOTE: burr/examples is excluded — end-of-file-fixer will append "\n"
41+
# to the symlink target turning "../examples" into "../examples\n",
42+
# which makes the symlink unresolvable on strict consumers (Apache RAT
43+
# and several Linux tarball extractors). See PR #748.
3644
- id: end-of-file-fixer
45+
exclude: '^burr/examples$'
3746
# sorts requirements
3847
- id: requirements-txt-fixer
3948
# valid python file

burr/examples

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
../examples
1+
../examples

scripts/verify_apache_artifacts.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,15 @@ def _check_licenses_with_rat(
318318
)
319319

320320
if result.returncode != 0:
321-
print(f" ⚠️ RAT exited with code {result.returncode}")
321+
# A nonzero exit means RAT crashed mid-scan (e.g. on a broken
322+
# symlink). The XML report it produced will be truncated and
323+
# parsing it gives a falsely clean result, so fail hard here.
324+
print(f" ✗ RAT exited with code {result.returncode}")
325+
if result.stderr:
326+
print(" --- RAT stderr ---")
327+
for line in result.stderr.splitlines()[-25:]:
328+
print(f" {line}")
329+
return False
322330

323331
print(f" ✓ RAT XML report: {rat_report_xml}")
324332
except Exception as e:

0 commit comments

Comments
 (0)