brightpearl-cli 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +22 -0
- data/README.md +21 -0
- data/bin/bp +5 -0
- data/bin/brightpearl +5 -0
- data/lib/brightpearl_cli.rb +351 -0
- data/lib/core/api.rb +7 -0
- data/lib/core/config.rb +175 -0
- data/lib/core/enums.rb +9 -0
- data/lib/core/git.rb +771 -0
- data/lib/core/jira.rb +43 -0
- data/lib/core/mysql.rb +48 -0
- data/lib/core/terminal.rb +389 -0
- data/lib/core/tools.rb +78 -0
- data/lib/core/validate.rb +7 -0
- data/lib/routes/build.rb +83 -0
- data/lib/routes/dummy_order.rb +151 -0
- data/lib/routes/git_branch.rb +55 -0
- data/lib/routes/git_checkout.rb +155 -0
- data/lib/routes/git_delete.rb +120 -0
- data/lib/routes/git_merge.rb +288 -0
- data/lib/routes/git_pull.rb +16 -0
- data/lib/routes/git_push.rb +16 -0
- data/lib/routes/git_stash.rb +27 -0
- data/lib/routes/git_update.rb +125 -0
- data/lib/routes/jira.rb +51 -0
- data/lib/routes/less.rb +37 -0
- data/lib/routes/reset.rb +33 -0
- data/lib/routes/review.rb +16 -0
- data/lib/routes/scripts_code_sniffer.rb +36 -0
- data/lib/routes/scripts_color.rb +52 -0
- data/lib/routes/setup.rb +15 -0
- data/lib/routes/tests.rb +69 -0
- data/lib/routes/update.rb +35 -0
- metadata +169 -0
data/lib/core/git.rb
ADDED
@@ -0,0 +1,771 @@
|
|
1
|
+
require 'columnist'
|
2
|
+
require 'date'
|
3
|
+
require 'highline'
|
4
|
+
|
5
|
+
module Brightpearl
|
6
|
+
|
7
|
+
class Git
|
8
|
+
|
9
|
+
include Columnist
|
10
|
+
|
11
|
+
DELIMITER = '*|*'
|
12
|
+
|
13
|
+
SORT_DATE = 'date'
|
14
|
+
SORT_REFNAME = 'refname'
|
15
|
+
|
16
|
+
LOCAL = 'local'
|
17
|
+
REMOTE = 'remote'
|
18
|
+
CODE = 'code'
|
19
|
+
DB = 'db'
|
20
|
+
|
21
|
+
MERGED_PREFIX = 'MERGED-'
|
22
|
+
MDASH = '━'
|
23
|
+
|
24
|
+
MASTER = 'master'
|
25
|
+
REFNAME = 'refname'
|
26
|
+
OBJECT_TYPE = 'objecttype'
|
27
|
+
OBJECT_SIZE = 'objectsize'
|
28
|
+
OBJECT_NAME = 'objectname'
|
29
|
+
TREE = 'tree'
|
30
|
+
NUM_PARENT = 'numparent'
|
31
|
+
COMMITTER_NAME = 'committername'
|
32
|
+
COMMITTER_EMAIL = 'committeremail'
|
33
|
+
COMMITTER_DATE = 'committerdate'
|
34
|
+
SUBJECT = 'subject'
|
35
|
+
UPSTREAM = 'upstream'
|
36
|
+
|
37
|
+
BRANCH_NAME = 'branch_name'
|
38
|
+
BRANCH_LOCATION = 'branch_location'
|
39
|
+
BRANCH_EXISTS = 'branch_exists'
|
40
|
+
BRANCH_EXISTS_LOCALLY = 'branch_exists_locally'
|
41
|
+
BRANCH_IS_CURRENT = 'branch_is_current'
|
42
|
+
BRANCH_IS_UP_TO_DATE = 'branch_is_up_to_date'
|
43
|
+
BRANCH_HAS_STASH = 'branch_has_stash'
|
44
|
+
BRANCH_HAS_UPSTREAM = 'branch_has_upstream'
|
45
|
+
|
46
|
+
def initialize
|
47
|
+
|
48
|
+
@origin_updated_code = false
|
49
|
+
@origin_updated_db = false
|
50
|
+
@branch_upstream_data = false
|
51
|
+
@branches_as_array = {
|
52
|
+
:local_code => nil,
|
53
|
+
:local_db => nil,
|
54
|
+
:local_both => nil,
|
55
|
+
:remote_code => nil,
|
56
|
+
:remote_db => nil,
|
57
|
+
:remote_both => nil
|
58
|
+
}
|
59
|
+
@branches_as_array_all = false
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
# Gets detailed info about local branches as Array.
|
64
|
+
# @return Array
|
65
|
+
def get_local_branches(sort = SORT_REFNAME, repo_dir = nil)
|
66
|
+
repos = []
|
67
|
+
repos_to_return = []
|
68
|
+
validate_sort(sort)
|
69
|
+
if repo_dir.nil?
|
70
|
+
repo_loop.each do |repo_dir_inner|
|
71
|
+
repos << repo_dir_inner
|
72
|
+
end
|
73
|
+
else
|
74
|
+
validate_repo_dir(repo_dir)
|
75
|
+
repos << repo_dir
|
76
|
+
end
|
77
|
+
repos.each do |repo_dir_inner|
|
78
|
+
unless File.directory?(repo_dir_inner)
|
79
|
+
Brightpearl::Terminal::error('Directory not found', "Directory doesn't exist: #{Brightpearl::Terminal::format_directory(repo_dir_inner)}", true)
|
80
|
+
end
|
81
|
+
raw_terminal_output = `
|
82
|
+
cd #{repo_dir_inner} &&
|
83
|
+
git for-each-ref refs/heads/ --format='%(#{REFNAME})#{DELIMITER}%(#{OBJECT_TYPE})#{DELIMITER}%(#{OBJECT_SIZE})#{DELIMITER}%(#{OBJECT_NAME})#{DELIMITER}%(tree)#{DELIMITER}%(#{NUM_PARENT})#{DELIMITER}%(#{COMMITTER_NAME})#{DELIMITER}%(#{COMMITTER_EMAIL})#{DELIMITER}%(#{COMMITTER_DATE})#{DELIMITER}%(#{SUBJECT})#{DELIMITER}%(#{UPSTREAM})#{DELIMITER}' | sed 's/refs\\/heads\\///g'
|
84
|
+
`
|
85
|
+
branches = {}
|
86
|
+
branch_count = 0
|
87
|
+
raw_terminal_output.split("\n").each do |line|
|
88
|
+
line_split = line.split(DELIMITER)
|
89
|
+
data = {}
|
90
|
+
data[:"#{REFNAME}"] = line_split[0]
|
91
|
+
data[:"#{OBJECT_TYPE}"] = line_split[1]
|
92
|
+
data[:"#{OBJECT_SIZE}"] = line_split[2]
|
93
|
+
data[:"#{OBJECT_NAME}"] = line_split[3]
|
94
|
+
data[:"#{TREE}"] = line_split[4]
|
95
|
+
data[:"#{NUM_PARENT}"] = line_split[5]
|
96
|
+
data[:"#{COMMITTER_NAME}"] = line_split[6]
|
97
|
+
data[:"#{COMMITTER_EMAIL}"] = line_split[7][1..-2]
|
98
|
+
data[:"#{COMMITTER_DATE}"] = DateTime.parse(line_split[8])
|
99
|
+
data[:"#{SUBJECT}"] = line_split[9]
|
100
|
+
data[:"#{UPSTREAM}"] = line_split[10]
|
101
|
+
case sort
|
102
|
+
when SORT_REFNAME
|
103
|
+
branches[data[:"#{REFNAME}"]] = data
|
104
|
+
when SORT_DATE
|
105
|
+
branches["#{data[:"#{COMMITTER_DATE}"].strftime('%Y-%m-%d-%H-%I-%S')}-#{branch_count}"] = data
|
106
|
+
branch_count = branch_count + 1
|
107
|
+
else
|
108
|
+
Brightpearl::Terminal::error('Sort not supported', "The following sorting option is not yet supported: #{sort}", true)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
branch_keys = branches.keys
|
112
|
+
case sort
|
113
|
+
when SORT_REFNAME
|
114
|
+
branch_keys.sort_by!(&:downcase)
|
115
|
+
when SORT_DATE
|
116
|
+
branch_keys.sort_by! { |value| value }
|
117
|
+
branch_keys = branch_keys.reverse
|
118
|
+
else
|
119
|
+
Brightpearl::Terminal::error('Sort not supported', "The following sorting option is not yet supported: #{sort}", true)
|
120
|
+
end
|
121
|
+
branch_data = []
|
122
|
+
branch_keys.each do |key|
|
123
|
+
branch_data << branches["#{key}"]
|
124
|
+
end
|
125
|
+
repos_to_return << branch_data
|
126
|
+
end
|
127
|
+
if repo_dir.nil?
|
128
|
+
return repos_to_return[0], repos_to_return[1]
|
129
|
+
else
|
130
|
+
repos_to_return[0]
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
# Gets detailed info about remote branches as Array.
|
135
|
+
# @return Array
|
136
|
+
def get_remote_branches(sort = SORT_REFNAME, repo_dir = nil)
|
137
|
+
repos = []
|
138
|
+
repos_to_return = []
|
139
|
+
validate_sort(sort)
|
140
|
+
if repo_dir.nil?
|
141
|
+
repo_loop.each do |repo_dir_inner|
|
142
|
+
repos << repo_dir_inner
|
143
|
+
end
|
144
|
+
else
|
145
|
+
validate_repo_dir(repo_dir)
|
146
|
+
repos << repo_dir
|
147
|
+
end
|
148
|
+
repos.each do |repo_dir_inner|
|
149
|
+
unless File.directory?(repo_dir_inner)
|
150
|
+
Brightpearl::Terminal::error('Directory not found', "Directory doesn't exist: #{Brightpearl::Terminal::format_directory(repo_dir)}", true)
|
151
|
+
end
|
152
|
+
update_origin(repo_dir_inner)
|
153
|
+
raw_terminal_output = `
|
154
|
+
cd #{repo_dir_inner} &&
|
155
|
+
for branch in \`git branch -r | grep -v HEAD\`; do echo \`git show --format="%cn#{DELIMITER}%ce#{DELIMITER}%cd#{DELIMITER}%s#{DELIMITER}" $branch | head -n 1\` $branch; done | sort -r | sed 's/origin\\///g'
|
156
|
+
`
|
157
|
+
branches = {}
|
158
|
+
branch_count = 0
|
159
|
+
raw_terminal_output.split("\n").each do |line|
|
160
|
+
line_split = line.split(DELIMITER)
|
161
|
+
data = {}
|
162
|
+
data[:"#{COMMITTER_NAME}"] = line_split[0]
|
163
|
+
data[:"#{COMMITTER_EMAIL}"] = line_split[1]
|
164
|
+
data[:"#{COMMITTER_DATE}"] = DateTime.parse(line_split[2])
|
165
|
+
data[:"#{SUBJECT}"] = line_split[3]
|
166
|
+
data[:"#{REFNAME}"] = line_split[4].to_s.strip
|
167
|
+
case sort
|
168
|
+
when SORT_REFNAME
|
169
|
+
branches[data[:"#{REFNAME}"]] = data
|
170
|
+
when SORT_DATE
|
171
|
+
branches["#{data[:"#{COMMITTER_DATE}"].strftime('%Y-%m-%d-%H-%I-%S')}-#{branch_count}"] = data
|
172
|
+
branch_count = branch_count + 1
|
173
|
+
else
|
174
|
+
Brightpearl::Terminal::error('Sort not supported', "The following sorting option is not yet supported: #{sort}", true)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
branch_keys = branches.keys
|
178
|
+
case sort
|
179
|
+
when SORT_REFNAME
|
180
|
+
branch_keys.sort_by!(&:downcase)
|
181
|
+
when SORT_DATE
|
182
|
+
branch_keys.sort_by! { |value| value }
|
183
|
+
branch_keys = branch_keys.reverse
|
184
|
+
else
|
185
|
+
Brightpearl::Terminal::error('Sort not supported', "The following sorting option is not yet supported: #{sort}", true)
|
186
|
+
end
|
187
|
+
branch_data = []
|
188
|
+
branch_keys.each do |key|
|
189
|
+
branch_data << branches["#{key}"]
|
190
|
+
end
|
191
|
+
repos_to_return << branch_data
|
192
|
+
end
|
193
|
+
if repo_dir.nil?
|
194
|
+
return repos_to_return[0], repos_to_return[1]
|
195
|
+
else
|
196
|
+
repos_to_return[0]
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
# Gets branch names as array.
|
201
|
+
# @return Array
|
202
|
+
def get_branches_as_array(local_remote = LOCAL, repo_dir = nil)
|
203
|
+
validate_local_remote(local_remote)
|
204
|
+
|
205
|
+
# Check if result is already cached.
|
206
|
+
if repo_dir.nil?
|
207
|
+
if local_remote == LOCAL
|
208
|
+
return @branches_as_array[:local_both] if @branches_as_array[:local_both] != nil
|
209
|
+
else
|
210
|
+
return @branches_as_array[:remote_both] if @branches_as_array[:remote_both] != nil
|
211
|
+
end
|
212
|
+
else
|
213
|
+
if repo_dir == Brightpearl::Config.param(Brightpearl::Config::WORKSTATION_PATH_TO_BP_CODE)
|
214
|
+
if local_remote == LOCAL
|
215
|
+
return @branches_as_array[:local_code] if @branches_as_array[:local_code] != nil
|
216
|
+
else
|
217
|
+
return @branches_as_array[:remote_code] if @branches_as_array[:remote_code] != nil
|
218
|
+
end
|
219
|
+
else
|
220
|
+
if local_remote == LOCAL
|
221
|
+
return @branches_as_array[:local_db] if @branches_as_array[:local_db] != nil
|
222
|
+
else
|
223
|
+
return @branches_as_array[:remote_db] if @branches_as_array[:remote_db] != nil
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
case local_remote
|
229
|
+
when LOCAL
|
230
|
+
if repo_dir.nil?
|
231
|
+
brightpearl_code, brightpearl_db = get_local_branches
|
232
|
+
repos_branches = [brightpearl_code, brightpearl_db]
|
233
|
+
else
|
234
|
+
branches = get_local_branches(SORT_REFNAME, repo_dir)
|
235
|
+
repos_branches = [branches]
|
236
|
+
end
|
237
|
+
else
|
238
|
+
if repo_dir.nil?
|
239
|
+
brightpearl_code, brightpearl_db = get_remote_branches
|
240
|
+
repos_branches = [brightpearl_code, brightpearl_db]
|
241
|
+
else
|
242
|
+
branches = get_remote_branches(SORT_REFNAME, repo_dir)
|
243
|
+
repos_branches = [branches]
|
244
|
+
end
|
245
|
+
end
|
246
|
+
repos_to_return = []
|
247
|
+
repos_branches.each do |repo_data|
|
248
|
+
branch_names = []
|
249
|
+
repo_data.each do |branch_data|
|
250
|
+
branch_names << branch_data[:"#{REFNAME}"]
|
251
|
+
end
|
252
|
+
repos_to_return << branch_names
|
253
|
+
end
|
254
|
+
if repo_dir.nil?
|
255
|
+
if local_remote == LOCAL
|
256
|
+
return @branches_as_array[:local_both] = repos_to_return[0], repos_to_return[1]
|
257
|
+
else
|
258
|
+
return @branches_as_array[:remote_both] = repos_to_return[0], repos_to_return[1]
|
259
|
+
end
|
260
|
+
else
|
261
|
+
if repo_dir == Brightpearl::Config.param(Brightpearl::Config::WORKSTATION_PATH_TO_BP_CODE)
|
262
|
+
if local_remote == LOCAL
|
263
|
+
return @branches_as_array[:local_code] = repos_to_return[0]
|
264
|
+
else
|
265
|
+
return @branches_as_array[:remote_code] = repos_to_return[0]
|
266
|
+
end
|
267
|
+
else
|
268
|
+
if local_remote == LOCAL
|
269
|
+
return @branches_as_array[:local_db] = repos_to_return[0]
|
270
|
+
else
|
271
|
+
return @branches_as_array[:remote_db] = repos_to_return[0]
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
# Gets EVERY SINGLE BRANCH that exists -- local & remote, code & db -- and puts them in a single, unique, array.
|
278
|
+
# @return Array
|
279
|
+
def get_all_branches_as_array
|
280
|
+
unless @branches_as_array_all
|
281
|
+
local_branches = get_branches_as_array(Brightpearl::Git::LOCAL)
|
282
|
+
remote_branches = get_branches_as_array(Brightpearl::Git::REMOTE)
|
283
|
+
@branches_as_array_all = local_branches[0].concat(local_branches[1]).concat(remote_branches[0]).concat(remote_branches[1])
|
284
|
+
@branches_as_array_all.uniq!
|
285
|
+
@branches_as_array_all.sort_by! { |m| m.downcase }
|
286
|
+
end
|
287
|
+
@branches_as_array_all
|
288
|
+
end
|
289
|
+
|
290
|
+
# Outputs list of branches to terminal.
|
291
|
+
# @return void
|
292
|
+
def show_branches(sort = SORT_REFNAME, local_remote = LOCAL)
|
293
|
+
# todo
|
294
|
+
puts
|
295
|
+
puts "\x1B[31mTODO!\x1B[0m Must do something with 'terminal_width' parameter."
|
296
|
+
puts
|
297
|
+
validate_sort(sort)
|
298
|
+
validate_local_remote(local_remote)
|
299
|
+
# terminal_width = HighLine::SystemExtensions.terminal_size
|
300
|
+
# terminal_width = terminal_width[0]
|
301
|
+
case local_remote
|
302
|
+
when LOCAL
|
303
|
+
brightpearl_code, brightpearl_db = get_local_branches(sort)
|
304
|
+
else
|
305
|
+
brightpearl_code, brightpearl_db = get_remote_branches(sort)
|
306
|
+
end
|
307
|
+
current_code_branch = current_branch_for_repo(Brightpearl::Config.param(Brightpearl::Config::WORKSTATION_PATH_TO_BP_CODE))
|
308
|
+
current_db_branch = current_branch_for_repo(Brightpearl::Config.param(Brightpearl::Config::WORKSTATION_PATH_TO_BP_DB))
|
309
|
+
column_width = [2, 20, 23, 15, 34, 1, 34, 15, 23, 20, 1]
|
310
|
+
Brightpearl::Tools::validate_report_width(column_width)
|
311
|
+
puts "\n"
|
312
|
+
table(:border => false) do
|
313
|
+
row do
|
314
|
+
column('', :align => 'right', :bold => 'true', :width => column_width[0])
|
315
|
+
column('Last Activity', :align => 'right', :bold => 'true', :width => column_width[1])
|
316
|
+
column('Developer', :align => 'right', :bold => 'true', :width => column_width[2])
|
317
|
+
column('Last Commit', :align => 'right', :bold => 'true', :width => column_width[3])
|
318
|
+
column('BRIGHTPEARL-CODE', :align => 'right', :bold => 'true', :width => column_width[4], :color => 32)
|
319
|
+
column('|', :align => 'center', :bold => 'true', :width => column_width[5])
|
320
|
+
column('BRIGHTPEARL-DB', :align => 'left', :bold => 'true', :width => column_width[6], :color => 160)
|
321
|
+
column('Last Commit', :align => 'left', :bold => 'true', :width => column_width[7])
|
322
|
+
column('Developer', :align => 'left', :bold => 'true', :width => column_width[8])
|
323
|
+
column('Last Activity', :align => 'left', :bold => 'true', :width => column_width[9])
|
324
|
+
column('', :align => 'left', :bold => 'true', :width => column_width[10])
|
325
|
+
end
|
326
|
+
show_branches_divider(column_width)
|
327
|
+
db_branches_shown = []
|
328
|
+
brightpearl_code.each do |code_branch|
|
329
|
+
db_branch = show_branches_get_db_branch(brightpearl_db, code_branch)
|
330
|
+
if db_branch[:"#{REFNAME}"] != MDASH
|
331
|
+
db_branches_shown << db_branch[:"#{REFNAME}"]
|
332
|
+
# branch_data = branch_data(code_branch[:"#{REFNAME}"])
|
333
|
+
else
|
334
|
+
# branch_data = branch_data(code_branch[:"#{REFNAME}"], CODE)
|
335
|
+
end
|
336
|
+
code_time_adjusted = code_branch[:"#{COMMITTER_DATE}"] - (1 / 24.0)
|
337
|
+
row do
|
338
|
+
code_accent, code_color, code_star, db_accent, db_color, db_star = show_branches_get_colors(code_branch, current_code_branch, current_db_branch, db_branch)
|
339
|
+
column("#{code_star}", :color => code_color)
|
340
|
+
column(Brightpearl::Tools::time_passed_since(code_time_adjusted), :color => code_color)
|
341
|
+
column(code_branch[:"#{COMMITTER_NAME}"], :color => code_color)
|
342
|
+
column(code_branch[:"#{COMMITTER_DATE}"].strftime('%d %^b %H:%M'), :color => code_color)
|
343
|
+
column(code_branch[:"#{REFNAME}"], :color => code_accent)
|
344
|
+
column('|')
|
345
|
+
column(db_branch[:"#{REFNAME}"], :color => db_accent)
|
346
|
+
column((db_branch[:"#{COMMITTER_DATE}"] == nil) ? MDASH : db_branch[:"#{COMMITTER_DATE}"].strftime('%d %^b %H:%M'), :color => db_color)
|
347
|
+
column(db_branch[:"#{COMMITTER_NAME}"], :color => db_color)
|
348
|
+
column((db_branch[:"#{COMMITTER_DATE}"] == nil) ? MDASH : Brightpearl::Tools::time_passed_since(db_branch[:"#{COMMITTER_DATE}"] - (1 / 24.0)), :color => db_color)
|
349
|
+
column("#{db_star}", :color => db_color)
|
350
|
+
end
|
351
|
+
end
|
352
|
+
brightpearl_db.each do |db_branch|
|
353
|
+
unless db_branches_shown.include? db_branch[:"#{REFNAME}"]
|
354
|
+
row do
|
355
|
+
code_accent, code_color, code_star, db_accent, db_color, db_star = show_branches_get_colors(nil, current_code_branch, current_db_branch, db_branch)
|
356
|
+
column('', :color => code_color)
|
357
|
+
column(MDASH, :color => code_color)
|
358
|
+
column(MDASH, :color => code_color)
|
359
|
+
column(MDASH, :color => code_color)
|
360
|
+
column(MDASH, :color => code_accent)
|
361
|
+
column('|')
|
362
|
+
column(db_branch[:"#{REFNAME}"], :color => db_accent)
|
363
|
+
column((db_branch[:"#{COMMITTER_DATE}"] == nil) ? MDASH : db_branch[:"#{COMMITTER_DATE}"].strftime('%d %^b %H:%M'), :color => db_color)
|
364
|
+
column(db_branch[:"#{COMMITTER_NAME}"], :color => db_color)
|
365
|
+
column((db_branch[:"#{COMMITTER_DATE}"] == nil) ? MDASH : Brightpearl::Tools::time_passed_since(db_branch[:"#{COMMITTER_DATE}"]), :color => db_color)
|
366
|
+
column('')
|
367
|
+
end
|
368
|
+
end
|
369
|
+
end
|
370
|
+
show_branches_divider(column_width)
|
371
|
+
end
|
372
|
+
puts "\n"
|
373
|
+
end
|
374
|
+
|
375
|
+
# Sub-method for 'show_branches'. Don't call independently.
|
376
|
+
# @return String(s)
|
377
|
+
def show_branches_get_colors(code_branch, current_code_branch, current_db_branch, db_branch)
|
378
|
+
code_star = nil
|
379
|
+
code_color = 240
|
380
|
+
code_accent = nil
|
381
|
+
db_star = nil
|
382
|
+
db_color = 240
|
383
|
+
db_accent = nil
|
384
|
+
current_branch_color = 46
|
385
|
+
unless code_branch.nil?
|
386
|
+
if current_code_branch == code_branch[:"#{REFNAME}"]
|
387
|
+
code_star = "\xe2\x98\x85"
|
388
|
+
code_color = current_branch_color
|
389
|
+
code_accent = current_branch_color
|
390
|
+
end
|
391
|
+
end
|
392
|
+
unless db_branch.nil?
|
393
|
+
if current_db_branch == db_branch[:"#{REFNAME}"]
|
394
|
+
db_star = "\xe2\x98\x85"
|
395
|
+
db_color = current_branch_color
|
396
|
+
db_accent = current_branch_color
|
397
|
+
end
|
398
|
+
end
|
399
|
+
return code_accent, code_color, code_star, db_accent, db_color, db_star
|
400
|
+
end
|
401
|
+
|
402
|
+
# Sub-method for 'show_branches'. Don't call independently.
|
403
|
+
# @return void
|
404
|
+
def show_branches_get_db_branch(brightpearl_db, code_branch)
|
405
|
+
brightpearl_db.each do |db_branch|
|
406
|
+
if db_branch[:"#{REFNAME}"] == code_branch[:"#{REFNAME}"]
|
407
|
+
return db_branch
|
408
|
+
end
|
409
|
+
end
|
410
|
+
db_branch = {}
|
411
|
+
db_branch[:"#{REFNAME}"] = MDASH
|
412
|
+
db_branch[:"#{COMMITTER_NAME}"] = MDASH
|
413
|
+
db_branch[:"#{COMMITTER_DATE}"] = nil
|
414
|
+
db_branch
|
415
|
+
end
|
416
|
+
|
417
|
+
# Sub-method for 'show_branches'. Don't call independently.
|
418
|
+
# @return void
|
419
|
+
def show_branches_divider(column_width, color = 'white')
|
420
|
+
row do
|
421
|
+
column(Brightpearl::Terminal::fill(column_width[0], MDASH), :color => color)
|
422
|
+
column(Brightpearl::Terminal::fill(column_width[1], MDASH), :color => color)
|
423
|
+
column(Brightpearl::Terminal::fill(column_width[2], MDASH), :color => color)
|
424
|
+
column(Brightpearl::Terminal::fill(column_width[3], MDASH), :color => color)
|
425
|
+
column(Brightpearl::Terminal::fill(column_width[4], MDASH), :color => color)
|
426
|
+
column(Brightpearl::Terminal::fill(column_width[5], MDASH), :color => color)
|
427
|
+
column(Brightpearl::Terminal::fill(column_width[6], MDASH), :color => color)
|
428
|
+
column(Brightpearl::Terminal::fill(column_width[7], MDASH), :color => color)
|
429
|
+
column(Brightpearl::Terminal::fill(column_width[8], MDASH), :color => color)
|
430
|
+
column(Brightpearl::Terminal::fill(column_width[9], MDASH), :color => color)
|
431
|
+
column(Brightpearl::Terminal::fill(column_width[10], MDASH), :color => color)
|
432
|
+
end
|
433
|
+
end
|
434
|
+
|
435
|
+
# Get current branch for repo.
|
436
|
+
# @return String
|
437
|
+
def current_branch_for_repo(repo_dir)
|
438
|
+
validate_repo_dir(repo_dir)
|
439
|
+
`cd #{repo_dir} && git symbolic-ref --short -q HEAD`.strip
|
440
|
+
end
|
441
|
+
|
442
|
+
# Updates origin (IE: remote branches)
|
443
|
+
# @return void
|
444
|
+
def update_origin(repo_dir = nil)
|
445
|
+
validate_repo_dir(repo_dir)
|
446
|
+
if @origin_updated_code && repo_dir == Brightpearl::Config.param(Brightpearl::Config::WORKSTATION_PATH_TO_BP_CODE) ||
|
447
|
+
@origin_updated_db && repo_dir == Brightpearl::Config.param(Brightpearl::Config::WORKSTATION_PATH_TO_BP_DB) ||
|
448
|
+
@origin_updated_code && @origin_updated_db && repo_dir.nil?
|
449
|
+
else
|
450
|
+
Brightpearl::Terminal::output("Updating origin (#{get_repo_shorthand(repo_dir)})")
|
451
|
+
case repo_dir
|
452
|
+
when Brightpearl::Config.param(Brightpearl::Config::WORKSTATION_PATH_TO_BP_CODE)
|
453
|
+
@origin_updated_code = true
|
454
|
+
Brightpearl::Terminal::command(['git fetch -p'], Brightpearl::Config.param(Brightpearl::Config::WORKSTATION_PATH_TO_BP_CODE))
|
455
|
+
when Brightpearl::Config.param(Brightpearl::Config::WORKSTATION_PATH_TO_BP_DB)
|
456
|
+
@origin_updated_db = true
|
457
|
+
Brightpearl::Terminal::command(['git fetch -p'], Brightpearl::Config.param(Brightpearl::Config::WORKSTATION_PATH_TO_BP_DB))
|
458
|
+
else
|
459
|
+
@origin_updated_code = true
|
460
|
+
@origin_updated_db = true
|
461
|
+
repo_loop.each do |repo_dir_inner|
|
462
|
+
Brightpearl::Terminal::command(['git fetch -p'], repo_dir_inner)
|
463
|
+
end
|
464
|
+
end
|
465
|
+
end
|
466
|
+
end
|
467
|
+
|
468
|
+
# Merges master into current branch (for repo) and pushes changes to origin.
|
469
|
+
# @deprecated
|
470
|
+
# @return void
|
471
|
+
def merge_master_into_current_branch(repo_dir, push_to_origin = true)
|
472
|
+
current_branch = current_branch_for_repo(repo_dir)
|
473
|
+
if current_branch == Brightpearl::Git::MASTER
|
474
|
+
return
|
475
|
+
end
|
476
|
+
commands = Array.new
|
477
|
+
commands << 'git checkout master'
|
478
|
+
commands << 'git pull'
|
479
|
+
if current_branch != Brightpearl::Git::MASTER
|
480
|
+
commands << "git checkout #{current_branch}"
|
481
|
+
commands << 'git pull'
|
482
|
+
commands << 'git merge master'
|
483
|
+
end
|
484
|
+
if push_to_origin
|
485
|
+
commands << 'git push'
|
486
|
+
end
|
487
|
+
Brightpearl::Terminal::command(commands, repo_dir)
|
488
|
+
end
|
489
|
+
|
490
|
+
# Makes sure that both BP-CODE & BP-DB are on the same branch.
|
491
|
+
# @return void
|
492
|
+
# @deprecated
|
493
|
+
def verify_same_branch
|
494
|
+
branch_names = Array.new
|
495
|
+
repo_loop.each do |repo_dir|
|
496
|
+
branch_names << current_branch_for_repo(repo_dir)
|
497
|
+
end
|
498
|
+
if branch_names[0] != branch_names[1]
|
499
|
+
puts
|
500
|
+
puts "\x1B[41m ERROR \x1B[0m Cannot continue because your repos are not on the same branch."
|
501
|
+
puts
|
502
|
+
puts "\x1B[33m/brightpearl-code\x1B[0m is on: \x1B[32m#{branch_names[0]}\x1B[0m"
|
503
|
+
puts "\x1B[33m/brightpearl-db \x1B[0m is on: \x1B[32m#{branch_names[1]}\x1B[0m"
|
504
|
+
puts
|
505
|
+
puts "Use \x1B[33mbrightpearl checkout\x1B[0m \x1B[32m[branch-name]\x1B[0m to switch both repos to the same branch."
|
506
|
+
puts
|
507
|
+
exit
|
508
|
+
end
|
509
|
+
branch_names[0]
|
510
|
+
end
|
511
|
+
|
512
|
+
# Checks if you have staged changes in current repo and if so, prompts to stash them.
|
513
|
+
# @return void
|
514
|
+
def stash_staged_changes
|
515
|
+
repo_loop.each do |repo_dir|
|
516
|
+
results = `cd #{repo_dir} && git status | grep 'Changes '`
|
517
|
+
results = results.split("\n")
|
518
|
+
if results.any?
|
519
|
+
Brightpearl::Terminal::command(['git status'], repo_dir)
|
520
|
+
current_branch = current_branch_for_repo(repo_dir)
|
521
|
+
if Brightpearl::Terminal::prompt_yes_no("Found uncommitted files on branch #{Brightpearl::Terminal::format_branch(current_branch)}", nil, "Would you like to #{Brightpearl::Terminal::format_action('stash')}\x1B[38;5;89m these changes before continuing?")
|
522
|
+
Brightpearl::Terminal::command('git stash', repo_dir)
|
523
|
+
else
|
524
|
+
unless Brightpearl::Terminal::prompt_yes_no('Continue without stashing?', "By selecting #{Brightpearl::Terminal::format_action('Yes')}\x1B[38;5;240m, you're changes will be carried over to the next branch.", nil, false)
|
525
|
+
Brightpearl::Terminal::abort(nil, nil, true, false)
|
526
|
+
end
|
527
|
+
end
|
528
|
+
end
|
529
|
+
end
|
530
|
+
end
|
531
|
+
|
532
|
+
# Checks if you currently have stashed changes for current branch and if so, prompt to un-stash them.
|
533
|
+
# @return void
|
534
|
+
def check_for_stash
|
535
|
+
repo_loop.each do |repo_dir|
|
536
|
+
results = check_for_stash_get_stashes(repo_dir)
|
537
|
+
if results.any?
|
538
|
+
results_output = Array.new
|
539
|
+
results.each do |result|
|
540
|
+
results_output << "#{result}"
|
541
|
+
end
|
542
|
+
stashes_to_skip = 0
|
543
|
+
while results.any?
|
544
|
+
stash_name = results[0].split(/:/).first
|
545
|
+
if Brightpearl::Terminal::prompt_yes_no("Found the following stash on #{Brightpearl::Terminal::format_branch(current_branch_for_repo(repo_dir))}", "#{results[0]}", "Would you like to #{Brightpearl::Terminal::format_action('apply')}\x1B[38;5;89m this stash now?")
|
546
|
+
stash_apply_successful = Brightpearl::Terminal::command(["git stash apply #{stash_name}"], repo_dir)
|
547
|
+
if stash_apply_successful[0] == true
|
548
|
+
Brightpearl::Terminal::command("git stash drop #{stash_name}", repo_dir)
|
549
|
+
results = check_for_stash_get_stashes(repo_dir)
|
550
|
+
else
|
551
|
+
Brightpearl::Terminal::error("Stash could not be applied successfully (and therefore wasn't dropped).", ["#{results[0]}", nil, "Please #{Brightpearl::Terminal::format_action('open an IDE')} and resolve your conflicts before continuing.", "Don't forget to drop your stash afterwards with: #{Brightpearl::Terminal::format_command("git stash drop #{stash_name}")}"], false)
|
552
|
+
results = []
|
553
|
+
end
|
554
|
+
else
|
555
|
+
stashes_to_skip = stashes_to_skip + 1
|
556
|
+
results = check_for_stash_get_stashes(repo_dir)
|
557
|
+
a = (stashes_to_skip + 0)
|
558
|
+
b = 0
|
559
|
+
while b < a do
|
560
|
+
results.shift
|
561
|
+
b += 1
|
562
|
+
end
|
563
|
+
end
|
564
|
+
end
|
565
|
+
end
|
566
|
+
end
|
567
|
+
end
|
568
|
+
|
569
|
+
# Sub-method for 'show_branches'. Don't call independently.
|
570
|
+
# @return Array
|
571
|
+
def check_for_stash_get_stashes(repo_dir)
|
572
|
+
results = `cd #{repo_dir} && git stash list | grep 'WIP on #{current_branch_for_repo(repo_dir)}:'`
|
573
|
+
results = results.split("\n")
|
574
|
+
end
|
575
|
+
|
576
|
+
# Returns an array that include info for BOTH repos. Finds out whether a branch exists and if it's current or not
|
577
|
+
# Only does it locally.
|
578
|
+
# @return Array
|
579
|
+
def branch_data(branch_name, code_db = nil, verbose = true)
|
580
|
+
data = []
|
581
|
+
repo_loop.each do |repo_dir|
|
582
|
+
unless code_db.nil?
|
583
|
+
validate_code_db(code_db)
|
584
|
+
case code_db
|
585
|
+
when CODE
|
586
|
+
if repo_dir == Brightpearl::Config.param(Brightpearl::Config::WORKSTATION_PATH_TO_BP_DB)
|
587
|
+
data << nil
|
588
|
+
next
|
589
|
+
end
|
590
|
+
else
|
591
|
+
if repo_dir == Brightpearl::Config.param(Brightpearl::Config::WORKSTATION_PATH_TO_BP_CODE)
|
592
|
+
data << nil
|
593
|
+
next
|
594
|
+
end
|
595
|
+
end
|
596
|
+
end
|
597
|
+
Brightpearl::Terminal::output("Retrieving branch data for #{Brightpearl::Terminal::format_branch(branch_name)} \xe2\x80\x94 (#{get_repo_shorthand(repo_dir)})")
|
598
|
+
repo_data = {}
|
599
|
+
repo_data
|
600
|
+
repo_data[:"#{BRANCH_NAME}"] = branch_name
|
601
|
+
repo_data[:"#{BRANCH_LOCATION}"] = repo_dir
|
602
|
+
repo_data[:"#{BRANCH_EXISTS}"] = true
|
603
|
+
repo_data[:"#{BRANCH_EXISTS_LOCALLY}"] = true
|
604
|
+
repo_data[:"#{BRANCH_HAS_STASH}"] = false
|
605
|
+
repo_data[:"#{BRANCH_HAS_UPSTREAM}"] = branch_has_upstream(repo_dir, branch_name)
|
606
|
+
repo_data[:"#{BRANCH_IS_CURRENT}"] = (current_branch_for_repo(repo_dir) == branch_name ? true : false)
|
607
|
+
if repo_data[:"#{BRANCH_HAS_UPSTREAM}"]
|
608
|
+
# @todo
|
609
|
+
repo_data[:"#{BRANCH_IS_UP_TO_DATE}"] = nil
|
610
|
+
else
|
611
|
+
# @todo
|
612
|
+
repo_data[:"#{BRANCH_IS_UP_TO_DATE}"] = nil
|
613
|
+
end
|
614
|
+
# Check branch exists
|
615
|
+
unless branch_exists(branch_name, repo_dir, Brightpearl::Git::LOCAL)
|
616
|
+
repo_data[:"#{BRANCH_EXISTS_LOCALLY}"] = false
|
617
|
+
Brightpearl::Terminal::warning("Branch #{Brightpearl::Terminal::format_branch(branch_name)} not found #{Brightpearl::Terminal::format_action('locally')} - (#{get_repo_shorthand(repo_dir)})", nil) if verbose
|
618
|
+
Brightpearl::Terminal::output('Checking origin') if verbose
|
619
|
+
unless branch_exists(branch_name, repo_dir, Brightpearl::Git::REMOTE)
|
620
|
+
Brightpearl::Terminal::warning("Branch #{Brightpearl::Terminal::format_branch(branch_name)} not found #{Brightpearl::Terminal::format_action('remotely')} - (#{get_repo_shorthand(repo_dir)})", nil) if verbose
|
621
|
+
repo_data[:"#{BRANCH_EXISTS}"] = false
|
622
|
+
data << repo_data
|
623
|
+
next
|
624
|
+
end
|
625
|
+
end
|
626
|
+
# Check for stashed changes
|
627
|
+
stashes = `cd #{repo_dir} && git stash list | grep 'WIP on #{branch_name}:'`
|
628
|
+
stashes = stashes.split("\n")
|
629
|
+
if stashes.any?
|
630
|
+
repo_data[:"#{BRANCH_HAS_STASH}"] = stashes.count
|
631
|
+
end
|
632
|
+
data << repo_data
|
633
|
+
end
|
634
|
+
data
|
635
|
+
end
|
636
|
+
|
637
|
+
# Returns TRUE if branch exists, FALSE if not
|
638
|
+
# @return Array
|
639
|
+
def branch_exists(branch_name, repo_dir, local_remote = LOCAL)
|
640
|
+
validate_repo_dir(repo_dir)
|
641
|
+
validate_local_remote(local_remote)
|
642
|
+
case local_remote
|
643
|
+
when LOCAL
|
644
|
+
branches = get_branches_as_array(LOCAL, repo_dir)
|
645
|
+
else
|
646
|
+
branches = get_branches_as_array(REMOTE, repo_dir)
|
647
|
+
end
|
648
|
+
unless branches.include?(branch_name)
|
649
|
+
return false
|
650
|
+
end
|
651
|
+
true
|
652
|
+
end
|
653
|
+
|
654
|
+
# Checks if branch exists ANYWHERE -- Local, Remote, Code, DB. If the branch name is found anywhere, will return FALSE.
|
655
|
+
# @return boolean
|
656
|
+
def branch_exists_anywhere(branch_name, case_sensitive = false)
|
657
|
+
existing_branches = get_all_branches_as_array
|
658
|
+
if case_sensitive
|
659
|
+
existing_branches.map!(&:downcase)
|
660
|
+
branch_name.downcase!
|
661
|
+
end
|
662
|
+
unless existing_branches.include?(branch_name)
|
663
|
+
return false
|
664
|
+
end
|
665
|
+
true
|
666
|
+
end
|
667
|
+
|
668
|
+
# Checks if a branch has an upstream (remote) branch. Returns TRUE or FALSE.
|
669
|
+
# @return boolean
|
670
|
+
# @deprecated
|
671
|
+
def branch_has_upstream(repo_dir, branch_name)
|
672
|
+
validate_repo_dir(repo_dir)
|
673
|
+
result = `cd #{repo_dir} && git branch -vv | grep 'origin/#{branch_name}'`
|
674
|
+
result == '' ? false : true
|
675
|
+
end
|
676
|
+
|
677
|
+
# Checks if a branch is at same HEAD as upstream. Returns TRUE or FALSE.
|
678
|
+
# @return boolean
|
679
|
+
# @deprecated
|
680
|
+
def branch_synced_with_upstream(repo_dir, branch_name)
|
681
|
+
validate_repo_dir(repo_dir)
|
682
|
+
result = `cd #{repo_dir} && git branch -vv | grep 'origin/#{branch_name}'`
|
683
|
+
result == '' ? false : true
|
684
|
+
end
|
685
|
+
|
686
|
+
# Gets upstream info for a branch
|
687
|
+
# @return hash
|
688
|
+
def branch_upstream_info(branch_name)
|
689
|
+
unless @branch_upstream_data
|
690
|
+
@branch_upstream_data = []
|
691
|
+
repo_loop.each do |repo_dir|
|
692
|
+
output = `git for-each-ref --shell --format='
|
693
|
+
b=%(refname:short)
|
694
|
+
u=${b}'@{upstream}'
|
695
|
+
if git rev-parse --verify --quiet "$u" >/dev/null 2>&1; then
|
696
|
+
test -n "$(git rev-list -n 1 "$u..$b")" &&
|
697
|
+
echo "$b: has unpushed commits"
|
698
|
+
else
|
699
|
+
echo "$b: no upstream configuration" >&2
|
700
|
+
fi
|
701
|
+
' refs/heads | sh`
|
702
|
+
|
703
|
+
@branch_upstream_data << output
|
704
|
+
end
|
705
|
+
end
|
706
|
+
puts @branch_upstream_data
|
707
|
+
end
|
708
|
+
|
709
|
+
# Checks if a branch is up-to-date with its remote
|
710
|
+
# @return boolea
|
711
|
+
def branch_is_up_to_date(repo_dir, branch_name)
|
712
|
+
validate_repo_dir(repo_dir)
|
713
|
+
result_local = `cd #{repo_dir} && git rev-parse #{branch_name}`
|
714
|
+
result_remote = `cd #{repo_dir} && git rev-parse origin/#{branch_name}`
|
715
|
+
result_local == result_remote ? true : false
|
716
|
+
|
717
|
+
end
|
718
|
+
|
719
|
+
# Returns array with the paths to both repos.
|
720
|
+
# @return Array
|
721
|
+
def repo_loop
|
722
|
+
Array[
|
723
|
+
Brightpearl::Config.param(Brightpearl::Config::WORKSTATION_PATH_TO_BP_CODE),
|
724
|
+
Brightpearl::Config.param(Brightpearl::Config::WORKSTATION_PATH_TO_BP_DB)
|
725
|
+
]
|
726
|
+
end
|
727
|
+
|
728
|
+
# Validates that a parameter is either 'local' or 'remote'
|
729
|
+
# @return void
|
730
|
+
def validate_local_remote(local_remote)
|
731
|
+
unless Array[LOCAL, REMOTE].include?(local_remote)
|
732
|
+
("'#{local_remote}' is not a valid parameter. Must be LOCAL or REMOTE.")
|
733
|
+
end
|
734
|
+
end
|
735
|
+
|
736
|
+
# Validates that a parameter is either 'code' or 'db'
|
737
|
+
# @return void
|
738
|
+
def validate_code_db(code_db)
|
739
|
+
unless Array[CODE, DB].include?(code_db)
|
740
|
+
abort("'#{code_db}' is not a valid parameter. Must be CODE or DB.")
|
741
|
+
end
|
742
|
+
end
|
743
|
+
|
744
|
+
# Makes sure the repo directory is valid.
|
745
|
+
# @return void
|
746
|
+
def validate_repo_dir(repo_dir)
|
747
|
+
unless Array[
|
748
|
+
Brightpearl::Config.param(Brightpearl::Config::WORKSTATION_PATH_TO_BP_CODE),
|
749
|
+
Brightpearl::Config.param(Brightpearl::Config::WORKSTATION_PATH_TO_BP_DB)
|
750
|
+
].include?(repo_dir)
|
751
|
+
abort("'#{repo_dir}' is not a valid directory.")
|
752
|
+
end
|
753
|
+
end
|
754
|
+
|
755
|
+
# Validates if sort option is supported.
|
756
|
+
# @return void
|
757
|
+
def validate_sort(sort_option)
|
758
|
+
unless Array[SORT_DATE, SORT_REFNAME].include?(sort_option)
|
759
|
+
abort("'#{sort_option}' is not a valid sort option.")
|
760
|
+
end
|
761
|
+
end
|
762
|
+
|
763
|
+
# Returns short-hand string for repo
|
764
|
+
# @return String
|
765
|
+
def get_repo_shorthand(repo_dir)
|
766
|
+
repo_dir == Brightpearl::Config.param(Brightpearl::Config::WORKSTATION_PATH_TO_BP_CODE) ? 'brightpearl-code' : 'brightpearl-db'
|
767
|
+
end
|
768
|
+
|
769
|
+
end
|
770
|
+
|
771
|
+
end
|