trollolo 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/README.md +4 -3
- data/lib/burndown_chart.rb +10 -6
- data/lib/burndown_data.rb +34 -16
- data/lib/card.rb +18 -0
- data/lib/checklist.rb +9 -0
- data/lib/cli.rb +36 -114
- data/lib/column.rb +5 -1
- data/lib/scrum_board.rb +40 -0
- data/lib/trello_wrapper.rb +5 -0
- data/lib/trollolo.rb +1 -0
- data/lib/version.rb +1 -1
- data/spec/data/attachment-data +1 -0
- data/spec/data/board.json +2 -1
- data/spec/data/burndown-data.yaml +6 -0
- data/spec/data/burndown_dir/burndown-data-02.yaml +13 -1
- data/spec/data/create_burndown_helper/burndown-08.png +0 -0
- data/spec/data/create_burndown_helper/burndown-23.png +0 -0
- data/spec/data/create_burndown_helper/burndown-31.png +0 -0
- data/spec/data/create_burndown_helper/burndown-35.png +0 -0
- data/spec/data/full-board.json +166 -22
- data/spec/unit/backup_spec.rb +5 -0
- data/spec/unit/burndown_chart_spec.rb +176 -85
- data/spec/unit/burndown_data_spec.rb +77 -45
- data/spec/unit/card_spec.rb +75 -0
- data/spec/unit/cli_spec.rb +71 -10
- data/spec/unit/support/update_webmock_data +22 -4
- data/spec/unit/trello_wrapper_spec.rb +30 -0
- data/trollolo.gemspec +2 -2
- data/yes_ship_it.conf +2 -2
- metadata +18 -19
- data/man/trollolo.1 +0 -128
- data/man/trollolo.1.html +0 -219
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b4ae1e203030317bbb9ec7e96f53ee12c5d81d82
|
4
|
+
data.tar.gz: d8943b820b15ce09f72b6147289af3c89ba207b0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 245e86bbe23e00552dd795479d44f271b11643ed82e9516d59541c50ce6b8bcf726de0fb0ab88ba68eb3bdab9f004e4bdb9357d4276c45b008b05855dc8069f5
|
7
|
+
data.tar.gz: a732a4c652a3769e90fa3b9c17206adb8c1dc1b5736e952974073ff576de1bf1924118dfdfdf116d63701604b83db2eba4b75cb2021e5bd17d6c4aa222a09e43
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
# Trollolo Changelog
|
2
2
|
|
3
|
+
## Version 0.0.6
|
4
|
+
|
5
|
+
* Track cards with unplanned work separately
|
6
|
+
* Fix error when parsing of meta data on card fails
|
7
|
+
* Implement `set-cover` command. This command uploads a picture to a given card,
|
8
|
+
which is then set as cover.
|
9
|
+
* Fix raw output of cards list
|
10
|
+
* Fix commands to get basic data
|
11
|
+
* Don't overwrite data on first day of sprint
|
12
|
+
|
3
13
|
## Version 0.0.5
|
4
14
|
|
5
15
|
* Allow done columns which have a name stating with `Done` and do not insist on
|
data/README.md
CHANGED
@@ -46,9 +46,10 @@ For creating a developer key go to the
|
|
46
46
|
[Developer API Keys](https://trello.com/1/appKey/generate) page on Trello. It's
|
47
47
|
the key in the first box.
|
48
48
|
|
49
|
-
For creating a member token
|
50
|
-
|
51
|
-
|
49
|
+
For creating a member token use the following URL, replacing `applicationkey` by
|
50
|
+
the key you obtained in the first step.
|
51
|
+
|
52
|
+
https://trello.com/1/authorize?key=applicationkey&name=trollolo&expiration=never&response_type=token
|
52
53
|
|
53
54
|
The board id is the cryptic string in the URL of your board.
|
54
55
|
|
data/lib/burndown_chart.rb
CHANGED
@@ -20,7 +20,6 @@ class BurndownChart
|
|
20
20
|
|
21
21
|
def initialize(settings)
|
22
22
|
@settings = settings
|
23
|
-
@burndown_data = BurndownData.new settings
|
24
23
|
|
25
24
|
@data = {
|
26
25
|
"meta" => {
|
@@ -74,7 +73,7 @@ class BurndownChart
|
|
74
73
|
|
75
74
|
def add_data(burndown_data)
|
76
75
|
new_entry = burndown_data.to_hash
|
77
|
-
if entry_exists?(burndown_data.date_time.to_date)
|
76
|
+
if entry_exists?(burndown_data.date_time.to_date) && days.length > 1
|
78
77
|
replace_entry(burndown_data.date_time.to_date, new_entry)
|
79
78
|
else
|
80
79
|
days.push(new_entry)
|
@@ -168,10 +167,15 @@ class BurndownChart
|
|
168
167
|
|
169
168
|
def update(options)
|
170
169
|
burndown_data_path = load_last_sprint(options['output'] || Dir.pwd)
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
170
|
+
|
171
|
+
burndown_data = BurndownData.new(@settings)
|
172
|
+
burndown_data.board_id = board_id
|
173
|
+
burndown_data.fetch
|
174
|
+
|
175
|
+
add_data(burndown_data)
|
176
|
+
|
177
|
+
write_data(burndown_data_path)
|
178
|
+
|
175
179
|
if options[:plot]
|
176
180
|
BurndownChart.plot(self.sprint, options)
|
177
181
|
end
|
data/lib/burndown_data.rb
CHANGED
@@ -34,16 +34,19 @@ class BurndownData
|
|
34
34
|
end
|
35
35
|
|
36
36
|
attr_accessor :story_points, :tasks, :extra_story_points, :extra_tasks,
|
37
|
+
:unplanned_story_points, :unplanned_tasks,
|
37
38
|
:board_id, :fast_lane_cards, :date_time
|
38
39
|
attr_reader :meta
|
39
40
|
|
40
41
|
def initialize(settings)
|
41
|
-
@settings
|
42
|
-
@story_points
|
43
|
-
@tasks
|
44
|
-
@extra_story_points
|
45
|
-
@extra_tasks
|
46
|
-
@
|
42
|
+
@settings = settings
|
43
|
+
@story_points = Result.new
|
44
|
+
@tasks = Result.new
|
45
|
+
@extra_story_points = Result.new
|
46
|
+
@extra_tasks = Result.new
|
47
|
+
@unplanned_story_points = Result.new
|
48
|
+
@unplanned_tasks = Result.new
|
49
|
+
@fast_lane_cards = Result.new
|
47
50
|
end
|
48
51
|
|
49
52
|
def to_hash
|
@@ -66,13 +69,22 @@ class BurndownData
|
|
66
69
|
}
|
67
70
|
}
|
68
71
|
if fast_lane_cards.total > 0
|
69
|
-
base
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
72
|
+
base["fast_lane"] = {
|
73
|
+
"total" => fast_lane_cards.total,
|
74
|
+
"open" => fast_lane_cards.open
|
75
|
+
}
|
76
|
+
end
|
77
|
+
if unplanned_story_points.total > 0
|
78
|
+
base["unplanned_story_points"] = {
|
79
|
+
"total" => unplanned_story_points.total,
|
80
|
+
"open" => unplanned_story_points.open
|
81
|
+
}
|
82
|
+
base["unplanned_tasks"] = {
|
83
|
+
"total" => unplanned_tasks.total,
|
84
|
+
"open" => unplanned_tasks.open
|
85
|
+
}
|
75
86
|
end
|
87
|
+
base
|
76
88
|
end
|
77
89
|
|
78
90
|
def trello
|
@@ -84,7 +96,7 @@ class BurndownData
|
|
84
96
|
end
|
85
97
|
|
86
98
|
def fetch
|
87
|
-
get_meta
|
99
|
+
@meta = get_meta
|
88
100
|
@story_points.done = board.done_story_points
|
89
101
|
@story_points.open = board.open_story_points
|
90
102
|
@tasks.open = board.tasks - board.closed_tasks
|
@@ -93,6 +105,10 @@ class BurndownData
|
|
93
105
|
@extra_story_points.open = board.extra_open_story_points
|
94
106
|
@extra_tasks.done = board.extra_closed_tasks
|
95
107
|
@extra_tasks.open = board.extra_tasks - board.extra_closed_tasks
|
108
|
+
@unplanned_story_points.done = board.unplanned_done_story_points
|
109
|
+
@unplanned_story_points.open = board.unplanned_open_story_points
|
110
|
+
@unplanned_tasks.done = board.unplanned_closed_tasks
|
111
|
+
@unplanned_tasks.open = board.unplanned_tasks - board.unplanned_closed_tasks
|
96
112
|
@fast_lane_cards.done = board.done_fast_lane_cards_count
|
97
113
|
@fast_lane_cards.open = board.open_fast_lane_cards_count
|
98
114
|
@date_time = DateTime.now
|
@@ -102,10 +118,12 @@ class BurndownData
|
|
102
118
|
|
103
119
|
def get_meta
|
104
120
|
meta_cards = board.meta_cards
|
105
|
-
return unless meta_cards.any?
|
121
|
+
return nil unless meta_cards.any?
|
106
122
|
current_sprint_meta_card = meta_cards.max_by(&:sprint_number)
|
107
|
-
|
108
|
-
|
123
|
+
meta = Card.parse_yaml_from_description(current_sprint_meta_card.desc)
|
124
|
+
return nil unless meta
|
125
|
+
meta['sprint'] = current_sprint_meta_card.sprint_number
|
126
|
+
meta
|
109
127
|
end
|
110
128
|
|
111
129
|
end
|
data/lib/card.rb
CHANGED
@@ -29,6 +29,10 @@ class Card
|
|
29
29
|
@card_data = @board_data["cards"].select{|c| c["id"] == card_id}.first
|
30
30
|
end
|
31
31
|
|
32
|
+
def as_json
|
33
|
+
JSON.pretty_generate(@card_data)
|
34
|
+
end
|
35
|
+
|
32
36
|
def estimated?
|
33
37
|
name =~ ESTIMATED_REGEX
|
34
38
|
end
|
@@ -66,6 +70,14 @@ class Card
|
|
66
70
|
@card_data["labels"]
|
67
71
|
end
|
68
72
|
|
73
|
+
def checklists
|
74
|
+
checklists = []
|
75
|
+
@card_data["checklists"].each do |checklist|
|
76
|
+
checklists.push(Checklist.new(checklist))
|
77
|
+
end
|
78
|
+
checklists
|
79
|
+
end
|
80
|
+
|
69
81
|
def desc
|
70
82
|
@card_data["desc"]
|
71
83
|
end
|
@@ -77,6 +89,12 @@ class Card
|
|
77
89
|
end
|
78
90
|
end
|
79
91
|
|
92
|
+
def unplanned?
|
93
|
+
self.card_labels.any? do |label|
|
94
|
+
label['name'].include?('Unplanned')
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
80
98
|
def meta_card?
|
81
99
|
name =~ SPRINT_NUMBER_REGEX
|
82
100
|
end
|
data/lib/checklist.rb
ADDED
data/lib/cli.rb
CHANGED
@@ -73,14 +73,15 @@ EOT
|
|
73
73
|
process_global_options options
|
74
74
|
require_trello_credentials
|
75
75
|
|
76
|
-
trello =
|
77
|
-
|
76
|
+
trello = TrelloWrapper.new(@@settings)
|
77
|
+
board = trello.board(options["board-id"])
|
78
|
+
lists = board.columns
|
78
79
|
|
79
80
|
if @@settings.raw
|
80
81
|
puts JSON.pretty_generate lists
|
81
82
|
else
|
82
83
|
lists.each do |list|
|
83
|
-
puts
|
84
|
+
puts list.name
|
84
85
|
end
|
85
86
|
end
|
86
87
|
end
|
@@ -91,78 +92,22 @@ EOT
|
|
91
92
|
process_global_options options
|
92
93
|
require_trello_credentials
|
93
94
|
|
94
|
-
trello =
|
95
|
-
|
96
|
-
cards =
|
95
|
+
trello = TrelloWrapper.new(@@settings)
|
96
|
+
board = trello.board(options["board-id"])
|
97
|
+
cards = board.cards
|
97
98
|
|
98
99
|
if @@settings.raw
|
99
|
-
|
100
|
-
else
|
101
|
-
burndown = BurndownData.new @@settings
|
102
|
-
burndown.board_id = options["board-id"]
|
103
|
-
|
104
|
-
todo_list_id = burndown.fetch_todo_list_id
|
105
|
-
doing_list_id = burndown.fetch_doing_list_id
|
106
|
-
done_list_id = burndown.fetch_done_list_id
|
107
|
-
|
108
|
-
cards_todo = Array.new
|
109
|
-
cards_doing = Array.new
|
110
|
-
cards_done = Array.new
|
111
|
-
|
112
|
-
above_waterline = true
|
113
|
-
|
100
|
+
cards_as_json = []
|
114
101
|
cards.each do |card|
|
115
|
-
|
116
|
-
list = card["idList"]
|
117
|
-
puts "CARD #{name} (#{list})"
|
118
|
-
|
119
|
-
if name == "Waterline"
|
120
|
-
above_waterline = false
|
121
|
-
next
|
122
|
-
end
|
123
|
-
|
124
|
-
if Card.name_to_points(name).nil?
|
125
|
-
next
|
126
|
-
end
|
127
|
-
|
128
|
-
if list == todo_list_id && above_waterline
|
129
|
-
cards_todo.push card
|
130
|
-
elsif list == doing_list_id
|
131
|
-
cards_doing.push card
|
132
|
-
elsif list == done_list_id
|
133
|
-
cards_done.push card
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
story_points_todo = 0
|
138
|
-
story_points_doing = 0
|
139
|
-
story_points_done = 0
|
140
|
-
|
141
|
-
puts
|
142
|
-
|
143
|
-
puts "Todo"
|
144
|
-
cards_todo.each do |card|
|
145
|
-
puts " #{card["name"]}"
|
146
|
-
story_points_todo += Card.name_to_points(card["name"])
|
147
|
-
end
|
148
|
-
|
149
|
-
puts "Doing"
|
150
|
-
cards_doing.each do |card|
|
151
|
-
puts " #{card["name"]}"
|
152
|
-
story_points_doing += Card.name_to_points(card["name"])
|
102
|
+
cards_as_json.push(card.as_json)
|
153
103
|
end
|
154
|
-
|
155
|
-
puts "
|
156
|
-
|
157
|
-
|
158
|
-
|
104
|
+
puts "["
|
105
|
+
puts cards_as_json.join(",")
|
106
|
+
puts "]"
|
107
|
+
else
|
108
|
+
cards.each do |card|
|
109
|
+
puts card.name
|
159
110
|
end
|
160
|
-
|
161
|
-
puts
|
162
|
-
|
163
|
-
story_points_total = story_points_todo + story_points_doing + story_points_done
|
164
|
-
|
165
|
-
puts "Done: #{story_points_done}/#{story_points_total} (#{story_points_doing} in progress)"
|
166
111
|
end
|
167
112
|
end
|
168
113
|
|
@@ -172,48 +117,15 @@ EOT
|
|
172
117
|
process_global_options options
|
173
118
|
require_trello_credentials
|
174
119
|
|
175
|
-
trello =
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
120
|
+
trello = TrelloWrapper.new(@@settings)
|
121
|
+
board = trello.board(options["board-id"])
|
122
|
+
board.cards.each do |card|
|
123
|
+
card.checklists.each do |checklist|
|
124
|
+
puts checklist.name
|
125
|
+
end
|
126
|
+
end
|
180
127
|
end
|
181
128
|
|
182
|
-
desc "fetch-burndown-data", "Fetch data for burndown chart"
|
183
|
-
option "board-id", :desc => "Id of Trello board", :required => true
|
184
|
-
def fetch_burndown_data
|
185
|
-
process_global_options options
|
186
|
-
require_trello_credentials
|
187
|
-
|
188
|
-
burndown = BurndownData.new @@settings
|
189
|
-
burndown.board_id = options["board-id"]
|
190
|
-
burndown.fetch
|
191
|
-
|
192
|
-
puts "Story points:"
|
193
|
-
puts " Open: #{burndown.story_points.open}"
|
194
|
-
puts " Done: #{burndown.story_points.done}"
|
195
|
-
puts " Total: #{burndown.story_points.total}"
|
196
|
-
puts
|
197
|
-
puts "Tasks:"
|
198
|
-
puts " Open: #{burndown.tasks.open}"
|
199
|
-
puts " Done: #{burndown.tasks.done}"
|
200
|
-
puts " Total: #{burndown.tasks.total}"
|
201
|
-
puts
|
202
|
-
puts "Extra story points:"
|
203
|
-
puts " Open: #{burndown.extra_story_points.open}"
|
204
|
-
puts " Done: #{burndown.extra_story_points.done}"
|
205
|
-
puts " Total: #{burndown.extra_story_points.total}"
|
206
|
-
puts "Extra tasks:"
|
207
|
-
puts " Open: #{burndown.extra_tasks.open}"
|
208
|
-
puts " Done: #{burndown.extra_tasks.done}"
|
209
|
-
puts " Total: #{burndown.extra_tasks.total}"
|
210
|
-
puts
|
211
|
-
puts "FastLane Cards:"
|
212
|
-
puts " Open: #{burndown.fast_lane_cards.open}"
|
213
|
-
puts " Done: #{burndown.fast_lane_cards.done}"
|
214
|
-
puts " Total: #{burndown.fast_lane_cards.total}"
|
215
|
-
end
|
216
|
-
|
217
129
|
desc "burndowns", "run multiple burndowns"
|
218
130
|
option "board-list", :desc => "path to board-list.yaml", :required => true
|
219
131
|
option :plot, :type => :boolean, :desc => "also plot the new data"
|
@@ -250,7 +162,7 @@ EOT
|
|
250
162
|
puts "Preparing directory..."
|
251
163
|
chart.setup(options[:output],options["board-id"])
|
252
164
|
end
|
253
|
-
|
165
|
+
|
254
166
|
desc "burndown", "Update burndown chart"
|
255
167
|
option :output, :aliases => :o, :desc => "Output directory", :required => false
|
256
168
|
option :new_sprint, :aliases => :n, :desc => "Create new sprint"
|
@@ -339,8 +251,18 @@ EOT
|
|
339
251
|
end
|
340
252
|
end
|
341
253
|
|
254
|
+
desc "set-cover <filename>", "Set cover picture"
|
255
|
+
option "card-id", :desc => "Id of card", :required => true
|
256
|
+
def set_cover(filename)
|
257
|
+
process_global_options(options)
|
258
|
+
require_trello_credentials
|
259
|
+
|
260
|
+
trello = TrelloWrapper.new(@@settings)
|
261
|
+
trello.add_attachment(options["card-id"], filename)
|
262
|
+
end
|
263
|
+
|
342
264
|
private
|
343
|
-
|
265
|
+
|
344
266
|
def process_global_options options
|
345
267
|
@@settings.verbose = options[:verbose]
|
346
268
|
@@settings.raw = options[:raw]
|
@@ -354,7 +276,7 @@ EOT
|
|
354
276
|
@@settings.developer_public_key = STDIN.gets.chomp
|
355
277
|
write_back = true
|
356
278
|
end
|
357
|
-
|
279
|
+
|
358
280
|
if !@@settings.member_token
|
359
281
|
puts "Put in Trello member token:"
|
360
282
|
@@settings.member_token = STDIN.gets.chomp
|
@@ -364,7 +286,7 @@ EOT
|
|
364
286
|
if write_back
|
365
287
|
@@settings.save_config
|
366
288
|
end
|
367
|
-
|
289
|
+
|
368
290
|
if !@@settings.developer_public_key || !@@settings.member_token
|
369
291
|
STDERR.puts "Require trello credentials in config file"
|
370
292
|
exit 1
|
data/lib/column.rb
CHANGED
@@ -44,8 +44,12 @@ class Column
|
|
44
44
|
cards.select{|c| c.extra?}
|
45
45
|
end
|
46
46
|
|
47
|
+
def unplanned_cards
|
48
|
+
cards.select{|c| c.unplanned?}
|
49
|
+
end
|
50
|
+
|
47
51
|
def committed_cards
|
48
|
-
cards.select{|c| !c.extra?}
|
52
|
+
cards.select{|c| !c.extra? && !c.unplanned?}
|
49
53
|
end
|
50
54
|
|
51
55
|
def fast_lane_cards
|
data/lib/scrum_board.rb
CHANGED
@@ -54,6 +54,7 @@ class ScrumBoard
|
|
54
54
|
committed_cards.map(&:tasks).sum
|
55
55
|
end
|
56
56
|
|
57
|
+
|
57
58
|
def extra_cards
|
58
59
|
(done_column.extra_cards + open_columns.map(&:extra_cards)).flatten(1)
|
59
60
|
end
|
@@ -82,6 +83,36 @@ class ScrumBoard
|
|
82
83
|
extra_cards.map(&:done_tasks).sum
|
83
84
|
end
|
84
85
|
|
86
|
+
|
87
|
+
def unplanned_cards
|
88
|
+
(done_column.unplanned_cards + open_columns.map(&:unplanned_cards)).flatten(1)
|
89
|
+
end
|
90
|
+
|
91
|
+
def unplanned_done_cards
|
92
|
+
done_column.unplanned_cards
|
93
|
+
end
|
94
|
+
|
95
|
+
def unplanned_done_story_points
|
96
|
+
unplanned_done_cards.map(&:story_points).sum
|
97
|
+
end
|
98
|
+
|
99
|
+
def unplanned_open_cards
|
100
|
+
open_columns.map{|col| col.cards.select{|c| c.unplanned?}}.flatten
|
101
|
+
end
|
102
|
+
|
103
|
+
def unplanned_open_story_points
|
104
|
+
unplanned_open_cards.map(&:story_points).sum
|
105
|
+
end
|
106
|
+
|
107
|
+
def unplanned_tasks
|
108
|
+
unplanned_cards.map(&:tasks).sum
|
109
|
+
end
|
110
|
+
|
111
|
+
def unplanned_closed_tasks
|
112
|
+
unplanned_cards.map(&:done_tasks).sum
|
113
|
+
end
|
114
|
+
|
115
|
+
|
85
116
|
def open_fast_lane_cards_count
|
86
117
|
open_columns.map(&:fast_lane_cards).flatten(1).count
|
87
118
|
end
|
@@ -101,4 +132,13 @@ class ScrumBoard
|
|
101
132
|
def id
|
102
133
|
@board_data["id"]
|
103
134
|
end
|
135
|
+
|
136
|
+
def cards
|
137
|
+
return @cards if @cards
|
138
|
+
@cards = []
|
139
|
+
columns.each do |column|
|
140
|
+
@cards += column.cards
|
141
|
+
end
|
142
|
+
@cards
|
143
|
+
end
|
104
144
|
end
|
data/lib/trello_wrapper.rb
CHANGED
data/lib/trollolo.rb
CHANGED
data/lib/version.rb
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
abc
|
data/spec/data/board.json
CHANGED
@@ -16,6 +16,7 @@
|
|
16
16
|
"selfJoin": false,
|
17
17
|
"cardCovers": true,
|
18
18
|
"cardAging": "regular",
|
19
|
+
"calendarFeedEnabled": false,
|
19
20
|
"background": "5319bb612fb0bcdf451401a8",
|
20
21
|
"backgroundColor": null,
|
21
22
|
"backgroundImage": "https://trello-backgrounds.s3.amazonaws.com/4e727168cb2ac700002cf6b6/990df8f044b98679ccbef943beff54d6/4268316033_6d847a0219_b.jpg",
|
@@ -57,7 +58,7 @@
|
|
57
58
|
"blue": "Sticky",
|
58
59
|
"sky": "",
|
59
60
|
"lime": "",
|
60
|
-
"pink": "",
|
61
|
+
"pink": "Unplanned",
|
61
62
|
"black": ""
|
62
63
|
}
|
63
64
|
}
|
@@ -6,4 +6,16 @@ meta:
|
|
6
6
|
weekend_lines:
|
7
7
|
- 3.5
|
8
8
|
- 7.5
|
9
|
-
days:
|
9
|
+
days:
|
10
|
+
- date: '2015-08-28'
|
11
|
+
updated_at: '2015-08-28T11:04:52+02:00'
|
12
|
+
story_points:
|
13
|
+
total: 24.0
|
14
|
+
open: 24.0
|
15
|
+
tasks:
|
16
|
+
total: 43
|
17
|
+
open: 28
|
18
|
+
story_points_extra:
|
19
|
+
done: 2.0
|
20
|
+
tasks_extra:
|
21
|
+
done: 5
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|