diff --git a/CHANGELOG.md b/CHANGELOG.md index 03d09b2..7593a44 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html ### Compatible changes ++ `geordi console` will now also take irb_flags from the local config file into account. These will have precedence over the global config file and flags automatically set by geordi. + ### Breaking changes @@ -19,7 +21,7 @@ This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html ## 12.2.0 2025-07-03 ### Compatible changes -* `geordi deploy` will now respect the configured deploy branch from teh Capistrano config. Previously, it would choose "production" for a deploy to the production stage, and master/main else. +* `geordi deploy` will now respect the configured deploy branch from the Capistrano config. Previously, it would choose "production" for a deploy to the production stage, and master/main else. ## 12.1.0 2025-05-03 diff --git a/README.md b/README.md index bdeb643..0bef522 100644 --- a/README.md +++ b/README.md @@ -95,7 +95,12 @@ Remote: `geordi console staging` Selecting the server: `geordi console staging -s` shows a menu with all available servers. When passed a number, directly connects to the selected server. -IRB flags can be given as `irb_flags: '...'` in the global Geordi config file (`~/.config/geordi/global.yml`). +IRB flags can be given as `irb_flags: '...'` in the global or local Geordi config file +(`~/.config/geordi/global.yml` / `./.geordi.yml`). If you define irb_flags in both files, the local config file will be +used. For IRB >=1.2 in combination with Ruby <3 geordi automatically sets the `--nomultiline` flag, to prevent slow +pasting. You can override this behavior by setting `--multiline` in the global config file or by defining `irb_flags` +in the local config file. The latter will always turn off the automatic behavior, even if you don't set any values for +the irb_flags key. **Options** - `-s, --select-server=[SERVER_NUMBER]`: Select a server to connect to diff --git a/features/console.feature b/features/console.feature index df43875..49fd6e5 100644 --- a/features/console.feature +++ b/features/console.feature @@ -1,7 +1,7 @@ Feature: The console command Most aspects of connection to a server are tested in shell feature. - Scenario: Opening a local Rails console with an irb version < 1.2.0 and preconfigured irb flags from the global settings + Scenario: Opening a local Rails console Given the irb version is "1.1.0" And a file named "tmp/global_settings.yml" with "irb_flags: --foo --baz" When I run `geordi console` @@ -10,15 +10,7 @@ Feature: The console command But the output should not contain "nomultiline" - Scenario: Opening a local Rails console with an Ruby version >= 3.0 - Given the Ruby version is "3.0" - When I run `geordi console` - Then the output should contain "# Opening a local Rails console" - And the output should contain "Util.run! (exec) bundle exec rails console -e development" - But the output should not contain "nomultiline" - - - Scenario: Opening a local Rails console with an irb version >= 1.2.0 and Ruby version < 3.0 + Scenario: IRB 1.2.0+ on Ruby <3 is horribly slow when pasting long strings – we work around this by automatically setting the --nomultiline switch Given the irb version is "1.2.0" And the Ruby version is "2.9" When I run `geordi console` @@ -27,7 +19,7 @@ Feature: The console command And the output should contain "Using --nomultiline switch for faster pasting" - Scenario: Opening a remote Rails console with an irb version >= 1.2.0 and Ruby version < 3.0 + Scenario: Opening a remote Rails console with a slow pasting IRB sets the --nomultiline switch Given the irb version is "1.2.0" And the Ruby version is "2.9" And a file named "Capfile" with "Capfile exists" @@ -45,10 +37,11 @@ Feature: The console command And the output should contain "Using --nomultiline switch for faster pasting" -Scenario: Opening a remote Rails console with an irb version >= 1.2.0, a Ruby version < 3.0 and preconfigured irb flags from the global settings +Scenario: Empty IRB flags in the local Geordi settings also override global IRB flags Given the irb version is "1.2.0" And the Ruby version is "2.9" - And a file named "tmp/global_settings.yml" with "irb_flags: --foo --baz" + And a file named "tmp/local_settings.yml" with "irb_flags:" + And a file named "tmp/global_settings.yml" with "irb_flags: --bar" And a file named "Capfile" with "Capfile exists" And a file named "config/deploy.rb" with "deploy file exists" And a file named "config/deploy/staging.rb" with: @@ -60,4 +53,4 @@ Scenario: Opening a remote Rails console with an irb version >= 1.2.0, a Ruby ve """ When I run `geordi console staging` Then the output should contain "# Opening a Rails console on staging" - And the output should contain "Util.run! ssh, user@www.example.com, -t, cd /var/www/example.com/current && bash --login -c 'bundle exec rails console -e staging -- --nomultiline --foo --baz" + And the output should contain "Util.run! ssh, user@www.example.com, -t, cd /var/www/example.com/current && bash --login -c 'bundle exec rails console -e staging" diff --git a/lib/geordi/commands/console.rb b/lib/geordi/commands/console.rb index d2e09d8..dc26d0d 100644 --- a/lib/geordi/commands/console.rb +++ b/lib/geordi/commands/console.rb @@ -7,7 +7,13 @@ Selecting the server: `geordi console staging -s` shows a menu with all available servers. When passed a number, directly connects to the selected server. -IRB flags can be given as `irb_flags: '...'` in the global Geordi config file (`~/.config/geordi/global.yml`). +IRB flags can be given as `irb_flags: '...'` in the global or local Geordi config file +(`~/.config/geordi/global.yml` / `./.geordi.yml`). If you define irb_flags in both files, the local config file will be +used. For IRB >=1.2 in combination with Ruby <3 geordi automatically sets the `--nomultiline` flag, to prevent slow +pasting. You can override this behavior by setting `--multiline` in the global config file or by defining `irb_flags` +in the local config file. The latter will always turn off the automatic behavior, even if you don't set any values for +the irb_flags key. + LONGDESC # This option is duplicated in shelll.rb diff --git a/lib/geordi/settings.rb b/lib/geordi/settings.rb index 1976757..ed54be4 100644 --- a/lib/geordi/settings.rb +++ b/lib/geordi/settings.rb @@ -16,7 +16,7 @@ class Settings linear_team_ids ].freeze - ALLOWED_LOCAL_SETTINGS = %w[ linear_team_ids ].freeze + ALLOWED_LOCAL_SETTINGS = %w[ linear_team_ids irb_flags ].freeze SETTINGS_WARNED = 'GEORDI_INVALID_SETTINGS_WARNED' @@ -26,7 +26,11 @@ def initialize # Global settings def irb_flags - @global_settings['irb_flags'] + if @local_settings.key? 'irb_flags' + [@local_settings['irb_flags'].to_s, :local] + elsif @global_settings.key? 'irb_flags' + [@global_settings['irb_flags'].to_s, :global] + end end def linear_api_key diff --git a/lib/geordi/util.rb b/lib/geordi/util.rb index 960c800..38c5fc9 100644 --- a/lib/geordi/util.rb +++ b/lib/geordi/util.rb @@ -94,13 +94,18 @@ def console_command(environment) elsif gem_major_version('rails') == 3 "#{binstub_or_fallback('rails')} console #{environment}" else - use_multiline = if irb_version >= Gem::Version.new('1.2') && ruby_version < Gem::Version.new('3.0') + + irb_flags_from_config, source = Settings.new.irb_flags + irb_flags = "" + + if irb_version >= Gem::Version.new('1.2') && ruby_version < Gem::Version.new('3.0') && (source != :local) Interaction.note 'Using --nomultiline switch for faster pasting' - '--nomultiline' + irb_flags << '--nomultiline ' end - irb_flags = [use_multiline, Settings.new.irb_flags].join(' ').strip - irb_flags.prepend('-- ') unless irb_flags.empty? + irb_flags << irb_flags_from_config if irb_flags_from_config + + irb_flags.prepend('-- ').strip! unless irb_flags.empty? "#{binstub_or_fallback('rails')} console -e #{environment} #{irb_flags}" end diff --git a/spec/settings_spec.rb b/spec/settings_spec.rb index 479efd6..62bf673 100644 --- a/spec/settings_spec.rb +++ b/spec/settings_spec.rb @@ -24,4 +24,61 @@ expect(described_class.new.send(:normalize_team_ids, team_id)).to eq normalized_team_id end end + + + describe '#irb_flags', type: :aruba do + let(:global_settings_file_path) { File.expand_path('./tmp/global_settings.yml') } + let(:local_settings_file_path) { File.expand_path('./tmp/local_settings.yml') } + + before do + FileUtils.mkdir_p(File.dirname(global_settings_file_path)) + FileUtils.mkdir_p(File.dirname(local_settings_file_path)) + end + + after do + FileUtils.rm_f(global_settings_file_path) + FileUtils.rm_f(local_settings_file_path) + end + + it 'uses the local settings if present' do + write_file(global_settings_file_path, 'irb_flags: --no-readline') + write_file(local_settings_file_path, 'irb_flags: --readline') + + expect(described_class.new.irb_flags).to eq ["--readline", :local] + end + + it 'uses the local settings if present, even if they are empty' do + write_file(global_settings_file_path, 'irb_flags: --no-readline') + write_file(local_settings_file_path, 'irb_flags: ') + + expect(described_class.new.irb_flags).to eq ["", :local] + end + + it "uses the global settings if local settings do not define irb_flags" do + write_file(global_settings_file_path, 'irb_flags: --no-readline') + write_file(local_settings_file_path, 'auto_update_chromedriver: true') + + expect(described_class.new.irb_flags).to eq ['--no-readline', :global] + end + + it "can handle multiple flags" do + write_file(local_settings_file_path, 'irb_flags: --readline --noinspect') + + expect(described_class.new.irb_flags).to eq ["--readline --noinspect", :local] + end + + it "returns nil if neither global nor local settings define irb_flags" do + write_file(global_settings_file_path, 'auto_update_chromedriver: false') + write_file(local_settings_file_path, 'auto_update_chromedriver: true') + + expect(described_class.new.irb_flags).to be_nil + end + + it "returns nil if neither global nor local settings exist" do + expect(File.exist?(global_settings_file_path)).to be false + expect(File.exist?(local_settings_file_path)).to be false + + expect(described_class.new.irb_flags).to be_nil + end + end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index e74c6c1..84cdc8b 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -15,6 +15,10 @@ require 'aruba/rspec' require 'pry' require 'byebug' + +# Disables execution of Util.run! calls +ENV['GEORDI_TESTING'] = 'true' + ::Dir.glob('./lib/geordi/*.rb').each { |f| require f } # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration diff --git a/spec/util_spec.rb b/spec/util_spec.rb index 1fbfc8e..b7be6bd 100644 --- a/spec/util_spec.rb +++ b/spec/util_spec.rb @@ -57,4 +57,105 @@ end end + + describe '.console_command', type: :aruba do + let(:global_settings_file_path) { File.expand_path('./tmp/global_settings.yml') } + let(:local_settings_file_path) { File.expand_path('./tmp/local_settings.yml') } + + around do |example| + original_ruby = ENV['GEORDI_TESTING_RUBY_VERSION'] + original_irb = ENV['GEORDI_TESTING_IRB_VERSION'] + + FileUtils.mkdir_p(File.dirname(global_settings_file_path)) + FileUtils.mkdir_p(File.dirname(local_settings_file_path)) + + example.run + + FileUtils.rm_f(global_settings_file_path) + FileUtils.rm_f(local_settings_file_path) + + ENV["GEORDI_TESTING_RUBY_VERSION"] = original_ruby + ENV["GEORDI_TESTING_IRB_VERSION"] = original_irb + end + + context "no irb_flags in geordi config files" do + it "does not automatically set --nomultiline option for Ruby 3+" do + ENV['GEORDI_TESTING_RUBY_VERSION'] = '3.0.0' + ENV['GEORDI_TESTING_IRB_VERSION'] = "1.2.0" + expect(described_class.console_command("development")).to eq "bundle exec rails console -e development " + end + + it "does not automatically set --nomultiline option for IRB < 1.2" do + ENV['GEORDI_TESTING_RUBY_VERSION'] = '2.7.4' + ENV['GEORDI_TESTING_IRB_VERSION'] = "1.1.0" + expect(described_class.console_command("development")).to eq "bundle exec rails console -e development " + end + + it "automatically sets --nomultiline option for IRB 1.2+ Ruby <3, to mitigate slow pasting" do + ENV['GEORDI_TESTING_RUBY_VERSION'] = '2.7.4' + ENV['GEORDI_TESTING_IRB_VERSION'] = "1.2.0" + expect(described_class.console_command("development")).to eq "bundle exec rails console -e development -- --nomultiline" + end + end + + context "irb_flags in global geordi config file" do + it "automatically sets --nomultiline option for IRB 1.2+ Ruby <3, to mitigate slow pasting and merges flags from config" do + write_file(global_settings_file_path, 'irb_flags: --no-readline') + ENV['GEORDI_TESTING_RUBY_VERSION'] = '2.7.4' + ENV['GEORDI_TESTING_IRB_VERSION'] = "1.2.0" + expect(described_class.console_command("development")).to eq "bundle exec rails console -e development -- --nomultiline --no-readline" + end + end + + context "irb_flags in local geordi config file" do + it "does not automatically set --nomultiline option for IRB 1.2+ Ruby <3" do + write_file(local_settings_file_path, 'irb_flags: --no-readline') + ENV['GEORDI_TESTING_RUBY_VERSION'] = '2.7.4' + ENV['GEORDI_TESTING_IRB_VERSION'] = "1.2.0" + expect(described_class.console_command("development")).to eq "bundle exec rails console -e development -- --no-readline" + end + + it "does not automatically set --nomultiline option for IRB 1.2+ Ruby <3 even with empty irb_flags" do + write_file(local_settings_file_path, 'irb_flags:') + ENV['GEORDI_TESTING_RUBY_VERSION'] = '2.7.4' + ENV['GEORDI_TESTING_IRB_VERSION'] = "1.2.0" + expect(described_class.console_command("development")).to eq "bundle exec rails console -e development " + end + end + + context "remote console" do + it "does not automatically set --nomultiline option for Ruby 3+" do + ENV['GEORDI_TESTING_RUBY_VERSION'] = '3.0.0' + ENV['GEORDI_TESTING_IRB_VERSION'] = "1.2.0" + expect(described_class.console_command("staging")).to eq "bundle exec rails console -e staging " + end + + it "does not automatically set --nomultiline option for IRB < 1.2" do + ENV['GEORDI_TESTING_RUBY_VERSION'] = '2.7.4' + ENV['GEORDI_TESTING_IRB_VERSION'] = "1.1.0" + expect(described_class.console_command("staging")).to eq "bundle exec rails console -e staging " + end + + it "automatically sets --nomultiline option for IRB 1.2+ Ruby <3, to mitigate slow pasting" do + ENV['GEORDI_TESTING_RUBY_VERSION'] = '2.7.4' + ENV['GEORDI_TESTING_IRB_VERSION'] = "1.2.0" + expect(described_class.console_command("staging")).to eq "bundle exec rails console -e staging -- --nomultiline" + end + + it "does not automatically set --nomultiline option, but uses irb_flags from local config file" do + write_file(local_settings_file_path, 'irb_flags: --no-readline') + ENV['GEORDI_TESTING_RUBY_VERSION'] = '2.7.4' + ENV['GEORDI_TESTING_IRB_VERSION'] = "1.2.0" + expect(described_class.console_command("staging")).to eq "bundle exec rails console -e staging -- --no-readline" + end + + it "does not automatically set --nomultiline option, but uses irb_flags from global config file" do + write_file(local_settings_file_path, 'irb_flags: --no-readline') + ENV['GEORDI_TESTING_RUBY_VERSION'] = '2.7.4' + ENV['GEORDI_TESTING_IRB_VERSION'] = "1.2.0" + expect(described_class.console_command("staging")).to eq "bundle exec rails console -e staging -- --no-readline" + end + end + + end end