gemfile-go π β πΉ
Parse Ruby's Gemfile and Gemfile.lock in pure Go - no Ruby required!

Overview
Ever wanted to parse Ruby's Gemfile.lock from Go? Maybe you're building developer tools, analyzing dependencies, or just curious about what's in that lockfile. This library lets you do it all without having Ruby installed!
Think of it as Bundler's lockfile parser, but speaking Go.
π Quick Start
go get github.com/contriboss/gemfile-go
π For Ruby Developers Learning Go
Welcome Ruby friend! π Here's a translation guide:
Ruby Concept |
Go Equivalent in This Library |
Bundler.locked_gems |
lockfile.ParseFile() |
gem.dependencies |
GemSpec.Dependencies |
Gem::Version |
String (but semver compatible) |
bundle install |
Parse lockfile β download gems |
Gemfile.lock |
Lockfile struct |
π» Examples
Parse a Gemfile.lock
package main
import (
"fmt"
"log"
"github.com/contriboss/gemfile-go/lockfile"
)
func main() {
// Parse your Gemfile.lock
lock, err := lockfile.ParseFile("Gemfile.lock")
if err != nil {
log.Fatal(err)
}
// How many gems do you have?
fmt.Printf("π¦ Found %d gems\n", len(lock.GemSpecs))
// What Ruby version was it bundled with?
fmt.Printf("π Bundled with: %s\n", lock.BundledWith)
// List all Rails-related gems (because why not?)
for _, gem := range lock.GemSpecs {
if strings.Contains(gem.Name, "rails") {
fmt.Printf("π %s (%s)\n", gem.Name, gem.Version)
}
}
}
Find a Specific Gem
// Finding gems is like `bundle show gemname`
gem := lock.FindGem("rails")
if gem != nil {
fmt.Printf("Rails version: %s\n", gem.Version)
fmt.Printf("Dependencies: %v\n", gem.Dependencies)
}
Parse a Gemfile
package main
import (
"github.com/contriboss/gemfile-go/gemfile"
)
func main() {
// Parse the Gemfile (the wishlist, not the lockfile!)
gems, err := gemfile.ParseFile("Gemfile")
if err != nil {
log.Fatal(err)
}
// See what's in the development group
for _, gem := range gems {
if gem.HasGroup("development") {
fmt.Printf("Dev gem: %s\n", gem.Name)
}
}
}
π Fun Features
// Check if a gem works on your platform
if gem.Platform == "" || gem.Platform == "ruby" {
fmt.Println("β
Pure Ruby gem - works everywhere!")
} else if gem.Platform == "x86_64-linux" {
fmt.Println("π§ Linux native extension detected!")
}
Security Checksums
// Verify gem integrity (just like Bundler does!)
if gem.Checksum != "" {
fmt.Printf("π Gem %s is checksum-protected\n", gem.Name)
}
Git Dependencies
// Find all gems from git repos (living on the edge!)
for _, gitGem := range lock.GitSpecs {
fmt.Printf("π₯ %s from %s (rev: %s)\n",
gitGem.Name, gitGem.Remote, gitGem.Revision[:7])
}
ποΈ Building
We use Mage for builds (it's like Rake but for Go!):
# Install Mage
go install github.com/magefile/mage@latest
# Run tests
mage test
# Run linter
mage lint
# Run benchmarks
mage bench
# Run everything (CI mode)
mage ci
π€ For Ruby Devs: Key Differences
-
No Version Operators: In Ruby you have ~>
, >=
, etc. In the lockfile, versions are exact, so we just use strings.
-
No Gem Installation: This library reads Gemfile.lock but doesn't install gems. Think of it as read-only Bundler.
-
Groups as Strings: Ruby uses symbols (:development
), we use strings ("development"
).
-
Error Handling: Go doesn't have exceptions. We return errors as second values:
// Ruby: lock = Bundler.locked_gems (might raise)
// Go:
lock, err := lockfile.ParseFile("Gemfile.lock")
if err != nil {
// Handle error
}
π― Use Cases
- CI/CD Tools: Analyze Ruby dependencies without Ruby
- Security Scanners: Check for vulnerable gems
- Developer Tools: Build IDE support for Ruby projects
- Dependency Analysis: Understand Ruby project dependencies
- Migration Tools: Help migrate from Ruby to other languages
- Fun Projects: Because parsing is fun! π
π API Documentation
Full API docs at pkg.go.dev
π§ͺ Testing
Every parser function has tests! We test with real Gemfile.lock files from popular Ruby projects like Rails, Sinatra, and Jekyll.
# Run tests with coverage
mage test
# Run tests with race detector
mage testrace
# Run benchmarks
mage bench
π€ Why This Exists
Sometimes you need to understand Ruby dependencies from Go:
- You're building polyglot developer tools
- You're analyzing dependencies across languages
- You're migrating from Ruby to Go (we don't judge!)
- You just want fast lockfile parsing
Parsing a typical Rails Gemfile.lock:
- gemfile-go: ~1ms π
- Bundler (Ruby): ~100ms
That's 100x faster! (Your mileage may vary)
π License
MIT - Use it, fork it, enjoy it!
π Acknowledgments
- The Bundler team for the lockfile format
- The Go community for being awesome
- Coffee β for making this possible
Made with π by @contriboss - Bridging Ruby and Go, one parser at a time!