geordi 9.5.1 → 9.6.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 506036483e1c31f8fab13388d6f92168227df95506f56ce5e28241f9ef867fc1
4
- data.tar.gz: 85ef8a779e3e699865d0eb3f589fd252dd345771946daaed057e3615fcca1ca5
3
+ metadata.gz: 8a4dc434853c2c8af63e6ac18e69cca013d3a15316401f710c90deab74cd9bbb
4
+ data.tar.gz: c158a1f4c095120bfbd3ce9aacbd6bf13424994cdfd1ea5c2d5d8b613db5179e
5
5
  SHA512:
6
- metadata.gz: fb8e5d65caf516ff4a4a5da1655ba5cf8001d8d0c875b68908e39e993dfbde7a3cdb4b887318192cb5bf22f5e2555a5d7796061c72fb2cf745c23c87a71c2ade
7
- data.tar.gz: 9ddb734143d4162be8e6cf053f7b9aa35f7c72c69558caedcdb4ed9021b6c16b1bfd3ee84d6c13ad089b4af154d0bd0a197873355ab0dafaebc26710150f38d4
6
+ metadata.gz: 2260516cf299c4202fbf276c36abbee42190fb9e48b0f583b1af05a457c7676f6d23ccaee7d2bd8ddc2bcdfa923a255cae706dc5c1414c97eab1be58635ad205
7
+ data.tar.gz: e556b2806dea5a5badbcdad1c22faad5fb56daf95923f1c5ac88f64f1a764d18aacf4d0d683ad0f2b050cbdb131482895da3d58157992af2e11d67e75d0e75bf
data/CHANGELOG.md CHANGED
@@ -10,10 +10,21 @@ This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html
10
10
  ### Breaking changes
11
11
 
12
12
 
13
- # 9.5.1 - 2023-04-26
13
+ # 9.6.1 2023-09-22
14
14
 
15
15
  ### Compatible changes
16
+ * `chromedriver-update` command: Retrieve chromedriver from new location
16
17
 
18
+
19
+ # 9.6.0 2023-07-24
20
+
21
+ ### Compatible changes
22
+ * Add suggestions of related commands
23
+
24
+
25
+ # 9.5.1 2023-04-26
26
+
27
+ ### Compatible changes
17
28
  * `cucumber` command: Support the passing of options without "="
18
29
 
19
30
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- geordi (9.5.1)
4
+ geordi (9.6.1)
5
5
  thor (~> 1)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -34,7 +34,7 @@ stored in `~/.config/geordi/global.yml`.
34
34
 
35
35
 
36
36
  ### `geordi capistrano COMMAND`
37
- Run a capistrano command on all deploy targets.
37
+ Run a Capistrano command on all deploy targets.
38
38
 
39
39
  Example: `geordi capistrano deploy`
40
40
 
@@ -26,6 +26,11 @@ def example
26
26
  Interaction.fail 'Option missing' unless options.opt?
27
27
 
28
28
  Interaction.success 'Done.'
29
+ Hint.did_you_know [
30
+ :update, # recommendation of another command
31
+ [:cucumber, :containing], # recommendation of another option
32
+ 'Geordi can automatically update chromedriver before Cucumber tests. See `geordi help chromedriver-update`.', # prose
33
+ ]
29
34
  end
30
35
 
31
36
  # Command mappings, usually not needed
@@ -1,9 +1,12 @@
1
1
  require 'open3'
2
2
  require 'net/http'
3
3
  require 'tempfile'
4
+ require 'json'
5
+ require 'fileutils'
4
6
 
5
7
  module Geordi
6
8
  class ChromedriverUpdater
9
+ VERSIONS_PER_MILESTONES_URL = "https://googlechromelabs.github.io/chrome-for-testing/latest-versions-per-milestone-with-downloads.json"
7
10
 
8
11
  def run(options)
9
12
  chrome_version = determine_chrome_version
@@ -11,7 +14,7 @@ module Geordi
11
14
 
12
15
  latest_chromedriver_version = latest_version(chrome_version)
13
16
  if current_chromedriver_version == latest_chromedriver_version
