pt 0.8.6 → 0.9.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.
- checksums.yaml +4 -4
- data/Changelog.md +4 -0
- data/Gemfile +1 -0
- data/README.md +2 -45
- data/bin/pt +1 -1
- data/lib/pt.rb +3 -1
- data/lib/pt/action.rb +151 -0
- data/lib/pt/cli.rb +183 -0
- data/lib/pt/client.rb +60 -50
- data/lib/pt/data_row.rb +5 -1
- data/lib/pt/data_table.rb +12 -1
- data/lib/pt/helper.rb +271 -0
- data/lib/pt/version.rb +1 -1
- data/pt.gemspec +6 -1
- metadata +75 -3
- data/lib/pt/ui.rb +0 -771
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1c872c7de07ff476f016e21cd526a26cde532c61
|
4
|
+
data.tar.gz: 2b5cd00d28ad94fcf20842d6c50b9eb02bf4ef8d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dae2f14490c2b022db21fc2f5408e29365907091b0f41992aa65577f2aeac8b037f41d4487459042ec05aaedba4489c67ae184391b31f571c8abe137de328535
|
7
|
+
data.tar.gz: eccedbf39e375f0389423657e0bf9abab46600211ed377735e91a4b364ac2798422a5269dfc1eebdb44efa246c48f031ff6ba6cefec078d26ab6ca66bccee6a6
|
data/Changelog.md
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -15,54 +15,11 @@ The first time you run it, `pt` will ask you some data about your Pivotal Tracke
|
|
15
15
|
|
16
16
|
## Usage
|
17
17
|
|
18
|
-
Run `pt` from the root folder of your project.
|
19
|
-
|
20
|
-
```
|
21
|
-
pt # show all available stories
|
22
|
-
|
23
|
-
pt todo <owner> # show all unscheduled stories
|
24
|
-
|
25
|
-
pt (unscheduled,started,finished,delivered, accepted, rejected) <owner> # show all (unscheduled,started,finished,delivered, accepted, rejected) stories
|
26
|
-
|
27
|
-
pt create [title] <owner> <type> -m # create a new story (and include description ala git commit)
|
28
|
-
|
29
|
-
pt show [id] # shows detailed info about a story
|
30
|
-
|
31
|
-
pt tasks [id] # manage tasks of story
|
32
|
-
|
33
|
-
pt open [id] # open a story in the browser
|
34
|
-
|
35
|
-
pt assign [id] <owner> # assign owner
|
36
|
-
|
37
|
-
pt comment [id] [comment] # add a comment
|
38
|
-
|
39
|
-
pt label [id] [label] # add a label
|
40
|
-
|
41
|
-
pt estimate [id] [0-3] # estimate a story in points scale
|
42
|
-
|
43
|
-
pt (start,finish,deliver,accept) [id] # mark a story as started
|
44
|
-
|
45
|
-
pt reject [id] [reason] # mark a story as rejected, explaining why
|
46
|
-
|
47
|
-
pt done [id] <0-3> <comment> # lazy mans finish story, opens, assigns to you, estimates, finish & delivers
|
48
|
-
|
49
|
-
pt find [query] # looks in your stories by title and presents it
|
50
|
-
|
51
|
-
pt list [owner] # list all stories for another pt user
|
52
|
-
|
53
|
-
pt list all # list all stories for all users
|
54
|
-
|
55
|
-
pt updates # shows number recent activity from your current project
|
56
|
-
|
57
|
-
pt recent # shows stories you've recently shown or commented on with pt
|
58
|
-
|
59
|
-
All commands can be run entirely without arguments for a wizard based UI. Otherwise [required] <optional>.
|
60
|
-
Anything that takes an id will also take the num (index) from the pt command.
|
61
|
-
```
|
18
|
+
Run `pt` from the root folder of your project will show all available command.
|
62
19
|
|
63
20
|
## Problems?
|
64
21
|
|
65
|
-
[Open a new issue](https://github.com/raul/pt/issues/new).
|
22
|
+
[Open a new issue](https://github.com/raul/pt/issues/new).
|
66
23
|
|
67
24
|
## Contribute
|
68
25
|
- `git clone https://github.com/raul/pt.git`
|
data/bin/pt
CHANGED
data/lib/pt.rb
CHANGED
data/lib/pt/action.rb
ADDED
@@ -0,0 +1,151 @@
|
|
1
|
+
module PT
|
2
|
+
module Action
|
3
|
+
def show_story(story)
|
4
|
+
title('========================================='.red)
|
5
|
+
title story.name.red
|
6
|
+
title('========================================='.red)
|
7
|
+
estimation = [-1, nil].include?(story.estimate) ? "Unestimated" : "#{story.estimate} points"
|
8
|
+
requester = story.requested_by ? story.requested_by.initials : @local_config[:user_name]
|
9
|
+
message "#{story.current_state.capitalize} #{story.story_type} | #{estimation} | Req: #{requester} | Owners: #{story.owners.map(&:initials).join(',')} | ID: #{story.id}"
|
10
|
+
|
11
|
+
if story.labels.present?
|
12
|
+
message "Labels: " + story.labels.map(&:name).join(', ')
|
13
|
+
end
|
14
|
+
message story.description.green unless story.description.nil? || story.description.empty?
|
15
|
+
message "View on pivotal: #{story.url}"
|
16
|
+
|
17
|
+
if story.tasks.present?
|
18
|
+
title('tasks'.yellow)
|
19
|
+
story.tasks.each{ |t| compact_message "- #{t.complete ? "[done]" : ""} #{t.description}" }
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
story.comments.each do |n|
|
24
|
+
title('......................................'.blue)
|
25
|
+
text = ">> #{n.person.initials}: #{n.text}"
|
26
|
+
text << "[#{n.file_attachment_ids.size}F]" if n.file_attachment_ids
|
27
|
+
message text
|
28
|
+
end
|
29
|
+
save_recent_task( story.id )
|
30
|
+
end
|
31
|
+
|
32
|
+
def tasks_story(story)
|
33
|
+
story_task = get_open_story_task_from_params(story)
|
34
|
+
if story_task.position == -1
|
35
|
+
description = ask('Title for new task')
|
36
|
+
story.create_task(:description => description)
|
37
|
+
congrats("New todo task added to \"#{story.name}\"")
|
38
|
+
else
|
39
|
+
edit_story_task story_task
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def open_story story
|
44
|
+
`open #{story.url}`
|
45
|
+
end
|
46
|
+
|
47
|
+
def assign_story story
|
48
|
+
if (owner = find_owner @params[1])
|
49
|
+
@client.assign_task(story, owner)
|
50
|
+
else
|
51
|
+
members = @client.get_members
|
52
|
+
table = PersonsTable.new(members.map(&:person))
|
53
|
+
owner = select("Please select a member to assign him the story", table)
|
54
|
+
end
|
55
|
+
|
56
|
+
congrats("story assigned to #{owner.initials}, thanks!")
|
57
|
+
end
|
58
|
+
|
59
|
+
def comment_story(story)
|
60
|
+
comment = @params[1] || ask("Write your comment")
|
61
|
+
if @client.comment_task(story, comment)
|
62
|
+
congrats("Comment sent, thanks!")
|
63
|
+
save_recent_task( story.id )
|
64
|
+
else
|
65
|
+
error("Ummm, something went wrong.")
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def label_story(story)
|
70
|
+
if @params[1]
|
71
|
+
label = @params[1]
|
72
|
+
else
|
73
|
+
label = ask("Which label?")
|
74
|
+
end
|
75
|
+
|
76
|
+
@client.add_label(story, label );
|
77
|
+
show_story(task_by_id_or_pt_id(story.id))
|
78
|
+
end
|
79
|
+
|
80
|
+
def estimate_story(story)
|
81
|
+
estimation ||= ask("How many points you estimate for it? (#{project.point_scale})")
|
82
|
+
@client.estimate_story(story, estimation)
|
83
|
+
congrats("Task estimated, thanks!")
|
84
|
+
end
|
85
|
+
|
86
|
+
def start_story story
|
87
|
+
@client.mark_task_as(story, 'started')
|
88
|
+
congrats("story started, go for it!")
|
89
|
+
end
|
90
|
+
|
91
|
+
def finish_story story
|
92
|
+
if story.story_type == 'chore'
|
93
|
+
@client.mark_task_as(story, 'accepted')
|
94
|
+
else
|
95
|
+
@client.mark_task_as(story, 'finished')
|
96
|
+
end
|
97
|
+
congrats("Another story bites the dust, yeah!")
|
98
|
+
end
|
99
|
+
|
100
|
+
def deliver_story story
|
101
|
+
return if story.story_type == 'chore'
|
102
|
+
@client.mark_task_as(story, 'delivered')
|
103
|
+
congrats("story delivered, congrats!")
|
104
|
+
end
|
105
|
+
|
106
|
+
def accept_story story
|
107
|
+
@client.mark_task_as(story, 'accepted')
|
108
|
+
congrats("Accepted")
|
109
|
+
end
|
110
|
+
|
111
|
+
def reject_story(story)
|
112
|
+
comment = @params[1] || ask("Please explain why are you rejecting the story.")
|
113
|
+
if @client.comment_task(story, comment)
|
114
|
+
@client.mark_task_as(story, 'rejected')
|
115
|
+
congrats("story rejected, thanks!")
|
116
|
+
else
|
117
|
+
error("Ummm, something went wrong.")
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def done_story(story)
|
122
|
+
#we need this for finding again later
|
123
|
+
story_id = story.id
|
124
|
+
|
125
|
+
if !@params[1] && story.estimate == -1
|
126
|
+
error("You need to give an estimate for this task")
|
127
|
+
return
|
128
|
+
end
|
129
|
+
|
130
|
+
if @params[1] && story.estimate == -1
|
131
|
+
if [0,1,2,3].include? @params[1].to_i
|
132
|
+
estimate_story(story, @params[1].to_i)
|
133
|
+
end
|
134
|
+
if @params[2]
|
135
|
+
story = task_by_id_or_pt_id story_id
|
136
|
+
@client.comment_task(story, @params[2])
|
137
|
+
end
|
138
|
+
else
|
139
|
+
@client.comment_task(story, @params[1]) if @params[1]
|
140
|
+
end
|
141
|
+
|
142
|
+
start_story story
|
143
|
+
|
144
|
+
finish_story story
|
145
|
+
|
146
|
+
deliver_story story
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
data/lib/pt/cli.rb
ADDED
@@ -0,0 +1,183 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'colored'
|
3
|
+
require 'highline'
|
4
|
+
require 'tempfile'
|
5
|
+
require 'uri'
|
6
|
+
require 'thor'
|
7
|
+
module PT
|
8
|
+
class CLI < Thor
|
9
|
+
include PT::Action
|
10
|
+
include PT::Helper
|
11
|
+
attr_reader :project
|
12
|
+
|
13
|
+
def initialize(*args)
|
14
|
+
super
|
15
|
+
@io = HighLine.new
|
16
|
+
@global_config = load_global_config
|
17
|
+
@local_config = load_local_config
|
18
|
+
@client = Client.new(@global_config[:api_number], @local_config)
|
19
|
+
@project = @client.project
|
20
|
+
end
|
21
|
+
|
22
|
+
%w[unscheduled started finished delivered accepted rejected].each do |state|
|
23
|
+
desc "#{state} <owner>", "show all #{state} stories"
|
24
|
+
define_method(state.to_sym) do |owner = nil|
|
25
|
+
filter = "state:#{state}"
|
26
|
+
filter << " owner:#{owner}" if owner
|
27
|
+
story = select_story_from_paginated_table do |page|
|
28
|
+
@client.get_stories(filter: filter, page: page)
|
29
|
+
end
|
30
|
+
show_story(story)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
%w[show tasks open assign comments label estimate start finish deliver accept reject done].each do |action|
|
35
|
+
desc "#{action} [id]", "#{action} story"
|
36
|
+
define_method(action.to_sym) do |story_id = nil|
|
37
|
+
if story_id
|
38
|
+
story = task_by_id_or_pt_id(story_id.to_i)
|
39
|
+
unless story
|
40
|
+
message("No matches found for '#{story_id}', please use a valid pivotal story Id")
|
41
|
+
return
|
42
|
+
end
|
43
|
+
else
|
44
|
+
method_name = "get_stories_to_#{action}"
|
45
|
+
story = select_story_from_paginated_table do |page|
|
46
|
+
if @client.respond_to?(method_name.to_sym)
|
47
|
+
@client.send("get_stories_to_#{action}", page: page)
|
48
|
+
else
|
49
|
+
@client.get_stories(page: page)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
title("#{action} '#{story.name}'")
|
54
|
+
send("#{action}_story", story)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
desc 'mywork', 'list all your stories'
|
59
|
+
def mywork
|
60
|
+
story = select_story_from_paginated_table do |page|
|
61
|
+
@client.get_stories(filter: "owner:#{@local_config[:user_name]} -state:accepted", page: page)
|
62
|
+
end
|
63
|
+
show_story(story)
|
64
|
+
end
|
65
|
+
|
66
|
+
desc "list [owner]", "list all stories from owner"
|
67
|
+
def list(owner = nil)
|
68
|
+
if owner
|
69
|
+
if owner == "all"
|
70
|
+
stories = @client.get_work
|
71
|
+
TasksTable.new(stories).print @global_config
|
72
|
+
else
|
73
|
+
stories = @client.get_my_work(owner)
|
74
|
+
TasksTable.new(stories).print @global_config
|
75
|
+
end
|
76
|
+
else
|
77
|
+
members = @client.get_members
|
78
|
+
table = MembersTable.new(members)
|
79
|
+
user = select("Please select a member to see his tasks.", table).name
|
80
|
+
title("Work for #{user} in #{project_to_s}")
|
81
|
+
stories = @client.get_my_work(user)
|
82
|
+
TasksTable.new(stories).print @global_config
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
desc "recent", "show stories you've recently shown or commented on with pt"
|
87
|
+
def recent
|
88
|
+
title("Your recent stories from #{project_to_s}")
|
89
|
+
stories = @project.stories( ids: @local_config[:recent_tasks].join(',') )
|
90
|
+
MultiUserTasksTable.new(stories).print @global_config
|
91
|
+
end
|
92
|
+
|
93
|
+
desc 'create [title] --owner <owner> --type <type> -m', "create a new story (and include description ala git commit)"
|
94
|
+
long_desc <<-LONGDESC
|
95
|
+
create story with title [title]
|
96
|
+
|
97
|
+
--owner, -o set owner
|
98
|
+
|
99
|
+
--type , -t set story type
|
100
|
+
|
101
|
+
-m enable add description using vim
|
102
|
+
|
103
|
+
omit all parameters will start interactive mode
|
104
|
+
LONGDESC
|
105
|
+
option :type, aliases: :t
|
106
|
+
option :owner, aliases: :o
|
107
|
+
option :m, type: :boolean
|
108
|
+
def create(title =nil)
|
109
|
+
owner = options[:owner]
|
110
|
+
type = options[:type]
|
111
|
+
requester_id = @local_config[:user_id]
|
112
|
+
if title
|
113
|
+
name = title
|
114
|
+
owner = owner || @local_config[:user_name]
|
115
|
+
type = task_type_or_nil(owner) || task_type_or_nil(type) || 'feature'
|
116
|
+
else
|
117
|
+
title("Let's create a new task:")
|
118
|
+
name = ask("Name for the new task:")
|
119
|
+
end
|
120
|
+
|
121
|
+
owner = @client.find_member(owner).person.id if owner.kind_of?(String)
|
122
|
+
|
123
|
+
unless owner
|
124
|
+
if ask('Do you want to assign it now? (y/n)').downcase == 'y'
|
125
|
+
members = @client.get_members
|
126
|
+
table = PersonsTable.new(members.map(&:person))
|
127
|
+
owner = select("Please select a member to assign him the task.", table).id
|
128
|
+
else
|
129
|
+
owner = nil
|
130
|
+
end
|
131
|
+
requester = @local_config[:user_name]
|
132
|
+
type = ask('Type? (c)hore, (b)ug, anything else for feature)')
|
133
|
+
end
|
134
|
+
|
135
|
+
type = case type
|
136
|
+
when 'c', 'chore'
|
137
|
+
'chore'
|
138
|
+
when 'b', 'bug'
|
139
|
+
'bug'
|
140
|
+
else
|
141
|
+
'feature'
|
142
|
+
end
|
143
|
+
|
144
|
+
owner_ids = [owner]
|
145
|
+
# did you do a -m so you can add a description?
|
146
|
+
if options[:m]
|
147
|
+
editor = ENV.fetch('EDITOR') { 'vi' }
|
148
|
+
temp_path = "/tmp/editor-#{ Process.pid }.txt"
|
149
|
+
system "#{ editor } #{ temp_path }"
|
150
|
+
|
151
|
+
description = File.read(temp_path)
|
152
|
+
end
|
153
|
+
|
154
|
+
story = @client.create_story(
|
155
|
+
name: name,
|
156
|
+
owner_ids: owner_ids,
|
157
|
+
requested_by_id: requester_id,
|
158
|
+
story_type: type,
|
159
|
+
description: description
|
160
|
+
)
|
161
|
+
congrats("#{type} for #{owner} open #{story.url}")
|
162
|
+
show_story(story)
|
163
|
+
end
|
164
|
+
|
165
|
+
desc "find [query] " ,"looks in your stories by title and presents it"
|
166
|
+
def find(query)
|
167
|
+
story = select_story_from_paginated_table do |page|
|
168
|
+
@client.get_stories(filter: query, page: page)
|
169
|
+
end
|
170
|
+
show_story(story)
|
171
|
+
end
|
172
|
+
|
173
|
+
desc "updates","shows number recent activity from your current project"
|
174
|
+
def updates
|
175
|
+
activities = @client.get_activities
|
176
|
+
tasks = @client.get_my_work
|
177
|
+
title("Recent Activity on #{project_to_s}")
|
178
|
+
activities.each do |activity|
|
179
|
+
show_activity(activity, tasks)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
data/lib/pt/client.rb
CHANGED
@@ -7,6 +7,7 @@ module PT
|
|
7
7
|
|
8
8
|
STORY_FIELDS=':default,requested_by,owners,tasks,comments(:default,person,file_attachments)'
|
9
9
|
|
10
|
+
attr_reader :config, :project
|
10
11
|
|
11
12
|
def self.get_api_token(email, password)
|
12
13
|
PivotalAPI::Me.retrieve(email, password)
|
@@ -14,9 +15,10 @@ module PT
|
|
14
15
|
raise PT::InputError.new("Bad email/password combination.")
|
15
16
|
end
|
16
17
|
|
17
|
-
def initialize(token)
|
18
|
+
def initialize(token, local_config=nil)
|
18
19
|
@client = TrackerApi::Client.new(token: token)
|
19
|
-
@
|
20
|
+
@config = local_config
|
21
|
+
@project = @client.project(local_config[:project_id]) if local_config
|
20
22
|
end
|
21
23
|
|
22
24
|
def get_project(project_id)
|
@@ -28,7 +30,7 @@ module PT
|
|
28
30
|
@client.projects
|
29
31
|
end
|
30
32
|
|
31
|
-
def get_membership(
|
33
|
+
def get_membership(email)
|
32
34
|
PivotalTracker::Membership.all(project).select{ |m| m.email == email }.first
|
33
35
|
end
|
34
36
|
|
@@ -40,117 +42,125 @@ module PT
|
|
40
42
|
PivotalTracker::Iteration.current(project)
|
41
43
|
end
|
42
44
|
|
43
|
-
def get_activities
|
45
|
+
def get_activities
|
44
46
|
project.activity
|
45
47
|
end
|
46
48
|
|
47
|
-
def get_work
|
49
|
+
def get_work
|
48
50
|
project.stories(filter: 'state:unscheduled,unstarted,started', fields: STORY_FIELDS )
|
49
51
|
end
|
50
52
|
|
51
|
-
def get_my_work
|
52
|
-
project.stories(filter: "owner:#{user_name} -state:accepted", limit: 50, fields: STORY_FIELDS)
|
53
|
+
def get_my_work
|
54
|
+
project.stories(filter: "owner:#{config[:user_name]} -state:accepted", limit: 50, fields: STORY_FIELDS)
|
53
55
|
end
|
54
56
|
|
55
|
-
def search_for_story(
|
56
|
-
|
57
|
+
def search_for_story(query, params={})
|
58
|
+
params[:filter] = "#{query}"
|
59
|
+
get_stories(params)
|
57
60
|
end
|
58
61
|
|
59
|
-
def get_task_by_id(
|
62
|
+
def get_task_by_id(id)
|
60
63
|
project.story(id, fields: STORY_FIELDS)
|
61
64
|
end
|
62
65
|
alias :get_story :get_task_by_id
|
63
66
|
|
64
|
-
def get_my_open_tasks(
|
65
|
-
|
67
|
+
def get_my_open_tasks(params={})
|
68
|
+
params[:filter] = "owner:#{config[:user_name]}"
|
69
|
+
get_stories(params)
|
66
70
|
end
|
67
71
|
|
68
|
-
def
|
69
|
-
|
72
|
+
def get_stories_to_estimate(params={})
|
73
|
+
params[:filter] = "owner:#{config[:user_name]} type:feature estimate:-1"
|
74
|
+
get_stories(params)
|
70
75
|
end
|
71
76
|
|
72
|
-
def
|
73
|
-
|
74
|
-
tasks
|
77
|
+
def get_stories_to_start(params={})
|
78
|
+
params[:filter] = "owner:#{config[:user_name]} type:feature,bug state:unscheduled,rejected,unstarted"
|
79
|
+
tasks = get_stories(params)
|
80
|
+
tasks.reject{ |t| (t.story_type == 'feature') && (!t.estimate) }
|
75
81
|
end
|
76
82
|
|
77
|
-
def
|
78
|
-
|
83
|
+
def get_stories_to_finish(params={})
|
84
|
+
params[:filter] = "owner:#{config[:user_name]} -state:unscheduled,rejected"
|
85
|
+
get_stories(params)
|
79
86
|
end
|
80
87
|
|
81
|
-
def
|
82
|
-
|
88
|
+
def get_stories_to_deliver(params={})
|
89
|
+
params[:filter] = "owner:#{config[:user_name]} -state:delivered,accepted,rejected"
|
90
|
+
get_stories(params)
|
83
91
|
end
|
84
92
|
|
85
|
-
def
|
86
|
-
|
93
|
+
def get_stories_to_accept(params={})
|
94
|
+
params[:filter] = "owner:#{config[:user_name]} -state:accepted"
|
95
|
+
get_stories(params)
|
87
96
|
end
|
88
97
|
|
89
|
-
def
|
90
|
-
|
98
|
+
def get_stories_to_reject(params={})
|
99
|
+
params[:filter] = "owner:#{config[:user_name]} -state:rejected"
|
100
|
+
get_stories(params)
|
91
101
|
end
|
92
102
|
|
93
|
-
def
|
94
|
-
|
103
|
+
def get_stories_to_assign(params={})
|
104
|
+
params[:filter] = "-state:accepted"
|
105
|
+
get_stories(params)
|
95
106
|
end
|
96
107
|
|
97
|
-
def
|
98
|
-
|
108
|
+
def get_stories(params={})
|
109
|
+
limit = config[:limit] || 20
|
110
|
+
page = params[:page] || 0
|
111
|
+
offset = page*limit
|
112
|
+
filter = params[:filter] || '-state=accepted'
|
113
|
+
project.stories limit: limit, fields: STORY_FIELDS, auto_paginate: false, offset: offset, filter: filter
|
99
114
|
end
|
100
115
|
|
101
116
|
|
102
|
-
def get_member(
|
117
|
+
def get_member(query)
|
103
118
|
member = project.memberships.select{ |m| m.person.name.downcase.start_with?(query.downcase) || m.person.initials.downcase == query.downcase }
|
104
119
|
member.empty? ? nil : member.first
|
105
120
|
end
|
106
121
|
|
107
|
-
def find_member(
|
108
|
-
|
122
|
+
def find_member(query)
|
123
|
+
project.memberships.detect do |m|
|
109
124
|
m.person.name.downcase.start_with?(query.downcase) || m.person.initials.downcase == query.downcase
|
110
125
|
end
|
111
126
|
end
|
112
127
|
|
113
|
-
def get_members
|
128
|
+
def get_members
|
114
129
|
project.memberships fields: ':default,person'
|
115
130
|
end
|
116
131
|
|
117
132
|
|
118
|
-
def mark_task_as(
|
119
|
-
task = get_story(
|
133
|
+
def mark_task_as(task, state)
|
134
|
+
task = get_story(task.id)
|
120
135
|
task.current_state = state
|
121
136
|
task.save
|
122
137
|
end
|
123
138
|
|
124
|
-
def
|
125
|
-
task = get_story(
|
139
|
+
def estimate_story(task, points)
|
140
|
+
task = get_story(task.id)
|
126
141
|
task.estimate = points
|
127
142
|
task.save
|
128
143
|
end
|
129
144
|
|
130
|
-
def assign_task(
|
131
|
-
task = get_story(
|
145
|
+
def assign_task(task, owner)
|
146
|
+
task = get_story(task.id)
|
132
147
|
task.add_owner(owner)
|
133
148
|
end
|
134
149
|
|
135
|
-
def add_label(
|
136
|
-
task = get_story(
|
150
|
+
def add_label(task, label)
|
151
|
+
task = get_story(task.id)
|
137
152
|
task.add_label(label)
|
138
153
|
task.save
|
139
154
|
end
|
140
155
|
|
141
|
-
def comment_task(
|
142
|
-
task = get_story(
|
156
|
+
def comment_task(task, comment)
|
157
|
+
task = get_story(task.id)
|
143
158
|
task.create_comment(text: comment)
|
144
159
|
end
|
145
160
|
|
146
|
-
def
|
147
|
-
project.create_story(
|
161
|
+
def create_story(args)
|
162
|
+
project.create_story(args)
|
148
163
|
end
|
149
164
|
|
150
|
-
def create_task_with_description(project, name, owner, task_type, description)
|
151
|
-
project.create_story(:name => name, :story_type => task_type, :description => description)
|
152
|
-
end
|
153
|
-
|
154
|
-
|
155
165
|
end
|
156
166
|
end
|