geordi 12.6.0 → 12.6.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2f8359f51e8fa9d619b9d84ede59104e711d59e33c2f034e6a3bc1a8933fd457
4
- data.tar.gz: 2d234986282ecc98a4853a8d6b4f8103556ca10694596b399b534aab3b8ce3d5
3
+ metadata.gz: 82d19a3fa4a8f87dbabccaa717770bd143c6ed3d6f899443dd5032396112dfdf
4
+ data.tar.gz: 6e2067c01c9ea400b51a4e66886bbd3626d0b21fb06412372e16333b0c810b42
5
5
  SHA512:
6
- metadata.gz: 8415640931dfa6738300ab40b3a4ace0d232993cf7b29aacc924f3b9de3a13b82b45b9064984dcc263883ec50bcc8717e97671140c8c45413842a94566e6ff13
7
- data.tar.gz: c4f0ed717cd6dadfc770019444b35e47fc8176ff65971a99fef0e71eeb37d2e740201b000738db5e12bdf8d3043e957f77a05d92165fc2562fde9de6ea8239ec
6
+ metadata.gz: bef2284d579d11de45367b3a31ea0bf15f1a850f1aa73213fb48fc969498d5282fbeb429af301dd8e3ab040fe60f1dba75a205354b200e68306dda6543dd0eeb
7
+ data.tar.gz: 56aea49f59fc45cd027f381001b1ffa783021fcb15ab1c2e42e6ab770b767e4d9fee1d4b0641fd2e8574a268e26f6b5036db7899654eb9ad6304d707f81017e5
data/CHANGELOG.md CHANGED
@@ -10,12 +10,26 @@ This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html
10
10
  ### Breaking changes
11
11
 
12
12
 
13
- ## 12.6.0 2025-09-22
13
+ ## 12.6.2 2026-01-30
14
+
15
+ ### Compatible changes
16
+ * `chromedriver-update` command: handles offline and DNS resolution errors.
17
+ * Remove a newly inherited `tree` command.
18
+ * Fixed a keyword typo in LinearClient.
19
+
20
+
21
+ ## 12.6.1 2025-09-23
14
22
 
15
23
  ### Compatible changes
24
+ * User prompts are now pink, and printed commands cyan (colors swapped).
25
+ * Restored backwards compatibility with older versions of `dumple` installed on a server.
16
26
 
17
- - `geordi dump`: Allow to forward the compression option to the underlying `dumple` command, e.g. `geordi dump --compress=zstd:3` (for PostgreSQL) or `geordi dump --compress` (for MySQL).
18
- - `dumple`: Allow to specify a compression algorithm for PostgreSQL, e.g. `dumple --compress=zstd:3`. The already supported compression for MySQL `dumple --compress` is kept untouched.
27
+
28
+ ## 12.6.0 2025-09-22
29
+
30
+ ### Compatible changes
31
+ * `geordi dump`: Allow to forward the compression option to the underlying `dumple` command, e.g. `geordi dump --compress=zstd:3` (for PostgreSQL) or `geordi dump --compress` (for MySQL).
32
+ * `dumple`: Allow to specify a compression algorithm for PostgreSQL, e.g. `dumple --compress=zstd:3`. The already supported compression for MySQL `dumple --compress` is kept untouched.
19
33
 
20
34
 
21
35
  ## 12.5.0 2025-09-09
@@ -117,7 +131,7 @@ This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html
117
131
  # 9.6.1 2023-09-22
118
132
 
119
133
  ### Compatible changes
120
- * `chromedriver-update` command: Retrieve chromedriver from new location
134
+ * `chromedriver-update` command: Retrieve chromedriver from new location
121
135
 
122
136
 
123
137
  # 9.6.0 2023-07-24
@@ -129,7 +143,7 @@ This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html
129
143
  # 9.5.1 2023-04-26
130
144
 
131
145
  ### Compatible changes
132
- * `cucumber` command: Support the passing of options without "="
146
+ * `cucumber` command: Support the passing of options without "="
133
147
 
134
148
 
135
149
  # 9.5.0 2023-03-22
@@ -225,7 +239,7 @@ This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html
225
239
  * Removed VNC test browser support for integration tests – Headless Chrome has
