trollolo 0.0.9 → 0.0.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -0
- data/Gemfile +1 -1
- data/README.md +97 -0
- data/lib/card.rb +0 -14
- data/lib/cli.rb +66 -27
- data/lib/empty_column.rb +5 -0
- data/lib/scrum/backlog_mover.rb +47 -0
- data/lib/scrum/card_type_detection.rb +23 -0
- data/lib/scrum/creator.rb +30 -0
- data/lib/scrum/prioritizer.rb +24 -0
- data/lib/scrum/priority_name.rb +15 -0
- data/lib/scrum/scrum_boards.rb +11 -0
- data/lib/scrum/sprint_board.rb +82 -0
- data/lib/scrum/sprint_cleaner.rb +41 -0
- data/lib/scrum/sprint_planning_board.rb +26 -0
- data/lib/scrum.rb +13 -0
- data/lib/scrum_board.rb +17 -7
- data/lib/settings.rb +36 -12
- data/lib/trello_service.rb +22 -0
- data/lib/trello_wrapper.rb +9 -23
- data/lib/trollolo.rb +3 -2
- data/lib/version.rb +1 -1
- data/man/trollolo.1.md +22 -1
- data/spec/data/board.json +3 -4
- data/spec/data/full-board-with-accepted.json +1817 -0
- data/spec/data/full-board.json +3 -27
- data/spec/data/trollolorc +13 -0
- data/spec/data/trollolorc_with_board_aliases +9 -0
- data/spec/data/vcr/creator_custom_config.yml +824 -0
- data/spec/data/vcr/creator_default_config.yml +824 -0
- data/spec/data/vcr/move_backlog.yml +2375 -0
- data/spec/data/vcr/move_backlog_missing_backlog.yml +155 -0
- data/spec/data/vcr/move_backlog_missing_waterbed.yml +364 -0
- data/spec/data/vcr/prioritize_backlog_list.yml +2335 -0
- data/spec/data/vcr/prioritize_no_backlog_list.yml +190 -0
- data/spec/data/vcr/sprint_board.yml +624 -0
- data/spec/data/vcr/sprint_board_no_waterline.yml +556 -0
- data/spec/data/vcr/sprint_cleanup.yml +1239 -7500
- data/spec/data/vcr/sprint_planning_board.yml +239 -0
- data/spec/integration/create_burndown_spec.rb +1 -1
- data/spec/unit/card_spec.rb +0 -41
- data/spec/unit/cli_spec.rb +74 -1
- data/spec/unit/empty_column_spec.rb +9 -0
- data/spec/unit/scrum/backlog_mover_spec.rb +26 -0
- data/spec/unit/scrum/card_type_detection_spec.rb +35 -0
- data/spec/unit/scrum/creator_spec.rb +23 -0
- data/spec/unit/scrum/prioritizer_spec.rb +45 -0
- data/spec/unit/scrum/priority_name_spec.rb +35 -0
- data/spec/unit/scrum/sprint_board_spec.rb +22 -0
- data/spec/unit/scrum/sprint_cleaner_spec.rb +26 -0
- data/spec/unit/scrum/sprint_planning_board_spec.rb +14 -0
- data/spec/unit/scrum_board_spec.rb +90 -0
- data/spec/unit/settings_spec.rb +42 -6
- data/spec/unit/spec_helper.rb +3 -2
- data/spec/unit/support/update_webmock_data +3 -1
- data/spec/unit/support/vcr.rb +8 -8
- data/spec/unit/support/webmocks.rb +9 -0
- data/spec/unit/trello_wrapper_spec.rb +20 -0
- data/trollolo.gemspec +2 -1
- metadata +52 -9
- data/lib/prioritizer.rb +0 -34
- data/lib/sprint_cleanup.rb +0 -54
- data/spec/unit/prioritizer_spec.rb +0 -47
- data/spec/unit/sprint_cleanup_spec.rb +0 -18
data/lib/scrum_board.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
class ScrumBoard
|
2
2
|
|
3
3
|
class DoneColumnNotFoundError < StandardError; end
|
4
|
+
class AcceptedColumnNotFoundError < StandardError; end
|
4
5
|
|
5
6
|
def initialize(board_data, settings)
|
6
7
|
@settings = settings
|
@@ -22,8 +23,17 @@ class ScrumBoard
|
|
22
23
|
end
|
23
24
|
end
|
24
25
|
|
26
|
+
def accepted_column
|
27
|
+
accepted_columns = columns.select{|c| c.name =~ @settings.accepted_column_name_regex }
|
28
|
+
if accepted_columns.empty?
|
29
|
+
EmptyColumn.new
|
30
|
+
else
|
31
|
+
accepted_columns.max_by{|c| c.name.match(@settings.accepted_column_name_regex).captures.first.to_i }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
25
35
|
def done_cards
|
26
|
-
done_column.committed_cards
|
36
|
+
done_column.committed_cards + accepted_column.committed_cards
|
27
37
|
end
|
28
38
|
|
29
39
|
def open_columns
|
@@ -56,11 +66,11 @@ class ScrumBoard
|
|
56
66
|
|
57
67
|
|
58
68
|
def extra_cards
|
59
|
-
(done_column.extra_cards + open_columns.map(&:extra_cards)).flatten(1)
|
69
|
+
(done_column.extra_cards + accepted_column.extra_cards + open_columns.map(&:extra_cards)).flatten(1)
|
60
70
|
end
|
61
71
|
|
62
72
|
def extra_done_cards
|
63
|
-
done_column.extra_cards
|
73
|
+
done_column.extra_cards + accepted_column.extra_cards
|
64
74
|
end
|
65
75
|
|
66
76
|
def extra_done_story_points
|
@@ -85,11 +95,11 @@ class ScrumBoard
|
|
85
95
|
|
86
96
|
|
87
97
|
def unplanned_cards
|
88
|
-
(done_column.unplanned_cards + open_columns.map(&:unplanned_cards)).flatten(1)
|
98
|
+
(done_column.unplanned_cards + accepted_column.unplanned_cards + open_columns.map(&:unplanned_cards)).flatten(1)
|
89
99
|
end
|
90
100
|
|
91
101
|
def unplanned_done_cards
|
92
|
-
done_column.unplanned_cards
|
102
|
+
done_column.unplanned_cards + accepted_column.unplanned_cards
|
93
103
|
end
|
94
104
|
|
95
105
|
def unplanned_done_story_points
|
@@ -118,11 +128,11 @@ class ScrumBoard
|
|
118
128
|
end
|
119
129
|
|
120
130
|
def done_fast_lane_cards_count
|
121
|
-
done_column.fast_lane_cards.count
|
131
|
+
done_column.fast_lane_cards.count + accepted_column.fast_lane_cards.count
|
122
132
|
end
|
123
133
|
|
124
134
|
def scrum_cards
|
125
|
-
open_columns.map(&:fast_lane_cards).flatten(1) + done_column.cards
|
135
|
+
open_columns.map(&:fast_lane_cards).flatten(1) + done_column.cards + accepted_column.cards
|
126
136
|
end
|
127
137
|
|
128
138
|
def meta_cards
|
data/lib/settings.rb
CHANGED
@@ -17,9 +17,9 @@
|
|
17
17
|
|
18
18
|
class Settings
|
19
19
|
|
20
|
-
attr_accessor :developer_public_key, :member_token, :
|
21
|
-
:not_done_columns, :todo_column, :
|
22
|
-
:todo_column_name_regex
|
20
|
+
attr_accessor :developer_public_key, :member_token, :board_aliases, :verbose,
|
21
|
+
:raw, :not_done_columns, :todo_column, :accepted_column_name_regex,
|
22
|
+
:done_column_name_regex, :todo_column_name_regex, :scrum
|
23
23
|
|
24
24
|
def initialize config_file_path
|
25
25
|
@config_file_path = config_file_path
|
@@ -27,17 +27,20 @@ class Settings
|
|
27
27
|
@config = YAML.load_file(config_file_path)
|
28
28
|
|
29
29
|
if @config
|
30
|
-
@developer_public_key
|
31
|
-
@member_token
|
32
|
-
@
|
33
|
-
@
|
34
|
-
@
|
35
|
-
@
|
30
|
+
@developer_public_key = @config["developer_public_key"]
|
31
|
+
@member_token = @config["member_token"]
|
32
|
+
@board_aliases = @config["board_aliases"] || {}
|
33
|
+
@scrum = OpenStruct.new(@config["scrum"] || scrum_defaults)
|
34
|
+
@not_done_columns = @config["not_done_columns"].freeze || ["Sprint Backlog", "Doing"]
|
35
|
+
@todo_column = @config["todo_column"].freeze
|
36
|
+
@done_column_name_regex = @config["done_column_name_regex"].freeze || /\ADone/
|
37
|
+
@accepted_column_name_regex = @config["accepted_column_name_regex"].freeze || /\AAccepted/
|
38
|
+
@todo_column_name_regex = @config["todo_column_name_regex"].freeze || /\ATo Do\Z/
|
36
39
|
else
|
37
40
|
raise "Couldn't read config data from '#{config_file_path}'"
|
38
41
|
end
|
39
42
|
end
|
40
|
-
|
43
|
+
|
41
44
|
@verbose = false
|
42
45
|
@raw = false
|
43
46
|
end
|
@@ -46,14 +49,35 @@ class Settings
|
|
46
49
|
@config = {}
|
47
50
|
@config["developer_public_key"] = @developer_public_key
|
48
51
|
@config["member_token"] = @member_token
|
49
|
-
|
52
|
+
|
50
53
|
File.open(@config_file_path,"w") do |f|
|
51
54
|
f.write(@config.to_yaml)
|
52
55
|
end
|
53
56
|
end
|
54
|
-
|
57
|
+
|
55
58
|
def version
|
56
59
|
Trollolo::VERSION
|
57
60
|
end
|
58
61
|
|
62
|
+
private
|
63
|
+
|
64
|
+
def scrum_defaults
|
65
|
+
{
|
66
|
+
"board_names" => {
|
67
|
+
"planning" => "Planning Board",
|
68
|
+
"sprint" => "Sprint Board"
|
69
|
+
},
|
70
|
+
"label_names" => {
|
71
|
+
"sticky" => "Sticky",
|
72
|
+
"waterline" => "Under waterline"
|
73
|
+
},
|
74
|
+
"list_names" => {
|
75
|
+
"sprint_backlog" => "Sprint Backlog",
|
76
|
+
"sprint_qa" => "QA",
|
77
|
+
"sprint_doing" => "Doing",
|
78
|
+
"planning_backlog" => "Backlog",
|
79
|
+
"planning_ready" => "Ready for Estimation"
|
80
|
+
},
|
81
|
+
}.freeze
|
82
|
+
end
|
59
83
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class TrelloService
|
2
|
+
attr_reader :settings
|
3
|
+
|
4
|
+
def initialize(settings)
|
5
|
+
@settings = settings
|
6
|
+
init_trello
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.find_list(board_id, name)
|
10
|
+
board = Trello::Board.find(board_id)
|
11
|
+
return board, board.lists.find { |l| l.name == name }
|
12
|
+
end
|
13
|
+
|
14
|
+
protected
|
15
|
+
|
16
|
+
def init_trello
|
17
|
+
Trello.configure do |config|
|
18
|
+
config.developer_public_key = @settings.developer_public_key
|
19
|
+
config.member_token = @settings.member_token
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/trello_wrapper.rb
CHANGED
@@ -16,34 +16,24 @@
|
|
16
16
|
# you may find current contact information at www.suse.com
|
17
17
|
require 'trello'
|
18
18
|
|
19
|
-
class TrelloWrapper
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
def initialize(settings)
|
24
|
-
@settings = settings
|
25
|
-
init_trello
|
19
|
+
class TrelloWrapper < TrelloService
|
20
|
+
def board(board_id)
|
21
|
+
@board ||= ScrumBoard.new(retrieve_board_data(board_id), @settings)
|
26
22
|
end
|
27
23
|
|
28
24
|
def client
|
29
|
-
Trello::Client.new(
|
25
|
+
@client ||= Trello::Client.new(
|
30
26
|
developer_public_key: @settings.developer_public_key,
|
31
27
|
member_token: @settings.member_token
|
32
28
|
)
|
33
29
|
end
|
34
30
|
|
35
|
-
def board(board_id)
|
36
|
-
return @board if @board
|
37
|
-
|
38
|
-
@board = ScrumBoard.new(retrieve_board_data(board_id), @settings)
|
39
|
-
end
|
40
|
-
|
41
31
|
def retrieve_board_data(board_id)
|
42
|
-
JSON.parse(
|
32
|
+
JSON.parse(get_board(board_id))
|
43
33
|
end
|
44
34
|
|
45
35
|
def backup(board_id)
|
46
|
-
|
36
|
+
get_board(board_id)
|
47
37
|
end
|
48
38
|
|
49
39
|
def organization(org_id)
|
@@ -88,13 +78,9 @@ class TrelloWrapper
|
|
88
78
|
client.put("/cards/#{card_id}/name?value=#{name}")
|
89
79
|
end
|
90
80
|
|
91
|
-
|
81
|
+
def get_board(board_id)
|
82
|
+
raise TrolloloError.new("Board id cannot be blank") if board_id.blank?
|
92
83
|
|
93
|
-
|
94
|
-
Trello.configure do |config|
|
95
|
-
config.developer_public_key = @settings.developer_public_key
|
96
|
-
config.member_token = @settings.member_token
|
97
|
-
end
|
84
|
+
client.get("/boards/#{board_id}?lists=open&cards=open&card_checklists=all")
|
98
85
|
end
|
99
|
-
|
100
86
|
end
|
data/lib/trollolo.rb
CHANGED
@@ -27,13 +27,14 @@ require_relative 'settings'
|
|
27
27
|
require_relative 'column'
|
28
28
|
require_relative 'card'
|
29
29
|
require_relative 'scrum_board'
|
30
|
+
require_relative 'trello_service'
|
30
31
|
require_relative 'trello_wrapper'
|
31
32
|
require_relative 'burndown_chart'
|
32
33
|
require_relative 'burndown_data'
|
33
34
|
require_relative 'backup'
|
34
35
|
require_relative 'checklist'
|
35
|
-
require_relative '
|
36
|
-
require_relative '
|
36
|
+
require_relative 'scrum'
|
37
|
+
require_relative 'empty_column'
|
37
38
|
|
38
39
|
class TrolloloError < StandardError
|
39
40
|
end
|
data/lib/version.rb
CHANGED
data/man/trollolo.1.md
CHANGED
@@ -23,7 +23,10 @@ and cards and has functionality for extracting data for burndown charts.
|
|
23
23
|
|
24
24
|
* `--board-id`:
|
25
25
|
Most commands take a `board-id` parameter. This is the id of the Trello
|
26
|
-
board. It is the cryptic part of the URL of the Trello board.
|
26
|
+
board. It is the cryptic part of the URL of the Trello board. Since the
|
27
|
+
actual id is hard to remember, you can set an alias in the `.trollolorc`
|
28
|
+
file and use that instead of the actual id.
|
29
|
+
See [CONFIGURATION](#CONFIGURATION) section below.
|
27
30
|
|
28
31
|
* `--raw`:
|
29
32
|
Some of the commands take a `raw` option. If this is provided the commands
|
@@ -126,6 +129,24 @@ in the Trello API documentation.
|
|
126
129
|
|
127
130
|
The board id is the cryptic string in the URL of your board.
|
128
131
|
|
132
|
+
The `.trollolorc` file can also be used to set aliases for board ids. When set,
|
133
|
+
you will be able to use the alias instead of the board-id in the various
|
134
|
+
commands. E.g.
|
135
|
+
|
136
|
+
With the following configuration
|
137
|
+
|
138
|
+
```
|
139
|
+
board_aliases:
|
140
|
+
MyTrelloBoard: 53186e8391ef8671265ebf9e
|
141
|
+
|
142
|
+
```
|
143
|
+
|
144
|
+
You can issue the command:
|
145
|
+
|
146
|
+
```
|
147
|
+
trollolo get-cards --board-id=MyTrelloBoard
|
148
|
+
```
|
149
|
+
|
129
150
|
|
130
151
|
## CONVENTIONS FOR SCRUM BOARDS
|
131
152
|
|
data/spec/data/board.json
CHANGED
@@ -18,7 +18,6 @@
|
|
18
18
|
"cardAging": "regular",
|
19
19
|
"calendarFeedEnabled": false,
|
20
20
|
"background": "5319bb612fb0bcdf451401a8",
|
21
|
-
"backgroundColor": null,
|
22
21
|
"backgroundImage": "https://trello-backgrounds.s3.amazonaws.com/4e727168cb2ac700002cf6b6/990df8f044b98679ccbef943beff54d6/4268316033_6d847a0219_b.jpg",
|
23
22
|
"backgroundImageScaled": [
|
24
23
|
{
|
@@ -44,9 +43,9 @@
|
|
44
43
|
],
|
45
44
|
"backgroundTile": false,
|
46
45
|
"backgroundBrightness": "light",
|
47
|
-
"canBePublic":
|
48
|
-
"canBeOrg":
|
49
|
-
"canBePrivate":
|
46
|
+
"canBePublic": true,
|
47
|
+
"canBeOrg": true,
|
48
|
+
"canBePrivate": true,
|
50
49
|
"canInvite": true
|
51
50
|
},
|
52
51
|
"labelNames": {
|