Skip to content

tank-bohr/rush

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

451 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

rush

CI codecov Gem

A POSIX shell written in pure Ruby. rush implements the POSIX.1-2017 Shell Command Language (IEEE Std 1003.1, §2) to the letter, with dash as its differential oracle: a large corpus of language tests verifies that rush and dash -c produce the same [stdout, exit status] byte for byte. Where dash itself diverges from the standard, the standard wins and the divergence is documented.

Install

gem install rush-shell

Ruby >= 4.0 is required — the floor is what CI actually proves. The gem is rush-shell; the executable is rush.

Use

rush                       # interactive shell
rush -c 'echo hello'       # run a command string
rush script.sh arg1 arg2   # run a script
echo 'ls | wc -l' | rush   # read commands from stdin

rush accepts the standard sh invocation: -c, -o option/+o option, the set-builtin flag letters (-e, -x, -u, -m, …), -- to end options, and behaves as a login shell when invoked with a leading-dash argv[0]. Interactive mode (auto-detected on a terminal) has Reline line editing and full job control: process groups, terminal handover, Ctrl-Z, jobs, fg, bg, and pre-prompt status change reports — matching dash's picture byte-for-byte in the pty smoke tests. Persistent history and the POSIX fc builtin are on the roadmap.

The full §2 language is implemented: quoting, all parameter-expansion forms, command substitution, arithmetic expansion, field splitting, pathname expansion (including bracket expressions and locale collation via glibc), redirections and here-documents, pipelines and lists, compound commands, functions, traps, aliases, getopts, and the special builtins.

Why trust a shell?

Correctness in rush is not a claim, it is machinery:

  • Differential testing — the language corpus runs every case against a checksum-pinned dash 0.5.13.4 and compares [stdout, exit status]; CI repeats this natively and inside a Docker oracle image.
  • 2831 examples, ~99.8% line / ~98.8% branch coverage — irreducible fork/exec paths are pinned by out-of-process differential tests instead.
  • Mutation testingmutant over ~38,800 mutations gates CI at a ratcheted threshold.
  • Two independent type systems — inline Sorbet sig {} and RBS checked by Steep, kept deliberately separate so each catches what the other misses.

Development

mise install         # Ruby from .tool-versions
bundle install
make install-hooks   # once per clone: Conventional Commits hook (cog)
bundle exec rake     # the full parallel quality gate

bundle exec rake compiles the Racc parser from grammar/shell.y, then runs rubocop, reek, flay/flog, Steep, Sorbet and the sharded RSpec suite concurrently. bin/test-in-docker runs the same gate plus container-only smokes against the pinned oracle image. lib/rush/parser.rb is generated and committed; regenerate via rake compile, audit with rake check_parser_drift.

The architecture is a unidirectional pipeline over shared shell state:

Source → Lexer → Racc Parser → AST → Expander → Executor

with one feedback wire (the parser nudges lexer state for POSIX grammar rules 1–9) and all OS access funneled through one injectable port (Rush::SystemCalls). Design decisions and per-slice lessons live in docs/architecture/ and docs/journal.md; agent/contributor workflow lives in AGENTS.md. Notable research: Steep vs Sorbet under extreme quality pressure.

Releases are cut from the live branch: semantic-release computes the version from Conventional Commits and the gem is published to RubyGems via OIDC trusted publishing with sigstore attestations — no long-lived credentials.

License

MIT

About

No description, website, or topics provided.

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages