Skip to content
Open
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
1 change: 1 addition & 0 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
nodejs 24.10.0
ruby 3.2.2
Copy link
Copy Markdown
Author

@estraph estraph Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already seem to have a .tools-version file used by the asdf version manager, so we might as well support Ruby in there as well.

4 changes: 2 additions & 2 deletions rails/Gemfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
source 'https://rubygems.org'
ruby '>= 3.0'
ruby '>= 3.0', '< 3.4'
Copy link
Copy Markdown
Author

@estraph estraph Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using standard syntax in the Gemfile to prevent execution with a Ruby version higher than 3.4. This already does most of what we want - however, the setup script contains its own version checks and outputs information to the user which could just be more confusing if not updated as well.

Your Ruby version is 3.4.4, but your Gemfile specified >= 3.0, < 3.4


gem 'rails', '7.0.7.2'

Expand All @@ -20,4 +20,4 @@ gem 'puma'

gem 'pry'

gem 'tzinfo-data', platforms: [:x64_mingw, :mingw, :mswin]
gem 'tzinfo-data', platforms: [:x64_mingw, :mingw, :mswin]
36 changes: 24 additions & 12 deletions rails/bin/determinator
Original file line number Diff line number Diff line change
@@ -1,29 +1,39 @@
#!/usr/bin/env ruby

gemfile = File.read("./Gemfile")
REQUIRED_RUBY_VERSION = gemfile[/ruby ['"]>=(.+)['"]/, 1]
ACTUAL_RUBY_VERSION = RUBY_VERSION
PREFERRED_RUBY_VERSION = File.read("../.ruby-version").strip
Copy link
Copy Markdown
Author

@estraph estraph Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we already have a .ruby-version file used by Intercom to internally maintain this gem, we can use the version defined there as the recommended Ruby version known to work - and not the minimum set in the Gemfile.


HOMEBREW_INSTALLATION_COMMAND = '/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"'
RY_INSTALLATION_COMMAND = "brew update && brew install ry"

RUBY_VERSION_MANAGER_INSTALLATION_INSTRUCTIONS = {
"asdf" => {
"install" => "asdf install ruby #{PREFERRED_RUBY_VERSION}",
"use" => "asdf set ruby #{PREFERRED_RUBY_VERSION}",
},
"rbenv" => {
"install" => "rbenv install #{REQUIRED_RUBY_VERSION}",
"use" => "rbenv shell #{REQUIRED_RUBY_VERSION}",
"install" => "rbenv install #{PREFERRED_RUBY_VERSION}",
"use" => "rbenv shell #{PREFERRED_RUBY_VERSION}",
},
"rvm" => {
"install" => "rvm install #{REQUIRED_RUBY_VERSION}",
"use" => "rvm #{REQUIRED_RUBY_VERSION}",
"install" => "rvm install #{PREFERRED_RUBY_VERSION}",
"use" => "rvm #{PREFERRED_RUBY_VERSION}",
},
"ry" => {
"install" => "ry install #{REQUIRED_RUBY_VERSION}",
"use" => "eval $(ry setup); ry use #{REQUIRED_RUBY_VERSION}",
"install" => "ry install #{PREFERRED_RUBY_VERSION}",
"use" => "eval $(ry setup); ry use #{PREFERRED_RUBY_VERSION}",
}
}
PREFERRED_RUBY_VERSION_MANAGERS = RUBY_VERSION_MANAGER_INSTALLATION_INSTRUCTIONS.keys.reject { |key| key == "ry" }
FALLBACK_RUBY_VERSION_MANAGER = "ry"

def parse_ruby_version_constraints
File.read("./Gemfile")[/ruby .*/][5..].split(',').map do |constraint|
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic builds on the regex approach already present in this repo and makes some tightly coupled assumptions about the code in this repository (Gemfiles are basically code and parsing them with regex is brittle) - which is not ideal but "fine" and doesn't make the code any worse than before.

constraint = constraint.gsub(/['"]/, '')
Gem::Dependency.new('ruby', constraint)
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Version constraints are much more complex than how we're treating them so far. At the moment we just assume the number set is the minimum version. We could've just continued down that path and also parsed out a max version to achieve what we need.

However, there is already a class that exists to solve this and it's already installed as part of RubyGems - here we start using the Gem::Depencency class to parse all constraints set in the Gemfile to compare the current version of Ruby against any constraints set out. This is simpler and more reliable than what we did before.

end
end

def command_exists?(command)
system("command -v #{command} &> /dev/null")
end
Expand All @@ -50,11 +60,13 @@ def ry_needs_to_be_installed?
!command_exists?("ry")
end

RUBY_VERSION_CONSTRAINTS = parse_ruby_version_constraints

puts ""
puts "🤖 I am The Determinator! Come with me if you want to use the right Ruby version!"
puts "ℹ️ Minicom uses Ruby #{REQUIRED_RUBY_VERSION} or greater. Let me check what version of Ruby you have…"
puts "ℹ️ Minicom uses Ruby #{RUBY_VERSION_CONSTRAINTS.map{ |d| d.requirement.to_s }.join(', ')}. Let me check what version of Ruby you have…"

if REQUIRED_RUBY_VERSION <= ACTUAL_RUBY_VERSION
if RUBY_VERSION_CONSTRAINTS.all?{ |d| d.match?('ruby', ACTUAL_RUBY_VERSION) }
puts "✅ You’re using Ruby #{ACTUAL_RUBY_VERSION}. You’re all set!"
exit(0)
else
Expand All @@ -73,8 +85,8 @@ else
end
end

puts "💎 Install Ruby #{REQUIRED_RUBY_VERSION} with `#{RUBY_VERSION_MANAGER_INSTALLATION_INSTRUCTIONS[ruby_version_manager_to_use]['install']}`"
puts "💎 Switch to Ruby #{REQUIRED_RUBY_VERSION} with `#{RUBY_VERSION_MANAGER_INSTALLATION_INSTRUCTIONS[ruby_version_manager_to_use]['use']}`"
puts "💎 Install Ruby #{PREFERRED_RUBY_VERSION} with `#{RUBY_VERSION_MANAGER_INSTALLATION_INSTRUCTIONS[ruby_version_manager_to_use]['install']}`"
puts "💎 Switch to Ruby #{PREFERRED_RUBY_VERSION} with `#{RUBY_VERSION_MANAGER_INSTALLATION_INSTRUCTIONS[ruby_version_manager_to_use]['use']}`"
puts "🔄 Run `bin/determinator` again to double-check you’re using the right Ruby version"

exit(1)
5 changes: 4 additions & 1 deletion script/rails/setup
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#!/bin/bash

set -e
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we don't set the -e option, bash will continue to run the below commands even if one step fails, which makes things confusing to the candidate, i.e. if the version of Ruby doesn't match. We don't want to continue installing things if such a fundamental requirement is not met.


cd rails
./bin/determinator
gem install bundler
bundle install
bundle exec rake db:setup
bundle exec rake db:setup