gemfile-go

module
v0.0.0-...-e4271dc Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 23, 2025 License: MIT

README ΒΆ

gemfile-go πŸ’Ž β†’ 🐹

Parse Ruby's Gemfile and Gemfile.lock in pure Go - no Ruby required!

CI Go Reference Go Report Card

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

Ruby Platform Detection
// 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

  1. No Version Operators: In Ruby you have ~>, >=, etc. In the lockfile, versions are exact, so we just use strings.

  2. No Gem Installation: This library reads Gemfile.lock but doesn't install gems. Think of it as read-only Bundler.

  3. Groups as Strings: Ruby uses symbols (:development), we use strings ("development").

  4. 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

πŸš„ Performance

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!

Directories ΒΆ

Path Synopsis
Parse a Gemfile.lock and display fun statistics!
Parse a Gemfile.lock and display fun statistics!
Package gemfile provides a parser for Ruby's Gemfile format.
Package gemfile provides a parser for Ruby's Gemfile format.
Package lockfile provides a pure Go parser for Ruby's Gemfile.lock format.
Package lockfile provides a pure Go parser for Ruby's Gemfile.lock format.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL