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.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +14 -0
  3. data/Gemfile +1 -1
  4. data/README.md +97 -0
  5. data/lib/card.rb +0 -14
  6. data/lib/cli.rb +66 -27
  7. data/lib/empty_column.rb +5 -0
  8. data/lib/scrum/backlog_mover.rb +47 -0
  9. data/lib/scrum/card_type_detection.rb +23 -0
  10. data/lib/scrum/creator.rb +30 -0
  11. data/lib/scrum/prioritizer.rb +24 -0
  12. data/lib/scrum/priority_name.rb +15 -0
  13. data/lib/scrum/scrum_boards.rb +11 -0
  14. data/lib/scrum/sprint_board.rb +82 -0
  15. data/lib/scrum/sprint_cleaner.rb +41 -0
  16. data/lib/scrum/sprint_planning_board.rb +26 -0
  17. data/lib/scrum.rb +13 -0
  18. data/lib/scrum_board.rb +17 -7
  19. data/lib/settings.rb +36 -12
  20. data/lib/trello_service.rb +22 -0
  21. data/lib/trello_wrapper.rb +9 -23
  22. data/lib/trollolo.rb +3 -2
  23. data/lib/version.rb +1 -1
  24. data/man/trollolo.1.md +22 -1
  25. data/spec/data/board.json +3 -4
  26. data/spec/data/full-board-with-accepted.json +1817 -0
  27. data/spec/data/full-board.json +3 -27
  28. data/spec/data/trollolorc +13 -0
  29. data/spec/data/trollolorc_with_board_aliases +9 -0
  30. data/spec/data/vcr/creator_custom_config.yml +824 -0
  31. data/spec/data/vcr/creator_default_config.yml +824 -0
  32. data/spec/data/vcr/move_backlog.yml +2375 -0
  33. data/spec/data/vcr/move_backlog_missing_backlog.yml +155 -0
  34. data/spec/data/vcr/move_backlog_missing_waterbed.yml +364 -0
  35. data/spec/data/vcr/prioritize_backlog_list.yml +2335 -0
  36. data/spec/data/vcr/prioritize_no_backlog_list.yml +190 -0
  37. data/spec/data/vcr/sprint_board.yml +624 -0
  38. data/spec/data/vcr/sprint_board_no_waterline.yml +556 -0
  39. data/spec/data/vcr/sprint_cleanup.yml +1239 -7500
  40. data/spec/data/vcr/sprint_planning_board.yml +239 -0
  41. data/spec/integration/create_burndown_spec.rb +1 -1
  42. data/spec/unit/card_spec.rb +0 -41
  43. data/spec/unit/cli_spec.rb +74 -1
  44. data/spec/unit/empty_column_spec.rb +9 -0
  45. data/spec/unit/scrum/backlog_mover_spec.rb +26 -0
  46. data/spec/unit/scrum/card_type_detection_spec.rb +35 -0
  47. data/spec/unit/scrum/creator_spec.rb +23 -0
  48. data/spec/unit/scrum/prioritizer_spec.rb +45 -0
  49. data/spec/unit/scrum/priority_name_spec.rb +35 -0
  50. data/spec/unit/scrum/sprint_board_spec.rb +22 -0
  51. data/spec/unit/scrum/sprint_cleaner_spec.rb +26 -0
  52. data/spec/unit/scrum/sprint_planning_board_spec.rb +14 -0
  53. data/spec/unit/scrum_board_spec.rb +90 -0
  54. data/spec/unit/settings_spec.rb +42 -6
  55. data/spec/unit/spec_helper.rb +3 -2
  56. data/spec/unit/support/update_webmock_data +3 -1
  57. data/spec/unit/support/vcr.rb +8 -8
  58. data/spec/unit/support/webmocks.rb +9 -0
  59. data/spec/unit/trello_wrapper_spec.rb +20 -0
  60. data/trollolo.gemspec +2 -1
  61. metadata +52 -9
  62. data/lib/prioritizer.rb +0 -34
  63. data/lib/sprint_cleanup.rb +0 -54
  64. data/spec/unit/prioritizer_spec.rb +0 -47
  65. 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, :verbose, :raw,
21
- :not_done_columns, :todo_column, :done_column_name_regex,
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 = @config["developer_public_key"]
31
- @member_token = @config["member_token"]
32
- @not_done_columns = @config["not_done_columns"].freeze || ["Sprint Backlog", "Doing"]
33
- @todo_column = @config["todo_column"].freeze
34
- @done_column_name_regex = @config["done_column_name_regex"].freeze || /\ADone/
35
- @todo_column_name_regex = @config["todo_column_name_regex"].freeze || /\ATo Do\Z/
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
@@ -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
- attr_accessor :board
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(client.get("/boards/#{board_id}?lists=open&cards=open&card_checklists=all"))
32
+ JSON.parse(get_board(board_id))
43
33
  end
44
34
 
45
35
  def backup(board_id)
46
- client.get("/boards/#{board_id}?lists=open&cards=open&card_checklists=all")
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
- private
81
+ def get_board(board_id)
82
+ raise TrolloloError.new("Board id cannot be blank") if board_id.blank?
92
83
 
93
- def init_trello
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 'prioritizer'
36
- require_relative 'sprint_cleanup'
36
+ require_relative 'scrum'
37
+ require_relative 'empty_column'
37
38
 
38
39
  class TrolloloError < StandardError
39
40
  end
data/lib/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Trollolo
2
2
 
3
- VERSION = "0.0.9"
3
+ VERSION = "0.0.10"
4
4
 
5
5
  end
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": false,
48
- "canBeOrg": false,
49
- "canBePrivate": false,
46
+ "canBePublic": true,
47
+ "canBeOrg": true,
48
+ "canBePrivate": true,
50
49
  "canInvite": true
51
50
  },
52
51
  "labelNames": {