geordi 3.0.0 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -1
  3. data/CHANGELOG.md +36 -2
  4. data/Gemfile.lock +1 -1
  5. data/README.md +46 -3
  6. data/lib/geordi/COMMAND_TEMPLATE +2 -3
  7. data/lib/geordi/chromedriver_updater.rb +7 -8
  8. data/lib/geordi/cli.rb +0 -1
  9. data/lib/geordi/commands/_setup_vnc.rb +22 -22
  10. data/lib/geordi/commands/bundle_install.rb +1 -1
  11. data/lib/geordi/commands/capistrano.rb +4 -4
  12. data/lib/geordi/commands/clean.rb +6 -5
  13. data/lib/geordi/commands/commit.rb +1 -1
  14. data/lib/geordi/commands/console.rb +11 -3
  15. data/lib/geordi/commands/create_database_yml.rb +2 -2
  16. data/lib/geordi/commands/create_databases.rb +1 -1
  17. data/lib/geordi/commands/cucumber.rb +16 -9
  18. data/lib/geordi/commands/delete_dumps.rb +5 -5
  19. data/lib/geordi/commands/deploy.rb +19 -19
  20. data/lib/geordi/commands/drop_databases.rb +3 -3
  21. data/lib/geordi/commands/dump.rb +8 -9
  22. data/lib/geordi/commands/firefox.rb +2 -2
  23. data/lib/geordi/commands/migrate.rb +3 -3
  24. data/lib/geordi/commands/png_optimize.rb +5 -5
  25. data/lib/geordi/commands/rake.rb +1 -1
  26. data/lib/geordi/commands/remove_executable_flags.rb +2 -2
  27. data/lib/geordi/commands/rspec.rb +5 -5
  28. data/lib/geordi/commands/security_update.rb +76 -19
  29. data/lib/geordi/commands/server.rb +2 -2
  30. data/lib/geordi/commands/setup.rb +3 -3
  31. data/lib/geordi/commands/shell.rb +7 -3
  32. data/lib/geordi/commands/tests.rb +1 -1
  33. data/lib/geordi/commands/unit.rb +2 -2
  34. data/lib/geordi/commands/update.rb +2 -2
  35. data/lib/geordi/commands/with_rake.rb +2 -2
  36. data/lib/geordi/commands/yarn_install.rb +1 -1
  37. data/lib/geordi/cucumber.rb +18 -17
  38. data/lib/geordi/db_cleaner.rb +21 -22
  39. data/lib/geordi/dump_loader.rb +5 -4
  40. data/lib/geordi/firefox_for_selenium.rb +17 -19
  41. data/lib/geordi/gitpt.rb +10 -53
  42. data/lib/geordi/interaction.rb +2 -6
  43. data/lib/geordi/remote.rb +17 -6
  44. data/lib/geordi/settings.rb +155 -0
  45. data/lib/geordi/util.rb +14 -9
  46. data/lib/geordi/version.rb +1 -1
  47. metadata +4 -3
@@ -1,19 +1,20 @@
1
1
  class Gitpt
2
- include Geordi::Interaction
3
2
  require 'yaml'
4
3
  require 'highline'
5
4
  require 'tracker_api'
6
5
 
7
- SETTINGS_FILE_NAME = '.gitpt'.freeze
8
- PROJECT_IDS_FILE_NAME = '.pt_project_id'.freeze
6
+ # This require-style is to prevent Ruby from loading files of a different
7
+ # version of Geordi.
8
+ require File.expand_path('settings', __dir__)
9
9
 
10
10
  def initialize
11
11
  self.highline = HighLine.new
12
- self.client = build_client(read_settings)
12
+ self.settings = Geordi::Settings.new
13
+ self.client = build_client
13
14
  end
14
15
 
15
16
  def run(git_args)
16
- warn <<-WARNING unless Geordi::Util.staged_changes?
17
+ Geordi::Interaction.warn <<-WARNING unless Geordi::Util.staged_changes?
17
18
  No staged changes. Will create an empty commit.
18
19
  WARNING
19
20
 
@@ -25,57 +26,17 @@ No staged changes. Will create an empty commit.
25
26
 
26
27
  private
27
28
 
28
- attr_accessor :highline, :client
29
+ attr_accessor :highline, :client, :settings
29
30
 
30
- def read_settings
31
- file_path = File.join(ENV['HOME'], SETTINGS_FILE_NAME)
32
-
33
- unless File.exist?(file_path)
34
- highline.say HighLine::RESET
35
- highline.say "Welcome to #{bold 'gitpt'}.\n\n"
36
-
37
- highline.say highlight('Your settings are missing or invalid.')
38
- highline.say "Please configure your Pivotal Tracker access.\n\n"
39
- token = highline.ask bold('Your API key:') + ' '
40
- highline.say "\n"
41
-
42
- settings = { token: token }
43
- File.open(file_path, 'w') do |file|
44
- file.write settings.to_yaml
45
- end
46
- end
47
-
48
- YAML.load_file(file_path)
49
- end
50
-
51
- def build_client(settings)
52
- TrackerApi::Client.new(token: settings.fetch(:token))
31
+ def build_client
32
+ TrackerApi::Client.new(token: settings.pivotal_tracker_api_key)
53
33
  end
54
34
 
55
35
  def load_projects
56
- project_ids = read_project_ids
36
+ project_ids = settings.pivotal_tracker_project_ids
57
37
  project_ids.collect { |project_id| client.project(project_id) }
58
38
  end
59
39
 
60
- def read_project_ids
61
- file_path = PROJECT_IDS_FILE_NAME
62
-
63
- if File.exist?(file_path)
64
- project_ids = File.read('.pt_project_id').split(/[\s]+/).map(&:to_i)
65
- end
66
-
67
- if project_ids && (project_ids.size > 0)
68
- project_ids
69
- else
70
- warn "Sorry, I could not find a project ID in #{file_path} :("
71
- puts
72
-
73
- puts "Please put at least one Pivotal Tracker project id into #{file_path} in this directory."
74
- puts 'You may add multiple IDs, separated using white space.'
75
- exit 1
76
- end
77
- end
78
-
79
40
  def applicable_stories
80
41
  projects = load_projects
81
42
  projects.collect do |project|
@@ -135,8 +96,4 @@ No staged changes. Will create an empty commit.
135
96
  HighLine::BOLD + string + HighLine::RESET
136
97
  end
137
98
 
138
- def highlight(string)
139
- bold HighLine::BLUE + string
140
- end
141
-
142
99
  end
@@ -3,6 +3,8 @@
3
3
  module Geordi
4
4
  module Interaction
5
5
 
6
+ module_function
7
+
6
8
  # Start your command by `announce`-ing what you're about to do
7
9
  def announce(text)
8
10
  message = "\n# #{text}"
@@ -42,12 +44,6 @@ module Geordi
42
44
  puts "\e[32m#{message}\e[0m" # green
43
45
  end
44
46
 
45
- def strip_heredoc(string)
46
- leading_whitespace = (string.match(/\A( +)[^ ]+/) || [])[1]
47
- string.gsub! /^#{leading_whitespace}/, '' if leading_whitespace
48
- string
49
- end
50
-
51
47
  # Returns the user's input.
52
48
  # If agreement_regex is given, returns whether the input matches the regex.
53
49
  def prompt(text, default = nil, agreement_regex = nil)
@@ -6,7 +6,6 @@ require 'pathname'
6
6
 
7
7
  module Geordi
8
8
  class Remote
9
- include Geordi::Interaction
10
9
 
11
10
  REMOTE_DUMP_PATH = '~/dumps/dump_for_download.dump'.freeze
12
11
 
@@ -35,7 +34,6 @@ module Geordi
35
34
  # Generate dump on the server
36
35
  shell options.merge({
37
36
  remote_command: "dumple #{@config.env} --for_download",
38
- select_server: nil, # Dump must be generated on the primary server
39
37
  })
40
38
 
41
39
  destination_directory = File.join(@config.root, 'tmp')
@@ -43,11 +41,11 @@ module Geordi
43
41
  destination_path = File.join(destination_directory, "#{@stage}.dump")
44
42
  relative_destination = Pathname.new(destination_path).relative_path_from Pathname.new(@config.root)
45
43
 
