geordi 4.1.0 → 5.1.0

Sign up to get free protection for your applications and to get access to all the features.
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.'