14
- Interaction.success "No update required: Chromedriver is already on the latest version v#{latest_chromedriver_version}!" unless options[:quiet_if_matching]
17
+ Interaction.note "No update required. Chromedriver is already on the latest version #{latest_chromedriver_version}." unless options[:quiet_if_matching]
15
18
  else
16
19
  update_chromedriver(latest_chromedriver_version)
17
20
  end
@@ -49,8 +52,8 @@ module Geordi
49
52
 
50
53
  # Check https://groups.google.com/a/chromium.org/g/chromium-discuss/c/4BB4jmsRyv8/m/TY3FXS4HBgAJ
51
54
  # for information how chrome version numbers work
52
- def major_version(full_version)
53
- full_version.match(/^(\d+\.\d+\.\d+)\.\d+$/)[1]
55
+ def milestone_version(full_version)
56
+ full_version.match(/^\d+/)[0]
54
57
  end
55
58
 
56
59
  def update_chromedriver(latest_chromedriver_version)
@@ -62,39 +65,68 @@ module Geordi
62
65
  Interaction.success "Chromedriver updated to v#{determine_chromedriver_version}."
63
66
  end
64
67
 
65
- def download_chromedriver(latest_version)
66
- uri = URI("https://chromedriver.storage.googleapis.com/#{latest_version}/chromedriver_linux64.zip")
67
- response = Net::HTTP.get_response(uri)
68
-
69
- if response.is_a?(Net::HTTPSuccess)
70
- file = Tempfile.new(['chromedriver', '.zip'])
68
+ def download_chromedriver(version)
69
+ fetch_response(chromedriver_url(version), "Could not download chromedriver v#{version}.") do |response|
70
+ file = Tempfile.new(%w[chromedriver .zip])
71
71
  file.write(response.body)
72
72
 
73
73
  file
74
- else
75
- Interaction.fail("Could not download chromedriver v#{latest_version}.")
76
74
  end
77
75
  end
78
76
 
79
- def latest_version(chrome_version)
80
- return @latest_version if @latest_version
81
-
82
- uri = URI("https://chromedriver.storage.googleapis.com/LATEST_RELEASE_#{major_version(chrome_version)}")
77
+ def fetch_response(url, error_message)
78
+ uri = URI(url)
83
79
  response = Net::HTTP.get_response(uri)
84
80
 
85
81
  if response.is_a?(Net::HTTPSuccess)
86
- @latest_version = response.body.to_s
82
+ yield(response)
87
83
  else
88
- Interaction.fail("Could not download the chromedriver v#{chrome_version}.")
84
+ Interaction.fail(error_message)
85
+ end
86
+ end
87
+
88
+ def chromedriver_url(chrome_version)
89
+ chromedriver_per_platform = chromedriver_download_data.dig("milestones", milestone_version(chrome_version), "downloads", "chromedriver")
90
+ chromedriver = chromedriver_per_platform&.find do |chromedriver|
91
+ chromedriver["platform"] == "linux64"
92
+ end
93
+
94
+ if chromedriver && chromedriver["url"]
95
+ chromedriver["url"]
96
+ else
97
+ Interaction.fail("Could not find chromedriver download url for Chrome version v#{chrome_version}.")
98
+ end
99
+ end
100
+
101
+ def chromedriver_download_data
102
+ return @chromedriver_download_data if @chromedriver_download_data
103
+
104
+ fetch_response(VERSIONS_PER_MILESTONES_URL, "Could not find chromedriver download data") do |response|
105
+ begin
106
+ chromedriver_download_data = JSON.parse(response.body)
107
+ rescue JSON::ParserError
108
+ Interaction.fail("Could not parse chromedriver download data.")
109
+ end
110
+ @chromedriver_download_data = chromedriver_download_data
89
111
  end
90
112
  end
91
113
 
114
+ def latest_version(chrome_version)
115
+ latest_version = chromedriver_download_data.dig("milestones", milestone_version(chrome_version), "version")
116
+ latest_version || Interaction.fail("Could not find matching chromedriver for Chrome v#{chrome_version}.")
117
+ end
118
+
92
119
  def unzip(zip, output_dir)
93
120
  _stdout_str, _error_str, status = Open3.capture3('unzip', '-d', output_dir, '-o', zip.path)
94
121
 
95
122
  unless status.success?
96
123
  Interaction.fail("Could not unzip #{zip.path}.")
97
124
  end
125
+
126
+ # the archive contains a folder in which the relevant files are located. These files must be moved to ~/bin.
127
+ FileUtils.mv("#{output_dir}/chromedriver-linux64/chromedriver", output_dir)
128
+ FileUtils.mv("#{output_dir}/chromedriver-linux64//LICENSE.chromedriver", output_dir)
129
+ FileUtils.rm_rf("#{output_dir}/chromedriver-linux64")
98
130
  end
99
131
  end
100
132
  end
data/lib/geordi/cli.rb CHANGED
@@ -2,6 +2,7 @@ require 'thor'
2
2
  require 'bundler'
3
3
  require 'geordi/interaction'
4
4
  require 'geordi/util'
5
+ require 'geordi/hint'
5
6
 
6
7
  module Geordi
7
8
  class CLI < Thor
@@ -11,4 +11,9 @@ option :from_master, aliases: '-m', type: :boolean, desc: 'Branch from master in
11
11
  def branch
12
12
  require 'geordi/gitpt'
13
13
  Gitpt.new.run_branch(from_master: options.from_master)
14
+
15
+ Hint.did_you_know [
16
+ :commit,
17
+ [:branch, :from_master],
18
+ ]
14
19
  end
@@ -1,4 +1,4 @@
1
- desc 'capistrano COMMAND', 'Run a capistrano command on all deploy targets'
1
+ desc 'capistrano COMMAND', 'Run a Capistrano command on all deploy targets'
2
2
  long_desc <<-LONGDESC
3
3
  Example: `geordi capistrano deploy`
4
4
  LONGDESC
@@ -12,4 +12,8 @@ def clean
12
12
  Interaction.note pattern
13
13
  `find . -name #{pattern} -exec rm {} ';'`
14
14
  end
15
+
16
+ Hint.did_you_know [
17
+ :remove_executable_flags
18
+ ]
15
19
  end
@@ -11,4 +11,8 @@ LONGDESC
11
11
  def commit(*git_args)
12
12
  require 'geordi/gitpt'
13
13
  Gitpt.new.run_commit(git_args)
14
+
15
+ Hint.did_you_know [
16
+ :branch
17
+ ]
14
18
  end
@@ -15,6 +15,11 @@ option :select_server, type: :string, aliases: '-s', banner: '[SERVER_NUMBER]',
15
15
  def console(target = 'development', *_args)
16
16
  require 'geordi/remote'
17
17
 
18
+ Hint.did_you_know [
19
+ :shelll,
20
+ [:console, :select_server],
21
+ ]
22
+
18
23
  if target == 'development'
19
24
  invoke_geordi 'bundle_install'
20
25
  invoke_geordi 'yarn_install'
@@ -72,6 +72,13 @@ def cucumber(*args)
72
72
 
73
73
  Interaction.success 'Features green.'
74
74
 
75
+ Hint.did_you_know [
76
+ :rspec,
77
+ [:cucumber, :modified],
78
+ [:cucumber, :containing],
79
+ [:cucumber, :debug],
80
+ 'Geordi can automatically update chromedriver before Cucumber tests. See `geordi help chromedriver-update`.'
81
+ ]
75
82
  else
76
83
  Interaction.note 'Cucumber not employed.'
77
84
  end
@@ -38,4 +38,9 @@ def delete_dumps(*locations)
38
38
  deletable_dumps.each &File.method(:delete)
39
39
  Interaction.success 'Done.'
40
40
  end
41
+
42
+ Hint.did_you_know [
43
+ :clean,
44
+ :drop_databases
45
+ ]
41
46
  end
@@ -108,6 +108,11 @@ def deploy(target_stage = nil)
108
108
  Util.run!(capistrano_call, show_cmd: true)
109
109
 
110
110
  Interaction.success 'Deployment complete.'
