根据日期或 Ruby 版本设置 Ruby 环境

Setup Ruby environment based on date or Ruby version

出于测试目的,我想安装一个基于过去日期的 Ruby 环境。例如,Ruby 2.5.0p0 于 2017-12-25 发布,我在某处读到 Rails 5.2.6 是与之一起使用的版本。我想要的是一种编程方式来了解 gem 的 version/date 应该与 Ruby 的哪个版本一起使用。我是否缺少一些超级简单的方法来做到这一点?

编辑:

我的想法是在 Ruby 环境中进行测试,该环境本来会在某个日期存在,这似乎很棘手,而且可能没有必要。所以我要做的是 运行 通过几个主要的 Ruby 版本并安装它们的 best Rails versions 并让所有其他 gem 浮动到任何被拖入的版本。

Ruby    Rails
2.5.0   5.2.6
2.5.9   5.2.6
2.6.7   6.0.3.7
2.7.3   6.0.3.7
3.0.1   latest

Rails 和所有其他 gem 可以说明所需的最低 ruby 版本。这将在 运行ning bundle update.

时自动考虑

但是,有两个问题:

  1. 图书馆作者并不总是完美地做到这一点——所以你可能运行一个现代的gem旧 ruby 版本,直到 运行 时才发现不兼容。

  2. 图书馆作者无法预测未来;他们可能正确地指定了一个 minimum 所需的 ruby 版本,但他们不可能提前知道一个 maximum 兼容的 ruby 版本.

不过,也有一线希望:Ruby 向后兼容非常好。所以除非你尝试 运行 一个 大项目 与古代图书馆和现代 ruby (例如 rails 4 项目使用 ruby 2.7 ), 你在这里不太可能有太多问题。

而且,正如我上面所建议的,这可能只是 large gems 的问题,例如 rails 框架。 It's fairly well documented which minimum version of ruby is supported by each major rails release:

Rails 7 requires Ruby 2.7.0 or newer.

Rails 6 requires Ruby 2.5.0 or newer.

Rails 5 requires Ruby 2.2.2 or newer.

What I want is a programmatic way to know what version/date of a gem should go with what version of Ruby.

一种方法是使用 the API provided by RubyGems.org:

# run with ruby get_versions.rb gemname rubyversion

require 'json'
require 'uri'
require 'net/http'
require 'pp'

gemname = ARGV[0] || 'rails'
uri = URI("https://rubygems.org/api/v1/versions/#{gemname}.json")
target_ruby_version = Gem::Version.new(ARGV[1] || '2.7.0')

puts "getting #{uri}"

response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
  puts '...'
  request = Net::HTTP::Get.new uri
  http.request(request)
end
# error handling is boring so lets just assume this will always work
json = JSON.parse(response.body)
compatible = json.each_with_object({}) do |gem_version, hash|
  hash[gem_version["number"]] = gem_version["ruby_version"]
end.select do |gemv, rubyv|
  Gem::Requirement.new(rubyv)
                  .satisfied_by?(target_ruby_version)
end

puts "The following versions of #{gemname} satifisy the Ruby requirement #{target_ruby_version}:"

pp compatible.keys

然而,它在测试 gem 是否与给定版本的 Ruby 实际兼容方面的实际用途非常值得怀疑。由于作者通常不会指定 ruby 版本的范围,它只会告诉您给定的 Ruby 版本是否满足最低版本要求。 Tom Lord 很好地描述了为什么这是有问题的。

您在 运行 Rails 0.8.0 在 Ruby 2.7.0 上的体验可能会有所不同。