geordi 5.2.3 → 6.0.0

Sign up to get free protection for your applications and to get access to all the features.
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