46
- note "Downloading remote dump to #{relative_destination} ..."
44
+ Interaction.note "Downloading remote dump to #{relative_destination} ..."
47
45
  server = @config.primary_server
48
46
  Util.system! "scp -C #{@config.user(server)}@#{server}:#{REMOTE_DUMP_PATH} #{destination_path}"
49
47
 
50
- success "Dumped the #{@stage} database to #{relative_destination}."
48
+ Interaction.success "Dumped the #{@stage} database to #{relative_destination}."
51
49
 
52
50
  destination_path
53
51
  end
@@ -57,12 +55,25 @@ module Geordi
57
55
  end
58
56
 
59
57
  def shell(options = {})
60
- server = options[:select_server] ? select_server : @config.primary_server
58
+ server_option = options[:select_server]
59
+ server_number = server_option.to_i
60
+
61
+ server = if server_option == 'select_server'
62
+ select_server
63
+ elsif server_number != 0 && server_number <= @config.servers.count
64
+ server_index = server_number - 1
65
+ @config.servers[server_index]
66
+ elsif server_option.nil?
67
+ @config.primary_server
68
+ else
69
+ Interaction.warn "Invalid server number: #{server_option}"
70
+ select_server
71
+ end
61
72
 
62
73
  remote_command = "cd #{@config.remote_root} && #{@config.shell}"
63
74
  remote_command << " -c '#{options[:remote_command]}'" if options[:remote_command]
64
75
 
65
- note 'Connecting to ' + server.to_s
76
+ Interaction.note 'Connecting to ' + server.to_s
66
77
  Util.system! 'ssh', "#{@config.user(server)}@#{server}", '-t', remote_command
67
78
  end
68
79
 
