geordi 5.2.3 → 6.0.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.
data/lib/geordi/gitpt.rb CHANGED
@@ -1,99 +1,185 @@
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}"
46
45
 
47
- def choose_story
48
- if Geordi::Util.testing?
49
- return OpenStruct.new(id: 12, name: 'Test Story')
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)
50
63
  end
51
64
 
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"
65
+ def load_projects
66
+ project_ids = settings.pivotal_tracker_project_ids
67
+ project_ids.collect do |project_id|
68
+ begin
69
+ client.project(project_id)
70
+ rescue TrackerApi::Errors::ClientError
71
+ puts # Start a new line
72
+ Geordi::Interaction.warn "Could not access project #{project_id}. Skipping."
73
+ end
74
+ end.compact
75
+ end
76
+
77
+ def applicable_stories
78
+ if Util.testing?
79
+ return ENV['GEORDI_TESTING_NO_PT_STORIES'] == 'true' ? [] : [OpenStruct.new(id: 12, name: 'Test Story')]
80
+ end
56
81
 
57
- highline.choose do |menu|
58
- menu.header = 'Choose a story'
82
+ projects = load_projects
83
+ projects.collect do |project|
84
+ project.stories(filter: 'state:started,finished,rejected', fields: ':default,owners(id,name)')
85
+ end.flatten
86
+ end
59
87
 
60
- stories.each do |story|
61
- print '.' # Progress
88
+ def choose_story
89
+ loading_message = 'Connecting to Pivotal Tracker ...'
90
+ print(loading_message)
91
+ stories = applicable_stories
92
+ reset_loading_message = "\r#{' ' * (loading_message.length + stories.length)}\r"
62
93
 
63
- state = story.current_state
64
- owners = story.owners
65
- owner_is_me = owners.collect(&:id).include?(client.me.id)
94
+ Geordi::Interaction.fail('No stories to offer.') if stories.empty?
66
95
 
67
- if state == 'started'
68
- state = HighLine::GREEN + state + HighLine::RESET
69
- elsif state != 'finished'
70
- state = HighLine::RED + state + HighLine::RESET
96
+ if Util.testing?
97
+ return stories[0]
98
+ end
99
+
100
+ my_id = client.me.id
101
+
102
+ highline.choose do |menu|
103
+ menu.header = 'Choose a story'
104
+
105
+ stories.each do |story|
106
+ print '.' # Progress
107
+
108
+ state = story.current_state
109
+ owners = story.owners
110
+ owner_is_me = owners.collect(&:id).include?(my_id)
111
+
112
+ if state == 'started'
113
+ state = HighLine::GREEN + state + HighLine::RESET
114
+ elsif state != 'finished'
115
+ state = HighLine::RED + state + HighLine::RESET
116
+ end
117
+
118
+ state += HighLine::BOLD if owner_is_me
119
+
120
+ label = "(#{owners.collect(&:name).join(', ')}, #{state}) #{story.name}"
121
+ label = bold(label) if owner_is_me
122
+
123
+ menu.choice(label) { return story }
71
124
  end
72
125
 
73
- state += HighLine::BOLD if owner_is_me
126
+ menu.hidden ''
127
+ print reset_loading_message # Once menu is build
128
+ end
129
+
130
+ nil # Return nothing
131
+ end
74
132
 
75
- label = "(#{owners.collect(&:name).join(', ')}, #{state}) #{story.name}"
76
- label = bold(label) if owner_is_me
133
+ def create_commit(message, *git_args)
134
+ extra = highline.ask("\nAdd an optional message").strip
135
+ message << ' - ' << extra if extra != ''
77
136
 
78
- menu.choice(label) { return story }
137
+ Util.run!(['git', 'commit', '--allow-empty', '-m', message, *git_args])
138
+ end
139
+
140
+ def bold(string)
141
+ HighLine::BOLD + string + HighLine::RESET
142
+ end
143
+
144
+ def checkout_branch(name, new_branch: false)
145
+ if new_branch
146
+ Util.run! ['git', 'checkout', 'master']
147
+ Util.run! ['git', 'checkout', '-b', name]
148
+ else
149
+ Util.run! ['git', 'checkout', name]
79
150
  end
151
+ end
80
152
 
81
- menu.hidden ''
82
- print reset_loading_message # Once menu is build
153
+ def normalize_string(name)
154
+ name.gsub!('ä', 'ae')
155
+ name.gsub!('ö', 'oe')
156
+ name.gsub!('ü', 'ue')
157
+ name.gsub!('ß', 'ss')
158
+ name.tr!('^A-Za-z0-9_ ', '')
159
+ name.squeeze! ' '
160
+ name.gsub!(' ', '-')
161
+ name.downcase!
162
+ name
83
163
  end
84
164
 
85
- nil # Return nothing
86
- end
165
+ def git_user_initials
166
+ stdout_str = if Util.testing?
167
+ ENV['GEORDI_TESTING_GIT_USERNAME']
168
+ else
169
+ `git config user.name`
170
+ end
87
171
 
88
- def create_commit(message, *git_args)
89
- extra = highline.ask("\nAdd an optional message").strip
90
- message << ' - ' << extra if extra != ''
172
+ git_user_initials = unless stdout_str.nil?
173
+ stdout_str.strip.split(' ').map(&:chars).map(&:first).join.downcase
174
+ end
91
175
 
92
- Geordi::Util.run!(['git', 'commit', '--allow-empty', '-m', message, *git_args])
93
- end
176
+ git_user_initials = Interaction.prompt 'Enter your initals:', git_user_initials
94
177
 
95
- def bold(string)
96
- HighLine::BOLD + string + HighLine::RESET
178
+ if git_user_initials.nil?
179
+ Interaction.fail('Could not determine the git user\'s initials.')
180
+ else
181
+ git_user_initials
182
+ end
183
+ end
97
184
  end
98
-
99
185
  end
@@ -11,8 +11,9 @@ module Geordi
11
11
  puts "\e[4;34m#{message}\e[0m" # blue underline
12
12
  end
13
13
 
14
- # Any hints, comments, infos or explanations should be `note`d. Please do
15
- # not print any output (data, file contents, lists) with `note`.
14
+ # Any meta information, i.e. hints, comments, infos or explanations should
15
+ # be printed with `note`.
16
+ # Please do not use it for command output (data, file contents, lists etc).
16
17
  def note(text)
17
18
  puts '> ' + text
18
19
  end
@@ -38,7 +39,8 @@ module Geordi
38
39
  exit(1)
39
40
  end
40
41
 
41
- # When you're done, inform the user with a `success` and a short message
42
+ # When you're done, inform the user with a `success` and a short message. It
43
+ # should be a sentence (i.e. ending with [.!?]).
42
44
  def success(text)
43
45
  message = "\n> #{text}"
44
46
  puts "\e[32m#{message}\e[0m" # green
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
@@ -59,7 +60,7 @@ module Geordi
59
60
  server_option = options[:select_server]
60
61
  server_number = server_option.to_i
61
62
 
62
- server = if server_option == 'select_server'
63
+ server = if server_option == 'select_server'
63
64
  select_server
64
65
  elsif server_number != 0 && server_number <= @config.servers.count
65
66
  server_index = server_number - 1
@@ -8,8 +8,10 @@ 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
12
- ALLOWED_LOCAL_SETTINGS = %w[ use_vnc pivotal_tracker_project_ids ].freeze
11
+ ALLOWED_GLOBAL_SETTINGS = %w[ pivotal_tracker_api_key auto_update_chromedriver pivotal_tracker_project_ids ].freeze
12
+ ALLOWED_LOCAL_SETTINGS = %w[ pivotal_tracker_project_ids ].freeze
13
+
14
+ SETTINGS_WARNED = 'GEORDI_INVALID_SETTINGS_WARNED'
13
15
 
14
16
  def initialize
15
17
  read_settings
@@ -34,26 +36,14 @@ module Geordi
34
36
  save_global_settings
35
37
  end
36
38
 
37
- # Local settings
38
- # They should not be changed by geordi to avoid unexpected diffs, therefore
39
- # there are no setters for these settings
40
- def use_vnc?
41
- @local_settings.fetch('use_vnc', true)
42
- end
43
-
44
39
  def pivotal_tracker_project_ids
45
- project_ids = @local_settings['pivotal_tracker_project_ids'] || pt_project_ids_old
40
+ local_project_ids = @local_settings['pivotal_tracker_project_ids'] || pt_project_ids_old
41
+ global_project_ids = @global_settings['pivotal_tracker_project_ids']
46
42
 
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
43
+ local_project_ids = array_wrap_project_ids(local_project_ids)
44
+ global_project_ids = array_wrap_project_ids(global_project_ids)
45
+
46
+ project_ids = local_project_ids | global_project_ids
57
47
 
58
48
  if project_ids.empty?
59
49
  puts
@@ -78,14 +68,20 @@ module Geordi
78
68
  global_path = GLOBAL_SETTINGS_FILE_NAME
79
69
  local_path = LOCAL_SETTINGS_FILE_NAME
80
70
 
81
- if File.exists?(global_path)
82
- global_settings = YAML.safe_load(File.read(global_path))
83
- check_for_invalid_keys(global_settings, ALLOWED_GLOBAL_SETTINGS, global_path)
71
+ global_settings = if File.exists?(global_path)
72
+ YAML.safe_load(File.read(global_path))
73
+ end
74
+ local_settings = if File.exists?(local_path)
75
+ YAML.safe_load(File.read(local_path))
84
76
  end
85
77
 
86
- if File.exists?(local_path)
87
- local_settings = YAML.safe_load(File.read(local_path))
78
+ # Prevent duplicate warnings caused by another instance of Settings
79
+ unless ENV[SETTINGS_WARNED]
80
+ check_for_invalid_keys(global_settings, ALLOWED_GLOBAL_SETTINGS, global_path)
88
81
  check_for_invalid_keys(local_settings, ALLOWED_LOCAL_SETTINGS, local_path)
82
+ Interaction.warn "Unsupported config file \".firefox-version\". Please remove it." if File.exists?('.firefox-version')
83
+
84
+ ENV[SETTINGS_WARNED] = 'true'
89
85
  end
90
86
 
91
87
  @global_settings = global_settings || {}
@@ -93,21 +89,12 @@ module Geordi
93
89
  end
94
90
 
95
91
  def check_for_invalid_keys(settings, allowed_keys, file)
92
+ return if settings.nil?
93
+
96
94
  invalid_keys = settings.keys - allowed_keys
97
95
  unless invalid_keys.empty?
98
- Geordi::Interaction.warn "Geordi detected unknown keys in #{file}.\n"
99
-
100
- invalid_keys.sort.each do |key|
101
- puts "* #{key}"
102
- end
103
-
104
- puts "\nAllowed keys are:"
105
- allowed_keys.sort.each do |key|
106
- puts "* #{key}"
107
- end
108
- puts
109
-
110
- exit 1
96
+ Interaction.warn "Unknown settings in #{file}: #{invalid_keys.join(", ")}"
97
+ Interaction.note "Supported settings in #{file} are: #{allowed_keys.join(", ")}"
111
98
  end
112
99
  end
113
100
 
@@ -160,5 +147,18 @@ module Geordi
160
147
  end
161
148
  end
162
149
 
150
+ def array_wrap_project_ids(project_ids)
151
+ case project_ids
152
+ when Array
153
+ project_ids
154
+ when String
155
+ project_ids.split(/[\s]+/).map(&:to_i)
156
+ when Integer
157
+ [project_ids]
158
+ else
159
+ []
160
+ end
161
+ end
162
+
163
163
  end
164
164
  end
@@ -1,3 +1,3 @@
1
1
  module Geordi
2
- VERSION = '5.2.3'.freeze
2
+ VERSION = '6.0.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.2.3
4
+ version: 6.0.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-01-27 00:00:00.000000000 Z
11
+ date: 2021-06-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -32,12 +32,12 @@ executables:
32
32
  - b
33
33
  - dumple
34
34
  - geordi
35
- - launchy_browser
36
35
  extensions: []
37
36
  extra_rdoc_files: []
38
37
  files:
39
38
  - ".github/workflows/test.yml"
40
39
  - ".gitignore"
40
+ - ".rspec"
41
41
  - ".ruby-version"
42
42
  - CHANGELOG.md
43
43
  - Gemfile
@@ -48,15 +48,14 @@ files:
48
48
  - exe/b
49
49
  - exe/dumple
50
50
  - exe/geordi
51
- - exe/launchy_browser
52
51
  - geordi.gemspec
53
52
  - lib/geordi.rb
54
53
  - lib/geordi/COMMAND_TEMPLATE
55
54
  - lib/geordi/capistrano_config.rb
56
55
  - lib/geordi/chromedriver_updater.rb
57
56
  - lib/geordi/cli.rb
58
- - lib/geordi/commands/_setup_vnc.rb
59
57
  - lib/geordi/commands/apache_site.rb
58
+ - lib/geordi/commands/branch.rb
60
59
  - lib/geordi/commands/bundle_install.rb
61
60
  - lib/geordi/commands/capistrano.rb
62
61
  - lib/geordi/commands/chromedriver_update.rb
@@ -71,7 +70,6 @@ files:
71
70
  - lib/geordi/commands/docker.rb
72
71
  - lib/geordi/commands/drop_databases.rb
73
72
  - lib/geordi/commands/dump.rb
74
- - lib/geordi/commands/firefox.rb
75
73
  - lib/geordi/commands/migrate.rb
76
74
  - lib/geordi/commands/png_optimize.rb
77
75
  - lib/geordi/commands/rake.rb
@@ -85,14 +83,12 @@ files:
85
83
  - lib/geordi/commands/unit.rb
86
84
  - lib/geordi/commands/update.rb
87
85
  - lib/geordi/commands/version.rb
88
- - lib/geordi/commands/vnc.rb
89
86
  - lib/geordi/commands/with_rake.rb
90
87
  - lib/geordi/commands/yarn_install.rb
91
88
  - lib/geordi/cucumber.rb
92
89
  - lib/geordi/db_cleaner.rb
93
90
  - lib/geordi/docker.rb
94
91
  - lib/geordi/dump_loader.rb
95
- - lib/geordi/firefox_for_selenium.rb
96
92
  - lib/geordi/gitpt.rb
97
93
  - lib/geordi/interaction.rb
98
94
  - lib/geordi/remote.rb
@@ -103,7 +99,10 @@ homepage: https://makandra.com
103
99
  licenses:
104
100
  - MIT
105
101
  metadata: {}
106
- post_install_message:
102
+ post_install_message: 'Support for sequential running of integration tests tagged
103
+ with @solo has been dropped.
104
+
105
+ '
107
106
  rdoc_options: []
108
107
  require_paths:
109
108
  - lib