Repository navigation
Fix File.basename with the ".*" suffix on leading-dot names - #89
jiro-by-nori[bot] wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Reviewed head 4e968c8.
Checks observed: CI success at this head, with checks not weakened, lint, docs, front-end (the desugarer against CRuby), proofs (build, every book, axioms, soundness, comparator), and conformance (the model against CRuby) all success. No unresolved review threads.
Files reviewed: difftest/corpus/regressions/file-basename-dot-suffix.json, difftest/corpus/regressions/file-basename-dot-suffix.rb, ruby-lean/prelude/prelude.rb, ruby-lean/RubyCore/Generated/Prelude.lean, ruby-lean/RubyCore/Generated/PreludeJson.lean.
Validation:
- Compared the new
".*"branch with CRuby'sfile.c(enc_find_basename+rmext): for suffix.*, CRuby skips the leading run of dots, records the last dot after that run, and shortens there, returning the whole basename when no later dot exists. The new prelude loop mirrors that. I walked all nine expectations in the new regression file and each matches that logic ("..","...","..foo","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/a/..",".bashrc",".a.b","foo.ext","foo.","a..."). - The proofs job runs
make gen-check, which passed, soPreludeJson.leanandPrelude.leanare fresh for the edited prelude. The__dt_t88..__dt_t101renumbering is the expected one-slot shift from the added temporary. - The conformance job executes the new regressions case against CRuby 4.0.5; it passed.
checks not weakenedalso passed, and the sidecar declares"status": "fixed", so the case must now agree. - I did not run the full Lean build or CRuby locally.
Risk: none beyond the generated-file dependence, which gen-check already covers. The change is confined to the ".*" branch of File.basename and its generated artifacts.
Verdict: approve.
4e968c8 to
74d2082
Compare
Summary
File.basename(path, ".*")stripped a leading run of dots as if it were anextension. A leading run of dots names the file, not an extension, so the model
answered
"."where CRuby answers"..":File.basename("..", ".*")"."".."File.basename("...", ".*")"..""..."File.basename("..foo", ".*")".""..foo"File.basename("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/a/..", ".*")"."".."This is a wrong answer, not a gated shape:
File.basenameis a pure path helperthe model already claims to model. The fix mirrors CRuby's
ruby_enc_find_basename: skip the leading dot run, then strip from the last dotafter it. A real extension after the run still comes off (
".a.b"→".a","foo.ext"->"foo"), and names with no extension are unchanged.This is the basename half of the leading-dot class fixed for
File.extnamein#58; it does not touch the
dirname/extname/joinchanges there or thenon-String refusal in #77.
Changes
ruby-lean/prelude/prelude.rb— the".*"branch ofFile.basename.ruby-lean/RubyCore/Generated/PreludeJson.lean,ruby-lean/RubyCore/Generated/Prelude.lean— regenerated from the prelude.difftest/corpus/regressions/file-basename-dot-suffix.rband its sidecar —pins the wrong answers and the shapes that must keep stripping.
Test plan
bin/ruby-lean --comparebefore the fix (DIFFER)and after (
AGREE) on..,...,..foo,/a/..,.bashrc,.a.b,foo.ext,foo.,a....{a, b, ., /}(1,365 programs),File.basename(s, ".*")agrees with CRuby4.0.5 byte-for-byte under
bin/ruby-lean --compare.held; the regressions tier is 219 held, 1 gated,0 failures.
scripts/check-conformance.shholds the baseline exactly.lake buildforrubycoreand every book (1399 jobs) succeeds;check-metatheory.shprints OK (including the booted-heap probes) andcheck-soundness.sh --proofs-onlyprintsSOUNDNESS CHECK PASSED.make gen-checkequivalent: regeneratedPreludeJson.lean/Prelude.leanarefresh, and
CRubyNames.lean,Unicode.leanand the audited checker are staleonly if their inputs changed, which they did not.
scripts/check-not-weakened.py --base origin/main:CHECKS NOT WEAKENED.this sandbox does not have; the changed code does not pass through Sorbet).
Authored by Jiro, an autonomous coding agent, including this description.