geordi 1.2.3 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,10 +8,7 @@ def capistrano(*args)
8
8
 
9
9
  note 'Found the following deploy targets:'
10
10
  puts targets
11
- puts
12
-
13
- print 'Continue? [yN] '
14
- exit unless $stdin.gets =~ /[yes]+/
11
+ prompt('Continue?', 'n', /y|yes/) or fail 'Cancelled.'
15
12
 
16
13
  targets << nil if targets.empty? # default target
17
14
  targets.each do |stage|
@@ -2,13 +2,19 @@ desc 'cucumber [FILES]', 'Run Cucumber features'
2
2
  long_desc <<-LONGDESC
3
3
  Example: `geordi cucumber features/authentication_feature:3`
4
4
 
5
- Runs Cucumber as you want: with `bundle exec`, `cucumber_spinner` detection,
6
- separate Firefox for Selenium, etc.
5
+ Runs Cucumber as you want: with `bundle exec`, using parallel tests, with
6
+ a VNC session holding Selenium test browsers, support for using a dedicated
7
+ testing firefox and beta support for rerunning failed scenarios.
7
8
 
8
- Sometimes, the dot-printing Cucumber formatter does not show errors. In case a
9
- feature fails without a message, try calling with `--debug` or `-d`.
9
+ - *@solo:* Generally, features are run in parallel. However, scenarios tagged
10
+ with @solo are excluded and will be run sequentially, _after_ the parallel run.
10
11
 
11
- Any unknown option will be passed through to Cucumber, e.g. `--format pretty`.
12
+ - *Debugging:* Sometimes, the dot-printing Cucumber formatter does not show
13
+ errors. In case a feature fails without a message, try running it with `--debug`
14
+ or `-d`.
15
+
16
+ - *Options:* Any unknown option will be passed through to Cucumber,
17
+ e.g. `--format pretty`.
12
18
  LONGDESC
13
19
 
14
20
  option :verbose, :aliases => '-v', :type => :boolean,
@@ -35,10 +41,17 @@ def cucumber(*files)
35
41
  fail 'Features failed.' if (i == options.rerun) # All reruns done?
36
42
 
37
43
  announce "Rerun ##{ i + 1 } of #{ options.rerun }"
38
- break if Geordi::Cucumber.new.run(%w[--profile rerun], :verbose => options.verbose)
44
+ break if Geordi::Cucumber.new.run(%w[--profile rerun], :verbose => options.verbose, :parallel => false)
39
45
  end
40
46
  end
41
47
 
48
+ # Serial run of @solo scenarios
49
+ solo_tag_usages = `grep -r '@solo' features`.split("\n")
50
+ if solo_tag_usages.any?
51
+ announce 'Running @solo features'
52
+ Geordi::Cucumber.new.run %w[--tags @solo], :verbose => options.verbose, :parallel => false
53
+ end
54
+
42
55
  else
43
56
  note 'Cucumber not employed.'
44
57
  end
@@ -5,13 +5,13 @@ Example: `geordi deploy production`
5
5
  Merge, push and deploy with a single command! There are several scenarios where
6
6
  this command comes in handy:
7
7
 
8
- 1) Production deploy. From the master branch, run `geordi deploy production`.
8
+ 1) *Production deploy:* From the master branch, run `geordi deploy production`.
9
9
  This will merge `master` to `production`, push and deploy to production.
10
10
 
11
- 2) Feature branch deploy. From the feature branch, run `geordi deploy staging`.
11
+ 2) *Feature branch deploy:* From the feature branch, run `geordi deploy staging`.
12
12
  This will merge the feature branch to `master`, push and deploy to staging.
13
13
 
14
- 3) Simple deploy. If the source branch matches the target branch, merging will
14
+ 3) *Simple deploy:* If the source branch matches the target branch, merging will
15
15
  be skipped.
16
16
 
17
17
  Calling the command without arguments will infer the target stage from the
@@ -36,38 +36,33 @@ def deploy(target_stage = nil)
36
36
  merge_needed = (source_branch != target_branch)
37
37
 
38
38
  announce "Checking whether your #{source_branch} branch is ready"
39
- diff_size = `git fetch && git diff #{source_branch} origin/#{source_branch} | wc -l`.strip
40
- changes_size = `git status -s | wc -l`.strip
41
-
42
- if merge_needed and diff_size != '0'
43
- fail "Your #{source_branch} branch is not the same as on origin. Fix that first."
44
- elsif changes_size != '0'
39
+ if `git status -s | wc -l`.strip != '0'
45
40
  fail "Your #{source_branch} branch holds uncommitted changes. Fix that first."
46
41
  else
47
42
  note 'All good.'
48
43
  end
49
44
 
50
45
  if merge_needed
51
- announce "Checking what's in your #{target_branch} branch right now ..."
46
+ announce "Checking what's in your #{target_branch} branch right now"
52
47
  Util.system! "git checkout #{target_branch} && git pull"
53
48
  end
54
49
 
55
- announce "You are about to #{'merge & ' if merge_needed}push & deploy the following commits"
50
+ announce "You are about to #{'merge & ' if merge_needed}push & deploy"
56
51
  note "From branch #{source_branch}"
57
52
  note "Merge into branch #{target_branch}" if merge_needed
58
53
  note "Deploy to #{target_stage}"
59
54
  Util.system! "git --no-pager log origin/#{target_branch}..#{source_branch} --oneline"
60
55
 
61
56
  if prompt('Go ahead with the deployment?', 'n', /y|yes/)
57
+ cap3 = file_containing?('Capfile', 'capistrano/setup')
62
58
  capistrano_call = "cap #{target_stage} deploy"
63
- capistrano_call << ':migrations' unless options.no_migrations
59
+ capistrano_call << ':migrations' unless cap3 || options.no_migrations
64
60
  capistrano_call = "bundle exec #{capistrano_call}" if file_containing?('Gemfile', /capistrano/)
65
61
 
66
62
  puts
67
63
  command = "git push && #{capistrano_call}"
68
64
  command = "git merge #{source_branch} && " << command if merge_needed
69
- puts 'Pretending to execute:', command
70
- # Util.system! command, :show_cmd => true
65
+ Util.system! command, :show_cmd => true
71
66
 
72
67
  success 'Deployment complete.'
73
68
  else
@@ -1,15 +1,17 @@
1
- desc 'firefox COMMAND', 'Run a command with firefox for selenium set up'
1
+ desc 'firefox COMMAND', 'Run a command with VNC set up (and the test firefox, if present)'
2
2
  long_desc <<-LONGDESC
3
3
  Example: `geordi firefox b cucumber` or `geordi firefox --setup 24.0`
4
4
 
5
- Useful when you need Firefox for Selenium, but can't use the `geordi cucumber`
6
- command.
5
+ Useful when you need Firefox for Selenium or the VNC set up, but can't use the
6
+ `geordi cucumber` command.
7
7
 
8
8
  *Install* a special Firefox by calling with `--setup <version>`.
9
+
10
+ This command is aliased `chrome` for users running Selenium in Chrome.
9
11
  LONGDESC
10
12
 
11
13
  option :setup, :type => :string, :banner => 'setup=FIREFOX_VERSION',
12
- :desc => 'If set, will install a special Firefox with the given version'
14
+ :desc => 'Install a special test-runner Firefox with the given version'
13
15
 
14
16
  def firefox(*command)
15
17
  if options.setup
@@ -17,9 +19,8 @@ def firefox(*command)
17
19
  Geordi::FirefoxForSelenium.install(options.setup)
18
20
 
19
21
  else
20
- note 'Setting up Firefox for Selenium ...'
21
-
22
22
  require 'geordi/cucumber'
23
+
23
24
  Cucumber.new.setup_vnc
24
25
  FirefoxForSelenium.setup_firefox
25
26
 
@@ -28,3 +29,5 @@ def firefox(*command)
28
29
  system *command # Util.system! would reset the Firefox PATH
29
30
  end
30
31
  end
32
+
33
+ map 'chrome' => 'firefox'
@@ -1,4 +1,4 @@
1
- desc 'png-optimize', 'Optimize .png files'
1
+ desc 'png-optimize PATH', 'Optimize .png files'
2
2
  long_desc <<-LONGDESC
3
3
  - Removes color profiles: cHRM, sRGB, gAMA, ICC, etc.
4
4
  - Eliminates unused colors and reduces bit-depth (if possible)
@@ -17,7 +17,7 @@ Optimize a single file:
17
17
  geordi png-optimize input.png
18
18
  LONGDESC
19
19
 
20
- def png_optimize(*args)
20
+ def png_optimize(path)
21
21
  require 'fileutils'
22
22
 
23
23
  announce 'Optimizing .png files'
@@ -27,7 +27,6 @@ def png_optimize(*args)
27
27
  end
28
28
 
29
29
  po = PngOptimizer.new
30
- path = args[0]
31
30
  if File.directory?(path)
32
31
  po.batch_optimize_inplace(path)
33
32
  elsif File.file?(path)
@@ -1,6 +1,3 @@
1
- # This method has a triple 'l' because :shell is a Thor reserved word. However,
2
- # it can still be called with `geordi shell` :)
3
-
4
1
  desc 'shell TARGET', 'Open a shell on a Capistrano deploy target'
5
2
  long_desc <<-LONGDESC
6
3
  Example: `geordi shell production`
@@ -12,6 +9,8 @@ LONGDESC
12
9
 
13
10
  option :select_server, :default => false, :type => :boolean, :aliases => '-s'
14
11
 
12
+ # This method has a triple 'l' because :shell is a Thor reserved word. However,
13
+ # it can still be called with `geordi shell` :)
15
14
  def shelll(target, *args)
16
15
  require 'geordi/remote'
17
16
 
@@ -15,14 +15,14 @@ module Geordi
15
15
  VNC_VIEWER_COMMAND = "vncviewer #{VNC_DISPLAY}"
16
16
  VNC_ENV_VARIABLES = %w[DISPLAY BROWSER LAUNCHY_BROWSER]
17
17
 
18
- def run(files, options)
18
+ def run(files, options = {})
19
19
  self.argv = files
20
20
 
21
21
  consolidate_rerun_txt_files
22
22
  show_features_to_run
23
23
  setup_vnc
24
24
 
25
- command = use_parallel_tests? ? parallel_execution_command : serial_execution_command
25
+ command = use_parallel_tests?(options) ? parallel_execution_command : serial_execution_command
26
26
  note_cmd(command) if options[:verbose]
27
27
 
28
28
  puts
@@ -36,7 +36,7 @@ module Geordi
36
36
  end
37
37
  unless $?.success?
38
38
  if $?.exitstatus == 127
39
- fail 'VNC viewer not found. Install it with `geordi setup-vnc`.'
39
+ fail 'VNC viewer not found. Install it with `geordi vnc --setup`.'
40
40
  else
41
41
  note 'VNC viewer could not be opened:'
42
42
  puts error
@@ -60,7 +60,7 @@ module Geordi
60
60
  ENV["BROWSER"] = ENV["LAUNCHY_BROWSER"] = File.expand_path('../../../bin/launchy_browser', __FILE__)
61
61
  ENV["DISPLAY"] = VNC_DISPLAY
62
62
 
63
- note 'Selenium is running in a VNC window. Use `geordi vnc-show` to view it.'
63
+ note 'VNC is ready to hold Selenium test browsers. Use `geordi vnc` to view them.'
64
64
  end
65
65
  end
66
66
 
@@ -81,14 +81,17 @@ module Geordi
81
81
  self.argv = argv - command_line_features
82
82
  gem 'parallel_tests', parallel_tests_version
83
83
  require 'parallel_tests'
84
+
84
85
  type_arg = Gem::Version.new(::ParallelTests::VERSION) > Gem::Version.new('0.7.0') ? 'cucumber' : 'features'
85
- features_to_run = command_line_features
86
- features_to_run = find_all_features_recursively('features') if features_to_run.empty?
87
- features_to_run = features_to_run.join(" ")
88
- parallel_tests_args = "-t #{type_arg}"
89
- cucumber_args = command_line_args.join(' ')
86
+ features = features_to_run
87
+ features = find_all_features_recursively('features') if features.empty?
90
88
 
91
- [use_firefox_for_selenium, 'b parallel_test', parallel_tests_args, cucumber_args, "-- #{features_to_run}"].flatten.compact.join(" ")
89
+ [
90
+ use_firefox_for_selenium,
91
+ 'b parallel_test -t ' + type_arg,
92
+ "-o '#{ command_line_options.join(' ') } --tags ~@solo'",
93
+ "-- #{ features.join(' ') }"
94
+ ].compact.join(' ')
92
95
  end
93
96
 
94
97
  def use_firefox_for_selenium
@@ -105,7 +108,11 @@ module Geordi
105
108
  end
106
109
 
107
110
  def show_features_to_run
108
- if features_to_run.empty?
111
+ if command_line_options.include? '@solo'
112
+ note 'All features tagged with @solo'
113
+ elsif command_line_options.include? 'rerun'
114
+ note 'Rerunning failed scenarios'
115
+ elsif features_to_run.empty?
109
116
  note 'All features in features/'
110
117
  else
111
118
  notification = 'Only: ' + features_to_run.join(', ')
@@ -116,7 +123,7 @@ module Geordi
116
123
 
117
124
  def features_to_run
118
125
  @features_to_run ||= begin
119
- features = command_line_features
126
+ features = find_all_features_recursively(command_line_features)
120
127
  features = rerun_txt_features if features.empty?
121
128
  features
122
129
  end
@@ -133,18 +140,18 @@ module Geordi
133
140
  end
134
141
 
135
142
  def command_line_features
136
- @command_line_features ||= argv - command_line_args
143
+ @command_line_features ||= argv - command_line_options
137
144
  end
138
145
 
139
- def command_line_args
140
- @command_line_args ||= Array.new.tap do |args|
146
+ def command_line_options
147
+ @command_line_options ||= Array.new.tap do |args|
141
148
  # Sorry for this mess. Option parsing doesn't get much prettier.
142
149
  argv.each_cons(2) do |a, b|
143
150
  break if a == '--' # This is the common no-options-beyond marker
144
151
 
145
152
  case a
146
- when '-f', '--format', '-p', '--profile'
147
- args << a << b # b is the value of the option
153
+ when '-f', '--format', '-p', '--profile', '-t', '--tags'
154
+ args << a << b # b is the value for the option
148
155
  else
149
156
  args << a if a.start_with? '-'
150
157
  end
@@ -183,17 +190,10 @@ module Geordi
183
190
  end.flatten.uniq.compact
184
191
  end
185
192
 
186
- def features_can_run_with_parallel_tests?(features)
187
- features.none? { |f| f.include? ':' }
188
- end
189
-
190
- # Check if cucumber_spinner is available
191
193
  def spinner_available?
192
194
  @spinner_available ||= File.exists?('Gemfile') && File.open('Gemfile').read.scan(/cucumber_spinner/).any?
193
195
  end
194
196
 
195
-
196
- # Check if parallel_tests is available
197
197
  def parallel_tests_available?
198
198
  not parallel_tests_version.nil?
199
199
  end
@@ -208,10 +208,11 @@ module Geordi
208
208
  end
209
209
  end
210
210
 
211
- def use_parallel_tests?
212
- not(argv.include?('rerun') or features_to_run.size == 1) &&
211
+ def use_parallel_tests?(options)
212
+ options.fetch(:parallel, true) &&
213
+ features_to_run.size != 1 &&
213
214
  parallel_tests_available? &&
214
- features_can_run_with_parallel_tests?(features_to_run)
215
+ features_to_run.none? { |f| f.include? ':' }
215
216
  end
216
217
 
217
218
  def try_and_start_vnc
@@ -225,7 +226,7 @@ module Geordi
225
226
  98 # was already running after all
226
227
  true
227
228
  when 127 # not installed
228
- warn 'Could not launch VNC server. Install it with `geordi setup-vnc`.'
229
+ warn 'Could not launch VNC server. Install it with `geordi vnc --setup`.'
229
230
  false
230
231
  else
231
232
  warn 'Starting VNC failed:'
@@ -1,21 +1,36 @@
1
1
  require 'pathname'
2
2
  require 'tempfile'
3
+ require 'geordi/interaction'
3
4
 
4
5
  module Geordi
5
6
  module FirefoxForSelenium
6
- include Geordi::Interaction
7
+ extend Geordi::Interaction
7
8
 
8
9
  FIREFOX_FOR_SELENIUM_BASE_PATH = Pathname.new('~/bin/firefoxes').expand_path
9
10
  FIREFOX_FOR_SELENIUM_PROFILE_NAME = 'firefox-for-selenium'
10
- DEFAULT_FIREFOX_VERSION = "5.0.1"
11
- VERSION_SPECIFICATION_FILE = Pathname.new(".firefox-version")
11
+ FIREFOX_VERSION_FILE = Pathname.new('.firefox-version')
12
12
 
13
13
  def self.install(version)
14
14
  Installer.new(version).run
15
15
  end
16
16
 
17
17
  def self.path_from_config
18
- PathFromConfig.new.run
18
+ version = FIREFOX_VERSION_FILE.exist? && File.read(FIREFOX_VERSION_FILE).strip
19
+
20
+ if version and version != 'system'
21
+ unless FirefoxForSelenium.binary(version).exist?
22
+ warn "Firefox #{ version } not found"
23
+
24
+ note strip_heredoc(<<-INSTRUCTIONS)
25
+ Install it with
26
+ geordi firefox --setup #{ version }
27
+ INSTRUCTIONS
28
+
29
+ prompt 'Run tests anyway?', 'n', /y|yes/ or fail 'Cancelled.'
30
+ end
31
+
32
+ path(version)
33
+ end
19
34
  end
20
35
 
21
36
  def self.path(version)
@@ -28,68 +43,14 @@ module Geordi
28
43
 
29
44
  def self.setup_firefox
30
45
  path = path_from_config
46
+
31
47
  if path
32
48
  ENV['PATH'] = "#{path}:#{ENV['PATH']}"
49
+ note 'Firefox for Selenium set up'
33
50
  end
34
51
  end
35
52
 
36
53
 
37
- class PathFromConfig
38
- include Geordi::Interaction
39
-
40
- def run
41
- unless system_firefox
42
- get_version
43
- validate_install
44
- path
45
- end
46
- end
47
-
48
- private
49
-
50
- def path
51
- FirefoxForSelenium.path(@version)
52
- end
53
-
54
- def system_firefox
55
- version_from_cuc_file == "system"
56
- end
57
-
58
- def get_version
59
- @version = version_from_cuc_file || default_version
60
- end
61
-
62
- def default_version
63
- warn "No firefox version given, defaulting to #{DEFAULT_FIREFOX_VERSION}."
64
- note "Specify a version by putting it in a file named \"#{VERSION_SPECIFICATION_FILE}\"."
65
- puts
66
- DEFAULT_FIREFOX_VERSION
67
- end
68
-
69
- def validate_install
70
- unless FirefoxForSelenium.binary(@version).exist?
71
- note "Firefox #{@version} not found."
72
-
73
- puts strip_heredoc(<<-INSTRUCTIONS)
74
- Install it with
75
- geordi setup_firefox_for_selenium #{@version}
76
-
77
- If you want to use your system firefox and not see this message, add
78
- a .firefox-version file with the content "system".
79
-
80
- INSTRUCTIONS
81
-
82
- prompt "Press ENTER to continue or press CTRL+C to abort."
83
- end
84
- end
85
-
86
- def version_from_cuc_file
87
- File.read(VERSION_SPECIFICATION_FILE).strip if VERSION_SPECIFICATION_FILE.exist?
88
- end
89
-
90
- end
91
-
92
-
93
54
  class Installer
94
55
  include Geordi::Interaction
95
56
 
@@ -43,7 +43,6 @@ module Geordi
43
43
  message = "#{text} "
44
44
  message << "[#{default}] " if default
45
45
 
46
- puts
47
46
  print "\e[36m#{message}\e[0m" # cyan
48
47
  input = $stdin.gets.strip
49
48
  input = default if input.empty? && default
data/lib/geordi/remote.rb CHANGED
@@ -32,16 +32,20 @@ module Geordi
32
32
  end
33
33
 
34
34
  def dump(options = {})
35
- shell(options.merge :remote_command => "dumple #{@config.env} --for_download")
35
+ # Generate dump on the server
36
+ shell options.merge({
37
+ :remote_command => "dumple #{@config.env} --for_download",
38
+ :select_server => nil # Dump must be generated on the primary server
39
+ })
36
40
 
37
41
  destination_directory = File.join(@config.root, 'tmp')
