go-ruby-pathname

Ruby's Pathname path algebra in pure Go โ€” MRI-compatible, no cgo.

pure Go ยท zero cgo Pathname-compatible lexical ยท no I/O cleanpath relative_path_from basename ยท dirname ยท extname join ยท split ยท ascend "/"-based on every OS MRI byte-exact 100% coverage 6 arches
Documentation GitHub
Documentation (MkDocs Material + mike) License: BSD-3-Clause Go 1.26.4+ Coverage 100%

go-ruby-pathname is a pure-Go (no cgo) reimplementation of the path-manipulation surface of Ruby's Pathname โ€” the deterministic, interpreter-independent path algebra. It wraps a path string and exposes the lexical operations Pathname offers โ€” basename, dirname, extname, cleanpath, relative_path_from, join/+, split, each_filename, ascend/descend โ€” without any Ruby runtime and without touching the filesystem. Like Ruby's Pathname, it hardcodes "/" as the separator on every platform, so the behaviour is identical on Linux, macOS and Windows. It is the path-algebra backend for go-embedded-ruby, bound by rbgo as a native module just like go-ruby-regexp and go-ruby-erb โ€” differential-tested against MRI, 100% coverage, CI green across 6 arches and 3 OSes.

Basename, dirname & extname ready

Basename/BasenameSuffix, Dirname/Parent and Extname/SubExt follow MRI’s rules byte-for-byte โ€” including File.extname’s fiddly trailing-dot cases ("foo." โ†’ ".", "a..b" โ†’ ".b") and the dotfile rule (".foo" โ†’ "").

Cleanpath ready

Collapses ., .. and redundant separators exactly as MRI does: a .. past the root of an absolute path is dropped, a .. escaping a relative path is kept ("/a/../../b" โ†’ "/b", "a/../../b" โ†’ "../b").

RelativePathFrom ready

MRI’s lexical relative_path_from algorithm, with its two ArgumentError cases โ€” mixing absolute and relative, and a .. in the base โ€” carrying MRI’s exact message text.

Join, split & traversal ready

Plus/Join (+) where an absolute component resets to the root; Split/EachFilename/Filenames for the component list; and Ascend/Descend walking up to the root and back via Go-callback blocks.

Predicates & comparison ready

The Absolute/Relative/Root predicate trio, plus Cmp (<=>), Eql (==/eql?) and a stable FNV Hash.

Differential oracle & coverage ready

Every method checked against the system ruby’s Pathname over a corpus of edge cases; the deterministic ruby-free tests alone hold 100% coverage, gofmt + go vet clean, green across all six 64-bit Go arches and three OSes (incl. Windows).

A faithful port of Ruby's Pathname path algebra in pure Go, cgo disabled, so it cross-compiles and embeds anywhere. It performs only lexical string surgery โ€” cleanpath, relative_path_from, basename/dirname/extname, join/split/ascend โ€” never touching the filesystem; the File/Dir delegations stay host-side. Validated differentially against the system ruby binary. It is a standalone, reusable module bound into the sibling org github.com/go-embedded-ruby.