geordi 5.3.0 → 5.4.0

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: 693551524b9b50f70e2daf649cd8184cc197b1576153beaf675ebaae01a88e84
4
- data.tar.gz: 915a4c3e1449f0883e31bd828a850354db26bcdcf57523ffdf28ade6e51bee1e
3
+ metadata.gz: 87cda39f50721b8821dc5042de4a4ead24b4f8a27d5601bcb1742aa5f1a7cd00
4
+ data.tar.gz: baf33c3c575963062318374024cfae1071dd1002aaebbdd1c353cc7dc8c4c0c0
5
5
  SHA512:
6
- metadata.gz: bcbd43ffb224b54a7ba553c6bbcab6931d06b15df4a5e2e3eb9a93fe019187df47174bb2b61030a54d2408fb80235a1937eae7ff0a0f3c17e58756d3cbfc94b0
7
- data.tar.gz: 03ef92df5d677f51ee70bec10bf035034824980b5c16c15c38e587de5b2a2cf683ddbce64067695e566fc9ee207d26af6f1986d909210b9fda61d9570bb91add
6
+ metadata.gz: 0a66597a85f305bf90bf01ec56f0141ad4c3a7fcbd4d21032e8a7f64b2b5fece841e37084c8f783d7f8b9269e484d4cd7d6b35523435b032d67e472125c14043
7
+ data.tar.gz: 74954d6cf80dc9dea5b3f8d233fa2f2c2cb0c65fb229c385b96cb202f667dfdab14a1fd32212f3a168658cbeacbe4a279300a6a6fbcb9eee44f91a85b5da241f
data/CHANGELOG.md CHANGED
@@ -1,14 +1,26 @@
1
1
  # Changelog
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
-
5
4
  This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
6
5
 
6
+
7
7
  ## Unreleased
8
8
 
9
9
  ### Compatible changes
10
+
10
11
  ### Breaking changes
11
12
 
13
+
14
+ ## 5.4.0 2021-02-01
15
+
16
+ ### Compatible changes
17
+ * Add `geordi branch` command that checks out a feature branch based on a story from Pivotal Tracker
18
+ * Faster MySQL dumping with [`--single-transaction` and `--quick`](https://dev.mysql.com/doc/refman/5.7/en/mysqldump.html#option_mysqldump_single-transaction)
19
+ * Allow pivotal tracker ids in the global config file
20
+ * Fix missing require for `Fileutils` in the dump load command (#145)
21
+ * Document `PARALLEL_TEST_PROCESSORS`
22
+
23
+
12
24
  ## 5.3.0 2021-02-01
13
25
 
14
26
  ### Compatible changes
data/README.md CHANGED
@@ -25,6 +25,15 @@ You can always run `geordi help <command>` to quickly look up command help.
25
25
  Enable the given virtual host, disabling all others.
26
26
 
27
27
 
28
+ ### `geordi branch`
29
+ Check out a feature branch based on a story from Pivotal Tracker.
30
+
31
+ Example: `geordi branch`
32
+
33
+ On the first execution we ask for your Pivotal Tracker API token. It will be
34
+ stored in `~/.config/geordi/global.yml`.
35
+
36
+
28
37
  ### `geordi capistrano COMMAND`
29
38
  Run a capistrano command on all deploy targets.
30
39
 
@@ -100,6 +109,9 @@ sign, i.e. have each option a contiguous string.
100
109
  headless test browser anyway, you can disable VNC by setting `use_vnc: false`
101
110
  in `.geordi.yml` in the project root.
102
111
 
112
+ - In order to limit processes in a parallel run, you can set an environment
113
+ variable like this: `PARALLEL_TEST_PROCESSORS=6 geordi cucumber`
114
+
103
115
  **Options**
104
116
  - `-m, [--modified], [--no-modified]`: Run all modified features
105
117
  - `-c, [--containing=STRING]`: Run all features that contain STRING
@@ -281,7 +293,10 @@ Run RSpec.
281
293
 
282
294
  Example: `geordi rspec spec/models/user_spec.rb:13`
283
295
 
284
- Runs RSpec with RSpec 1/2 support, parallel_tests detection and `bundle exec`.
296
+ Runs RSpec with version 1/2 support, parallel_tests detection and `bundle exec`.
297
+
298
+ In order to limit processes in a parallel run, you can set an environment
299
+ variable like this: `PARALLEL_TEST_PROCESSORS=6 geordi rspec`
285
300
 
286
301
 
287
302
  ### `geordi security-update [STEP]`
data/exe/dumple CHANGED
@@ -78,6 +78,13 @@ begin
78
78
  command << " -p\"#{config['password']}\""
79
79
  command << " #{config['database']}"
80
80
  command << " -r #{dump_path}"
81
+ # Using a transaction to allow concurrent request while creating a dump.
82
+ # This works only reliable for InnoDB tables.
83
+ # More details: https://dev.mysql.com/doc/refman/5.7/en/mysqldump.html#option_mysqldump_single-transaction
84
+ command << ' --single-transaction'
85
+ # Disable buffering in memory to avoid a memory overflow for large tables
86
+ # More details https://dev.mysql.com/doc/refman/5.7/en/mysqldump.html#option_mysqldump_quick
87
+ command << ' --quick'
81
88
  if port
82
89
  command << " -h#{host || '127.0.0.1'} -P#{port}"
83
90
  else
@@ -0,0 +1,12 @@
1
+ desc 'branch', 'Check out a feature branch based on a story from Pivotal Tracker'
2
+ long_desc <<-LONGDESC
3
+ Example: `geordi branch`
4
+
5
+ On the first execution we ask for your Pivotal Tracker API token. It will be
6
+ stored in `~/.config/geordi/global.yml`.
7
+ LONGDESC
8
+
9
+ def branch
10
+ require 'geordi/gitpt'
11
+ Gitpt.new.run_branch
12
+ end
@@ -10,5 +10,5 @@ LONGDESC
10
10
 
11
11
  def commit(*git_args)
12
12
  require 'geordi/gitpt'
13
- Gitpt.new.run(git_args)
13
+ Gitpt.new.run_commit(git_args)
14
14
  end
@@ -20,6 +20,9 @@ sign, i.e. have each option a contiguous string.
20
20
  - *VNC:* By default, test browsers will run in a VNC session. When using a
21
21
  headless test browser anyway, you can disable VNC by setting `use_vnc: false`
22
22
  in `.geordi.yml` in the project root.
23
+
24
+ - In order to limit processes in a parallel run, you can set an environment
25
+ variable like this: `PARALLEL_TEST_PROCESSORS=6 geordi cucumber`
23
26
  LONGDESC
24
27
 
25
28
  option :modified, aliases: '-m', type: :boolean,
@@ -57,6 +57,9 @@ def dump(target = nil, *_args)
57
57
  Interaction.announce "Sourcing dump into the #{loader.config['database']} db"
58
58
  loader.load
59
59
 
60
+ Util.run! "rm #{dump_path}"
61
+ Interaction.note "Dump file removed"
62
+
60
63
  Interaction.success "Your #{loader.config['database']} database has now the data of #{target}#{database_label}."
61
64
  end
62
65
  end
@@ -2,7 +2,10 @@ desc 'rspec [FILES]', 'Run RSpec'
2
2
  long_desc <<-LONGDESC
3
3
  Example: `geordi rspec spec/models/user_spec.rb:13`
4
4
 
5
- Runs RSpec with RSpec 1/2 support, parallel_tests detection and `bundle exec`.
5
+ Runs RSpec with version 1/2 support, parallel_tests detection and `bundle exec`.
6
+
7
+ In order to limit processes in a parallel run, you can set an environment
8
+ variable like this: `PARALLEL_TEST_PROCESSORS=6 geordi rspec`
6
9
  LONGDESC
7
10
 
8
11
  def rspec(*files)
@@ -57,11 +57,7 @@ module Geordi
57
57
  Interaction.note 'Source file: ' + dump_file
58
58
 
59
59
  source_command = send("#{config['adapter']}_command")
60
- Util.run! source_command, fail_message: "An error occured loading #{File.basename(dump_file)}"
61
-
62
- Interaction.announce 'Clean up'
63
- Interaction.note 'Removing: ' + dump_file
64
- Util.run!("rm #{dump_file}")
60
+ Util.run! source_command, fail_message: "An error occurred loading #{File.basename(dump_file)}"
65
61
  end
66
62
 
67
63
  end
data/lib/geordi/gitpt.rb CHANGED
@@ -1,99 +1,170 @@
1
- class Gitpt
2
- require 'yaml'
3
- require 'highline'
4
- require 'tracker_api'
5
-
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
-
10
- def initialize
11
- self.highline = HighLine.new
12
- self.settings = Geordi::Settings.new
13
- self.client = build_client
14
- end
1
+ require 'yaml'
2
+ require 'highline'
3
+ require 'tracker_api'
4
+
5
+ module Geordi
6
+ class Gitpt
7
+
8
+ # This require-style is to prevent Ruby from loading files of a different
9
+ # version of Geordi.
10
+ require File.expand_path('settings', __dir__)
15
11
 
16
- def run(git_args)
17
- Geordi::Interaction.warn <<-WARNING unless Geordi::Util.staged_changes?
12
+ def initialize
13
+ self.highline = HighLine.new
14
+ self.settings = Settings.new
15
+ self.client = build_client
16
+ end
17
+
18
+ def run_commit(git_args)
19
+ Interaction.warn <<-WARNING unless Util.staged_changes?
18
20
  No staged changes. Will create an empty commit.
19
- WARNING
21
+ WARNING
20
22
 
21
- story = choose_story
22
- if story
23
- create_commit "[##{story.id}] #{story.name}", *git_args
23
+ story = choose_story
24
+ if story
25
+ create_commit "[##{story.id}] #{story.name}", *git_args
26
+ end
24
27
  end
25
- end
26
28
 
27
- private
29
+ def run_branch
30
+ story = choose_story || Interaction.fail('No story selected.')
28
31
 
29
- attr_accessor :highline, :client, :settings
32
+ normalized_story_name = normalize_string(story.name)
30
33
 
31
- def build_client
32
- TrackerApi::Client.new(token: settings.pivotal_tracker_api_key)
33
- end
34
+ branch_list_string = if Util.testing?
35
+ ENV['GEORDI_TESTING_GIT_BRANCHES'] || ''
36
+ else
37
+ `git branch --format="%(refname:short)"`
38
+ end
34
39
 
35
- def load_projects
36
- project_ids = settings.pivotal_tracker_project_ids
37
- project_ids.collect { |project_id| client.project(project_id) }
38
- end
40
+ if branch_list_string.nil? || branch_list_string.strip.empty?
41
+ Interaction.fail 'Could not determine local git branches.'
42
+ end
39
43
 
40
- def applicable_stories
41
- projects = load_projects
42
- projects.collect do |project|
43
- project.stories(filter: 'state:started,finished,rejected')
44
- end.flatten
45
- end
44
+ new_branch_name = "#{git_user_initials}/#{normalized_story_name}-#{story.id}"
45
+
46
+ local_branches = branch_list_string.split("\n")
47
+ branch_name = local_branches.find { |branch_name| branch_name == new_branch_name }
48
+ branch_name ||= local_branches.find { |branch_name| branch_name.include? story.id.to_s }
49
+
50
+ if branch_name.present?
51
+ checkout_branch branch_name, new_branch: false
52
+ else
53
+ checkout_branch new_branch_name, new_branch: true
54
+ end
55
+ end
56
+
57
+ private
58
+
59
+ attr_accessor :highline, :client, :settings
60
+
61
+ def build_client
62
+ TrackerApi::Client.new(token: settings.pivotal_tracker_api_key)
63
+ end
64
+
65
+ def load_projects
66
+ project_ids = settings.pivotal_tracker_project_ids
67
+ project_ids.collect { |project_id| client.project(project_id) }
68
+ end
46
69
 
47
- def choose_story
48
- if Geordi::Util.testing?
49
- return OpenStruct.new(id: 12, name: 'Test Story')
70
+ def applicable_stories
71
+ projects = load_projects
72
+ projects.collect do |project|
73
+ project.stories(filter: 'state:started,finished,rejected')
74
+ end.flatten
50
75
  end
51
76
 
52
- loading_message = 'Connecting to Pivotal Tracker ...'
53
- print(loading_message)
54
- stories = applicable_stories
55
- reset_loading_message = "\r#{' ' * (loading_message.length + stories.length)}\r"
77
+ def choose_story
78
+ if Util.testing?
79
+ return OpenStruct.new(id: 12, name: 'Test Story')
80
+ end
81
+
82
+ loading_message = 'Connecting to Pivotal Tracker ...'
83
+ print(loading_message)
84
+ stories = applicable_stories
85
+ reset_loading_message = "\r#{' ' * (loading_message.length + stories.length)}\r"
86
+
87
+ highline.choose do |menu|
88
+ menu.header = 'Choose a story'
89
+
90
+ stories.each do |story|
91
+ print '.' # Progress
92
+
93
+ state = story.current_state
94
+ owners = story.owners
95
+ owner_is_me = owners.collect(&:id).include?(client.me.id)
56
96
 
57
- highline.choose do |menu|
58
- menu.header = 'Choose a story'
97
+ if state == 'started'
98
+ state = HighLine::GREEN + state + HighLine::RESET
99
+ elsif state != 'finished'
100
+ state = HighLine::RED + state + HighLine::RESET
101
+ end
59
102
 
60
- stories.each do |story|
61
- print '.' # Progress
103
+ state += HighLine::BOLD if owner_is_me
62
104
 
63
- state = story.current_state
64
- owners = story.owners
65
- owner_is_me = owners.collect(&:id).include?(client.me.id)
105
+ label = "(#{owners.collect(&:name).join(', ')}, #{state}) #{story.name}"
106
+ label = bold(label) if owner_is_me
66
107
 
67
- if state == 'started'
68
- state = HighLine::GREEN + state + HighLine::RESET
69
- elsif state != 'finished'
70
- state = HighLine::RED + state + HighLine::RESET
108
+ menu.choice(label) { return story }
71
109
  end
72
110
 
73
- state += HighLine::BOLD if owner_is_me
111
+ menu.hidden ''
112
+ print reset_loading_message # Once menu is build
113
+ end
114
+
115
+ nil # Return nothing
116
+ end
74
117
 
75
- label = "(#{owners.collect(&:name).join(', ')}, #{state}) #{story.name}"
76
- label = bold(label) if owner_is_me
118
+ def create_commit(message, *git_args)
119
+ extra = highline.ask("\nAdd an optional message").strip
120
+ message << ' - ' << extra if extra != ''
121
+
122
+ Util.run!(['git', 'commit', '--allow-empty', '-m', message, *git_args])
123
+ end
77
124
 
78
- menu.choice(label) { return story }
125
+ def bold(string)
126
+ HighLine::BOLD + string + HighLine::RESET
127
+ end
128
+
129
+ def checkout_branch(name, new_branch: false)
130
+ if new_branch
131
+ Util.run! ['git', 'checkout', 'master']
132
+ Util.run! ['git', 'checkout', '-b', name]
133
+ else
134
+ Util.run! ['git', 'checkout', name]
79
135
  end
136
+ end
80
137
 
81
- menu.hidden ''
82
- print reset_loading_message # Once menu is build
138
+ def normalize_string(name)
139
+ name.gsub!('ä', 'ae')
140
+ name.gsub!('ö', 'oe')
141
+ name.gsub!('ü', 'ue')
142
+ name.gsub!('ß', 'ss')
143
+ name.tr!('^A-Za-z0-9_ ', '')
144
+ name.squeeze! ' '
145
+ name.gsub!(' ', '-')
146
+ name.downcase!
147
+ name
83
148
  end
84
149
 
85
- nil # Return nothing
86
- end
150
+ def git_user_initials
151
+ stdout_str = if Util.testing?
152
+ ENV['GEORDI_TESTING_GIT_USERNAME']
153
+ else
154
+ `git config user.name`
155
+ end
87
156
 
88
- def create_commit(message, *git_args)
89
- extra = highline.ask("\nAdd an optional message").strip
90
- message << ' - ' << extra if extra != ''
157
+ git_user_initials = unless stdout_str.nil?
158
+ stdout_str.strip.split(' ').map(&:chars).map(&:first).join.downcase
159
+ end
91
160
 
92
- Geordi::Util.run!(['git', 'commit', '--allow-empty', '-m', message, *git_args])
93
- end
161
+ git_user_initials = Interaction.prompt 'Enter your initals:', git_user_initials
94
162
 
95
- def bold(string)
96
- HighLine::BOLD + string + HighLine::RESET
163
+ if git_user_initials.nil?
164
+ Interaction.fail('Could not determine the git user\'s initials.')
165
+ else
166
+ git_user_initials
167
+ end
168
+ end
97
169
  end
98
-
99
170
  end
data/lib/geordi/remote.rb CHANGED
@@ -3,6 +3,7 @@ require 'geordi/interaction'
3
3
  require 'geordi/util'
4
4
  require 'highline/import'
5
5
  require 'pathname'
6
+ require 'fileutils'
6
7
 
7
8
  module Geordi
8
9
  class Remote
@@ -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 ].freeze
11
+ ALLOWED_GLOBAL_SETTINGS = %w[ pivotal_tracker_api_key auto_update_chromedriver pivotal_tracker_project_ids ].freeze
12
12
  ALLOWED_LOCAL_SETTINGS = %w[ use_vnc pivotal_tracker_project_ids ].freeze
13
13
 
14
14
  def initialize
@@ -42,18 +42,13 @@ module Geordi
42
42
  end
43
43
 
44
44
  def pivotal_tracker_project_ids
45
- project_ids = @local_settings['pivotal_tracker_project_ids'] || pt_project_ids_old
45
+ local_project_ids = @local_settings['pivotal_tracker_project_ids'] || pt_project_ids_old
46
+ global_project_ids = @global_settings['pivotal_tracker_project_ids']
46
47
 
47
- case project_ids
48
- when Array
49
- # nothing to do
50
- when String
51
- project_ids = project_ids.split(/[\s]+/).map(&:to_i)
52
- when Integer
53
- project_ids = [project_ids]
54
- else
55
- project_ids = []
56
- end
48
+ local_project_ids = array_wrap_project_ids(local_project_ids)
49
+ global_project_ids = array_wrap_project_ids(global_project_ids)
50
+
51
+ project_ids = local_project_ids | global_project_ids
57
52
 
58
53
  if project_ids.empty?
59
54
  puts
@@ -160,5 +155,18 @@ module Geordi
160
155
  end
161
156
  end
162
157
 
158
+ def array_wrap_project_ids(project_ids)
159
+ case project_ids
160
+ when Array
161
+ project_ids
162
+ when String
163
+ project_ids.split(/[\s]+/).map(&:to_i)
164
+ when Integer
165
+ [project_ids]
166
+ else
167
+ []
168
+ end
169
+ end
170
+
163
171
  end
164
172
  end
@@ -1,3 +1,3 @@
1
1
  module Geordi
2
- VERSION = '5.3.0'.freeze
2
+ VERSION = '5.4.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: 5.3.0
4
+ version: 5.4.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-02-01 00:00:00.000000000 Z
11
+ date: 2021-02-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -57,6 +57,7 @@ files:
57
57
  - lib/geordi/cli.rb
58
58
  - lib/geordi/commands/_setup_vnc.rb
59
59
  - lib/geordi/commands/apache_site.rb
60
+ - lib/geordi/commands/branch.rb
60
61
  - lib/geordi/commands/bundle_install.rb
61
62
  - lib/geordi/commands/capistrano.rb
62
63
  - lib/geordi/commands/chromedriver_update.rb
@@ -118,7 +119,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
118
119
  - !ruby/object:Gem::Version
119
120
  version: '0'
120
121
  requirements: []
121
- rubygems_version: 3.0.8
122
+ rubygems_version: 3.1.4
122
123
  signing_key:
123
124
  specification_version: 4
124
125
  summary: Collection of command line tools we use in our daily work with Ruby, Rails