class Geordi::Util
Public Class Methods
# File lib/geordi/util.rb, line 85 def binstub_or_fallback(executable) binstub_file = "bin/#{executable}" File.exist?(binstub_file) ? binstub_file : "bundle exec #{executable}" end
check if given cmd is executable. Absolute path or command in $PATH allowed.
# File lib/geordi/util.rb, line 152 def cmd_exists?(cmd) system("which #{cmd} > /dev/null") $?.exitstatus.zero? end
# File lib/geordi/util.rb, line 91 def console_command(environment) if gem_major_version('rails') == 2 "script/console #{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') Interaction.note 'Using --nomultiline switch for faster pasting' '--nomultiline' end irb_flags = [use_multiline, Settings.new.irb_flags].join(' ').strip irb_flags.prepend('-- ') unless irb_flags.empty? "#{binstub_or_fallback('rails')} console -e #{environment} #{irb_flags}" end end
# File lib/geordi/util.rb, line 213 def cucumber_path?(path) %r{(^|\/)features|\.feature($|:)}.match?(path) end
# File lib/geordi/util.rb, line 117 def current_branch if testing? 'master' else `git rev-parse --abbrev-ref HEAD`.strip end end
try to guess user’s favorite cli text editor
# File lib/geordi/util.rb, line 141 def decide_texteditor %w[/usr/bin/editor vi].each do |texteditor| if cmd_exists?(texteditor) && texteditor.start_with?('$') return ENV[texteditor[1..-1]] elsif cmd_exists? texteditor return texteditor end end end
# File lib/geordi/util.rb, line 134 def deploy_targets Dir['config/deploy/*'].map do |f| File.basename f, '.rb' # Filename without .rb extension end end
# File lib/geordi/util.rb, line 190 def file_containing?(file, regex) File.exist?(file) && File.read(file).scan(regex).any? end
# File lib/geordi/util.rb, line 170 def gem_available?(gem) !!gem_version(gem) end
Get the major version or for the given gem by parsing the Gemfile.lock. Returns nil if the gem is not used.
# File lib/geordi/util.rb, line 176 def gem_major_version(gem) gem_version = gem_version(gem) gem_version && gem_version.segments[0] end
Get the version for the given gem by parsing Gemfile.lock. Returns nil if the gem is not used.
# File lib/geordi/util.rb, line 183 def gem_version(gem) lock_file = Bundler::LockfileParser.new(Bundler.read_file(Bundler.default_lockfile)) spec = lock_file.specs.detect { |spec| spec.name == gem } spec && spec.version end
Geordi
commands sometimes require external gems. However, we don’t want all employed gems as runtime dependencies because that would unnecessarily slow down all commands. Thus, we have this handy method here.
# File lib/geordi/util.rb, line 13 def installing_missing_gems yield rescue LoadError => error error.message =~ /-- (\S+)\Z/ Regexp.last_match(1) || raise # could not extract a gem name from the error message, re-raise the error gem_name = Regexp.last_match(1).strip.split('/').first install_command = 'gem install ' + gem_name # install missing gem Interaction.warn 'Probably missing gem: ' + gem_name Interaction.prompt('Install it now?', 'y', /y|yes/) || Interaction.fail('Missing Gems.') Util.run!(install_command, show_cmd: true) # retry Gem.clear_paths Interaction.note 'Retrying ...' require gem_name retry end
# File lib/geordi/util.rb, line 198 def irb_version version_string = if testing? ENV['GEORDI_TESTING_IRB_VERSION'] else `irb --version`[/irb (\d+\.\d+\.\d+)/, 1] end Gem::Version.new(version_string) end
# File lib/geordi/util.rb, line 157 def is_port_open?(port) socket = TCPSocket.new('127.0.0.1', port) socket.close true rescue Errno::ECONNREFUSED false end
# File lib/geordi/util.rb, line 217 def rspec_path?(path) %r{(^|\/)spec|_spec\.rb($|:)}.match?(path) end
# File lib/geordi/util.rb, line 208 def ruby_version version_string = testing? ? ENV['GEORDI_TESTING_RUBY_VERSION'] : RUBY_VERSION Gem::Version.new(version_string) end
Run a command with a clean environment. Print an error message and exit if the command fails.
show_cmd: Whether to print the command confirm: Whether to ask for confirmation before running it fail_message: The text to print on command failure exec: Whether to run the command with ‘exec` instead of `system`
# File lib/geordi/util.rb, line 41 def run!(command, show_cmd: false, confirm: false, fail_message: 'Something went wrong.', exec: false) # Disable shell features for arrays https://stackoverflow.com/questions/13338147/ruby-system-method-arguments # Conversion: ['ls *', 'some arg'] => ['ls', '*', 'some arg'] # If you need shell features, you need to pass in a String instead of an array. if command.is_a?(Array) real_command, *arguments = *command command = [real_command.split(' '), arguments].flatten show_command = command else show_command = [command] end if show_cmd # Join with spaces for better readability and copy-pasting Interaction.note_cmd show_command.join(' ') end if confirm Interaction.prompt('Run this now?', 'n', /y|yes/) or Interaction.fail('Cancelled.') end if testing? # Join with commas for precise argument distinction puts "Util.run!#{' (exec)' if exec} #{show_command.join(', ')}" else method = exec ? :exec : :system # Remove Geordi's Bundler environment when running commands. success = if !defined?(Bundler) Kernel.public_send(method, *command) elsif Gem::Version.new(Bundler::VERSION) >= Gem::Version.new('1.17.3') Bundler.with_original_env do Kernel.public_send(method, *command) end else method = exec ? :clean_exec : :clean_system Bundler.public_send(method, *command) end # This part will never be reached when `exec` is true success || Interaction.fail(fail_message) end end
# File lib/geordi/util.rb, line 109 def server_command if gem_major_version('rails') == 2 'script/server ""' else "#{binstub_or_fallback('rails')} server" end end
# File lib/geordi/util.rb, line 125 def staged_changes? if testing? ENV['GEORDI_TESTING_STAGED_CHANGES'] == 'true' else statuses = `git status --porcelain`.split("\n") statuses.any? { |l| /^[A-Z]/i =~ l } end end
splint lines e.g. read from a file into lines and clean those up
# File lib/geordi/util.rb, line 166 def stripped_lines(input_string) input_string.lines.map(&:chomp).map(&:strip) end
# File lib/geordi/util.rb, line 194 def testing? !!ENV['GEORDI_TESTING'] end