trollolo 0.0.9 → 0.0.10
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 +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": {
|