226
240
  matured and is almost a drop-in replacement. Also, key binding issues have
227
241
  increased with VNC and recent Linux.
228
- * Please use a headless Chrome setup <https://makandracards.com/makandra/492109-capybara-running-tests-with-headless-chrome>.
242
+ * Please use a headless Chrome setup <https://makandracards.com/makandra/492109-capybara-running-tests-with-headless-chrome>.
229
243
  * You might also want to get rid of your local VNC server `sudo apt remove tightvncserver`.
230
244
  * Removed support for serial execution of scenarios tagged with @solo. Serial
231
245
  execution is not needed with Headless Chrome, as Headless instances cannot
@@ -294,7 +308,7 @@ This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html
294
308
  ## 4.2.0 2020-10-02
295
309
 
296
310
  ### Compatible changes
297
- * Add `auto_update_chromedriver` as global setting option to automatically update chromedriver before cucumber
311
+ * Add `auto_update_chromedriver` as global setting option to automatically update chromedriver before cucumber
298
312
  tests, if Chrome and chromedriver versions don't match.
299
313
  * Dump command: Add support for multiple databases (#103 by @kajatiger)
300
314
  * Add Ruby 2.7 to list of supported Ruby versions
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- geordi (12.6.0)
4
+ geordi (12.6.2)
5
5
  highline
6
6
  thor (~> 1)
7
7
 
data/README.md CHANGED
@@ -170,11 +170,9 @@ Finds available Capistrano stages by their prefix, e.g. `geordi deploy p` will
170
170
  deploy production, `geordi deploy mak` will deploy a `makandra` stage if there
171
171
  is a file config/deploy/makandra.rb.
172
172
 
173
- If Linear team ids are configured (see `geordi commit`), will offer to move deployed issues to a new state. Disable with "skip".
173
+ If Linear team ids are configured (see `geordi commit`), will offer to move deployed issues to a new state. Disable this with "skip".
174
174
 
175
- When your project is running Capistrano 3, deployment will use `cap deploy`
176
- instead of `cap deploy:migrations`. You can force using `deploy` by passing the
177
- -M option: `geordi deploy -M staging`.
175
+ If your project is running Capistrano 2, Geordi will use `cap deploy:migrations` by default. Skip migrations by passing the -M option: `geordi deploy -M staging`.
178
176
 
179
177
  **Options**
180
178
  - `-M, --no-migrations`: Run cap deploy instead of cap deploy:migrations
data/Rakefile CHANGED
@@ -18,9 +18,9 @@ task :rspec do
18
18
  end
19
19
 
20
20
  task :check do
21
- Geordi::Interaction.prompt('Are all specs & features green?', 'y', /y|yes/) || Geordi::Interaction.fail('Please run all tests with `rake`.')
22
- Geordi::Interaction.prompt('Have you updated the README?', 'y', /y|yes/) || Geordi::Interaction.fail('Please update the README with `rake readme`.')
23
- Geordi::Interaction.prompt('Have you updated the CHANGELOG', 'y', /y|yes/) || Geordi::Interaction.fail('Please update the CHANGELOG with the latest changes.')
21
+ Geordi::Interaction.confirm_or_cancel('Are all specs & features green?', 'Please run all tests with `rake`.', default: 'n')
22
+ Geordi::Interaction.confirm_or_cancel('Have you updated the README?', 'Please update the README with `rake readme`.', default: 'n')
23
+ Geordi::Interaction.confirm_or_cancel('Have you updated the CHANGELOG?', 'Please update the CHANGELOG with the latest changes.', default: 'n')
24
24
  end
25
25
 
26
26
  task :readme do
@@ -52,7 +52,7 @@ Commands will occasionally print "did you know" hints of other Geordi features.
52
52
  You can always run `geordi help <command>` to quickly look up command help.
53
53
  TEXT
54
54
 
55
- Geordi::CLI.all_commands.sort.each do |_, command|
55
+ Geordi::CLI.all_commands.sort.each do |_name, command|
56
56
  next if command.hidden?
57
57
 
58
58
  geordi_section << "\n### `geordi #{command.usage}`\n"
@@ -92,7 +92,8 @@ module Geordi
92
92
 
93
93
  # Rescue Errno::NOERROR, Errno::ENOENT, Errno::EACCES, Errno::EFAULT, Errno::ECONNREFUSED, Errno::ECONNABORTED, Errno::ECONNRESET, Errno::EHOSTDOWN, Errno::EHOSTUNREACH, ...,
94
94
  # all of which are a subclass of SystemCallError
95
- rescue SystemCallError => e
95
+ # and DNS / resolution errors (SocketError, including Socket::ResolutionError on 3.3+)
96
+ rescue SystemCallError, SocketError => e
96
97
  raise ProcessingError, "Request failed: #{e.message}"
97
98
  end
98
99
 
@@ -110,15 +111,14 @@ module Geordi
110
111
  end
111
112
 
112
113
  def chromedriver_download_data
113
- return @chromedriver_download_data if @chromedriver_download_data
114
-
115
- fetch_response(VERSIONS_PER_MILESTONES_URL, "Could not find chromedriver download data") do |response|
116
- begin
117
- chromedriver_download_data = JSON.parse(response.body)
118
- rescue JSON::ParserError
119
- raise ProcessingError, "Could not parse chromedriver download data."
114
+ @chromedriver_download_data ||= begin
115
+ fetch_response(VERSIONS_PER_MILESTONES_URL, "Could not find chromedriver download data") do |response|
116
+ begin
117
+ JSON.parse(response.body)
118
+ rescue JSON::ParserError
119
+ raise ProcessingError, "Could not parse chromedriver download data."
120
+ end
120
121
  end
121
- @chromedriver_download_data = chromedriver_download_data
122
122
  end
123
123
  end
124
124
 
data/lib/geordi/cli.rb CHANGED
@@ -7,6 +7,10 @@ require 'geordi/hint'
7
7
  module Geordi
8
8
  class CLI < Thor
9
9
 
10
+ # Internal command, prints commands as tree.
11
+ # We don't need this, and it pollutes the README as well as the command prefixes.
12
+ remove_command :tree
13
+
10
14
  def self.exit_on_failure?
11
15
  true
12
16
  end
@@ -17,7 +21,7 @@ module Geordi
17
21
  end
18
22
 
19
23
  no_commands do
20
- # fix weird implementation of #invoke
24
+ # Fix weird implementation of #invoke
21
25
  def invoke_geordi(name, *args)
22
26
  options = args.last.is_a?(Hash) ? args.pop : {}
23
27
  invoke(name, args, options)
@@ -8,7 +8,7 @@ def capistrano(*args)
8
8
 
9
9
  Interaction.note 'Found the following deploy targets:'
10
10
  puts targets
11
- Interaction.prompt('Continue?', 'n', /y|yes/) || Interaction.fail('Cancelled.')
11
+ Interaction.confirm_or_cancel(default: 'n')
12
12
 
13
13
  targets << nil if targets.empty? # default target
14
14
  targets.each do |stage|
@@ -5,8 +5,8 @@ Example: `geordi chromedriver_update`
5
5
  This command will find and install the matching chromedriver for the currently
6
6
  installed Chrome.
7
7
 
8
- Setting `auto_update_chromedriver` to `true` in your global Geordi config file
9
- (`~/.config/geordi/global.yml`), will automatically update chromedriver before
8
+ Setting `auto_update_chromedriver` to `true` in your global Geordi config file
9
+ (`~/.config/geordi/global.yml`), will automatically update chromedriver before
10
10
  cucumber tests if a newer chromedriver version is available.
11
11
  LONGDESC
12
12
 
@@ -10,8 +10,8 @@ servers. When passed a number, directly connects to the selected server.
10
10
  IRB flags can be given as `irb_flags: '...'` in the global or local Geordi config file
11
11
  (`~/.config/geordi/global.yml` / `./.geordi.yml`). If you define irb_flags in both files, the local config file will be
12
12
  used. For IRB >=1.2 in combination with Ruby <3 geordi automatically sets the `--nomultiline` flag, to prevent slow
13
- pasting. You can override this behavior by setting `--multiline` in the global config file or by defining `irb_flags`
14
- in the local config file. The latter will always turn off the automatic behavior, even if you don't set any values for
13
+ pasting. You can override this behavior by setting `--multiline` in the global config file or by defining `irb_flags`
14
+ in the local config file. The latter will always turn off the automatic behavior, even if you don't set any values for
15
15
  the irb_flags key.
16
16
 
17
17
  LONGDESC
@@ -33,7 +33,7 @@ def delete_dumps(*locations)
33
33
  Interaction.warn 'No dump files found.'
34
34
  else
35
35
  puts deletable_dumps
36
- Interaction.prompt('Delete these files?', 'n', /y|yes/) || Interaction.fail('Cancelled.')
36
+ Interaction.confirm_or_cancel('Delete these files?', default: 'n')
37
37
 
38
38
  deletable_dumps.each &File.method(:delete)
39
39
  Interaction.success 'Done.'
@@ -28,11 +28,9 @@ Finds available Capistrano stages by their prefix, e.g. `geordi deploy p` will
28
28
  deploy production, `geordi deploy mak` will deploy a `makandra` stage if there
29
29
  is a file config/deploy/makandra.rb.
30
30
 
31
- If Linear team ids are configured (see `geordi commit`), will offer to move deployed issues to a new state. Disable with "skip".
31
+ If Linear team ids are configured (see `geordi commit`), will offer to move deployed issues to a new state. Disable this with "skip".
32
32
 
33
- When your project is running Capistrano 3, deployment will use `cap deploy`
34
- instead of `cap deploy:migrations`. You can force using `deploy` by passing the
35
- -M option: `geordi deploy -M staging`.
33
+ If your project is running Capistrano 2, Geordi will use `cap deploy:migrations` by default. Skip migrations by passing the -M option: `geordi deploy -M staging`.
36
34
  LONGDESC
37
35
 
38
36
  option :no_migrations, aliases: '-M', type: :boolean,
@@ -55,7 +53,7 @@ def deploy(target_stage = nil)
55
53
  target_stage || Interaction.warn('Given deployment stage not found')
56
54
  end
57
55
 
58
- # Ask for required information
56
+ # Retrieve required information ##############################################
59
57
  target_stage ||= Interaction.prompt 'Deployment stage:', branch_stage_map.fetch(Git.current_branch, 'staging')
60
58
  capistrano_config = CapistranoConfig.new(target_stage)
61
59
 
@@ -82,46 +80,50 @@ def deploy(target_stage = nil)
82
80
  config_state = 'skip' if config_state.empty?
83
81
  target_state = Interaction.prompt("Move deployed Linear issues to state:", config_state)
84
82
  target_state = '' if target_state.empty? || target_state == 'skip'
85
- settings.persist_linear_state_after_deploy(target_stage, target_state)
86
83
  end
87
84
 
88
85
  merge_needed = (source_branch != target_branch)
89
86
  push_needed = merge_needed || `git cherry -v | wc -l`.strip.to_i > 0
87
+ linear_issue_ids = []
88
+ if push_needed
89
+ commit_messages = Git.commits_between(source_branch, target_branch)
90
+ linear_issue_ids = LinearClient.extract_issue_ids(commit_messages)
91
+ end
92
+ move_issues = !linear_issue_ids.empty? && target_state && !target_state.empty?
90
93
 
91
- Interaction.announce "Checking whether your #{source_branch} branch is ready" ############
94
+ # Checks #####################################################################
95
+ Interaction.note "Checking whether your #{source_branch} branch is ready"
92
96
  Util.run!("git checkout #{source_branch}")
93
97
  if (`git status -s | wc -l`.strip != '0') && !Util.testing?
94
98
  Interaction.warn "Your #{source_branch} branch holds uncommitted changes."
95
99
  Interaction.prompt('Continue anyway?', 'n', /y|yes/) || raise('Cancelled.')
96
100
  else
97
- Interaction.note 'All good.'
101
+ puts 'All good.'
98
102
  end
99
103
 
100
104
  if merge_needed
101
- Interaction.announce "Checking what's in your #{target_branch} branch right now" #######
105
+ Interaction.note "Checking what's in your #{target_branch} branch right now"
102
106
  Util.run!("git checkout #{target_branch} && git pull")
103
107
  end
104
108
 
105
- Interaction.announce 'You are about to:' #################################################
109
+ # Confirm ####################################################################
110
+ Interaction.announce 'Planned actions'
106
111
  Interaction.note "Merge branch #{source_branch} into #{target_branch}" if merge_needed
107
- linear_issue_ids = []
108
112
  if push_needed
109
113
  Interaction.note 'Push these commits:'
110
114
  Util.run!("git --no-pager log origin/#{target_branch}..#{source_branch} --oneline")
111
-
112
- commit_messages = Git.commits_between(source_branch, target_branch)
113
- linear_issue_ids = linear_client.extract_issue_ids(commit_messages)
114
115
  end
115
116
  Interaction.note "Deploy to #{target_stage}"
116
117
  Interaction.note "From current branch #{source_branch}" if options.current_branch
117
118
 
118
- if !linear_issue_ids.empty? && target_state && !target_state.empty?
119
+ if move_issues
119
120
  relevant_commits = linear_client.filter_by_issue_ids(commit_messages, linear_issue_ids)
120
121
  Interaction.note("Move these Linear issues to state \"#{target_state}\":")
121
122
  puts relevant_commits.join("\n")
122
123
  end
123
124
 
124
- if Interaction.prompt('Go ahead with the deployment?', 'n', /y|yes/)
125
+ # Execute ####################################################################
126
+ if Interaction.prompt('Execute this now?', 'y', /y|yes/)
125
127
  puts
126
128
  git_call = []
127
129
  git_call << "git merge #{source_branch}" if merge_needed
@@ -140,11 +142,12 @@ def deploy(target_stage = nil)
140
142
 
141
143
  Util.run!(capistrano_call, show_cmd: true)
142
144
 
143
- if !linear_issue_ids.empty? && target_state && !target_state.empty?
145
+ if move_issues
144
146
  linear_client.move_issues_to_state(linear_issue_ids, target_state)
147
+ settings.persist_linear_state_after_deploy(target_stage, target_state)
145
148
  end
146
149
 
147
- Interaction.success 'Deployment complete.'
150
+ Interaction.success "Successfully deployed to #{target_stage}."
148
151
 
149
152
  Hint.did_you_know [
150
153
  :capistrano,
@@ -152,6 +155,6 @@ def deploy(target_stage = nil)
152
155
  ]
153
156
  else
154
157
  Util.run!("git checkout #{source_branch}")
155
- Interaction.fail 'Deployment cancelled.'
158
+ Interaction.fail 'Cancelled.'
156
159
  end
157
160
  end
@@ -7,8 +7,8 @@ and offer to delete them. Excluded are databases that are whitelisted. This come
7
7
  in handy when you're keeping your currently active projects in the whitelist files
8
8
  and perform regular housekeeping with Geordi.
9
9
 
10
- Per default, Geordi will try to connect to the databases as a local user without
11
- password authorization.
10
+ Per default, Geordi will try to connect to the databases as a local user without
11
+ password authorization.
12
12
 
13
13
  Geordi will ask for confirmation before actually dropping databases and will
14
14
  offer to edit the whitelist instead.
@@ -18,7 +18,7 @@ def security_update(step = 'prepare')
18
18
  Interaction.announce 'Preparing for security update'
19
19
  Interaction.warn 'Please read https://makandracards.com/makandra/1587 before applying security updates!'
20
20
  Interaction.note 'About to checkout production and pull.'
21
- Interaction.prompt('Continue?', 'y', /y|yes/) || Interaction.fail('Cancelled.')
21
+ Interaction.confirm_or_cancel
22
22
 
23
23
  Util.run!('git checkout production', show_cmd: true)
24
24
  Util.run!('git pull', show_cmd: true)
@@ -42,7 +42,7 @@ def security_update(step = 'prepare')
42
42
  Interaction.prompt('Have you successfully run all tests?', 'n', /y|yes/) || Interaction.fail('Please run tests first.')
43
43
 
44
44
  Interaction.note "About to: push production, checkout & pull #{master}, merge production, push #{master}."
45
- Interaction.prompt('Continue?', 'n', /y|yes/) || Interaction.fail('Cancelled.')
45
+ Interaction.confirm_or_cancel
46
46
 
47
47
  Util.run!('git push', show_cmd: true)
48
48
  Util.run!("git checkout #{master}", show_cmd: true)
@@ -58,12 +58,12 @@ def security_update(step = 'prepare')
58
58
 
59
59
  if all_deploy_targets.include?('staging')
60
60
  Interaction.note 'There is a staging environment.'
61
- Interaction.prompt('Deploy staging now?', 'y', /y|yes/) || Interaction.fail('Cancelled.')
61
+ Interaction.confirm_or_cancel('Deploy staging now?')
62
62
 
63
63
  Interaction.announce 'Deploy staging'
64
64
  Util.run! "bundle exec cap staging #{deploy}", show_cmd: true
65
65
 
66
- 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.')
66
+ Interaction.confirm_or_cancel('Is the deployment log okay and is the application still running on staging?', 'Please fix the deployment issues on staging before you continue.', default: 'n')
67
67
  else
68
68
  Interaction.note 'There is no staging environment.'
69
69
  end
@@ -77,14 +77,14 @@ def security_update(step = 'prepare')
77
77
  Interaction.note 'Found the following other stages:'
78
78
  puts deploy_targets_without_staging
79
79
  puts
80
- Interaction.prompt('Deploy other stages now?', 'y', /y|yes/) || Interaction.fail('Cancelled.')
80
+ Interaction.confirm_or_cancel('Deploy other stages now?')
81
81
 
82
82
  deploy_targets_without_staging.each do |target|
83
83
  Interaction.announce "Deploy #{target}"
84
84
  Util.run!("bundle exec cap #{target} #{deploy}", show_cmd: true)
85
85
  end
86
86
 
87
- 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!')
87
+ Interaction.confirm_or_cancel('Are *all* the deployment logs okay and is the application still running on *all* other stages?', 'Please fix the application immediately!', default: 'n')
88
88
  end
89
89
 
90
90
  Interaction.success 'Successfully pushed and deployed security update'
@@ -3,7 +3,7 @@ long_desc <<-LONGDESC
3
3
  When running `geordi tests` without any arguments, all unit tests, rspec specs
4
4
  and cucumber features will be run.
5
5
 
6
- When passing file paths or directories as arguments, Geordi will forward them to `rspec` and `cucumber`.
6
+ When passing file paths or directories as arguments, Geordi will forward them to `rspec` and `cucumber`.
7
7
  All rspec specs and cucumber features matching the given paths will be run.
8
8
  LONGDESC
9
9
 
@@ -230,8 +230,8 @@ module Geordi
230
230
  until %w[y n].include? proceed
231
231
  deletable_dbs = filter_allowlisted(dbtype, database_list)
232
232
  if deletable_dbs.empty?
233
- Interaction.note "No #{dbtype} databases found that were not allowlisted."
234
- if Interaction.prompt('Edit the allowlist? [y]es or [n]o') == 'y'
233
+ Interaction.note "No deletable #{dbtype} databases found."
234
+ if Interaction.prompt('Edit the allowlist?', 'y', /y|yes/)
235
235
  proceed = 'e'
236
236
  else
237
237
  return []
@@ -245,6 +245,7 @@ module Geordi
245
245
  Interaction.note "These #{dbtype} databases are not allowlisted and can be deleted."
246
246
  proceed = Interaction.prompt('Proceed? [y]es, [n]o or [e]dit allowlist')
247
247
  end
248
+
248
249
  case proceed
249
250
  when 'e'
250
251
  proceed = '' # reset user selection
@@ -28,7 +28,7 @@ module Geordi
28
28
  # Also see Util.run!
29
29
  def note_cmd(text)
30
30
  message = "> #{text}"
31
- puts "\e[35m#{message}\e[0m" # pink
31
+ puts "\e[36m#{message}\e[0m" # cyan
32
32
  end
33
33
 
34
34
  # Exit execution with status code 1 and give a short note what happened,
@@ -52,7 +52,7 @@ module Geordi
52
52
  message = "#{text} "
53
53
  message << "[#{default}] " if default
54
54
 
55
- print "\e[36m#{message}\e[0m" # cyan
55
+ print "\e[35m#{message}\e[0m" # pink
56
56
  input = $stdin.gets.strip
57
57
  input = default if input.empty? && default
58
58
 
@@ -61,5 +61,9 @@ module Geordi
61
61
  fail 'Cancelled.'
62
62
  end
63
63
 
64
+ def confirm_or_cancel(message = 'Continue?', cancel_message = 'Cancelled.', default: 'y')
65
+ prompt(message, default, /y|yes/) or fail(cancel_message)
66
+ end
67
+
64
68
  end
65
69
  end
@@ -11,6 +11,20 @@ module Geordi
11
11
 
12
12
  API_ENDPOINT = 'https://api.linear.app/graphql'.freeze
13
13
 
14
+ def self.extract_issue_ids(strings)
15
+ found_ids = []
16
+
17
+ regex = /^\[[A-Z]+\d*-\d+\]/
18
+
19
+ strings&.each do |string|
20
+ string&.scan(regex) do |match|
21
+ found_ids << match
22
+ end
23
+ end
24
+
25
+ found_ids.map { |id| id.delete('[]') } # [W-365] => W-365
26
+ end
27
+
14
28
  def initialize
15
29
  self.highline = HighLine.new
16
30
  self.settings = Settings.new
@@ -62,7 +76,7 @@ module Geordi
62
76
  issue_identifiers.each do |identifier|
63
77
  issue = issues.find { |i| i['identifier'] == identifier }
64
78
 
65
- skip unless issue && (state_id = state_ids_by_team_id[issue.dig('team', 'id')])
79
+ next unless issue && (state_id = state_ids_by_team_id[issue.dig('team', 'id')])
66
80
 
67
81
  update_issue_state(issue['id'], state_id)
68
82
  end
@@ -87,20 +101,6 @@ module Geordi
87
101
  end
88
102
  end
89
103
 
90
- def extract_issue_ids(commit_messages)
91
- found_ids = []
92
-
93
- regex = /^\[[A-Z]+\d*-\d+\]/
94
-
95
- commit_messages&.each do |line|
96
- line&.scan(regex) do |match|
97
- found_ids << match
98
- end
99
- end
100
-
101
- found_ids.map { |id| id.delete('[]') } # [W-365] => W-365
102
- end
103
-
104
104
  def filter_by_issue_ids(list_of_strings, issue_ids)
105
105
  list_of_strings.select do |message|
106
106
  issue_ids.any? { |id| message.start_with?("[#{id}]") }
data/lib/geordi/util.rb CHANGED
@@ -21,7 +21,7 @@ module Geordi
21
21
 
22
22
  # install missing gem
23
23
  Interaction.warn 'Probably missing gem: ' + gem_name
24
- Interaction.prompt('Install it now?', 'y', /y|yes/) || Interaction.fail('Missing Gems.')
24
+ Interaction.confirm_or_cancel('Install it now?', 'Missing Gems.')
25
25
  Util.run!(install_command, show_cmd: true)
26
26
 
27
27
  # retry
@@ -50,13 +50,12 @@ module Geordi
50
50
  show_command = [command]
51
51
  end
52
52
 
53
- if show_cmd
54
- # Join with spaces for better readability and copy-pasting
53
+ if show_cmd || confirm
55
54
  Interaction.note_cmd show_command.join(' ')
56
55
  end
57
56
 
58
57
  if confirm
59
- Interaction.prompt('Run this now?', 'n', /y|yes/) or Interaction.fail('Cancelled.')
58
+ Interaction.confirm_or_cancel('Run this now?')
60
59
  end
61
60
 
62
61
  if testing?
@@ -130,7 +129,7 @@ module Geordi
130
129
  cmd << environment
131
130
  cmd << options[:database]
132
131
  cmd << compress
133
- cmd << '--for-download' if options[:for_download]
132
+ cmd << '--for_download' if options[:for_download]
134
133
 
135
134
  cmd.compact.join(' ')
136
135
  end
@@ -1,3 +1,3 @@
1
1
  module Geordi
2
- VERSION = '12.6.0'.freeze
2
+ VERSION = '12.6.2'.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: 12.6.0
4
+ version: 12.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Henning Koch
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-09-22 00:00:00.000000000 Z
11
+ date: 2026-01-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor