Class: Geordi::Util
- Inherits:
-
Object
- Object
- Geordi::Util
- Defined in:
- lib/geordi/util.rb
Class Method Summary collapse
- .binstub_or_fallback(executable) ⇒ Object
-
.cmd_exists?(cmd) ⇒ Boolean
check if given cmd is executable.
- .console_command(environment) ⇒ Object
- .cucumber_path?(path) ⇒ Boolean
- .current_branch ⇒ Object
-
.decide_texteditor ⇒ Object
try to guess user’s favorite cli text editor.
- .deploy_targets ⇒ Object
- .file_containing?(file, regex) ⇒ Boolean
- .gem_available?(gem) ⇒ Boolean
-
.gem_major_version(gem) ⇒ Object
Get the major version or for the given gem by parsing the Gemfile.lock.
-
.gem_version(gem) ⇒ Object
Get the version for the given gem by parsing Gemfile.lock.
- .git_default_branch ⇒ Object
-
.installing_missing_gems ⇒ Object
Geordi commands sometimes require external gems.
- .irb_version ⇒ Object
- .is_port_open?(port) ⇒ Boolean
- .rspec_path?(path) ⇒ Boolean
- .ruby_version ⇒ Object
-
.run!(command, show_cmd: false, confirm: false, fail_message: 'Something went wrong.', exec: false) ⇒ Object
Run a command with a clean environment.
- .server_command ⇒ Object
- .staged_changes? ⇒ Boolean
-
.stripped_lines(input_string) ⇒ Object
splint lines e.g.
- .testing? ⇒ Boolean
Class Method Details
.binstub_or_fallback(executable) ⇒ Object
85 86 87 88 89 |
# 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 |
.cmd_exists?(cmd) ⇒ Boolean
check if given cmd is executable. Absolute path or command in $PATH allowed.
152 153 154 155 |
# File 'lib/geordi/util.rb', line 152 def cmd_exists?(cmd) system("which #{cmd} > /dev/null") $?.exitstatus.zero? end |
.console_command(environment) ⇒ Object
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# 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 |
.cucumber_path?(path) ⇒ Boolean
213 214 215 |
# File 'lib/geordi/util.rb', line 213 def cucumber_path?(path) %r{(^|\/)features|\.feature($|:)}.match?(path) end |
.current_branch ⇒ Object
117 118 119 120 121 122 123 |
# File 'lib/geordi/util.rb', line 117 def current_branch if testing? git_default_branch else `git rev-parse --abbrev-ref HEAD`.strip end end |
.decide_texteditor ⇒ Object
try to guess user’s favorite cli text editor
141 142 143 144 145 146 147 148 149 |
# 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 |
.deploy_targets ⇒ Object
134 135 136 137 138 |
# 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_containing?(file, regex) ⇒ Boolean
190 191 192 |
# File 'lib/geordi/util.rb', line 190 def file_containing?(file, regex) File.exist?(file) && File.read(file).scan(regex).any? end |
.gem_available?(gem) ⇒ Boolean
170 171 172 |
# File 'lib/geordi/util.rb', line 170 def gem_available?(gem) !!gem_version(gem) end |
.gem_major_version(gem) ⇒ Object
Get the major version or for the given gem by parsing the Gemfile.lock. Returns nil if the gem is not used.
176 177 178 179 |
# File 'lib/geordi/util.rb', line 176 def gem_major_version(gem) gem_version = gem_version(gem) gem_version && gem_version.segments[0] end |
.gem_version(gem) ⇒ Object
Get the version for the given gem by parsing Gemfile.lock. Returns nil if the gem is not used.
183 184 185 186 187 188 |
# 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 |
.git_default_branch ⇒ Object
221 222 223 224 225 226 227 228 229 230 |
# File 'lib/geordi/util.rb', line 221 def git_default_branch default_branch = if testing? ENV['GEORDI_TESTING_DEFAULT_BRANCH'] else head_symref = `git ls-remote --symref origin HEAD` head_symref[%r{\Aref: refs/heads/(\S+)\sHEAD}, 1] end default_branch || 'master' end |
.installing_missing_gems ⇒ Object
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.
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/geordi/util.rb', line 13 def installing_missing_gems yield rescue LoadError => error error. =~ /-- (\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 |
.irb_version ⇒ Object
198 199 200 201 202 203 204 205 206 |
# 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 |
.is_port_open?(port) ⇒ Boolean
157 158 159 160 161 162 163 |
# 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 |
.rspec_path?(path) ⇒ Boolean
217 218 219 |
# File 'lib/geordi/util.rb', line 217 def rspec_path?(path) %r{(^|\/)spec|_spec\.rb($|:)}.match?(path) end |
.ruby_version ⇒ Object
208 209 210 211 |
# 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!(command, show_cmd: false, confirm: false, fail_message: 'Something went wrong.', exec: false) ⇒ Object
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`
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# 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() end end |
.server_command ⇒ Object
109 110 111 112 113 114 115 |
# 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 |
.staged_changes? ⇒ Boolean
125 126 127 128 129 130 131 132 |
# 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 |
.stripped_lines(input_string) ⇒ Object
splint lines e.g. read from a file into lines and clean those up
166 167 168 |
# File 'lib/geordi/util.rb', line 166 def stripped_lines(input_string) input_string.lines.map(&:chomp).map(&:strip) end |
.testing? ⇒ Boolean
194 195 196 |
# File 'lib/geordi/util.rb', line 194 def testing? !!ENV['GEORDI_TESTING'] end |