v2gpti 1.1.3 → 1.1.4
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 +4 -4
- data/bin/git-newbug +19 -0
- data/bin/git-newfeature +19 -0
- data/bin/git-qa +9 -0
- data/bin/git-uat +19 -0
- data/lib/git-pivotal-tracker-integration/command/base.rb +215 -31
- data/lib/git-pivotal-tracker-integration/command/configuration.rb +19 -0
- data/lib/git-pivotal-tracker-integration/command/deliver.rb +100 -100
- data/lib/git-pivotal-tracker-integration/command/finish.rb +30 -23
- data/lib/git-pivotal-tracker-integration/command/newbug.rb +59 -0
- data/lib/git-pivotal-tracker-integration/command/newfeature.rb +62 -0
- data/lib/git-pivotal-tracker-integration/command/prepare-commit-msg-win.sh +26 -0
- data/lib/git-pivotal-tracker-integration/command/release.rb +20 -16
- data/lib/git-pivotal-tracker-integration/command/report.rb +13 -12
- data/lib/git-pivotal-tracker-integration/command/start.rb +6 -3
- data/lib/git-pivotal-tracker-integration/util/git.rb +1 -1
- data/lib/git-pivotal-tracker-integration/util/story.rb +14 -9
- data/lib/git-pivotal-tracker-integration/util/togglV8.rb +23 -5
- metadata +28 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ddfe68a5f08f7c46ebd79f8b1277fb6ced6533be
|
4
|
+
data.tar.gz: d23cdf958c43817260520461db06a09c329beb18
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7d843750f7bb7c647632d544743593e01a4d48b2bf5a965cac62df86a4247e5f3b01133af486553e82f2214f89b1ef488fda9e7b1d17051dc07b5343f2f77612
|
7
|
+
data.tar.gz: 05880930ebe371fec450857aca6979bf2cb3a6d82ee563d08d052edce2a33d84716e5beb53c916a658f9e063f342bf13373f44c688a6820f1ab4a709948bd104
|
data/bin/git-newbug
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env ruby -U
|
2
|
+
# Git Pivotal Tracker Integration
|
3
|
+
# Copyright (c) 2013 the original author or authors.
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
|
17
|
+
require 'git-pivotal-tracker-integration/command/newbug'
|
18
|
+
|
19
|
+
GitPivotalTrackerIntegration::Command::Newbug.new().run ARGV
|
data/bin/git-newfeature
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env ruby -U
|
2
|
+
# Git Pivotal Tracker Integration
|
3
|
+
# Copyright (c) 2013 the original author or authors.
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
|
17
|
+
require 'git-pivotal-tracker-integration/command/newfeature'
|
18
|
+
|
19
|
+
GitPivotalTrackerIntegration::Command::Newfeature.new().run ARGV
|
data/bin/git-qa
ADDED
data/bin/git-uat
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env ruby -U
|
2
|
+
# Git Pivotal Tracker Integration
|
3
|
+
# Copyright (c) 2013 the original author or authors.
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
|
17
|
+
require 'git-pivotal-tracker-integration/command/release'
|
18
|
+
|
19
|
+
GitPivotalTrackerIntegration::Command::Release.new().run ARGV[0]
|
@@ -19,6 +19,7 @@ require 'git-pivotal-tracker-integration/util/git'
|
|
19
19
|
require 'pivotal-tracker'
|
20
20
|
require 'parseconfig'
|
21
21
|
require 'logger'
|
22
|
+
require 'os'
|
22
23
|
|
23
24
|
# An abstract base class for all commands
|
24
25
|
# @abstract Subclass and override {#run} to implement command functionality
|
@@ -41,25 +42,46 @@ class GitPivotalTrackerIntegration::Command::Base
|
|
41
42
|
end
|
42
43
|
|
43
44
|
@repository_root = GitPivotalTrackerIntegration::Util::Git.repository_root
|
44
|
-
@configuration
|
45
|
-
@toggl
|
45
|
+
@configuration = GitPivotalTrackerIntegration::Command::Configuration.new
|
46
|
+
@toggl = Toggl.new
|
46
47
|
|
47
|
-
PivotalTracker::Client.token
|
48
|
-
PivotalTracker::Client.use_ssl
|
48
|
+
PivotalTracker::Client.token = @configuration.api_token
|
49
|
+
PivotalTracker::Client.use_ssl = true
|
49
50
|
|
50
|
-
@project
|
51
|
-
|
52
|
-
|
51
|
+
@project = PivotalTracker::Project.find @configuration.project_id
|
52
|
+
@platform = @configuration.platform_name
|
53
|
+
|
54
|
+
my_projects = PivotalTracker::Project.all
|
53
55
|
my_all_projects_ids = Array.new
|
54
56
|
my_projects.collect{|project| my_all_projects_ids.push project.id.to_i }
|
55
|
-
current_project_id
|
56
|
-
|
57
|
+
current_project_id = @configuration.project_id.to_i
|
58
|
+
project_manager_name = @configuration.pconfig["project"]["project-manager"]
|
59
|
+
project_manager_email = @configuration.pconfig["project"]["project-manager-email"]
|
60
|
+
project_name = @configuration.pconfig["project"]["project-name"]
|
61
|
+
abort "This project requires access to the Pivotal Tracker project [#{project_name} - #{current_project_id}]. Please speak with project manager [#{project_manager_name} - #{project_manager_email}] and ask him to add you to the project in Pivotal Tracker." unless my_all_projects_ids.include?(current_project_id)
|
57
62
|
end
|
63
|
+
|
58
64
|
def finish_toggle(configuration, time_spent)
|
59
65
|
current_story = @configuration.story(@project)
|
60
|
-
|
61
|
-
|
66
|
+
|
67
|
+
# If a story gets rejected and the developer works on it, then we need to check if the task is already created or not.
|
68
|
+
params = parameters(configuration, time_spent)
|
69
|
+
if params[:tid].nil?
|
70
|
+
begin
|
71
|
+
@toggl.create_task(parameters(params))
|
72
|
+
rescue TogglException => te
|
73
|
+
puts ""
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
#If for some reason time entry cannot be done, then catch exception and continue.
|
78
|
+
begin
|
79
|
+
@toggl.create_time_entry(parameters(configuration, time_spent))
|
80
|
+
rescue TogglException => te
|
81
|
+
puts "Unable to log the time."
|
82
|
+
end
|
62
83
|
end
|
84
|
+
|
63
85
|
def start_logging
|
64
86
|
$LOG = Logger.new("#{logger_filename}", 'weekly')
|
65
87
|
end
|
@@ -69,15 +91,17 @@ class GitPivotalTrackerIntegration::Command::Base
|
|
69
91
|
end
|
70
92
|
|
71
93
|
def check_version
|
72
|
-
gem_latest_version
|
94
|
+
gem_latest_version = (GitPivotalTrackerIntegration::Util::Shell.exec "gem list v2gpti --remote")[/\(.*?\)/].delete "()"
|
73
95
|
gem_installed_version = Gem.loaded_specs["v2gpti"].version.version
|
74
96
|
if (gem_installed_version == gem_latest_version)
|
75
97
|
$LOG.info("v2gpti verison #{gem_installed_version} is up to date.")
|
76
98
|
else
|
77
99
|
$LOG.fatal("Out of date")
|
78
|
-
abort "\n\nYou are using v2gpti version #{gem_installed_version}, but the current version is #{gem_latest_version}.\nPlease update your gem with the following command.\n\n sudo gem update v2gpti\n\n"
|
79
|
-
|
100
|
+
abort "\n\nYou are using v2gpti version #{gem_installed_version}, but the current version is #{gem_latest_version}.\nPlease update your gem with the following command.\n\n sudo gem update v2gpti\n\n"
|
101
|
+
|
80
102
|
end
|
103
|
+
rescue StandardError => se
|
104
|
+
puts ""
|
81
105
|
end
|
82
106
|
|
83
107
|
# The main entry point to the command's execution
|
@@ -103,19 +127,19 @@ class GitPivotalTrackerIntegration::Command::Base
|
|
103
127
|
"d" => (60 * 60 * 8) # a work day is 8 hours
|
104
128
|
}
|
105
129
|
def parameters(configuration, time_spent)
|
106
|
-
current_story
|
107
|
-
params
|
108
|
-
params[:name]
|
130
|
+
current_story = configuration.story(@project)
|
131
|
+
params = Hash.new
|
132
|
+
params[:name] = "#{current_story.id}" + " - " + "#{current_story.name}"
|
109
133
|
params[:estimated_seconds] = estimated_seconds current_story
|
110
|
-
params[:pid]
|
111
|
-
params[:uid]
|
112
|
-
params[:tags]
|
113
|
-
params[:active]
|
114
|
-
params[:description]
|
115
|
-
params[:created_with]
|
116
|
-
params[:duration]
|
117
|
-
params[:start]
|
118
|
-
task
|
134
|
+
params[:pid] = configuration.toggl_project_id
|
135
|
+
params[:uid] = @toggl.me["id"]
|
136
|
+
params[:tags] = [current_story.story_type]
|
137
|
+
params[:active] = false
|
138
|
+
params[:description] = "#{current_story.id}" + " commit:" + "#{(GitPivotalTrackerIntegration::Util::Shell.exec "git rev-parse HEAD").chomp[0..6]}"
|
139
|
+
params[:created_with] = "v2gpti"
|
140
|
+
params[:duration] = seconds_spent(time_spent)
|
141
|
+
params[:start] = (Time.now - params[:duration]).iso8601
|
142
|
+
task = @toggl.get_project_task_with_name(configuration.toggl_project_id, "#{current_story.id}")
|
119
143
|
if !task.nil?
|
120
144
|
params[:tid] = task['id']
|
121
145
|
end
|
@@ -172,11 +196,11 @@ class GitPivotalTrackerIntegration::Command::Base
|
|
172
196
|
end
|
173
197
|
end
|
174
198
|
|
175
|
-
new_story
|
176
|
-
new_story.project_id
|
177
|
-
new_story.story_type
|
199
|
+
new_story = PivotalTracker::Story.new
|
200
|
+
new_story.project_id = @project.id
|
201
|
+
new_story.story_type = new_story_type
|
178
202
|
new_story.current_state = "unstarted"
|
179
|
-
new_story.name
|
203
|
+
new_story.name = new_story_title
|
180
204
|
if new_story_type == "feature"
|
181
205
|
new_story.estimate = new_story_estimate
|
182
206
|
end
|
@@ -185,4 +209,164 @@ class GitPivotalTrackerIntegration::Command::Base
|
|
185
209
|
|
186
210
|
end
|
187
211
|
|
188
|
-
|
212
|
+
def create_icebox_bug_story(args)
|
213
|
+
new_bug_story_title = nil
|
214
|
+
args.each do |arg|
|
215
|
+
new_bug_story_title = arg if arg[0] != "-"
|
216
|
+
end
|
217
|
+
while (new_bug_story_title.nil? || new_bug_story_title.empty?)
|
218
|
+
new_bug_story_title = ask("Please enter the title for this bug story")
|
219
|
+
end
|
220
|
+
icebox_stories = Array.new
|
221
|
+
@project.stories.all.collect{|story| icebox_stories.push story if story.current_state == "unscheduled"}
|
222
|
+
new_bug_story = PivotalTracker::Story.new
|
223
|
+
new_bug_story.project_id = @project.id
|
224
|
+
new_bug_story.story_type = "bug"
|
225
|
+
new_bug_story.current_state = "unscheduled"
|
226
|
+
new_bug_story.name = new_bug_story_title
|
227
|
+
|
228
|
+
if args.any?{|arg| arg.include?("-tl") } && !(icebox_stories.empty? || icebox_stories.nil?)
|
229
|
+
icebox_first_story = icebox_stories.first
|
230
|
+
(new_bug_story.create).move(:before, icebox_first_story)
|
231
|
+
elsif args.any?{|arg| arg.include?("-bl")} && !(icebox_stories.empty? || icebox_stories.nil?)
|
232
|
+
icebox_last_story = icebox_stories.last
|
233
|
+
(new_bug_story.create).move(:after, icebox_last_story)
|
234
|
+
else
|
235
|
+
new_bug_story.create
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
def create_backlog_bug_story(args)
|
240
|
+
new_bug_story_title = nil
|
241
|
+
args.each do |arg|
|
242
|
+
new_bug_story_title = arg if arg[0] != "-"
|
243
|
+
end
|
244
|
+
while (new_bug_story_title.nil? || new_bug_story_title.empty?)
|
245
|
+
new_bug_story_title = ask("Please enter the title for this bug story")
|
246
|
+
end
|
247
|
+
backlog_stories = Array.new
|
248
|
+
@project.stories.all.collect{|story| backlog_stories.push story if story.current_state == "unstarted" && story.story_type != "release"}
|
249
|
+
new_bug_story = PivotalTracker::Story.new
|
250
|
+
new_bug_story.project_id = @project.id
|
251
|
+
new_bug_story.story_type = "bug"
|
252
|
+
new_bug_story.current_state = "unstarted"
|
253
|
+
new_bug_story.name = new_bug_story_title
|
254
|
+
if args.any?{|arg| arg.include?("-tl")} && !(backlog_stories.empty? || backlog_stories.nil?)
|
255
|
+
backlog_first_story = backlog_stories.first
|
256
|
+
(new_bug_story.create).move(:before, backlog_first_story)
|
257
|
+
elsif args.any?{|arg| arg.include?("-bl")} && !(backlog_stories.empty? || backlog_stories.nil?)
|
258
|
+
backlog_last_story = backlog_stories.last
|
259
|
+
(new_bug_story.create).move(:after, backlog_last_story)
|
260
|
+
else
|
261
|
+
new_bug_story.create
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
def create_icebox_feature_story(args)
|
266
|
+
new_feature_story_title = nil
|
267
|
+
new_feature_story_points = nil
|
268
|
+
args.each do |arg|
|
269
|
+
new_feature_story_title = arg if arg[0] != "-"
|
270
|
+
end
|
271
|
+
while (new_feature_story_title.nil? || new_feature_story_title.empty?)
|
272
|
+
new_feature_story_title = ask("\nPlease enter the title for this feature story")
|
273
|
+
end
|
274
|
+
icebox_stories = Array.new
|
275
|
+
@project.stories.all.collect{|story| icebox_stories.push story if story.current_state == "unscheduled"}
|
276
|
+
new_feature_story = PivotalTracker::Story.new
|
277
|
+
new_feature_story.project_id = @project.id
|
278
|
+
new_feature_story.story_type = "feature"
|
279
|
+
new_feature_story.current_state = "unscheduled"
|
280
|
+
new_feature_story.name = new_feature_story_title
|
281
|
+
|
282
|
+
args.each do |arg|
|
283
|
+
new_feature_story_points = arg[2] if arg[0] == "-" && arg[1].downcase == "p"
|
284
|
+
end
|
285
|
+
while (new_feature_story_points.nil? || new_feature_story_points.empty?)
|
286
|
+
new_feature_story_points = ask("\nPlease enter the estimate points(0/1/2/3) for this feature story.\nIf you don't want to estimate then enter n")
|
287
|
+
end
|
288
|
+
while (!["0","1","2","3","n"].include?(new_feature_story_points.downcase))
|
289
|
+
new_feature_story_points = ask("\nInvalid entry...Please enter the estimate points(0/1/2/3) for this feature story.\nIf you don't want to estimate then enter n")
|
290
|
+
end
|
291
|
+
if new_feature_story_points.downcase == "n"
|
292
|
+
new_feature_story.estimate = -1
|
293
|
+
else
|
294
|
+
new_feature_story.estimate = new_feature_story_points
|
295
|
+
end
|
296
|
+
|
297
|
+
|
298
|
+
if args.any?{|arg| arg.include?("-tl") } && !(icebox_stories.empty? || icebox_stories.nil?)
|
299
|
+
icebox_first_story = icebox_stories.first
|
300
|
+
(new_feature_story.create).move(:before, icebox_first_story)
|
301
|
+
elsif args.any?{|arg| arg.include?("-bl")} && !(icebox_stories.empty? || icebox_stories.nil?)
|
302
|
+
icebox_last_story = icebox_stories.last
|
303
|
+
(new_feature_story.create).move(:after, icebox_last_story)
|
304
|
+
else
|
305
|
+
icebox_first_story = icebox_stories.first
|
306
|
+
(new_feature_story.create).move(:before, icebox_first_story)
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
def create_backlog_feature_story(args)
|
311
|
+
new_feature_story_title = nil
|
312
|
+
new_feature_story_points = nil
|
313
|
+
args.each do |arg|
|
314
|
+
new_feature_story_title = arg if arg[0] != "-"
|
315
|
+
end
|
316
|
+
while (new_feature_story_title.nil? || new_feature_story_title.empty?)
|
317
|
+
new_feature_story_title = ask("\nPlease enter the title for this feature story")
|
318
|
+
end
|
319
|
+
backlog_stories = Array.new
|
320
|
+
@project.stories.all.collect{|story| backlog_stories.push story if story.current_state == "unstarted" && story.story_type != "release"}
|
321
|
+
new_feature_story = PivotalTracker::Story.new
|
322
|
+
new_feature_story.project_id = @project.id
|
323
|
+
new_feature_story.story_type = "feature"
|
324
|
+
new_feature_story.current_state = "unstarted"
|
325
|
+
new_feature_story.name = new_feature_story_title
|
326
|
+
|
327
|
+
args.each do |arg|
|
328
|
+
new_feature_story_points = arg[2] if arg[0] == "-" && arg[1].downcase == "p"
|
329
|
+
end
|
330
|
+
while (new_feature_story_points.nil? || new_feature_story_points.empty?)
|
331
|
+
new_feature_story_points = ask("\nPlease enter the estimate points(0/1/2/3) for this feature story.\nIf you don't want to estimate then enter n")
|
332
|
+
end
|
333
|
+
while (!["0","1","2","3","n"].include?(new_feature_story_points.downcase))
|
334
|
+
new_feature_story_points = ask("\nInvalid entry...Please enter the estimate points(0/1/2/3) for this feature story.\nIf you don't want to estimate then enter n")
|
335
|
+
end
|
336
|
+
if new_feature_story_points.downcase == "n"
|
337
|
+
new_feature_story.estimate = -1
|
338
|
+
else
|
339
|
+
new_feature_story.estimate = new_feature_story_points
|
340
|
+
end
|
341
|
+
|
342
|
+
if args.any?{|arg| arg.include?("-tl")} && !(backlog_stories.empty? || backlog_stories.nil?)
|
343
|
+
backlog_first_story = backlog_stories.first
|
344
|
+
(new_feature_story.create).move(:before, backlog_first_story)
|
345
|
+
elsif args.any?{|arg| arg.include?("-bl")} && !(backlog_stories.empty? || backlog_stories.nil?)
|
346
|
+
backlog_last_story = backlog_stories.last
|
347
|
+
(new_feature_story.create).move(:after, backlog_last_story)
|
348
|
+
else
|
349
|
+
backlog_first_story = backlog_stories.first
|
350
|
+
(new_feature_story.create).move(:before, backlog_first_story)
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
354
|
+
private
|
355
|
+
|
356
|
+
def pwd
|
357
|
+
command = OS.windows? ? 'echo %cd%': 'pwd'
|
358
|
+
GitPivotalTrackerIntegration::Util::Shell.exec(command).chop
|
359
|
+
end
|
360
|
+
|
361
|
+
def estimate_story(story)
|
362
|
+
story_points = nil
|
363
|
+
while (story_points.nil? || story_points.empty?)
|
364
|
+
story_points = ask("\nPlease enter the estimate points(0/1/2/3) for this story.")
|
365
|
+
end
|
366
|
+
while (!["0","1","2","3"].include?(story_points))
|
367
|
+
story_points = ask("\nInvalid entry...Please enter the estimate points(0/1/2/3) for this story.")
|
368
|
+
end
|
369
|
+
story.update(:estimate => story_points)
|
370
|
+
end
|
371
|
+
|
372
|
+
end
|
@@ -87,6 +87,23 @@ class GitPivotalTrackerIntegration::Command::Configuration
|
|
87
87
|
|
88
88
|
project_id
|
89
89
|
end
|
90
|
+
|
91
|
+
def platform_name
|
92
|
+
platform_name = GitPivotalTrackerIntegration::Util::Git.get_config KEY_PLATFORM_NAME, :inherited
|
93
|
+
|
94
|
+
if platform_name.empty?
|
95
|
+
platforms = ["ios", "non-ios"]
|
96
|
+
platform_name = choose do |menu|
|
97
|
+
menu.prompt = 'Please choose your project platform:'
|
98
|
+
menu.choices(*platforms) do |chosen|
|
99
|
+
chosen
|
100
|
+
end
|
101
|
+
end
|
102
|
+
GitPivotalTrackerIntegration::Util::Git.set_config KEY_PLATFORM_NAME, platform_name, :local
|
103
|
+
end
|
104
|
+
puts "Your project platform is:#{platform_name}"
|
105
|
+
platform_name
|
106
|
+
end
|
90
107
|
|
91
108
|
# Returns the story associated with the current development branch
|
92
109
|
#
|
@@ -112,6 +129,8 @@ class GitPivotalTrackerIntegration::Command::Configuration
|
|
112
129
|
KEY_API_TOKEN = 'pivotal.api-token'.freeze
|
113
130
|
|
114
131
|
KEY_PROJECT_ID = 'pivotal.project-id'.freeze
|
132
|
+
|
133
|
+
KEY_PLATFORM_NAME = 'platform.platform-name'.freeze
|
115
134
|
|
116
135
|
KEY_STORY_ID = 'pivotal-story-id'.freeze
|
117
136
|
|
@@ -34,53 +34,55 @@ class GitPivotalTrackerIntegration::Command::Deliver < GitPivotalTrackerIntegrat
|
|
34
34
|
# * +nil+
|
35
35
|
# @return [void]
|
36
36
|
def run(filter)
|
37
|
-
$LOG.debug("#{self.class} in project:#{@project.name} pwd:#{
|
37
|
+
$LOG.debug("#{self.class} in project:#{@project.name} pwd:#{pwd} branch:#{GitPivotalTrackerIntegration::Util::Git.branch_name}")
|
38
38
|
self.check_branch
|
39
39
|
story = GitPivotalTrackerIntegration::Util::Story.select_release @project
|
40
40
|
$LOG.debug("story:#{story.name}")
|
41
41
|
sort_for_deliver story
|
42
42
|
GitPivotalTrackerIntegration::Util::Story.pretty_print story
|
43
43
|
|
44
|
-
|
44
|
+
current_branch = GitPivotalTrackerIntegration::Util::Git.branch_name
|
45
45
|
|
46
|
-
|
47
|
-
|
46
|
+
puts "Merging from orgin develop..."
|
47
|
+
GitPivotalTrackerIntegration::Util::Shell.exec "git pull"
|
48
48
|
|
49
|
-
|
50
|
-
|
49
|
+
# checkout QA branch
|
50
|
+
# Merge develop into QA
|
51
51
|
GitPivotalTrackerIntegration::Util::Shell.exec "git checkout QA"
|
52
|
-
|
52
|
+
GitPivotalTrackerIntegration::Util::Shell.exec "git pull"
|
53
53
|
if (GitPivotalTrackerIntegration::Util::Shell.exec "git merge -s recursive --strategy-option theirs develop")
|
54
54
|
puts "Merged 'develop' in to 'QA'"
|
55
55
|
else
|
56
56
|
abort "FAILED to merge 'develop' in to 'QA'"
|
57
57
|
end
|
58
58
|
|
59
|
-
puts "storyNAME:#{story.name}"
|
60
|
-
|
61
59
|
# Update version and build numbers
|
62
|
-
build_number
|
63
|
-
build_number[0]
|
60
|
+
build_number = story.name.dup
|
61
|
+
build_number[0] = ""
|
62
|
+
working_directory = pwd
|
63
|
+
|
64
64
|
puts "storyNAME:#{story.name}"
|
65
65
|
puts "build_number:#{build_number}"
|
66
|
-
project_directory = ((GitPivotalTrackerIntegration::Util::Shell.exec 'find . -name "*.xcodeproj" 2>/dev/null').split /\/(?=[^\/]*$)/)[0]
|
67
|
-
working_directory = (GitPivotalTrackerIntegration::Util::Shell.exec "pwd").chop
|
68
66
|
puts "working_directory:#{working_directory}*"
|
69
|
-
|
70
|
-
# cd to the project_directory
|
71
|
-
Dir.chdir(project_directory)
|
72
67
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
68
|
+
if (OS.mac? && ["y","ios"].include?(@platform.downcase))
|
69
|
+
project_directory = ((GitPivotalTrackerIntegration::Util::Shell.exec 'find . -name "*.xcodeproj" 2>/dev/null').split /\/(?=[^\/]*$)/)[0]
|
70
|
+
|
71
|
+
# cd to the project_directory
|
72
|
+
Dir.chdir(project_directory)
|
77
73
|
|
78
|
-
|
79
|
-
|
74
|
+
# set build number and project number in project file
|
75
|
+
pwd
|
76
|
+
puts GitPivotalTrackerIntegration::Util::Shell.exec "xcrun agvtool new-version -all #{build_number}", false
|
77
|
+
puts GitPivotalTrackerIntegration::Util::Shell.exec "xcrun agvtool new-marketing-version SNAPSHOT"
|
78
|
+
|
79
|
+
# cd back to the working_directory
|
80
|
+
Dir.chdir(working_directory)
|
81
|
+
end
|
80
82
|
|
81
83
|
# Create a new build commit, push to QA, checkout develop
|
82
84
|
GitPivotalTrackerIntegration::Util::Git.create_commit( "Update build number to #{build_number} for delivery to QA", story)
|
83
|
-
puts GitPivotalTrackerIntegration::Util::Shell.exec "git push"
|
85
|
+
puts GitPivotalTrackerIntegration::Util::Shell.exec "git push"
|
84
86
|
puts GitPivotalTrackerIntegration::Util::Shell.exec "git checkout develop"
|
85
87
|
|
86
88
|
i_stories = included_stories @project, story
|
@@ -89,54 +91,50 @@ class GitPivotalTrackerIntegration::Command::Deliver < GitPivotalTrackerIntegrat
|
|
89
91
|
|
90
92
|
def check_branch
|
91
93
|
|
92
|
-
|
93
|
-
|
94
|
-
suggested_branch = "develop"
|
95
|
-
|
96
|
-
if !suggested_branch.nil? && suggested_branch.length !=0 && current_branch != suggested_branch
|
97
|
-
should_chage_branch = ask("Your currently checked out branch is '#{current_branch}'. You must be on the #{suggested_branch} branch to run this command.\n\n Do you want to checkout '#{suggested_branch}' before starting?(Y/n)")
|
98
|
-
if should_chage_branch != "n"
|
99
|
-
print "Checking out branch '#{suggested_branch}'...\n\n"
|
100
|
-
GitPivotalTrackerIntegration::Util::Shell.exec "git checkout #{suggested_branch}"
|
101
|
-
GitPivotalTrackerIntegration::Util::Shell.exec 'git pull'
|
102
|
-
|
103
|
-
else
|
104
|
-
abort "You must be on the #{suggested_branch} branch to run this command."
|
105
|
-
end
|
94
|
+
current_branch = GitPivotalTrackerIntegration::Util::Git.branch_name
|
95
|
+
suggested_branch = "develop"
|
106
96
|
|
97
|
+
if !suggested_branch.nil? && suggested_branch.length !=0 && current_branch != suggested_branch
|
98
|
+
should_chage_branch = ask("Your currently checked out branch is '#{current_branch}'. You must be on the #{suggested_branch} branch to run this command.\n\n Do you want to checkout '#{suggested_branch}' before starting?(Y/n)")
|
99
|
+
if should_chage_branch != "n"
|
100
|
+
print "Checking out branch '#{suggested_branch}'...\n\n"
|
101
|
+
GitPivotalTrackerIntegration::Util::Shell.exec "git checkout #{suggested_branch}"
|
102
|
+
GitPivotalTrackerIntegration::Util::Shell.exec 'git pull'
|
103
|
+
else
|
104
|
+
abort "You must be on the #{suggested_branch} branch to run this command."
|
107
105
|
end
|
108
|
-
|
106
|
+
end
|
109
107
|
end
|
110
108
|
|
111
109
|
private
|
112
110
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
def deliver_stories(stories, build_story)
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
end
|
111
|
+
CANDIDATE_STATES = %w(finished unstarted).freeze
|
112
|
+
CANDIDATE_TYPES = %w(bug chore feature release)
|
113
|
+
|
114
|
+
def deliver_stories(stories, build_story)
|
115
|
+
all_stories = stories.dup
|
116
|
+
all_stories << build_story
|
117
|
+
all_stories.each {|story|
|
118
|
+
# puts "story class:#{story.class}"
|
119
|
+
s_labels_string = story.labels
|
120
|
+
s_labels = ""
|
121
|
+
if (s_labels_string)
|
122
|
+
s_labels = s_labels_string.split(",")
|
123
|
+
s_labels << build_story.name
|
124
|
+
s_labels_string = s_labels.uniq.join(",")
|
125
|
+
else
|
126
|
+
s_labels_string = build_story.name
|
127
|
+
end
|
128
|
+
|
129
|
+
# puts "labels:#{s_labels_string}"
|
130
|
+
story.update(:labels => s_labels_string)
|
131
|
+
if (story.story_type == "feature") || (story.story_type == "bug")
|
132
|
+
story.update(:current_state => "delivered")
|
133
|
+
elsif (story.story_type == "chore")
|
134
|
+
story.update(:current_state => "accepted")
|
135
|
+
end
|
136
|
+
}
|
137
|
+
end
|
140
138
|
|
141
139
|
def included_stories(project, build_story)
|
142
140
|
|
@@ -145,7 +143,7 @@ end
|
|
145
143
|
:limit => 1000,
|
146
144
|
:story_type => CANDIDATE_TYPES
|
147
145
|
}
|
148
|
-
|
146
|
+
|
149
147
|
|
150
148
|
candidates = project.stories.all criteria
|
151
149
|
|
@@ -153,43 +151,43 @@ end
|
|
153
151
|
estimated_candidates = Array.new
|
154
152
|
val_is_valid = true
|
155
153
|
puts "Included stories:\n"
|
156
|
-
candidates.each
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
154
|
+
candidates.each do |val|
|
155
|
+
val_is_valid = true
|
156
|
+
if (val.id == build_story.id)
|
157
|
+
next
|
158
|
+
end
|
159
|
+
if (val.current_state != "finished")
|
160
|
+
val_is_valid = false
|
161
|
+
end
|
162
|
+
if (val.story_type == "release")
|
163
|
+
val_is_valid = false
|
164
|
+
end
|
165
|
+
if val_is_valid
|
166
|
+
# puts "val_is_valid:#{val_is_valid}"
|
167
|
+
estimated_candidates << val
|
168
|
+
puts "#{val.id}"
|
169
|
+
|
170
|
+
end
|
171
|
+
end
|
174
172
|
candidates = estimated_candidates
|
175
173
|
end
|
176
174
|
|
177
175
|
|
178
176
|
def development_branch_name(story)
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
177
|
+
prefix = "#{story.id}-"
|
178
|
+
story_name = "#{story.name.gsub(/[^0-9a-z\\s]/i, '_')}"
|
179
|
+
if(story_name.length > 30)
|
180
|
+
suggested_suffix = story_name[0..27]
|
181
|
+
suggested_suffix << "__"
|
182
|
+
else
|
183
|
+
suggested_suffix = story_name
|
184
|
+
end
|
185
|
+
branch_name = "#{prefix}" + ask("Enter branch name (#{story.id}-<#{suggested_suffix}>): ")
|
186
|
+
puts
|
187
|
+
if branch_name == "#{prefix}"
|
188
|
+
branch_name << suggested_suffix
|
189
|
+
end
|
190
|
+
branch_name.gsub(/[^0-9a-z\\s\-]/i, '_')
|
193
191
|
end
|
194
192
|
|
195
193
|
def start_on_tracker(story)
|
@@ -208,13 +206,15 @@ end
|
|
208
206
|
last_release = stories[0]
|
209
207
|
stories.shift
|
210
208
|
end
|
209
|
+
abort "\nThere are no last release stories or finished stories to deliver" if last_release.nil?
|
211
210
|
stories << release_story
|
212
211
|
previous_story = last_release.dup
|
213
212
|
|
214
213
|
puts "Last release:#{previous_story.name}"
|
215
|
-
stories.each
|
214
|
+
stories.each do |story|
|
216
215
|
story.move(:after, previous_story)
|
217
216
|
previous_story = story.dup
|
218
|
-
|
217
|
+
end
|
219
218
|
end
|
219
|
+
|
220
220
|
end
|