@@ -0,0 +1,155 @@
1
+ require 'yaml'
2
+
3
+ require File.expand_path('util', __dir__)
4
+ require File.expand_path('interaction', __dir__)
5
+
6
+ module Geordi
7
+ class Settings
8
+ GLOBAL_SETTINGS_FILE_NAME = Util.testing? ? './tmp/global_settings.yml'.freeze : File.join(ENV['HOME'], '.config/geordi/global.yml').freeze
9
+ LOCAL_SETTINGS_FILE_NAME = Util.testing? ? './tmp/local_settings.yml'.freeze : './.geordi.yml'.freeze
10
+
11
+ ALLOWED_GLOBAL_SETTINGS = %w[ pivotal_tracker_api_key ].freeze
12
+ ALLOWED_LOCAL_SETTINGS = %w[ use_vnc pivotal_tracker_project_ids ].freeze
13
+
14
+ def initialize
15
+ read_settings
16
+ end
17
+
18
+ # Global settings
19
+ def pivotal_tracker_api_key
20
+ @global_settings['pivotal_tracker_api_key'] || gitpt_api_key_old || inquire_pt_api_key
21
+ end
22
+
23
+ def pivotal_tracker_api_key=(value)
24
+ @global_settings['pivotal_tracker_api_key'] = value
25
+ save_global_settings
26
+ end
27
+
28
+ # Local settings
29
+ # They should not be changed by geordi to avoid unexpected diffs, therefore
30
+ # there are no setters for these settings
31
+ def use_vnc?
32
+ @local_settings.fetch('use_vnc', true)
33
+ end
34
+
35
+ def pivotal_tracker_project_ids
36
+ project_ids = @local_settings['pivotal_tracker_project_ids'] || pt_project_ids_old
37
+
38
+ case project_ids
39
+ when Array
40
+ # nothing to do
41
+ when String
42
+ project_ids = project_ids.split(/[\s]+/).map(&:to_i)
43
+ when Integer
44
+ project_ids = [project_ids]
45
+ else
46
+ project_ids = []
47
+ end
48
+
49
+ if project_ids.empty?
50
+ puts
51
+ Geordi::Interaction.warn "Sorry, I could not find a project ID in .geordi.yml :("
52
+ puts
53
+
54
+ puts "Please put at least one Pivotal Tracker project id into the .geordi.yml file in this directory, e.g."
55
+ puts
56
+ puts "pivotal_tracker_project_ids:"
57
+ puts "- 123456"
58
+ puts
59
+ puts 'You may add multiple IDs.'
60
+ exit 1
61
+ end
62
+
63
+ project_ids
64
+ end
65
+
66
+ private
67
+
68
+ def read_settings
69
+ global_path = GLOBAL_SETTINGS_FILE_NAME
70
+ local_path = LOCAL_SETTINGS_FILE_NAME
71
+
72
+ if File.exists?(global_path)
73
+ global_settings = YAML.safe_load(File.read(global_path))
74
+ check_for_invalid_keys(global_settings, ALLOWED_GLOBAL_SETTINGS, global_path)
75
+ end
76
+
77
+ if File.exists?(local_path)
78
+ local_settings = YAML.safe_load(File.read(local_path))
79
+ check_for_invalid_keys(local_settings, ALLOWED_LOCAL_SETTINGS, local_path)
80
+ end
81
+
82
+ @global_settings = global_settings || {}
83
+ @local_settings = local_settings || {}
84
+ end
85
+
86
+ def check_for_invalid_keys(settings, allowed_keys, file)
87
+ invalid_keys = settings.keys - allowed_keys
88
+ unless invalid_keys.empty?
89
+ Geordi::Interaction.warn "Geordi detected unknown keys in #{file}.\n"
90
+
91
+ invalid_keys.sort.each do |key|
92
+ puts "* #{key}"
93
+ end
94
+
95
+ puts "\nAllowed keys are:"
96
+ allowed_keys.sort.each do |key|
97
+ puts "* #{key}"
98
+ end
99
+ puts
100
+
101
+ exit 1
102
+ end
103
+ end
104
+
105
+ def save_global_settings
106
+ global_path = GLOBAL_SETTINGS_FILE_NAME
107
+ global_directory = File.dirname(global_path)
108
+ FileUtils.mkdir_p(global_directory) unless File.directory? global_directory
109
+ File.open(global_path, 'w') do |file|
110
+ file.write @global_settings.to_yaml
111
+ end
112
+ end
113
+
114
+ # deprecated
115
+ def gitpt_api_key_old
116
+ file_path = File.join(ENV['HOME'], '.gitpt')
117
+ if File.exist?(file_path) && !Util.testing?
118
+ token = YAML.load_file(file_path).fetch :token
119
+ self.pivotal_tracker_api_key = token
120
+
121
+ Geordi::Interaction.warn "The ~/.gitpt file is deprecated."
122
+ Geordi::Interaction.note "The contained setting has been moved to ~/.config/geordi/global.yml."
123
+ Geordi::Interaction.note "If you don't need to work with an older version of geordi you can delete ~/.gitpt now."
124
+
125
+ token
126
+ end
127
+ end
128
+
129
+ def inquire_pt_api_key
130
+ Geordi::Interaction.warn 'Your settings are missing or invalid.'
131
+ Geordi::Interaction.warn "Please configure your Pivotal Tracker access."
132
+ token = Geordi::Interaction.prompt 'Your API key:'
133
+ self.pivotal_tracker_api_key = token
134
+ puts
135
+
136
+ token
137
+ end
138
+
139
+ # deprecated
140
+ def pt_project_ids_old
141
+ if File.exist?('.pt_project_id')
142
+ project_ids = File.read('.pt_project_id')
143
+ puts # Make sure to start on a new line (e.g. when invoked after a #print)
144
+ Geordi::Interaction.warn "The usage of the .pt_project_id file is deprecated."
145
+ Geordi::Interaction.note Util.strip_heredoc(<<-INSTRUCTIONS)
146
+ Please remove this file from your project and add or extend the .geordi.yml file with the following content:
147
+ pivotal_tracker_project_ids: #{project_ids}
148
+ INSTRUCTIONS
149
+
150
+ project_ids
151
+ end
152
+ end
153
+
154
+ end
155
+ end
@@ -4,7 +4,6 @@ require 'socket'
4
4
  module Geordi
5
5
  class Util
6
6
  class << self
7
- include Geordi::Interaction
8
7
 
9
8
  # Geordi commands sometimes require external gems. However, we don't want
10
9
  # all employed gems as runtime dependencies because that would
