pt 0.5.8 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/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.
|