pt 0.5.8 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Changelog.md +5 -0
- data/README.md +7 -3
- data/lib/pt.rb +1 -1
- data/lib/pt/client.rb +1 -1
- data/lib/pt/data_table.rb +14 -0
- data/lib/pt/ui.rb +134 -45
- metadata +3 -3
data/Changelog.md
CHANGED
data/README.md
CHANGED
@@ -16,10 +16,14 @@ Run `pt` from the root folder of your project.
|
|
16
16
|
|
17
17
|
pt todo # show all unscheduled tasks
|
18
18
|
|
19
|
+
pt started # show all started stories
|
20
|
+
|
19
21
|
pt create [title] ~[owner] ~[type] # create a new task
|
20
22
|
|
21
23
|
pt show [id] # shows detailed info about a task
|
22
24
|
|
25
|
+
pt tasks [id] # manage tasks of story
|
26
|
+
|
23
27
|
pt open [id] # open a task in the browser
|
24
28
|
|
25
29
|
pt assign [id] [member] # assign owner
|
@@ -43,8 +47,8 @@ Run `pt` from the root folder of your project.
|
|
43
47
|
pt done [id] ~[0-3] ~[comment] # lazy mans finish task, does everything
|
44
48
|
|
45
49
|
pt list [member] # list all tasks for another pt user
|
46
|
-
|
47
|
-
|
50
|
+
|
51
|
+
pt list all # list all tasks for all users
|
48
52
|
|
49
53
|
pt updates [number] # shows number recent activity from your current project
|
50
54
|
|
@@ -69,4 +73,4 @@ You can [open a new issue](https://github.com/raul/pt/issues/new). It can be hel
|
|
69
73
|
See the LICENSE file included in the distribution.
|
70
74
|
|
71
75
|
## Copyright
|
72
|
-
Copyright (C) 2011 Raul Murciano <raul@murciano.net>.
|
76
|
+
Copyright (C) 2011 Raul Murciano <raul@murciano.net>.
|
data/lib/pt.rb
CHANGED
data/lib/pt/client.rb
CHANGED
data/lib/pt/data_table.rb
CHANGED
data/lib/pt/ui.rb
CHANGED
@@ -32,8 +32,14 @@ class PT::UI
|
|
32
32
|
PT::TasksTable.new(stories).print @global_config
|
33
33
|
end
|
34
34
|
|
35
|
+
def started
|
36
|
+
title("Stories started for #{project_to_s}")
|
37
|
+
stories = @project.stories.all(:current_state => 'started')
|
38
|
+
PT::TasksTable.new(stories).print @global_config
|
39
|
+
end
|
40
|
+
|
35
41
|
def list
|
36
|
-
if @params[0]
|
42
|
+
if @params[0]
|
37
43
|
if @params[0] == "all"
|
38
44
|
stories = @client.get_work(@project)
|
39
45
|
PT::TasksTable.new(stories).print @global_config
|
@@ -64,7 +70,7 @@ class PT::UI
|
|
64
70
|
title("Let's create a new task:")
|
65
71
|
name = ask("Name for the new task:")
|
66
72
|
end
|
67
|
-
|
73
|
+
|
68
74
|
unless owner
|
69
75
|
if ask('Do you want to assign it now? (y/n)').downcase == 'y'
|
70
76
|
members = @client.get_members(@project)
|
@@ -76,7 +82,7 @@ class PT::UI
|
|
76
82
|
requester = @local_config[:user_name]
|
77
83
|
task_type = ask('Type? (c)hore, (b)ug, anything else for feature)')
|
78
84
|
end
|
79
|
-
|
85
|
+
|
80
86
|
task_type = case task_type
|
81
87
|
when 'c', 'chore'
|
82
88
|
'chore'
|
@@ -94,7 +100,7 @@ class PT::UI
|
|
94
100
|
end
|
95
101
|
|
96
102
|
def open
|
97
|
-
if @params[0]
|
103
|
+
if @params[0]
|
98
104
|
tasks = @client.get_my_work(@project, @local_config[:user_name])
|
99
105
|
table = PT::TasksTable.new(tasks)
|
100
106
|
task = table[ @params[0].to_i ]
|
@@ -118,7 +124,7 @@ class PT::UI
|
|
118
124
|
else
|
119
125
|
title("Tasks for #{user_s} in #{project_to_s}")
|
120
126
|
task = select("Please select a story to comment it", table)
|
121
|
-
comment = ask("Write your comment")
|
127
|
+
comment = ask("Write your comment")
|
122
128
|
end
|
123
129
|
if @client.comment_task(@project, task, comment)
|
124
130
|
congrats("Comment sent, thanks!")
|
@@ -133,7 +139,7 @@ class PT::UI
|
|
133
139
|
table = PT::TasksTable.new(tasks)
|
134
140
|
task = table[@params[0].to_i]
|
135
141
|
owner = find_owner @params[1]
|
136
|
-
else
|
142
|
+
else
|
137
143
|
title("Tasks for #{user_s} in #{project_to_s}")
|
138
144
|
tasks = @client.get_tasks_to_assign(@project, @local_config[:user_name])
|
139
145
|
table = PT::TasksTable.new(tasks)
|
@@ -157,8 +163,8 @@ class PT::UI
|
|
157
163
|
tasks = @client.get_my_work(@project, @local_config[:user_name])
|
158
164
|
table = PT::TasksTable.new(tasks)
|
159
165
|
task = table[@params[0].to_i]
|
160
|
-
title("Estimating '#{task.name}'")
|
161
|
-
|
166
|
+
title("Estimating '#{task.name}'")
|
167
|
+
|
162
168
|
if [0,1,2,3].include? @params[1].to_i
|
163
169
|
estimation = @params[1]
|
164
170
|
end
|
@@ -168,8 +174,8 @@ class PT::UI
|
|
168
174
|
title("Tasks for #{user_s} in #{project_to_s}")
|
169
175
|
task = select("Please select a story to estimate it", table)
|
170
176
|
end
|
171
|
-
|
172
|
-
estimation ||= ask("How many points you estimate for it? (#{@project.point_scale})")
|
177
|
+
|
178
|
+
estimation ||= ask("How many points you estimate for it? (#{@project.point_scale})")
|
173
179
|
result = @client.estimate_task(@project, task, estimation)
|
174
180
|
if result.errors.any?
|
175
181
|
error(result.errors.errors)
|
@@ -178,7 +184,7 @@ class PT::UI
|
|
178
184
|
end
|
179
185
|
end
|
180
186
|
|
181
|
-
def start
|
187
|
+
def start
|
182
188
|
if @params[0]
|
183
189
|
tasks = @client.get_my_work(@project, @local_config[:user_name])
|
184
190
|
table = PT::TasksTable.new(tasks)
|
@@ -188,7 +194,7 @@ class PT::UI
|
|
188
194
|
tasks = @client.get_my_tasks_to_start(@project, @local_config[:user_name])
|
189
195
|
table = PT::TasksTable.new(tasks)
|
190
196
|
title("Tasks for #{user_s} in #{project_to_s}")
|
191
|
-
task = select("Please select a story to mark it as started", table)
|
197
|
+
task = select("Please select a story to mark it as started", table)
|
192
198
|
end
|
193
199
|
start_task task
|
194
200
|
end
|
@@ -203,7 +209,7 @@ class PT::UI
|
|
203
209
|
tasks = @client.get_my_tasks_to_finish(@project, @local_config[:user_name])
|
204
210
|
table = PT::TasksTable.new(tasks)
|
205
211
|
title("Tasks for #{user_s} in #{project_to_s}")
|
206
|
-
task = select("Please select a story to mark it as finished", table)
|
212
|
+
task = select("Please select a story to mark it as finished", table)
|
207
213
|
end
|
208
214
|
finish_task task
|
209
215
|
end
|
@@ -218,7 +224,7 @@ class PT::UI
|
|
218
224
|
tasks = @client.get_my_tasks_to_deliver(@project, @local_config[:user_name])
|
219
225
|
table = PT::TasksTable.new(tasks)
|
220
226
|
title("Tasks for #{user_s} in #{project_to_s}")
|
221
|
-
task = select("Please select a story to mark it as delivered", table)
|
227
|
+
task = select("Please select a story to mark it as delivered", table)
|
222
228
|
end
|
223
229
|
|
224
230
|
deliver_task task
|
@@ -234,7 +240,7 @@ class PT::UI
|
|
234
240
|
tasks = @client.get_my_tasks_to_accept(@project, @local_config[:user_name])
|
235
241
|
table = PT::TasksTable.new(tasks)
|
236
242
|
title("Tasks for #{user_s} in #{project_to_s}")
|
237
|
-
task = select("Please select a story to mark it as accepted", table)
|
243
|
+
task = select("Please select a story to mark it as accepted", table)
|
238
244
|
end
|
239
245
|
result = @client.mark_task_as(@project, task, 'accepted')
|
240
246
|
if result.errors.any?
|
@@ -246,17 +252,45 @@ class PT::UI
|
|
246
252
|
|
247
253
|
def show
|
248
254
|
title("Tasks for #{user_s} in #{project_to_s}")
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
else
|
254
|
-
task = select("Please select a story to show", table)
|
255
|
+
task = get_task_from_params "Please select a story to show"
|
256
|
+
unless task
|
257
|
+
message("No matches found for '#{@params[0]}', please use a valid pivotal story Id")
|
258
|
+
return
|
255
259
|
end
|
256
|
-
|
257
260
|
result = show_task(task)
|
258
261
|
end
|
259
262
|
|
263
|
+
def tasks
|
264
|
+
title("Open story tasks for #{user_s} in #{project_to_s}")
|
265
|
+
task = get_task_from_params "Please select a story to show pending tasks"
|
266
|
+
unless task
|
267
|
+
message("No matches found for '#{@params[0]}', please use a valid pivotal story Id")
|
268
|
+
return
|
269
|
+
end
|
270
|
+
story_task = get_open_story_task_from_params(task)
|
271
|
+
|
272
|
+
if story_task.position == -1
|
273
|
+
description = ask('Title for new task')
|
274
|
+
task.tasks.create(:description => description)
|
275
|
+
congrats("New todo task added to \"#{task.name}\"")
|
276
|
+
else
|
277
|
+
edit_story_task story_task
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
# takes a comma separated list of ids and prints the collection of tasks
|
282
|
+
def show_condensed
|
283
|
+
title("Tasks for #{user_s} in #{project_to_s}")
|
284
|
+
tasks = []
|
285
|
+
if @params[0]
|
286
|
+
@params[0].each_line(',') do |line|
|
287
|
+
tasks << @client.get_task_by_id(line.to_i)
|
288
|
+
end
|
289
|
+
table = PT::TasksTable.new(tasks)
|
290
|
+
table.print
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
260
294
|
def reject
|
261
295
|
title("Tasks for #{user_s} in #{project_to_s}")
|
262
296
|
if @params[0]
|
@@ -268,7 +302,7 @@ class PT::UI
|
|
268
302
|
tasks = @client.get_my_tasks_to_reject(@project, @local_config[:user_name])
|
269
303
|
table = PT::TasksTable.new(tasks)
|
270
304
|
title("Tasks for #{user_s} in #{project_to_s}")
|
271
|
-
task = select("Please select a story to mark it as rejected", table)
|
305
|
+
task = select("Please select a story to mark it as rejected", table)
|
272
306
|
end
|
273
307
|
|
274
308
|
if @params[1]
|
@@ -276,7 +310,7 @@ class PT::UI
|
|
276
310
|
else
|
277
311
|
comment = ask("Please explain why are you rejecting the task.")
|
278
312
|
end
|
279
|
-
|
313
|
+
|
280
314
|
if @client.comment_task(@project, task, comment)
|
281
315
|
result = @client.mark_task_as(@project, task, 'rejected')
|
282
316
|
congrats("Task rejected, thanks!")
|
@@ -285,7 +319,7 @@ class PT::UI
|
|
285
319
|
end
|
286
320
|
end
|
287
321
|
|
288
|
-
def done
|
322
|
+
def done
|
289
323
|
if @params[0]
|
290
324
|
tasks = @client.get_my_work(@project, @local_config[:user_name])
|
291
325
|
table = PT::TasksTable.new(tasks)
|
@@ -316,7 +350,7 @@ class PT::UI
|
|
316
350
|
|
317
351
|
task = find_my_task_by_task_id task_id
|
318
352
|
finish_task task
|
319
|
-
|
353
|
+
|
320
354
|
task = find_my_task_by_task_id task_id
|
321
355
|
deliver_task task
|
322
356
|
end
|
@@ -376,20 +410,20 @@ class PT::UI
|
|
376
410
|
|
377
411
|
if @params[0]
|
378
412
|
tasks = @client.get_my_work(@project, @local_config[:user_name])
|
379
|
-
matched_tasks = tasks.select do |
|
380
|
-
task.name.downcase.index(@params[0]) &&
|
413
|
+
matched_tasks = tasks.select do |story_task|
|
414
|
+
task.name.downcase.index(@params[0]) && story_task.current_state != 'delivered'
|
381
415
|
end
|
382
416
|
|
383
|
-
matched_tasks.each do |
|
384
|
-
title("--- [#{(tasks.index
|
385
|
-
show_task(
|
417
|
+
matched_tasks.each do |story_task|
|
418
|
+
title("--- [#{(tasks.index story_task) + 1 }] -----------------")
|
419
|
+
show_task(story_task)
|
386
420
|
end
|
387
421
|
message("No matches found for '#{@params[0]}'") if matched_tasks.empty?
|
388
422
|
else
|
389
423
|
message("You need to provide a substring for a tasks title.")
|
390
424
|
end
|
391
425
|
end
|
392
|
-
|
426
|
+
|
393
427
|
def updates
|
394
428
|
activities = @client.get_activities(@project, @params[0])
|
395
429
|
tasks = @client.get_my_work(@project, @local_config[:user_name])
|
@@ -399,17 +433,19 @@ class PT::UI
|
|
399
433
|
end
|
400
434
|
end
|
401
435
|
|
402
|
-
|
403
|
-
def help
|
436
|
+
|
437
|
+
def help
|
404
438
|
if ARGV[0] && ARGV[0] != 'help'
|
405
439
|
message("Command #{ARGV[0]} not recognized. Showing help.")
|
406
440
|
end
|
407
|
-
|
441
|
+
|
408
442
|
title("Command line usage")
|
409
443
|
puts("pt # show all available tasks")
|
410
444
|
puts("pt todo # show all unscheduled tasks")
|
445
|
+
puts("pt started # show all started stories")
|
411
446
|
puts("pt create [title] ~[owner] ~[type] # create a new task")
|
412
447
|
puts("pt show [id] # shows detailed info about a task")
|
448
|
+
puts("pt tasks [id] # manage tasks of story")
|
413
449
|
puts("pt open [id] # open a task in the browser")
|
414
450
|
puts("pt assign [id] [member] # assign owner")
|
415
451
|
puts("pt comment [id] [comment] # add a comment")
|
@@ -505,6 +541,10 @@ class PT::UI
|
|
505
541
|
puts "\n#{split_lines(msg)}"
|
506
542
|
end
|
507
543
|
|
544
|
+
def compact_message(*msg)
|
545
|
+
puts "#{split_lines(msg)}"
|
546
|
+
end
|
547
|
+
|
508
548
|
def error(*msg)
|
509
549
|
puts "\n#{split_lines(msg).red.bold}"
|
510
550
|
end
|
@@ -548,13 +588,13 @@ class PT::UI
|
|
548
588
|
end
|
549
589
|
|
550
590
|
def task_type_or_nil query
|
551
|
-
if (["feature", "bug", "chore"].index query)
|
591
|
+
if (["feature", "bug", "chore"].index query)
|
552
592
|
return query
|
553
593
|
end
|
554
594
|
nil
|
555
595
|
end
|
556
|
-
|
557
|
-
def find_task query
|
596
|
+
|
597
|
+
def find_task query
|
558
598
|
members = @client.get_members(@project)
|
559
599
|
members.each do | member |
|
560
600
|
if member.name.downcase.index query
|
@@ -563,8 +603,8 @@ class PT::UI
|
|
563
603
|
end
|
564
604
|
nil
|
565
605
|
end
|
566
|
-
|
567
|
-
def find_my_task_by_task_id task_id
|
606
|
+
|
607
|
+
def find_my_task_by_task_id task_id
|
568
608
|
tasks = @client.get_my_work(@project, @local_config[:user_name])
|
569
609
|
tasks.each do |task|
|
570
610
|
if task.id == task_id
|
@@ -573,25 +613,25 @@ class PT::UI
|
|
573
613
|
end
|
574
614
|
end
|
575
615
|
|
576
|
-
def find_owner query
|
616
|
+
def find_owner query
|
577
617
|
if query
|
578
618
|
member = @client.get_member(@project, query)
|
579
619
|
return member ? member.name : nil
|
580
620
|
end
|
581
621
|
nil
|
582
622
|
end
|
583
|
-
|
623
|
+
|
584
624
|
def show_task(task)
|
585
625
|
title task.name
|
586
626
|
estimation = [-1, nil].include?(task.estimate) ? "Unestimated" : "#{task.estimate} points"
|
587
627
|
message "#{task.current_state.capitalize} #{task.story_type} | #{estimation} | Req: #{task.requested_by} | Owns: #{task.owned_by} | Id: #{task.id}"
|
588
628
|
message task.description unless task.description.nil? || task.description.empty?
|
589
|
-
task.tasks.all.each{ |t|
|
629
|
+
task.tasks.all.each{ |t| compact_message "- #{t.complete ? "(done) " : "(pend)"} #{t.description}" }
|
590
630
|
task.notes.all.each{ |n| message "#{n.author}: \"#{n.text}\"" }
|
591
631
|
task.attachments.each{ |a| message "#{a.uploaded_by} uploaded: \"#{a.description && a.description.empty? ? "#{a.filename}" : "#{a.description} (#{a.filename})" }\" #{a.url}" }
|
592
632
|
puts task.url
|
593
633
|
end
|
594
|
-
|
634
|
+
|
595
635
|
def show_activity(activity, tasks)
|
596
636
|
story_id = activity.stories.first.id
|
597
637
|
task_id = nil
|
@@ -602,5 +642,54 @@ class PT::UI
|
|
602
642
|
end
|
603
643
|
message("#{activity.description} [#{task_id}]")
|
604
644
|
end
|
605
|
-
|
645
|
+
|
646
|
+
def get_open_story_task_from_params(task)
|
647
|
+
title "Pending tasks for '#{task.name}'"
|
648
|
+
task_struct = Struct.new(:description, :position)
|
649
|
+
|
650
|
+
pending_tasks = [
|
651
|
+
task_struct.new('<< Add new task >>', -1)
|
652
|
+
]
|
653
|
+
|
654
|
+
task.tasks.all.each{ |t| pending_tasks << t unless t.complete }
|
655
|
+
table = PT::TodoTaskTable.new(pending_tasks)
|
656
|
+
todo_task = select("Pick task to edit, 1 to add new task", table)
|
657
|
+
end
|
658
|
+
|
659
|
+
def get_task_from_params(prompt)
|
660
|
+
if @params[0]
|
661
|
+
task = @client.get_task_by_id(@params[0].to_i)
|
662
|
+
else
|
663
|
+
tasks = @client.get_my_work(@project, @local_config[:user_name])
|
664
|
+
table = PT::TasksTable.new(tasks)
|
665
|
+
task = select(prompt, table)
|
666
|
+
end
|
667
|
+
task
|
668
|
+
end
|
669
|
+
|
670
|
+
def edit_story_task(story_task)
|
671
|
+
action_class = Struct.new(:action, :key)
|
672
|
+
|
673
|
+
table = PT::ActionTable.new([
|
674
|
+
action_class.new('Complete', :complete),
|
675
|
+
action_class.new('Delete', :delete),
|
676
|
+
action_class.new('Edit', :edit)
|
677
|
+
# Move?
|
678
|
+
])
|
679
|
+
action_to_execute = select('What to do with todo?', table)
|
680
|
+
|
681
|
+
case action_to_execute.key
|
682
|
+
when :complete then
|
683
|
+
story_task.update(:complete => true)
|
684
|
+
congrats('Todo task completed!')
|
685
|
+
when :delete then
|
686
|
+
story_task.delete
|
687
|
+
congrats('Todo task removed')
|
688
|
+
when :edit then
|
689
|
+
new_description = ask('New task description')
|
690
|
+
story_task.update(:description => new_description)
|
691
|
+
congrats("Todo task changed to: \"#{story_task.description}\"")
|
692
|
+
end
|
693
|
+
end
|
694
|
+
|
606
695
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date:
|
14
|
+
date: 2013-01-23 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: pivotal-tracker
|
@@ -120,7 +120,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
120
120
|
version: '0'
|
121
121
|
requirements: []
|
122
122
|
rubyforge_project: pt
|
123
|
-
rubygems_version: 1.8.
|
123
|
+
rubygems_version: 1.8.23
|
124
124
|
signing_key:
|
125
125
|
specification_version: 3
|
126
126
|
summary: Client to use Pivotal Tracker from the console.
|