Skip to content

fix(builtins): getopts honors local OPTIND/OPTARG - #2591

Merged
chaliy merged 1 commit into
mainfrom
claude/getopts-optind
Oct 7, 2026
Merged

chaliy merged 1 commit into
mainfrom
claude/getopts-optind

Conversation

@chaliy

@chaliy chaliy commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Requested by Михайло · project thread

What changed

getopts now reads and writes OPTIND, OPTARG and the name variable through dynamic scope (set_variable/expand_variable), not the global map. Three smaller fixes come with it:

  • An unset or empty OPTIND starts at 1.
  • OPTIND stays on a clustered group (-ab) until the group is done.
  • Assigning OPTIND restarts the group, as bash does.

Why

This is a roadmap step 1 fidelity gap. The idiomatic option parser in a function, local OPTIND opt; while getopts ...; done; shift $((OPTIND-1)), parsed nothing in bashkit. It then failed with shift: -1: shift count out of range. Debian-oracle case getopts-loop now matches bash.

Before / After

Script Before After (= bash)
f(){ local OPTIND o; while getopts v o; do echo $o; done; }; f -v nothing, shift error v
getopts ab o -ab; echo $OPTIND `` 1
OPTIND=1; getopts ab o -ba after a partial group a b
f(){ local OPTARG; getopts x: o -x v; }; OPTARG=g; f; echo $OPTARG v g

Proof: new spec getopts-local-optind.test.sh (3 cases, bash-verified), and bash_comparison passes.

Risk

Low. The change is scoped to getopts plus one OPTIND assignment hook that resets the group index.

Checklist

  • Failing spec first
  • cargo test -p bashkit --lib / --test integration / bash_comparison
  • clippy -D warnings, fmt
  • knowledge/log.md

https://claude.ai/code/session_019aFikmptPc91Fj4N2iDXQA


Generated by Claude Code

getopts read and wrote the global OPTIND/OPTARG, so `local OPTIND` in a
function made every option loop parse nothing. Use dynamic scope, start
at 1 on empty OPTIND, keep OPTIND on an option group, and restart the
group when OPTIND is assigned.

Claude-Session: https://claude.ai/code/session_019aFikmptPc91Fj4N2iDXQA
@chaliy chaliy self-assigned this Oct 7, 2026
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
bashkit 3be3d24 Commit Preview URL

Branch Preview URL
Oct 07 2026, 07:54 PM

@chaliy
chaliy merged commit c5ae56d into main Oct 7, 2026
44 checks passed
@chaliy
chaliy deleted the claude/getopts-optind branch October 7, 2026 20:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant