geordi 4.1.0 → 5.1.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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +48 -0
  3. data/.ruby-version +1 -1
  4. data/CHANGELOG.md +49 -0
  5. data/Gemfile +2 -1
  6. data/Gemfile.lock +46 -28
  7. data/README.md +21 -4
  8. data/Rakefile +1 -1
  9. data/exe/dumple +9 -4
  10. data/geordi.gemspec +4 -4
  11. data/lib/geordi/COMMAND_TEMPLATE +1 -1
  12. data/lib/geordi/chromedriver_updater.rb +2 -2
  13. data/lib/geordi/cli.rb +1 -1
  14. data/lib/geordi/commands/_setup_vnc.rb +8 -10
  15. data/lib/geordi/commands/bundle_install.rb +1 -1
  16. data/lib/geordi/commands/capistrano.rb +1 -1
  17. data/lib/geordi/commands/chromedriver_update.rb +8 -1
  18. data/lib/geordi/commands/commit.rb +0 -4
  19. data/lib/geordi/commands/console.rb +4 -3
  20. data/lib/geordi/commands/create_database_yml.rb +1 -1
  21. data/lib/geordi/commands/create_databases.rb +7 -6
  22. data/lib/geordi/commands/cucumber.rb +9 -4
  23. data/lib/geordi/commands/deploy.rb +7 -7
  24. data/lib/geordi/commands/dump.rb +14 -4
  25. data/lib/geordi/commands/firefox.rb +1 -1
  26. data/lib/geordi/commands/migrate.rb +4 -4
  27. data/lib/geordi/commands/rake.rb +6 -4
  28. data/lib/geordi/commands/rspec.rb +5 -5
  29. data/lib/geordi/commands/security_update.rb +10 -10
  30. data/lib/geordi/commands/server.rb +3 -3
  31. data/lib/geordi/commands/setup.rb +5 -5
  32. data/lib/geordi/commands/shell.rb +1 -1
  33. data/lib/geordi/commands/tests.rb +4 -4
  34. data/lib/geordi/commands/unit.rb +3 -3
  35. data/lib/geordi/commands/update.rb +4 -4
  36. data/lib/geordi/commands/vnc.rb +1 -1
  37. data/lib/geordi/commands/with_rake.rb +3 -3
  38. data/lib/geordi/commands/yarn_install.rb +1 -1
  39. data/lib/geordi/cucumber.rb +5 -4
  40. data/lib/geordi/dump_loader.rb +1 -1
  41. data/lib/geordi/gitpt.rb +1 -1
  42. data/lib/geordi/interaction.rb +1 -1
  43. data/lib/geordi/remote.rb +5 -4
  44. data/lib/geordi/settings.rb +11 -2
  45. data/lib/geordi/util.rb +33 -21
  46. data/lib/geordi/version.rb +1 -1
  47. metadata +6 -6
  48. data/.travis.yml +0 -23
@@ -2,6 +2,6 @@ desc 'bundle-install', 'Run bundle install if required', hide: true
2
2
  def bundle_install
3
3
  if File.exist?('Gemfile') && !system('bundle check > /dev/null 2>&1')
4
4
  Interaction.announce 'Bundling'
5
- Util.system! 'bundle install'
5
+ Util.run!('bundle install')
6
6
  end
7
7
  end
@@ -17,6 +17,6 @@ def capistrano(*args)
17
17
  command = "bundle exec cap #{stage} " + args.join(' ')
18
18
  Interaction.note_cmd command
19
19
 
20
- Util.system!(command, fail_message: 'Capistrano failed. Have a look!')
20
+ Util.run!(command, fail_message: 'Capistrano failed. Have a look!')
21
21
  end
22
22
  end
@@ -4,10 +4,17 @@ Example: `geordi chromedriver_update`
4
4
 
5
5
  This command will find and install the matching chromedriver for the currently
6
6
  installed Chrome.
7
+
8
+ Setting `auto_update_chromedriver` to `true` in your global Geordi config file
9
+ (`~/.config/geordi/global.yml`), will automatically update chromedriver before
10
+ cucumber tests, in case Chrome and chromedriver versions don't match
7
11
  LONGDESC
8
12
 
13
+ option :quiet_if_matching, type: :boolean, default: false,
14
+ desc: 'Suppress notification if chromedriver and chrome versions match'
15
+
9
16
  def chromedriver_update
10
17
  require 'geordi/chromedriver_updater'
11
18
 
12
- ChromedriverUpdater.new.run
19
+ ChromedriverUpdater.new.run(options)
13
20
  end
@@ -9,10 +9,6 @@ stored in `~/.config/geordi/global.yml`.
9
9
  LONGDESC
10
10
 
11
11
  def commit(*git_args)
12
- raise <<-TEXT if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.1')
13
- Unsupported Ruby Version #{RUBY_VERSION}. `geordi commit` requires Ruby 2.1+.
14
- TEXT
15
-
16
12
  require 'geordi/gitpt'
17
13
  Gitpt.new.run(git_args)
18
14
  end
@@ -14,14 +14,15 @@ option :select_server, type: :string, aliases: '-s', banner: '[SERVER_NUMBER]',
14
14
 
15
15
  def console(target = 'development', *_args)
16
16
  require 'geordi/remote'
17
- invoke_cmd 'bundle_install'
17
+ invoke_geordi 'bundle_install'
18
18
 
19
19
  if target == 'development'
20
- invoke_cmd 'yarn_install'
20
+ invoke_geordi 'yarn_install'
21
21
 
22
22
  Interaction.announce 'Opening a local Rails console'
23
23
 
24
- Util.system! Util.console_command(target)
24
+ command = Util.console_command(target)
25
+ Util.run!(command)
25
26
  else
26
27
  Interaction.announce 'Opening a Rails console on ' + target
27
28
 
@@ -7,7 +7,7 @@ def create_database_yml
7
7
  Interaction.announce 'Creating ' + real_yml
8
8
 
9
9
  sample = File.read(sample_yml)
10
- adapter = sample.match(/adapter: (\w+)\n/).captures.first
10
+ adapter = sample.match(/adapter: (\w+)/).captures.first
11
11
 
12
12
  print "Please enter your #{adapter} password: "
13
13
  db_password = STDIN.gets.strip
@@ -1,16 +1,17 @@
1
1
  desc 'create-databases', 'Create all databases', hide: true
2
2
  def create_databases
3
- invoke_cmd 'create_database_yml'
4
- invoke_cmd 'bundle_install'
3
+ invoke_geordi 'create_database_yml'
4
+ invoke_geordi 'bundle_install'
5
5
 
6
6
  Interaction.announce 'Creating databases'
7
7
 
8
8
  if File.exist?('config/database.yml')
9
- command = Util.binstub 'rake'
10
- command << ' db:create:all'
11
- command << ' parallel:create' if Util.file_containing?('Gemfile', /parallel_tests/)
9
+ command = []
10
+ command << Util.binstub_or_fallback('rake')
11
+ command << 'db:create:all'
12
+ command << 'parallel:create' if Util.file_containing?('Gemfile', /parallel_tests/)
12
13
 
13
- Util.system! command
14
+ Util.run!(command)
14
15
  else
15
16
  puts 'config/database.yml does not exist. Nothing to do.'
16
17
  end
@@ -37,7 +37,7 @@ def cucumber(*args)
37
37
  if args.empty?
38
38
  # This is not testable as there is no way to stub `git` :(
39
39
  if options.modified?
40
- modified_features = `git status --short`.split($INPUT_RECORD_SEPARATOR).map do |line|
40
+ modified_features = `git status --short`.split("\n").map do |line|
41
41
  indicators = line.slice!(0..2) # Remove leading indicators
42
42
  line if line.include?('.feature') && !indicators.include?('D')
43
43
  end.compact
@@ -45,7 +45,7 @@ def cucumber(*args)
45
45
  end
46
46
 
47
47
  if options.containing
48
- matching_features = `grep -lri '#{options.containing}' --include=*.feature features/`.split($INPUT_RECORD_SEPARATOR)
48
+ matching_features = `grep -lri '#{options.containing}' --include=*.feature features/`.split("\n")
49
49
  args = matching_features.uniq
50
50
  end
51
51
  end
@@ -53,8 +53,13 @@ def cucumber(*args)
53
53
  if File.directory?('features')
54
54
  require 'geordi/cucumber'
55
55
 
56
- invoke_cmd 'bundle_install'
57
- invoke_cmd 'yarn_install'
56
+ settings = Geordi::Settings.new
57
+
58
+ invoke_geordi 'bundle_install'
59
+ invoke_geordi 'yarn_install'
60
+ if settings.auto_update_chromedriver
61
+ invoke_geordi 'chromedriver_update', quiet_if_matching: true
62
+ end
58
63
 
59
64
  cmd_opts, files = args.partition { |f| f.start_with? '-' }
60
65
  cmd_opts << '--format' << 'pretty' << '--backtrace' if options.debug
@@ -66,7 +66,7 @@ set :branch, ENV['DEPLOY_BRANCH'] || 'master'
66
66
  push_needed = false if Util.testing? # Hard to test
67
67
 
68
68
  Interaction.announce "Checking whether your #{source_branch} branch is ready" ############
69
- Util.system! "git checkout #{source_branch}"
69
+ Util.run!("git checkout #{source_branch}")
70
70
  if (`git status -s | wc -l`.strip != '0') && !Util.testing?
71
71
  Interaction.warn "Your #{source_branch} branch holds uncommitted changes."
72
72
  Interaction.prompt('Continue anyway?', 'n', /y|yes/) || raise('Cancelled.')
@@ -76,14 +76,14 @@ set :branch, ENV['DEPLOY_BRANCH'] || 'master'
76
76
 
77
77
  if merge_needed
78
78
  Interaction.announce "Checking what's in your #{target_branch} branch right now" #######
79
- Util.system! "git checkout #{target_branch} && git pull"
79
+ Util.run!("git checkout #{target_branch} && git pull")
80
80
  end
81
81
 
82
82
  Interaction.announce 'You are about to:' #################################################
83
83
  Interaction.note "Merge branch #{source_branch} into #{target_branch}" if merge_needed
84
84
  if push_needed
85
85
  Interaction.note 'Push these commits:' if push_needed
86
- Util.system! "git --no-pager log origin/#{target_branch}..#{source_branch} --oneline"
86
+ Util.run!("git --no-pager log origin/#{target_branch}..#{source_branch} --oneline")
87
87
  end
88
88
  Interaction.note "Deploy to #{target_stage}"
89
89
  Interaction.note "From current branch #{source_branch}" if options.current_branch
@@ -94,7 +94,7 @@ set :branch, ENV['DEPLOY_BRANCH'] || 'master'
94
94
  git_call << "git merge #{source_branch}" if merge_needed
95
95
  git_call << 'git push' if push_needed
96
96
 
97
- invoke_cmd 'bundle_install'
97
+ invoke_geordi 'bundle_install'
98
98
 
99
99
  capistrano_call = "cap #{target_stage} deploy"
100
100
  capistrano_call << ':migrations' unless Util.gem_major_version('capistrano') == 3 || options.no_migrations
@@ -102,14 +102,14 @@ set :branch, ENV['DEPLOY_BRANCH'] || 'master'
102
102
  capistrano_call = "DEPLOY_BRANCH=#{source_branch} #{capistrano_call}" if options.current_branch
103
103
 
104
104
  if git_call.any?
105
- Util.system! git_call.join(' && '), show_cmd: true
105
+ Util.run!(git_call.join(' && '), show_cmd: true)
106
106
  end
107
107
 
108
- Util.system! capistrano_call, show_cmd: true
108
+ Util.run!(capistrano_call, show_cmd: true)
109
109
 
110
110
  Interaction.success 'Deployment complete.'
111
111
  else
112
- Util.system! "git checkout #{source_branch}"
112
+ Util.run!("git checkout #{source_branch}")
113
113
  Interaction.fail 'Deployment cancelled.'
114
114
  end
115
115
  end
@@ -10,13 +10,21 @@ specified target's database and downloads it to `tmp/`.
10
10
 
11
11
  `geordi dump staging -l` (with a Capistrano deploy target and the `--load`
12
12
  option) sources the dump into the development database after downloading it.
13
+
14
+ If you are using multiple databases per environment, pass the database name like this:
15
+
16
+ geordi dump -d primary
17
+
18
+ Loading a dump into one of multiple local databases is not supported yet.
13
19
  DESC
14
20
 
15
21
  option :load, aliases: '-l', type: :string, desc: 'Load a dump', banner: '[DUMP_FILE]'
22
+ option :database, aliases: '-d', type: :string, desc: 'Database name, if there are multiple databases', banner: 'NAME'
16
23
 
17
24
  def dump(target = nil, *_args)
18
25
  require 'geordi/dump_loader'
19
26
  require 'geordi/remote'
27
+ database = options[:database] ? "#{options[:database]} " : ''
20
28
 
21
29
  if target.nil?
22
30
  if options.load
@@ -33,12 +41,14 @@ def dump(target = nil, *_args)
33
41
 
34
42
  else
35
43
  Interaction.announce 'Dumping the development database'
36
- Util.system! 'dumple development'
37
- Interaction.success 'Successfully dumped the development database.'
44
+ Util.run!("dumple development #{database}")
45
+ Interaction.success "Successfully dumped the #{database}development database."
38
46
  end
39
47
 
40
48
  else
41
- Interaction.announce 'Dumping the database of ' + target
49
+ database_label = options[:database] ? " (#{database}database)" : ""
50
+
51
+ Interaction.announce "Dumping the database of #{target}#{database_label}"
42
52
  dump_path = Geordi::Remote.new(target).dump(options)
43
53
 
44
54
  if options.load
@@ -47,7 +57,7 @@ def dump(target = nil, *_args)
47
57
  Interaction.announce "Sourcing dump into the #{loader.config['database']} db"
48
58
  loader.load
49
59
 
50
- Interaction.success "Your #{loader.config['database']} database has now the data of #{target}."
60
+ Interaction.success "Your #{loader.config['database']} database has now the data of #{target}#{database_label}."
51
61
  end
52
62
  end
53
63
  end
@@ -25,7 +25,7 @@ def firefox(*command)
25
25
 
26
26
  puts
27
27
  Interaction.note_cmd command.join(' ')
28
- system *command # Util.system! would reset the Firefox PATH
28
+ system *command # Util.run! would reset the Firefox PATH
29
29
  end
30
30
  end
31
31
 
@@ -8,8 +8,8 @@ with `db:migrate`.
8
8
  LONGDESC
9
9
 
10
10
  def migrate
11
- invoke_cmd 'bundle_install'
12
- invoke_cmd 'yarn_install'
11
+ invoke_geordi 'bundle_install'
12
+ invoke_geordi 'yarn_install'
13
13
  Interaction.announce 'Migrating'
14
14
 
15
15
  if File.directory?('db/migrate')
@@ -17,9 +17,9 @@ def migrate
17
17
  Interaction.note 'Development and parallel test databases'
18
18
  puts
19
19
 
20
- Util.system! Util.binstub('rake'), 'db:migrate', 'parallel:prepare'
20
+ Util.run!([Util.binstub_or_fallback('rake'), 'db:migrate', 'parallel:prepare'])
21
21
  else
22
- invoke_cmd 'rake', 'db:migrate'
22
+ invoke_geordi 'rake', 'db:migrate'
23
23
  end
24
24
  else
25
25
  Interaction.note 'No migrations directory found.'
@@ -10,14 +10,16 @@ Example: `geordi rake db:migrate`
10
10
  LONGDESC
11
11
 
12
12
  def rake(*args)
13
- invoke_cmd 'bundle_install'
13
+ invoke_geordi 'bundle_install'
14
14
 
15
15
  %w[development test cucumber].each do |env| # update long_desc when changing this
16
16
  if File.exist? "config/environments/#{env}.rb"
17
- call = [Util.binstub('rake')] + args + ["RAILS_ENV=#{env}"]
18
- Interaction.note_cmd call.join(' ')
17
+ command = []
18
+ command << Util.binstub_or_fallback('rake')
19
+ command += args
20
+ command << "RAILS_ENV=#{env}"
19
21
 
20
- Util.system! *call
22
+ Util.run!(command, show_cmd: true)
21
23
  end
22
24
  end
23
25
  end
@@ -7,14 +7,14 @@ LONGDESC
7
7
 
8
8
  def rspec(*files)
9
9
  if File.exist?('spec/spec_helper.rb')
10
- invoke_cmd 'bundle_install'
11
- invoke_cmd 'yarn_install'
10
+ invoke_geordi 'bundle_install'
11
+ invoke_geordi 'yarn_install'
12
12
 
13
13
  Interaction.announce 'Running specs'
14
14
 
15
15
  if Util.file_containing?('Gemfile', /parallel_tests/) && files.empty?
16
16
  Interaction.note 'All specs at once (using parallel_tests)'
17
- Util.system! Util.binstub('rake'), 'parallel:spec', fail_message: 'Specs failed.'
17
+ Util.run!([Util.binstub_or_fallback('rake'), 'parallel:spec'], fail_message: 'Specs failed.')
18
18
 
19
19
  else
20
20
  # tell which specs will be run
@@ -28,13 +28,13 @@ def rspec(*files)
28
28
  command = if File.exist?('script/spec')
29
29
  ['bundle exec spec -c'] # RSpec 1
30
30
  else
31
- [Util.binstub('rspec')]
31
+ [Util.binstub_or_fallback('rspec')]
32
32
  end
33
33
  command << '-r rspec_spinner -f RspecSpinner::Bar' if Util.file_containing?('Gemfile', /rspec_spinner/)
34
34
  command << files.join(' ')
35
35
 
36
36
  puts
37
- Util.system! command.join(' '), fail_message: 'Specs failed.'
37
+ Util.run!(command.join(' '), fail_message: 'Specs failed.')
38
38
  end
39
39
  else
40
40
  Interaction.note 'RSpec not employed.'
@@ -35,8 +35,8 @@ def security_update(step = 'prepare')
35
35
  Interaction.note 'About to checkout production and pull.'
36
36
  Interaction.prompt('Continue?', 'y', /y|yes/) || Interaction.fail('Cancelled.')
37
37
 
38
- Util.system! 'git checkout production', show_cmd: true
39
- Util.system! 'git pull', show_cmd: true
38
+ Util.run!('git checkout production', show_cmd: true)
39
+ Util.run!('git pull', show_cmd: true)
40
40
 
41
41
  Interaction.success 'Successfully prepared for security update'
42
42
  puts
@@ -47,7 +47,7 @@ def security_update(step = 'prepare')
47
47
  when 'f', 'finish'
48
48
  # ensure everything is committed
49
49
  if Util.testing?
50
- puts 'Util.system! git status --porcelain'
50
+ puts 'Util.run! git status --porcelain'
51
51
  else
52
52
  `git status --porcelain`.empty? || Interaction.fail('Please commit your changes before finishing the update.')
53
53
  end
@@ -59,11 +59,11 @@ def security_update(step = 'prepare')
59
59
  Interaction.note 'About to: push production, checkout & pull master, merge production, push master.'
60
60
  Interaction.prompt('Continue?', 'n', /y|yes/) || Interaction.fail('Cancelled.')
61
61
 
62
- Util.system! 'git push', show_cmd: true
63
- Util.system! 'git checkout master', show_cmd: true
64
- Util.system! 'git pull', show_cmd: true
65
- Util.system! 'git merge production', show_cmd: true
66
- Util.system! 'git push', show_cmd: true
62
+ Util.run!('git push', show_cmd: true)
63
+ Util.run!('git checkout master', show_cmd: true)
64
+ Util.run!('git pull', show_cmd: true)
65
+ Util.run!('git merge production', show_cmd: true)
66
+ Util.run!('git push', show_cmd: true)
67
67
 
68
68
  Interaction.announce 'Deployment'
69
69
  deploy = (Util.gem_major_version('capistrano') == 3) ? 'deploy' : 'deploy:migrations'
@@ -76,7 +76,7 @@ def security_update(step = 'prepare')
76
76
  Interaction.prompt('Deploy staging now?', 'y', /y|yes/) || Interaction.fail('Cancelled.')
77
77
 
78
78
  Interaction.announce 'Deploy staging'
79
- Util.system! "bundle exec cap staging #{deploy}", show_cmd: true
79
+ Util.run! "bundle exec cap staging #{deploy}", show_cmd: true
80
80
 
81
81
  Interaction.prompt('Is the deployment log okay and the application is still running on staging?', 'y', /y|yes/) || Interaction.fail('Please fix the deployment issues on staging before you continue.')
82
82
  else
@@ -96,7 +96,7 @@ def security_update(step = 'prepare')
96
96
 
97
97
  deploy_targets_without_staging.each do |target|
98
98
  Interaction.announce "Deploy #{target}"
99
- Util.system! "bundle exec cap #{target} #{deploy}", show_cmd: true
99
+ Util.run!("bundle exec cap #{target} #{deploy}", show_cmd: true)
100
100
  end
101
101
 
102
102
  Interaction.prompt('Is the application still running on all other stages and the logs are okay?', 'y', /y|yes/) || Interaction.fail('Please fix the application immediately!')
@@ -6,8 +6,8 @@ option :public, aliases: '-P', type: :boolean,
6
6
  desc: 'Make the server accessible from the local network'
7
7
 
8
8
  def server(port = nil)
9
- invoke_cmd 'bundle_install'
10
- invoke_cmd 'yarn_install'
9
+ invoke_geordi 'bundle_install'
10
+ invoke_geordi 'yarn_install'
11
11
  require 'geordi/util'
12
12
 
13
13
  Interaction.announce 'Booting a development server'
@@ -18,7 +18,7 @@ def server(port = nil)
18
18
  command = Util.server_command
19
19
  command << ' -b 0.0.0.0' if options.public
20
20
  command << ' -p ' << port
21
- Util.system! command
21
+ Util.run!(command)
22
22
  end
23
23
 
24
24
  map 'devserver' => 'server'
@@ -19,14 +19,14 @@ def setup
19
19
  Interaction.announce 'Running bin/setup'
20
20
  Interaction.note "Geordi's own setup routine is skipped"
21
21
 
22
- Util.system! 'bin/setup'
22
+ Util.run!('bin/setup')
23
23
  else
24
- invoke_cmd 'create_databases'
25
- invoke_cmd 'migrate'
24
+ invoke_geordi 'create_databases'
25
+ invoke_geordi 'migrate'
26
26
  end
27
27
 
28
28
  Interaction.success 'Successfully set up the project.'
29
29
 
30
- invoke_cmd 'dump', options.dump, load: true if options.dump
31
- invoke_cmd 'tests' if options.test
30
+ invoke_geordi 'dump', options.dump, load: true if options.dump
31
+ invoke_geordi 'tests' if options.test
32
32
  end
@@ -15,7 +15,7 @@ option :select_server, type: :string, aliases: '-s', banner: '[SERVER_NUMBER]',
15
15
  def shelll(target, *_args)
16
16
  require 'geordi/remote'
17
17
 
18
- invoke_cmd 'bundle_install'
18
+ invoke_geordi 'bundle_install'
19
19
 
20
20
  Interaction.announce 'Opening a shell on ' + target
21
21
  Geordi::Remote.new(target).shell(options)
@@ -1,13 +1,13 @@
1
1
  desc 'tests', 'Run all employed tests'
2
2
  def tests
3
- rake_result = invoke_cmd 'with_rake'
3
+ rake_result = invoke_geordi 'with_rake'
4
4
 
5
5
  # Since `rake` usually is configured to run all tests, only run them if `rake`
6
6
  # did not perform
7
7
  if rake_result == :did_not_perform
8
- invoke_cmd 'unit'
9
- invoke_cmd 'rspec'
10
- invoke_cmd 'cucumber'
8
+ invoke_geordi 'unit'
9
+ invoke_geordi 'rspec'
10
+ invoke_geordi 'cucumber'
11
11
  end
12
12
 
13
13
  Interaction.success 'Successfully ran tests.'