38
42
  FileUtils.mkdir_p destination_directory
39
43
  destination_path = File.join(destination_directory, "#{@stage}.dump")
40
44
  relative_destination = Pathname.new(destination_path).relative_path_from Pathname.new(@config.root)
41
45
 
42
- puts
43
46
  note "Downloading remote dump to #{relative_destination} ..."
44
- Util.system! "scp #{@config.user}@#{@config.primary_server}:#{REMOTE_DUMP_PATH} #{destination_path}"
47
+ server = @config.primary_server
48
+ Util.system! "scp #{ @config.user(server) }@#{ server }:#{REMOTE_DUMP_PATH} #{destination_path}"
45
49
 
46
50
  success "Dumped the #{@stage} database to #{relative_destination}."
47
51
 
@@ -55,11 +59,11 @@ module Geordi
55
59
  def shell(options = {})
56
60
  server = options[:select_server] ? select_server : @config.primary_server
57
61
 
58
- remote_command = "cd #{@config.path} && #{@config.shell}"
62
+ remote_command = "cd #{@config.remote_root} && #{@config.shell}"
59
63
  remote_command << " -c '#{options[:remote_command]}'" if options[:remote_command]
60
64
 
61
65
  note 'Connecting to ' + server.to_s
62
- Util.system! 'ssh', "#{@config.user}@#{server}", '-t', remote_command
66
+ Util.system! 'ssh', "#{ @config.user(server) }@#{ server }", '-t', remote_command
63
67
  end
64
68
 
65
69
  end
data/lib/geordi/util.rb CHANGED
@@ -38,8 +38,12 @@ module Geordi
38
38
  options = commands.last.is_a?(Hash) ? commands.pop : {}
39
39
  note_cmd commands.join(' ') if options[:show_cmd]
40
40
 
41
- # Remove Geordi's Bundler environment when running commands.
42
- Bundler.clean_system(*commands) or fail(options[:fail_message] || 'Something went wrong.')
41
+ if ENV['GEORDI_TESTING']
42
+ puts "Util.system! #{ commands.join(' ') }"
43
+ else
44
+ # Remove Geordi's Bundler environment when running commands.
45
+ Bundler.clean_system(*commands) or fail(options[:fail_message] || 'Something went wrong.')
46
+ end
43
47
  end
44
48
 
45
49
  def console_command(environment)
@@ -1,3 +1,3 @@
1
1
  module Geordi
2
- VERSION = '1.2.3'
2
+ VERSION = '1.3.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: geordi
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.3
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Henning Koch
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-11 00:00:00.000000000 Z
11
+ date: 2016-02-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -53,6 +53,7 @@ files:
53
53
  - .gitignore
54
54
  - .ruby-version
55
55
  - Gemfile
56
+ - Gemfile.lock
56
57
  - LICENSE
57
58
  - README.md
58
59
  - Rakefile
@@ -74,10 +75,15 @@ files:
74
75
  - bin/run_tests
75
76
  - bin/shell-for
76
77
  - bin/tests
78
+ - features/console.feature
79
+ - features/cucumber.feature
80
+ - features/dump.feature
81
+ - features/firefox.feature
82
+ - features/shell.feature
83
+ - features/support/env.rb
77
84
  - geordi.gemspec
78
85
  - lib/geordi.rb
79
86
  - lib/geordi/COMMAND_TEMPLATE
80
- - lib/geordi/capistrano.rb
81
87
  - lib/geordi/capistrano_config.rb
82
88
  - lib/geordi/cli.rb
83
89
  - lib/geordi/commands/_setup_vnc.rb
@@ -115,14 +121,13 @@ files:
115
121
  - lib/geordi/gitpt.rb
116
122
  - lib/geordi/interaction.rb
117
123
  - lib/geordi/remote.rb
118
- - lib/geordi/run_tests.rb
119
124
  - lib/geordi/util.rb
120
125
  - lib/geordi/version.rb
121
126
  homepage: http://makandra.com
122
127
  licenses:
123
128
  - MIT
124
129
  metadata: {}
125
- post_install_message: ! ' Binary `geordi` installed
130
+ post_install_message: ! 'Binary `geordi` installed
126
131
 
127
132
  '
128
133
  rdoc_options: []