trollolo 0.0.9 → 0.0.10

Sign up to get free protection for your applications and to get access to all the features.
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": {