Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wip: ruby provider #6

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions core/providers/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/railwayapp/railpack/core/providers/node"
"github.com/railwayapp/railpack/core/providers/php"
"github.com/railwayapp/railpack/core/providers/python"
"github.com/railwayapp/railpack/core/providers/ruby"
"github.com/railwayapp/railpack/core/providers/staticfile"
)

Expand All @@ -17,10 +18,11 @@ type Provider interface {

func GetLanguageProviders() []Provider {
return []Provider{
&php.PhpProvider{},
&golang.GoProvider{},
&node.NodeProvider{},
&php.PhpProvider{},
&python.PythonProvider{},
&golang.GoProvider{},
&ruby.RubyProvider{},
&staticfile.StaticfileProvider{},
}
}
Expand Down
95 changes: 95 additions & 0 deletions core/providers/ruby/ruby.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package ruby

import (
"fmt"
"strings"

"github.com/railwayapp/railpack/core/generate"
"github.com/railwayapp/railpack/core/plan"
)

const (
DEFAULT_RUBY_VERSION = "latest"
)

type RubyProvider struct{}

func (p *RubyProvider) Name() string {
return "ruby"
}

func (p *RubyProvider) Detect(ctx *generate.GenerateContext) (bool, error) {
hasRuby := ctx.App.HasMatch("Gemfile")

return hasRuby, nil
}

func (p *RubyProvider) Plan(ctx *generate.GenerateContext) error {
packages := p.packages(ctx)

_ = p.install(ctx, packages)

ctx.Start.Command = fmt.Sprintf("ruby %s", "app.rb")

return nil
}

func (p *RubyProvider) packages(ctx *generate.GenerateContext) *generate.MiseStepBuilder {
packages := ctx.GetMiseStepBuilder()

ruby := packages.Default("ruby", DEFAULT_RUBY_VERSION)

if envVersion, varName := ctx.Env.GetConfigVariable("RUBY_VERSION"); envVersion != "" {
packages.Version(ruby, envVersion, varName)
}

if version := p.gemfileRubyVersion(ctx); version != "" {
packages.Version(ruby, version, "Gemfile.lock")
}

return packages
}

func (p *RubyProvider) install(ctx *generate.GenerateContext, packages *generate.MiseStepBuilder) *generate.CommandStepBuilder {
install := ctx.NewCommandStep("install")
install.AddCommands([]plan.Command{
// make sure gem is updated
plan.NewExecCommand("gem update --system --no-document"),
// install bundler
plan.NewExecCommand("gem install -N bundler"),
plan.NewCopyCommand("Gemfile"),
plan.NewCopyCommand("Gemfile.lock"),
plan.NewExecCommand("bundle install"),
})

install.DependsOn = []string{packages.DisplayName}

return install
}

// scan for a Gemfile.lock and return the Ruby version
func (p *RubyProvider) gemfileRubyVersion(ctx *generate.GenerateContext) string {
if gemfileLock, err := ctx.App.ReadFile("Gemfile.lock"); err == nil {
foundRubyVersion := false
lines := strings.Split(string(gemfileLock), "\n")
for _, line := range lines {
// Look for the "RUBY VERSION" line
if strings.HasPrefix(line, "RUBY VERSION") {
foundRubyVersion = true
continue
}

// The Ruby version follows "RUBY VERSION"
if foundRubyVersion {
fields := strings.Fields(line)
if len(fields) >= 2 && fields[0] == "ruby" {
fmt.Println("Ruby Version:", fields[1])
return fields[1]
}
}
}
// packages.Version(ruby, string(versionFile), "Gemfile.lock")
}

return ""
}
54 changes: 54 additions & 0 deletions core/providers/ruby/ruby_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package ruby

import (
"testing"

testingUtils "github.com/railwayapp/railpack/core/testing"
"github.com/stretchr/testify/require"
)

func TestDetect(t *testing.T) {
tests := []struct {
name string
path string
want bool
}{
{
name: "sinatra",
path: "../../../examples/ruby-sinatra",
want: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ctx := testingUtils.CreateGenerateContext(t, tt.path)
provider := RubyProvider{}
got, err := provider.Detect(ctx)
require.NoError(t, err)
require.Equal(t, tt.want, got)
})
}
}
func TestGemfileRubyVersion(t *testing.T) {
tests := []struct {
name string
path string
want string
}{
{
name: "sinatra",
path: "../../../examples/ruby-sinatra",
want: "3.2",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ctx := testingUtils.CreateGenerateContext(t, tt.path)
provider := RubyProvider{}
version := provider.gemfileRubyVersion(ctx)
require.Equal(t, tt.want, version)
})
}
}
2 changes: 2 additions & 0 deletions examples/ruby-sinatra/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

source 'https://rubygems.org'
14 changes: 14 additions & 0 deletions examples/ruby-sinatra/Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
GEM
remote: https://rubygems.org/
specs:

PLATFORMS
arm64-darwin-21

DEPENDENCIES

RUBY VERSION
ruby 3.2

BUNDLED WITH
2.3.7
1 change: 1 addition & 0 deletions examples/ruby-sinatra/Procfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
web: ruby app.rb
5 changes: 5 additions & 0 deletions examples/ruby-sinatra/app.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
require 'sinatra'

get '/' do
'Hello world!'
end