geordi 9.0.0 → 9.3.0

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: 1060f10e77e6173a1b8d63fd8c2d89579e5be0597a683f5358b01173e4c266de
4
- data.tar.gz: 8a44e3cd313e779b84ae9ecfa0f92283f4dd3f45f7525ec0bc298b11a719c389
3
+ metadata.gz: e93051812acfd619f8d5a2db9c2641bb1ff19cf28835096cec1a2f6fd1487620
4
+ data.tar.gz: 4bc007b0985800b275de9dd0676cf0cbdf51a57800a4a426c0878738b9b00f43
5
5
  SHA512:
6
- metadata.gz: c7793fda9e1494d3b1a2cf50dfa7b8c10ff61e8c7462596828fe6e44721f50dedbfe18ba2a2c2fb4e0b354500de9528f6e948e8716c9c1a31ceb42a49c8ea845
7
- data.tar.gz: fedd7f3106bc5283b25b5f4e20fe1eda099d76c7e4b01483362cebde5cca516d559241d976ad51486a3bc71e11df5a3c21d14288c10805ad9af8307f48d7dab3
6
+ metadata.gz: 07105d522e4ed9c4412e95f0e8bd5dfbfbd4c8ea7bb7a58f7f347473eafb5807f7ceeaf82dc18f80dd85c77699970342f91396eec35f4a113a5aad8e0b73dc6d
7
+ data.tar.gz: 7bb8747a1352e983c3c3cecc848ae2097a01341e8c1bd0d1b32537e0470085d43cec4a639dbdc36eaacdd8fad5f4bce981032c8d06efe11c8ab0951afe4bbaec
data/CHANGELOG.md CHANGED
@@ -3,7 +3,6 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
5
5
 
6
-
7
6
  ## Unreleased
8
7
 
9
8
  ### Compatible changes
@@ -11,10 +10,30 @@ This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html
11
10
  ### Breaking changes
12
11
 
13
12
 
13
+ ## 9.3.0 2022-04-26
14
+
15
+ ### Compatible changes
16
+ * Add dump loading in multi-database-setups.
17
+
18
+
19
+ ## 9.2.0 2022-02-18
20
+
21
+ ### Compatible changes
22
+ * Change the update mechanism of `geordi chromedriver-update`: This command (and `geordi cucumber`/`geordi tests` if the `auto_update_chromedriver` option is active) will now always update to the latest version of chromedriver for the current chrome version.
23
+
24
+
25
+ ## 9.1.0 2022-02-14
26
+
27
+ ### Compatible changes
28
+ * `geordi dump` and `dumple` now default to "primary" database or the first
29
+ entry in a multi-db setup
30
+ * Also added feature tests for `dumple` and structured the script
31
+
32
+
14
33
  ## 9.0.0 2021-12-02
15
34
 
16
35
  ### Breaking changes
17
- * Remove the `geordi docker` command.
36
+ * Remove the `geordi docker` command set.
18
37
 
19
38
 
20
39
  ## 8.0.0 2021-11-08
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- geordi (9.0.0)
4
+ geordi (9.3.0)
5
5
  thor (~> 1)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -53,10 +53,10 @@ installed Chrome.
53
53
 
54
54
  Setting `auto_update_chromedriver` to `true` in your global Geordi config file
55
55
  (`~/.config/geordi/global.yml`), will automatically update chromedriver before
56
- cucumber tests, in case Chrome and chromedriver versions don't match
56
+ cucumber tests if a newer chromedriver version is available.
57
57
 
58
58
  **Options**
59
- - `[--quiet-if-matching], [--no-quiet-if-matching]`: Suppress notification if chromedriver and chrome versions match
59
+ - `[--quiet-if-matching], [--no-quiet-if-matching]`: Suppress notification if chromedriver is already on the latest version
60
60
 
61
61
 
62
62
  ### `geordi clean`
@@ -194,15 +194,21 @@ specified target's database and downloads it to `tmp/`.
194
194
  `geordi dump staging -l` (with a Capistrano deploy target and the `--load`
195
195
  option) sources the dump into the development database after downloading it.
