-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
200 additions
and
109 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,46 +1,47 @@ | ||
require_relative "version_parts" | ||
|
||
class RubyVersion | ||
# Uses def <=> to implement >=, <=, etc. | ||
include Comparable | ||
|
||
# Returns a file name without the extension (no direcory) | ||
attr_reader :plain_file_name | ||
def initialize(version = ENV.fetch("VERSION")) | ||
@parts = VersionParts.new(version) | ||
end | ||
|
||
# Full URL of the ruby binary on ruby-lang (if it exists) | ||
attr_reader :download_url | ||
private def parts | ||
@parts | ||
end | ||
|
||
# Returns file name with tar extension (no directory) | ||
# Returns file name with tar extension (but no directory) | ||
# This is the file name that will be uploaded to Heroku | ||
# | ||
# Preview and release candidates are output as their | ||
# major.minor.patch (without the `-preview` suffix) | ||
attr_reader :tar_file_name_output | ||
|
||
# Version without an extra bits at the end | ||
attr_reader :major_minor_patch | ||
|
||
attr_reader :raw_version | ||
|
||
def initialize(version = ENV.fetch("VERSION")) | ||
@raw_version = version | ||
# e.g. "ruby-3.1.4.tgz" | ||
def tar_file_name_output | ||
"ruby-#{parts.bundler_format}.tgz" | ||
end | ||
|
||
parts = version.split(".") | ||
major = parts.shift | ||
minor = parts.shift | ||
patch = parts.shift.match(/\d+/)[0] | ||
# Returns a file name without the extension (no directory) | ||
def download_file_name | ||
"ruby-#{parts.download_format}" | ||
end | ||
|
||
@major_minor_patch = "#{major}.#{minor}.#{patch}" | ||
@plain_file_name = "ruby-#{@raw_version}" | ||
@download_url = "https://ftp.ruby-lang.org/pub/ruby/#{major}.#{minor}/#{@plain_file_name}.tar.gz" | ||
# Ruby packages their source with a top level directory matching the name of the download file | ||
# see the docs in `tar_and_untar.rb` for more details on expected tar formats | ||
def ruby_source_dir_name | ||
"ruby-#{parts.download_format}" | ||
end | ||
|
||
@tar_file_name_output = "ruby-#{major}.#{minor}.#{patch}.tgz" | ||
@compare_version = Gem::Version.new(raw_version) | ||
def <=>(other) | ||
Gem::Version.new(parts.bundler_format) <=> Gem::Version.new(other) | ||
end | ||
end | ||
|
||
def preview? | ||
@raw_version != @major_minor_patch | ||
class DownloadRuby | ||
def initialize(parts:) | ||
@parts = parts | ||
end | ||
|
||
def <=>(other) | ||
@compare_version <=> Gem::Version.new(other) | ||
def url | ||
"https://ftp.ruby-lang.org/pub/ruby/#{@parts.major}.#{@parts.minor}/ruby-#{@parts.download_format}.tar.gz" | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
|
||
# Normalize Ruby versions | ||
# | ||
# Released ruby versions have a "major.minor.patch" and nothing else. | ||
# Prerelease ruby versions have "major.minor.patch" and a trailing identifier | ||
# for example "3.3.0-preview3". | ||
# | ||
# Ruby stores these versions on its download server using a dash for example: | ||
# https://ftp.ruby-lang.org/pub/ruby/3.3/ruby-3.3.0-preview2.tar.gz | ||
# | ||
# However once you install that version and run `ruby -v` you get a different | ||
# representation: | ||
# | ||
# ``` | ||
# $ ruby -v | ||
# ruby 3.3.0preview2 (2023-09-14 master e50fcca9a7) [x86_64-linux] | ||
# ``` | ||
# | ||
# And it's in yet another representation in bundler: | ||
# | ||
# ``` | ||
# $ cat Gemfile.lock | grep RUBY -A 2 | ||
# RUBY VERSION | ||
# ruby 3.3.0.preview2 | ||
# ``` | ||
# | ||
# This format comes from this logic https://github.com/rubygems/rubygems/blob/85edf547391043ddd9ff21d8426c9dd5903435b2/lib/rubygems.rb#L858-L875 | ||
# | ||
# Note that: | ||
# | ||
# - Download ruby has a dash (`-`) seperator | ||
# - Version output from `ruby -v` has no separator | ||
# - Bundler uses a dot (`.`) separator | ||
# | ||
# We need to round trip: | ||
# | ||
# - Download a ruby source tarball | ||
# - Build it into a binary (`make install` etc.) | ||
# - Zip/tar that binary up and upload it to S3 (filename is coupled to buildpack logic) | ||
# | ||
# Then later the buildpack has to: | ||
# | ||
# - Take the output of `bundle platform` and turn that into an S3 url | ||
# - Download and unzip that tarball and place it on the path | ||
# | ||
# For this to function we care about: | ||
# | ||
# - Download format (because we need to get the source from the ftp site) | ||
# - Bundler format (because `bundle platform` output is how we lookup the donload, | ||
# therefore it's the format we must use to zip/tar the file). | ||
# | ||
# This class can take in a version string containing: | ||
# | ||
# - Ruby version without pre-release information | ||
# - Ruby version with pre-release in download format | ||
# - Ruby version with pre-release in bundler format | ||
# | ||
# And it will normalize the format to be consistent | ||
class VersionParts | ||
attr_reader :major, :minor, :patch, :separator, :pre | ||
|
||
# Normalize a version string with an optional pre-release | ||
def initialize(version) | ||
# https://rubular.com/r/HgtMk8O0Lscfvv | ||
parts = version.match(/(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)(?<separator>[-.])?(?<pre>.*)/) | ||
|
||
@major = parts[:major] or raise "Does not contain major #{version}: #{parts}" | ||
@minor = parts[:minor] or raise "Does not contain minor #{version}: #{parts}" | ||
@patch = parts[:patch] or raise "Does not contain patch #{version}: #{parts}" | ||
@separator = parts[:separator] || "" | ||
@pre = parts[:pre] || "" | ||
end | ||
|
||
def download_format | ||
"#{major}.#{minor}.#{patch}#{separator.empty? ? "" : "-"}#{pre}" | ||
end | ||
|
||
def bundler_format | ||
"#{major}.#{minor}.#{patch}#{separator.empty? ? "" : "."}#{pre}" | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.