@@ -20,13 +19,13 @@ module Geordi
20
19
  install_command = 'gem install ' + gem_name
21
20
 
22
21
  # install missing gem
23
- warn 'Probably missing gem: ' + gem_name
24
- prompt('Install it now?', 'y', /y|yes/) || raise('Missing Gems.')
22
+ Interaction.warn 'Probably missing gem: ' + gem_name
23
+ Interaction.prompt('Install it now?', 'y', /y|yes/) || Interaction.fail('Missing Gems.')
25
24
  system! install_command, show_cmd: true
26
25
 
27
26
  # retry
28
27
  Gem.clear_paths
29
- note 'Retrying ...'
28
+ Interaction.note 'Retrying ...'
30
29
  require gem_name
31
30
  retry
32
31
  end
@@ -39,10 +38,10 @@ module Geordi
39
38
  # @option fail_message: The text to print on command failure
40
39
  def system!(*commands)
41
40
  options = commands.last.is_a?(Hash) ? commands.pop : {}
42
- note_cmd commands.join(' ') if options[:show_cmd]
41
+ Interaction.note_cmd commands.join(' ') if options[:show_cmd]
43
42
 
44
43
  if options[:confirm]
45
- prompt('Run this now?', 'n', /y|yes/) || raise('Cancelled.')
44
+ Interaction.prompt('Run this now?', 'n', /y|yes/) or Interaction.fail('Cancelled.')
46
45
  end
47
46
 
48
47
  if testing?
@@ -59,7 +58,7 @@ module Geordi
59
58
  Bundler.clean_system(*commands)
60
59
  end
61
60
 
62
- success || raise(options[:fail_message] || 'Something went wrong.')
61
+ success || Interaction.fail(options[:fail_message] || 'Something went wrong.')
63
62
  end
64
63
  end
65
64
 
@@ -94,7 +93,7 @@ module Geordi
94
93
  ENV['GEORDI_TESTING_STAGED_CHANGES'] == 'true'
95
94
  else
96
95
  statuses = `git status --porcelain`.split("\n")
97
- statuses.any? { |l| l.start_with? /[A-Z]/i }
96
+ statuses.any? { |l| /^[A-Z]/i =~ l }
98
97
  end
99
98
  end
100
99
 
@@ -118,7 +117,7 @@ module Geordi
118
117
  # check if given cmd is executable. Absolute path or command in $PATH allowed.
119
118
  def cmd_exists?(cmd)
120
119
  system("which #{cmd} > /dev/null")
121
- $CHILD_STATUS.exitstatus.zero?
120
+ $?.exitstatus.zero?
122
121
  end
123
122
 
124
123
  def is_port_open?(port)
@@ -167,6 +166,12 @@ module Geordi
167
166
  !!ENV['GEORDI_TESTING']
168
167
  end
169
168
 
169
+ def strip_heredoc(string)
170
+ leading_whitespace = (string.match(/\A( +)[^ ]+/) || [])[1]
171
+ string.gsub! /^#{leading_whitespace}/, '' if leading_whitespace
172
+ string
173
+ end
174
+
170
175
  private
171
176
 
172
177
  def bundle_list
@@ -1,3 +1,3 @@
1
1
  module Geordi
2
- VERSION = '3.0.0'.freeze
2
+ VERSION = '3.2.0'.freeze
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: 3.0.0
4
+ version: 3.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Henning Koch
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-05-04 00:00:00.000000000 Z
11
+ date: 2020-07-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -123,6 +123,7 @@ files:
123
123
  - lib/geordi/gitpt.rb
124
124
  - lib/geordi/interaction.rb
125
125
  - lib/geordi/remote.rb
126
+ - lib/geordi/settings.rb
126
127
  - lib/geordi/util.rb
127
128
  - lib/geordi/version.rb
128
129
  homepage: http://makandra.com
@@ -144,7 +145,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
144
145
  - !ruby/object:Gem::Version
145
146
  version: '0'
146
147
  requirements: []
147
- rubygems_version: 3.0.8
148
+ rubygems_version: 3.0.3
148
149
  signing_key:
149
150
  specification_version: 4
150
151
  summary: Collection of command line tools we use in our daily work with Ruby, Rails