196
196
 
197
- If you are using multiple databases per environment, pass the database name like this:
197
+ If you are using multiple databases per environment, Geordi defaults to the
198
+ "primary" database, or the first entry in database.yml. To target a specific
199
+ database, pass the database name like this:
200
+ ```
201
+ geordi dump -d primary
202
+ ```
198
203
 
199
- geordi dump -d primary
200
-
201
- Loading a dump into one of multiple local databases is not supported yet.
204
+ When used with the blank `load` option ("dump and source"), the `database` option
205
+ will be respected both for the remote *and* the local database. If these should
206
+ not match, please issue separate commands for dumping (`dump -d`) and sourcing
207
+ (`dump -l -d`).
202
208
 
203
209
  **Options**
204
210
  - `-l, [--load=[DUMP_FILE]]`: Load a dump
205
- - `-d, [--database=NAME]`: Database name, if there are multiple databases
211
+ - `-d, [--database=NAME]`: Target database, if there are multiple databases
206
212
 
207
213
 
208
214
  ### `geordi help [COMMAND]`
data/exe/dumple CHANGED
@@ -1,28 +1,33 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'erb'
4
-
5
- fail_gently = ARGV.include?("--fail-gently")
6
- compress = ARGV.include?("--compress")
7
-
8
3
  if ARGV.include?("-i")
9
4
  puts "*******************************************************"
10
5
  puts
11
6
  system("du -sh ~/dumps")
12
7
  puts
13
8
  puts "*******************************************************"
9
+
14
10
  exit
15
11
  end
16
12
 
17
- ###
18
-
13
+ require 'erb'
19
14
  require "yaml"
20
- config_path = 'config/database.yml'
21
15
 
22
- begin
23
- # go to project root
16
+ DB_CONFIG_PATH = 'config/database.yml'
17
+ DUMPS_DIR = "#{ENV['HOME']}/dumps"
18
+
19
+ def run(*args)
20
+ if !!ENV['GEORDI_TESTING']
21
+ puts "system #{args.join(', ')}"
22
+ true # "Command succeeded"
23
+ else
24
+ system *args
25
+ end
26
+ end
27
+
28
+ def cd_to_project_root(fail_gently)
24
29
  current = Dir.pwd
25
- until (File.exists? config_path)
30
+ until File.exists?(DB_CONFIG_PATH)
26
31
  Dir.chdir '..'
27
32
  if current == Dir.pwd
28
33
  if fail_gently
@@ -38,46 +43,24 @@ begin
38
43
  sleep 5
39
44
  exit
40
45
  else
41
- raise "Call me from inside a Rails project."
46
+ raise "x Call me from inside a Rails project."
42
47
  end
43
48
  end
44
49
  current = Dir.pwd
45
50
  end
51
+ end
46
52
 