111
+
112
+ Hint.did_you_know [
113
+ :capistrano,
114
+ :security_update
115
+ ]
111
116
  else
112
117
  Util.run!("git checkout #{source_branch}")
113
118
  Interaction.fail 'Deployment cancelled.'
@@ -47,4 +47,8 @@ def drop_databases
47
47
  cleaner = DBCleaner.new(extra_flags)
48
48
  cleaner.clean_mysql unless options.postgres_only
49
49
  cleaner.clean_postgres unless options.mysql_only
50
+
51
+ Hint.did_you_know [
52
+ :delete_dumps
53
+ ]
50
54
  end
@@ -68,4 +68,11 @@ def dump(target = nil, *_args)
68
68
  Interaction.success "Your #{loader.config['database']} database has now the data of #{target}#{database_label}."
69
69
  end
70
70
  end
71
+
72
+ Hint.did_you_know [
73
+ :delete_dumps,
74
+ :drop_databases,
75
+ :migrate,
76
+ 'Geordi can load a dump directly into the local database if passed a Capistrano stage and the option -l. See `geordi help dump`.'
77
+ ]
71
78
  end
@@ -22,4 +22,8 @@ def rake(*args)
22
22
  Util.run!(command, show_cmd: true)
23
23
  end
24
24
  end
25
+
26
+ Hint.did_you_know [
27
+ :capistrano
28
+ ]
25
29
  end
@@ -12,4 +12,8 @@ def remove_executable_flags
12
12
  end
13
13
 
14
14
  Interaction.success 'Done.'
15
+
16
+ Hint.did_you_know [
17
+ :clean
18
+ ]
15
19
  end
@@ -45,6 +45,10 @@ def rspec(*files)
45
45
 
46
46
  puts
47
47
  Util.run!(command.join(' '), fail_message: 'Specs failed.')
48
+
49
+ Hint.did_you_know [
50
+ :cucumber
51
+ ]
48
52
  end
49
53
  else
50
54
  Interaction.note 'RSpec not employed.'
@@ -6,6 +6,10 @@ 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
+ Hint.did_you_know [
10
+ [:server, :public]
11
+ ]
12
+
9
13
  invoke_geordi 'bundle_install'
10
14
  invoke_geordi 'yarn_install'
11
15
  require 'geordi/util'
@@ -27,6 +27,10 @@ def setup
27
27
 
28
28
  Interaction.success 'Successfully set up the project.'
29
29
 
30
+ Hint.did_you_know [
31
+ :update
32
+ ] unless options.dump || options.test
33
+
30
34
  invoke_geordi 'dump', options.dump, load: true if options.dump
31
35
  invoke_geordi 'tests' if options.test
32
36
  end
@@ -15,6 +15,10 @@ option :select_server, type: :string, aliases: '-s', banner: '[SERVER_NUMBER]',
15
15
  def shelll(target, *_args)
16
16
  require 'geordi/remote'
17
17
 
18
+ Hint.did_you_know [
19
+ :console
20
+ ]
21
+
18
22
  Interaction.announce 'Opening a shell on ' + target
19
23
  Geordi::Remote.new(target).shell(options)
20
24
  end
@@ -35,4 +35,8 @@ def tests(*args)
35
35
 
36
36
  Interaction.success 'Successfully ran tests.'
37
37
  end
38
+
39
+ Hint.did_you_know [
40
+ :deploy
41
+ ]
38
42
  end
@@ -27,7 +27,12 @@ def update
27
27
 
28
28
  Interaction.success 'Successfully updated the project.'
29
29
 
30
+ Hint.did_you_know [
31
+ :setup
32
+ ] unless options.dump || options.test
33
+
30
34
  invoke_geordi 'dump', options.dump, load: true if options.dump
31
35
  invoke_geordi 'tests' if options.test
32
36
  end
37
+
33
38
  end
@@ -0,0 +1,48 @@
1
+ # Use the methods in this file to hint at other geordi features
2
+ require File.expand_path('settings', __dir__)
3
+
4
+ module Geordi
5
+ class Hint
6
+ class << self
7
+
8
+ def did_you_know(hints)
9
+ settings_probability = Settings.new.hint_probability
10
+ default_probability = (Util.testing? ? 0 : 10) # Percent
11
+ should_print_hint = Random.new.rand(100) <= (settings_probability || default_probability)
12
+
13
+ generated_hints = hints.map(&method(:generate))
14
+ if generated_hints.any? && should_print_hint
15
+ puts
16
+ puts generated_hints.sample
17
+ puts 'You can configure the probability for these hints by setting hint_probability to a unitless percent number in ~/.config/geordi/global.yml' unless settings_probability
18
+ end
19
+
20
+ generated_hints
21
+ end
22
+
23
+ private
24
+
25
+ def generate(hint)
26
+ if hint.is_a?(Symbol)
27
+ command = Geordi::CLI.commands[hint.to_s]
28
+ description = downcase_first_letter(command.description)
29
+ "Did you know? `geordi #{command.name}` can #{description}."
30
+ elsif hint.is_a?(Array)
31
+ command = Geordi::CLI.commands[hint[0].to_s]
32
+ option = command.options[hint[1]]
33
+ banner = option.banner.nil? ? '' : " #{option.banner}"
34
+ description = downcase_first_letter(option.description)
35
+ "Did you know? `geordi #{command.name} #{option.aliases.first}#{banner}` can #{description}."
36
+ elsif hint.is_a?(String)
37
+ "Did you know? #{hint}"
38
+ else
39
+ raise "Unsupported hint input #{hint.inspect}"
40
+ end
41
+ end
42
+
43
+ def downcase_first_letter(str)
44
+ str[0].downcase + str[1..-1]
45
+ end
46
+ end
47
+ end
48
+ end
@@ -8,7 +8,7 @@ module Geordi
8
8
  GLOBAL_SETTINGS_FILE_NAME = Util.testing? ? './tmp/global_settings.yml'.freeze : File.join(ENV['HOME'], '.config/geordi/global.yml').freeze
9
9
  LOCAL_SETTINGS_FILE_NAME = Util.testing? ? './tmp/local_settings.yml'.freeze : './.geordi.yml'.freeze
10
10
 
11
- ALLOWED_GLOBAL_SETTINGS = %w[ pivotal_tracker_api_key auto_update_chromedriver pivotal_tracker_project_ids git_initials].freeze
11
+ ALLOWED_GLOBAL_SETTINGS = %w[ pivotal_tracker_api_key auto_update_chromedriver pivotal_tracker_project_ids git_initials hint_probability ].freeze
12
12
  ALLOWED_LOCAL_SETTINGS = %w[ pivotal_tracker_project_ids ].freeze
13
13
 
14
14
  SETTINGS_WARNED = 'GEORDI_INVALID_SETTINGS_WARNED'
@@ -27,6 +27,10 @@ module Geordi
27
27
  save_global_settings
28
28
  end
29
29
 
30
+ def hint_probability
31
+ @global_settings['hint_probability']
32
+ end
33
+
30
34
  def git_initials
31
35
  @global_settings['git_initials']
32
36
  end
@@ -1,3 +1,3 @@
1
1
  module Geordi
2
- VERSION = '9.5.1'.freeze
2
+ VERSION = '9.6.1'.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: 9.5.1
4
+ version: 9.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Henning Koch
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-04-26 00:00:00.000000000 Z
11
+ date: 2023-09-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -88,6 +88,7 @@ files:
88
88
  - lib/geordi/db_cleaner.rb
89
89
  - lib/geordi/dump_loader.rb
90
90
  - lib/geordi/gitpt.rb
91
+ - lib/geordi/hint.rb
91
92
  - lib/geordi/interaction.rb
92
93
  - lib/geordi/remote.rb
93
94
  - lib/geordi/settings.rb
@@ -116,7 +117,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
116
117
  - !ruby/object:Gem::Version
117
118
  version: '0'
118
119
  requirements: []
119
- rubygems_version: 3.2.32
120
+ rubygems_version: 3.1.6
120
121
  signing_key:
121
122
  specification_version: 4
122
123
  summary: Collection of command line tools we use in our daily work with Ruby, Rails