47
- config = YAML::load(ERB.new(File.read(config_path)).result)
48
- environment, database = ARGV.reject{ |arg| arg[0].chr == '-' }
49
- environment ||= 'production'
50
- config = config[environment] or raise "No #{environment} database found.\nUsage: dumple ENVIRONMENT [DATABASE]"
51
-
52
- if database
53
- config = config[database] or raise %(Unknown #{environment} database "#{database}")
54
- end
55
-
56
- dump_dir = "#{ENV['HOME']}/dumps"
57
- unless File.directory?(dump_dir)
58
- Dir.mkdir(dump_dir)
59
- system("chmod 700 #{dump_dir}")
60
- end
61
-
62
- if ARGV.find{ |arg| arg == '--for_download'}
63
- dump_path = "#{dump_dir}/dump_for_download.dump"
64
- else
65
- dump_path = "#{dump_dir}/#{config['database']}_#{Time.now.strftime("%Y%m%d_%H%M%S")}.dump"
66
- end
67
-
68
- given_database = database ? %(#{database} ) : ""
69
- puts "> Dumping #{given_database}database for \"#{environment}\" environment ..."
70
-
53
+ def dump_command(dump_file, config)
71
54
  host = config['host']
72
55
  port = config['port']
73
56
 
74
- dump_command = case config['adapter']
57
+ case config['adapter']
75
58
  when /mysql/
76
59
  command = "mysqldump"
77
60
  command << " -u\"#{config['username']}\""
78
61
  command << " -p\"#{config['password']}\""
79
62
  command << " #{config['database']}"
80
- command << " -r #{dump_path}"
63
+ command << " -r #{dump_file}"
81
64
  # Using a transaction to allow concurrent request while creating a dump.
82
65
  # This works only reliable for InnoDB tables.
83
66
  # More details: https://dev.mysql.com/doc/refman/5.7/en/mysqldump.html#option_mysqldump_single-transaction
@@ -96,25 +79,75 @@ begin
96
79
  command << " pg_dump #{config['database']}"
97
80
  command << " --clean"
98
81
  command << " --format=custom"
99
- command << " --file=#{dump_path}"
82
+ command << " --file=#{dump_file}"
100
83
  command << " --username=\"#{config['username']}\""
101
84
  command << " --host=#{host}" if host
102
85
  command << " --port=#{port}" if port
103
86
  command
104
87
  else
105
- raise "Adapter \"#{config['adapter']}\" is not supported"
88
+ raise %(x Adapter "#{config['adapter']}" is not supported.)
89
+ end
90
+ end
91
+
92
+ def find_database_config(config_path, environment, database)
93
+ environment ||= 'production'
94
+ database_yml = ERB.new(File.read(config_path)).result
95
+ config = YAML::load(database_yml)
96
+ config = config[environment] or raise "x No #{environment} database found.\nUsage: dumple ENVIRONMENT [DATABASE]"
97
+
98
+ if config.values[0].is_a? Hash # Multi-db setup
99
+ if database # Explicitly requested
100
+ config = config[database] or raise %(x Unknown #{environment} database "#{database}".)
101
+ elsif config.key? 'primary'
102
+ puts '> Multiple databases detected. Defaulting to primary database.'
103
+ config = config['primary']
104
+ else
105
+ puts "> Multiple databases detected. Defaulting to first entry (#{config.keys[0]})."
106
+ config = config.values[0]
107
+ end
108
+ else # Single-db setup
109
+ if database
110
+ raise %(x Could not select "#{database}" database in a single-db environment.)
111
+ end
106
112
  end
107
- success = system(dump_command)
108
- success or raise "Creating the dump failed"
109
113
 
110
- system "chmod 600 #{dump_path}"
114
+ config
115
+ end
116
+
117
+ def prepare_dump_path(config)
118
+ unless File.directory?(DUMPS_DIR)
119
+ Dir.mkdir(DUMPS_DIR)
120
+ run "chmod 700 #{DUMPS_DIR}"
121
+ end
122
+
123
+ if ARGV.include? '--for_download'
124
+ "#{DUMPS_DIR}/dump_for_download.dump"
125
+ else
126
+ "#{DUMPS_DIR}/#{config['database']}_#{Time.now.strftime("%Y%m%d_%H%M%S")}.dump"
127
+ end
128
+ end
129
+
130
+ begin
131
+ fail_gently = ARGV.include?("--fail-gently")
132
+ compress = ARGV.include?("--compress")
133
+ environment, database = ARGV.reject { |arg| arg[0].chr == '-' }
134
+
135
+ cd_to_project_root(fail_gently)
136
+ config = find_database_config(DB_CONFIG_PATH, environment, database)
137
+ dump_path = prepare_dump_path(config)
138
+
139
+ # Dump!
140
+ given_database = database ? %(#{database} ) : ""
141
+ command = dump_command(dump_path, config)
142
+ puts "> Dumping #{given_database}database for \"#{environment}\" environment ..."
143
+ run command or raise "x Creating the dump failed."
144
+ run "chmod 600 #{dump_path}"
111
145
 
112
146
  if compress
113
147
  puts "> Compressing the dump ..."
114
-
115
148
  # gzip compresses in place
116
- compress_success = system("gzip #{dump_path}")
117
- compress_success or raise "Compressing the dump failed"
149
+ compress_success = run "gzip #{dump_path}"
150
+ compress_success or raise "x Compressing the dump failed."
118
151
  dump_path << ".gz"
119
152
  end
120
153
 
data/geordi.gemspec CHANGED
@@ -13,6 +13,7 @@ Gem::Specification.new do |spec|
13
13
  spec.description = spec.summary
14
14
  spec.homepage = 'https://makandra.com'
15
15
  spec.license = 'MIT'
16
+ spec.metadata = { 'rubygems_mfa_required' => 'true' }
16
17
 
17
18
  # Specify which files should be added to the gem when it is released.
18
19
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
@@ -7,18 +7,13 @@ module Geordi
7
7
 
8
8
  def run(options)
9
9
  chrome_version = determine_chrome_version
10
- chromedriver_version = determine_chromedriver_version
10
+ current_chromedriver_version = determine_chromedriver_version
11
11
 
12
- if skip_update?(chrome_version, chromedriver_version)
13
- Interaction.success "No update required: both Chrome and chromedriver are on v#{chrome_version}!" unless options[:quiet_if_matching]
12
+ latest_chromedriver_version = latest_version(chrome_version)
13
+ 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]
14
15
  else
15
- chromedriver_zip = download_chromedriver(chrome_version)
16
- unzip(chromedriver_zip, File.expand_path('~/bin'))
17
-
18
- chromedriver_zip.unlink
19
-
20
- # We need to determine the version again, as it could be nil in case no chromedriver was installed before
21
- Interaction.success "Chromedriver updated to v#{determine_chromedriver_version}."
16
+ update_chromedriver(latest_chromedriver_version)
22
17
  end
23
18
  end
24
19
 
@@ -27,13 +22,13 @@ module Geordi
27
22
  def determine_chrome_version
28
23
  stdout_str, _error_str, status = Open3.capture3('google-chrome', '--version')
29
24
  chrome_version = unless stdout_str.nil?
30
- stdout_str[/\AGoogle Chrome (\d+)/, 1]
25
+ stdout_str[/\AGoogle Chrome ([\d.]+)/, 1]
31
26
  end
32
27
 
33
28
  if !status.success? || chrome_version.nil?
34
29
  Interaction.fail('Could not determine the version of Google Chrome.')
35
30
  else
36
- chrome_version.to_i
31
+ chrome_version
37
32
  end
38
33
  end
39
34
 
@@ -42,23 +37,32 @@ module Geordi
42
37
 
43
38
  stdout_str, _error_str, status = Open3.capture3('chromedriver', '-v')
44
39
  chromedriver_version = unless stdout_str.nil?
45
- stdout_str[/\AChromeDriver (\d+)/, 1]
40
+ stdout_str[/\AChromeDriver ([\d.]+)/, 1]
46
41
  end
47
42
 
48
43
  if !status.success? || chromedriver_version.nil?
49
44
  Interaction.fail('Could not determine the version of chromedriver.')
50
45
  else
51
- chromedriver_version.to_i
46
+ chromedriver_version
52
47
  end
53
48
  end
54
49
 
55
- def skip_update?(chrome_version, chromedriver_version)
56
- chrome_version == chromedriver_version
50
+ # Check https://groups.google.com/a/chromium.org/g/chromium-discuss/c/4BB4jmsRyv8/m/TY3FXS4HBgAJ
51
+ # for information how chrome version numbers work
52
+ def major_version(full_version)
53
+ full_version.match(/^(\d+\.\d+\.\d+)\.\d+$/)[1]
57
54
  end
58
55
 
59
- def download_chromedriver(chrome_version)
60
- latest_version = latest_version(chrome_version)
56
+ def update_chromedriver(latest_chromedriver_version)
57
+ chromedriver_zip = download_chromedriver(latest_chromedriver_version)
58
+
59
+ unzip(chromedriver_zip, File.expand_path('~/bin'))
61
60
 
61
+ # We need to determine the version again, as it could be nil in case no chromedriver was installed before
62
+ Interaction.success "Chromedriver updated to v#{determine_chromedriver_version}."
63
+ end
64
+
65
+ def download_chromedriver(latest_version)
62
66
  uri = URI("https://chromedriver.storage.googleapis.com/#{latest_version}/chromedriver_linux64.zip")
63
67
  response = Net::HTTP.get_response(uri)
64
68
 
@@ -73,11 +77,13 @@ module Geordi
73
77
  end
74
78
 
75
79
  def latest_version(chrome_version)
76
- uri = URI("https://chromedriver.storage.googleapis.com/LATEST_RELEASE_#{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
83
  response = Net::HTTP.get_response(uri)
78
84
 
79
85
  if response.is_a?(Net::HTTPSuccess)
80
- response.body.to_s
86
+ @latest_version = response.body.to_s
81
87
  else
82
88
  Interaction.fail("Could not download the chromedriver v#{chrome_version}.")
83
89
  end
@@ -7,11 +7,11 @@ installed Chrome.
7
7
 
8
8
  Setting `auto_update_chromedriver` to `true` in your global Geordi config file
9
9
  (`~/.config/geordi/global.yml`), will automatically update chromedriver before
10
- cucumber tests, in case Chrome and chromedriver versions don't match
10
+ cucumber tests if a newer chromedriver version is available.
11
11
  LONGDESC
12
12
 
13
13
  option :quiet_if_matching, type: :boolean, default: false,
14
- desc: 'Suppress notification if chromedriver and chrome versions match'
14
+ desc: 'Suppress notification if chromedriver is already on the latest version'
15
15
 
16
16
  def chromedriver_update
17
17
  require 'geordi/chromedriver_updater'
@@ -11,48 +11,53 @@ specified target's database and downloads it to `tmp/`.
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
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.
14
+ If you are using multiple databases per environment, Geordi defaults to the
15
+ "primary" database, or the first entry in database.yml. To target a specific
16
+ database, pass the database name like this:
17
+ ```
18
+ geordi dump -d primary
19
+ ```
20
+
21
+ When used with the blank `load` option ("dump and source"), the `database` option
22
+ will be respected both for the remote *and* the local database. If these should
23
+ not match, please issue separate commands for dumping (`dump -d`) and sourcing
24
+ (`dump -l -d`).
19
25
  DESC
20
26
 
21
27
  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'
28
+ option :database, aliases: '-d', type: :string, desc: 'Target database, if there are multiple databases', banner: 'NAME'
23
29
 
24
30
  def dump(target = nil, *_args)
25
31
  require 'geordi/dump_loader'
26
32
  require 'geordi/remote'
27
33
  database = options[:database] ? "#{options[:database]} " : ''
28
34
 
29
- if target.nil?
30
- if options.load
31
- # validate load option
35
+ if target.nil? # Local …
36
+ if options.load # … dump loading
32
37
  Interaction.fail 'Missing a dump file.' if options.load == 'load'
33
38
  File.exist?(options.load) || raise('Could not find the given dump file: ' + options.load)
34
39
 
35
- loader = DumpLoader.new(options.load)
40
+ loader = DumpLoader.new(options.load, options.database)
36
41
 
37
42
  Interaction.announce "Sourcing dump into the #{loader.config['database']} db"
38
43
  loader.load
39
44
 
40
45
  Interaction.success "Your #{loader.config['database']} database has now the data of #{options.load}."
41
46
 
42
- else
47
+ else # … dump creation
43
48
  Interaction.announce 'Dumping the development database'
44
49
  Util.run!("dumple development #{database}")
45
50
  Interaction.success "Successfully dumped the #{database}development database."
46
51
  end
47
52
 
48
- else
53
+ else # Remote dumping …
49
54
  database_label = options[:database] ? " (#{database}database)" : ""
50
55
 
51
56
  Interaction.announce "Dumping the database of #{target}#{database_label}"
52
57
  dump_path = Geordi::Remote.new(target).dump(options)
53
58
 
54
- if options.load
55
- loader = DumpLoader.new(dump_path)
59
+ if options.load # … and dump loading
60
+ loader = DumpLoader.new(dump_path, options.database)
56
61
 
57
62
  Interaction.announce "Sourcing dump into the #{loader.config['database']} db"
58
63
  loader.load
@@ -6,24 +6,45 @@ require 'geordi/util'
6
6
  module Geordi
7
7
  class DumpLoader
8
8
 
9
- def initialize(file)
9
+ def initialize(file, database)
10
10
  @dump_file = file
11
+ @database = database
11
12
  end
12
13
 
13
14
  def development_database_config
15
+ return @config if @config
16
+
14
17
  require 'yaml'
15
18
 
16
19
  evaluated_config_file = ERB.new(File.read('config/database.yml')).result
17
20
 
18
21
  # Allow aliases and a special set of classes like symbols and time objects
19
22
  permitted_classes = [Symbol, Time]
20
- @config ||= if Gem::Version.new(Psych::VERSION) >= Gem::Version.new('3.1.0')
23
+ database_config = if Gem::Version.new(Psych::VERSION) >= Gem::Version.new('3.1.0')
21
24
  YAML.safe_load(evaluated_config_file, permitted_classes: permitted_classes, aliases: true)
22
25
  else
23
26
  YAML.safe_load(evaluated_config_file, permitted_classes, [], true)
24
27
  end
25
28
 
26
- @config['development']
29
+ development_config = database_config['development']
30
+
31
+ if development_config.values[0].is_a? Hash # Multi-db setup
32
+ @config = if @database
33
+ development_config[@database] || Interaction.fail(%(Unknown development database "#{@database}".))
34
+ elsif development_config.has_key? 'primary'
35
+ development_config['primary']
36
+ else
37
+ development_config.values[0]
38
+ end
39
+ else # Single-db setup
40
+ if @database
41
+ Interaction.fail %(Could not select "#{@database}" database in a single-db setup.)
42
+ else
43
+ @config = development_config
44
+ end
45
+ end
46
+
47
+ @config
27
48
  end
28
49
  alias_method :config, :development_database_config
29
50
 
@@ -61,9 +82,12 @@ module Geordi
61
82
  end
62
83
 
63
84
  def load
85
+ adapter_command = "#{config['adapter']}_command"
86
+ Interaction.fail "Unknown database adapter #{config['adapter'].inspect} in config/database.yml." unless respond_to? adapter_command
87
+
64
88
  Interaction.note 'Source file: ' + dump_file
65
89
 
66
- source_command = send("#{config['adapter']}_command")
90
+ source_command = send(adapter_command)
67
91
  Util.run! source_command, fail_message: "An error occurred loading #{File.basename(dump_file)}"
68
92
  end
69
93
 
@@ -1,3 +1,3 @@
1
1
  module Geordi
2
- VERSION = '9.0.0'.freeze
2
+ VERSION = '9.3.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: 9.0.0
4
+ version: 9.3.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: 2021-12-02 00:00:00.000000000 Z
11
+ date: 2022-04-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -96,11 +96,12 @@ files:
96
96
  homepage: https://makandra.com
97
97
  licenses:
98
98
  - MIT
99
- metadata: {}
99
+ metadata:
100
+ rubygems_mfa_required: 'true'
100
101
  post_install_message: 'Support for sequential running of integration tests tagged
101
102
  with @solo has been dropped.
102
103
 
103
- '
104
+ '
104
105
  rdoc_options: []
105
106
  require_paths:
106
107
  - lib
@@ -115,7 +116,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
115
116
  - !ruby/object:Gem::Version
116
117
  version: '0'
117
118
  requirements: []
118
- rubygems_version: 3.2.32
119
+ rubygems_version: 3.2.30
119
120
  signing_key:
120
121
  specification_version: 4
121
122
  summary: Collection of command line tools we use in our daily work with Ruby, Rails