troo 0.0.1 → 0.0.2

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 (159) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +7 -0
  3. data/.ruby-version +1 -0
  4. data/Gemfile +0 -1
  5. data/Guardfile +6 -0
  6. data/LICENSE.txt +1 -0
  7. data/README.md +46 -3
  8. data/Rakefile +11 -0
  9. data/bin/troo +12 -0
  10. data/configuration.yml.example +7 -0
  11. data/features/add_board.feature +1 -0
  12. data/features/add_card.feature +1 -0
  13. data/features/add_comment.feature +1 -0
  14. data/features/add_list.feature +1 -0
  15. data/features/cleanup.feature +0 -0
  16. data/features/move_card_to_list.feature +1 -0
  17. data/features/refresh.feature +1 -0
  18. data/features/set_default.feature +7 -0
  19. data/features/show_board.feature +1 -0
  20. data/features/show_boards.feature +1 -0
  21. data/features/show_card.feature +1 -0
  22. data/features/show_comments.feature +1 -0
  23. data/features/show_list.feature +1 -0
  24. data/features/status.feature +1 -0
  25. data/features/step_definitions/troo_steps.rb +0 -0
  26. data/features/support/env.rb +31 -0
  27. data/features/troo.feature +1 -0
  28. data/features/version.feature +8 -0
  29. data/lib/troo.rb +24 -2
  30. data/lib/troo/actions/create_board.rb +43 -0
  31. data/lib/troo/actions/create_card.rb +43 -0
  32. data/lib/troo/actions/create_comment.rb +44 -0
  33. data/lib/troo/actions/create_list.rb +41 -0
  34. data/lib/troo/actions/move_card.rb +36 -0
  35. data/lib/troo/actions/refresh_all.rb +79 -0
  36. data/lib/troo/actions/set_default.rb +35 -0
  37. data/lib/troo/cli/add_cli.rb +83 -0
  38. data/lib/troo/cli/default_cli.rb +37 -0
  39. data/lib/troo/cli/main_cli.rb +130 -0
  40. data/lib/troo/cli/show_cli.rb +83 -0
  41. data/lib/troo/cli/thor_fixes.rb +9 -0
  42. data/lib/troo/display/board_decorator.rb +58 -0
  43. data/lib/troo/display/board_presenter.rb +65 -0
  44. data/lib/troo/display/card_decorator.rb +105 -0
  45. data/lib/troo/display/card_presenter.rb +27 -0
  46. data/lib/troo/display/comment_decorator.rb +32 -0
  47. data/lib/troo/display/comment_presenter.rb +35 -0
  48. data/lib/troo/display/decorator_helpers.rb +76 -0
  49. data/lib/troo/display/list_decorator.rb +53 -0
  50. data/lib/troo/display/list_presenter.rb +43 -0
  51. data/lib/troo/display/member_decorator.rb +24 -0
  52. data/lib/troo/display/member_presenter.rb +59 -0
  53. data/lib/troo/external/board.rb +49 -0
  54. data/lib/troo/external/board_adaptor.rb +43 -0
  55. data/lib/troo/external/card.rb +70 -0
  56. data/lib/troo/external/card_adaptor.rb +78 -0
  57. data/lib/troo/external/comment.rb +64 -0
  58. data/lib/troo/external/comment_adaptor.rb +53 -0
  59. data/lib/troo/external/list.rb +58 -0
  60. data/lib/troo/external/list_adaptor.rb +48 -0
  61. data/lib/troo/external/member.rb +52 -0
  62. data/lib/troo/external/member_adaptor.rb +63 -0
  63. data/lib/troo/models/board.rb +26 -0
  64. data/lib/troo/models/board_persistence.rb +53 -0
  65. data/lib/troo/models/board_retrieval.rb +45 -0
  66. data/lib/troo/models/card.rb +54 -0
  67. data/lib/troo/models/card_persistence.rb +53 -0
  68. data/lib/troo/models/card_retrieval.rb +49 -0
  69. data/lib/troo/models/comment.rb +32 -0
  70. data/lib/troo/models/comment_persistence.rb +53 -0
  71. data/lib/troo/models/comment_retrieval.rb +32 -0
  72. data/lib/troo/models/list.rb +27 -0
  73. data/lib/troo/models/list_persistence.rb +53 -0
  74. data/lib/troo/models/list_retrieval.rb +45 -0
  75. data/lib/troo/models/member.rb +18 -0
  76. data/lib/troo/models/member_persistence.rb +53 -0
  77. data/lib/troo/models/member_retrieval.rb +36 -0
  78. data/lib/troo/models/model_helpers.rb +32 -0
  79. data/lib/troo/models/refresh.rb +23 -0
  80. data/lib/troo/presentation/template.rb +31 -0
  81. data/lib/troo/troo.rb +69 -0
  82. data/lib/troo/version.rb +2 -1
  83. data/lib/troo/views/card.erb +17 -0
  84. data/lib/troo/views/comment.erb +3 -0
  85. data/logs/.gitkeep +0 -0
  86. data/test/cassettes/board_by_id.yml +59 -0
  87. data/test/cassettes/boards_all.yml +118 -0
  88. data/test/cassettes/card_by_card_id.yml +58 -0
  89. data/test/cassettes/cards_by_board_id.yml +117 -0
  90. data/test/cassettes/cards_by_list_id.yml +114 -0
  91. data/test/cassettes/comments_by_board_id.yml +122 -0
  92. data/test/cassettes/comments_by_card_id.yml +114 -0
  93. data/test/cassettes/comments_by_list_id.yml +109 -0
  94. data/test/cassettes/create_board.yml +62 -0
  95. data/test/cassettes/create_card.yml +63 -0
  96. data/test/cassettes/create_comment.yml +67 -0
  97. data/test/cassettes/create_list.yml +60 -0
  98. data/test/cassettes/list_by_list_id.yml +56 -0
  99. data/test/cassettes/lists_by_board_id.yml +118 -0
  100. data/test/cassettes/member_by_member_id.yml +60 -0
  101. data/test/cassettes/members_by_board_id.yml +109 -0
  102. data/test/cassettes/move_card.yml +61 -0
  103. data/test/lib/troo/actions/create_board_test.rb +47 -0
  104. data/test/lib/troo/actions/create_card_test.rb +54 -0
  105. data/test/lib/troo/actions/create_comment_test.rb +49 -0
  106. data/test/lib/troo/actions/create_list_test.rb +49 -0
  107. data/test/lib/troo/actions/move_card_test.rb +46 -0
  108. data/test/lib/troo/actions/refresh_all_test.rb +68 -0
  109. data/test/lib/troo/actions/set_default_test.rb +44 -0
  110. data/test/lib/troo/cli/add_cli_test.rb +216 -0
  111. data/test/lib/troo/cli/default_cli_test.rb +79 -0
  112. data/test/lib/troo/cli/main_cli_test.rb +232 -0
  113. data/test/lib/troo/cli/show_cli_test.rb +221 -0
  114. data/test/lib/troo/cli/thor_fixes_test.rb +21 -0
  115. data/test/lib/troo/display/board_decorator_test.rb +126 -0
  116. data/test/lib/troo/display/board_presenter_test.rb +77 -0
  117. data/test/lib/troo/display/card_decorator_test.rb +221 -0
  118. data/test/lib/troo/display/card_presenter_test.rb +38 -0
  119. data/test/lib/troo/display/comment_decorator_test.rb +65 -0
  120. data/test/lib/troo/display/comment_presenter_test.rb +47 -0
  121. data/test/lib/troo/display/decorator_helpers_test.rb +7 -0
  122. data/test/lib/troo/display/list_decorator_test.rb +98 -0
  123. data/test/lib/troo/display/list_presenter_test.rb +48 -0
  124. data/test/lib/troo/display/member_decorator_test.rb +42 -0
  125. data/test/lib/troo/display/member_presenter_test.rb +70 -0
  126. data/test/lib/troo/external/board_adaptor_test.rb +36 -0
  127. data/test/lib/troo/external/board_test.rb +69 -0
  128. data/test/lib/troo/external/card_adaptor_test.rb +50 -0
  129. data/test/lib/troo/external/card_test.rb +108 -0
  130. data/test/lib/troo/external/comment_adaptor_test.rb +41 -0
  131. data/test/lib/troo/external/comment_test.rb +88 -0
  132. data/test/lib/troo/external/list_adaptor_test.rb +38 -0
  133. data/test/lib/troo/external/list_test.rb +65 -0
  134. data/test/lib/troo/external/member_adaptor_test.rb +44 -0
  135. data/test/lib/troo/external/member_test.rb +65 -0
  136. data/test/lib/troo/models/board_persistence_test.rb +61 -0
  137. data/test/lib/troo/models/board_retrieval_test.rb +93 -0
  138. data/test/lib/troo/models/board_test.rb +50 -0
  139. data/test/lib/troo/models/card_persistence_test.rb +60 -0
  140. data/test/lib/troo/models/card_retrieval_test.rb +101 -0
  141. data/test/lib/troo/models/card_test.rb +102 -0
  142. data/test/lib/troo/models/comment_persistence_test.rb +65 -0
  143. data/test/lib/troo/models/comment_retrieval_test.rb +46 -0
  144. data/test/lib/troo/models/comment_test.rb +59 -0
  145. data/test/lib/troo/models/list_persistence_test.rb +60 -0
  146. data/test/lib/troo/models/list_retrieval_test.rb +93 -0
  147. data/test/lib/troo/models/list_test.rb +53 -0
  148. data/test/lib/troo/models/member_persistence_test.rb +59 -0
  149. data/test/lib/troo/models/member_retrieval_test.rb +58 -0
  150. data/test/lib/troo/models/member_test.rb +44 -0
  151. data/test/lib/troo/models/model_helpers_test.rb +103 -0
  152. data/test/lib/troo/models/refresh_test.rb +45 -0
  153. data/test/lib/troo/presentation/template_test.rb +40 -0
  154. data/test/support/fabrication.rb +56 -0
  155. data/test/support/template.erb +3 -0
  156. data/test/support/vcr_setup.rb +36 -0
  157. data/test/test_helper.rb +30 -0
  158. data/troo.gemspec +24 -5
  159. metadata +501 -23
@@ -0,0 +1,36 @@
1
+ module Troo
2
+ class MoveCard
3
+ class << self
4
+ def with(card, list)
5
+ new(card, list).perform
6
+ end
7
+ end
8
+
9
+ def initialize(card, list)
10
+ @card = card
11
+ @list = list
12
+ end
13
+
14
+ def perform
15
+ return update_cards if move_card
16
+ false
17
+ end
18
+
19
+ private
20
+ attr_reader :card, :list
21
+
22
+ def update_cards
23
+ Troo::External::Card.fetch(card.external_board_id)
24
+ end
25
+
26
+ def move_card
27
+ Trello::Card.new.
28
+ update_fields({ 'id' => card.external_card_id }).
29
+ move_to_list(list.external_list_id)
30
+ rescue Trello::InvalidAccessToken
31
+ raise Troo::InvalidAccessToken
32
+ rescue Trello::Error
33
+ false
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,79 @@
1
+ module Troo
2
+ class RefreshAll
3
+ class << self
4
+ def all(board = nil, options = {})
5
+ new(board, options).all
6
+ end
7
+
8
+ def default(board, options = {})
9
+ new(board, options).default
10
+ end
11
+
12
+ def lists(board, options = {})
13
+ new(board, options).lists
14
+ end
15
+
16
+ def cards(board, options = {})
17
+ new(board, options).cards
18
+ end
19
+ end
20
+
21
+ def initialize(board = nil, options = {})
22
+ @board = board
23
+ @options = options
24
+ end
25
+
26
+ def all
27
+ external_board_ids.map do |external_board_id|
28
+ External::List.fetch(external_board_id, options)
29
+ External::Member.fetch(external_board_id, options)
30
+ External::Card.fetch(external_board_id, options)
31
+ end
32
+ true
33
+ end
34
+
35
+ def default
36
+ new_lists = External::List.fetch(external_board_id, options)
37
+ new_cards = new_lists.map do |list|
38
+ External::Card.fetch(list.external_list_id, { mode: :list })
39
+ end
40
+ External::Member.fetch(external_board_id, options)
41
+ true
42
+ end
43
+
44
+ def lists
45
+ External::List.fetch(external_board_id, options)
46
+ end
47
+
48
+ def cards
49
+ External::Card.fetch(external_board_id, options)
50
+ end
51
+
52
+ private
53
+ attr_accessor :board
54
+
55
+ def options
56
+ defaults.merge!(@options)
57
+ end
58
+
59
+ def defaults
60
+ { mode: :board, debug: false }
61
+ end
62
+
63
+ def external_board_id
64
+ board.external_board_id
65
+ end
66
+
67
+ def external_board_ids
68
+ active_boards.map(&:external_board_id)
69
+ end
70
+
71
+ def active_boards
72
+ all_boards.delete_if { |b| b.nil? || b.closed == true }
73
+ end
74
+
75
+ def all_boards
76
+ @boards ||= External::Board.fetch_all
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,35 @@
1
+ module Troo
2
+ class SetDefault
3
+ class << self
4
+ def for(entity)
5
+ new(entity).set_default!
6
+ end
7
+ end
8
+
9
+ def initialize(entity)
10
+ @entity = entity
11
+ end
12
+
13
+ def set_default!
14
+ return false if already_default?
15
+ unset_default
16
+ set_new_default
17
+ entity
18
+ end
19
+
20
+ private
21
+ attr_reader :entity
22
+
23
+ def set_new_default
24
+ entity.update(default: true)
25
+ end
26
+
27
+ def unset_default
28
+ entity.class.update(default: false)
29
+ end
30
+
31
+ def already_default?
32
+ entity.default?
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,83 @@
1
+ module Troo
2
+ module CLI
3
+ class Add < ThorFixes
4
+ package_name "add"
5
+
6
+ desc "board <name> (<description>)",
7
+ "Add a new board with <name> and optional <description>."
8
+ def board(name = nil, description = nil)
9
+ if name.nil?
10
+ name = ask("Please enter a name for this board:")
11
+ end
12
+
13
+ if result = Troo::CreateBoard.with(name, description)
14
+ say "New board '#{result.name}' created."
15
+ else
16
+ say "Board could not be created."
17
+ end
18
+ rescue Troo::InvalidAccessToken
19
+ say "Your Trello access credentials have expired, please renew and try again."
20
+ end
21
+
22
+ desc "card <list_id> <name> (<description>)",
23
+ "Add a new card to <list_id> with <name> and optional <description>."
24
+ def card(list_id, name = nil, description = nil)
25
+ if name.nil?
26
+ name = ask("Please enter a name for this card:")
27
+ end
28
+
29
+ if list = Troo::ListRetrieval.retrieve(list_id)
30
+ if result = Troo::CreateCard.for(list, name, description)
31
+ say "New card '#{result.name}' created."
32
+ else
33
+ say "Card could not be created."
34
+ end
35
+ else
36
+ say "Card could not be created, as list was not found."
37
+ end
38
+ rescue Troo::InvalidAccessToken
39
+ say "Your Trello access credentials have expired, please renew and try again."
40
+ end
41
+
42
+ desc "comment <card_id> <comment>",
43
+ "Add a new comment to <card_id>."
44
+ def comment(card_id, comment = nil)
45
+ if comment.nil?
46
+ comment = ask("Please enter a comment:")
47
+ end
48
+
49
+ if card = Troo::CardRetrieval.retrieve(card_id)
50
+ if Troo::CreateComment.for(card, comment)
51
+ say "New comment created."
52
+ else
53
+ say "Comment could not be created."
54
+ end
55
+ else
56
+ say "Comment could not be created, as card was not found."
57
+ end
58
+ rescue Troo::InvalidAccessToken
59
+ say "Your Trello access credentials have expired, please renew and try again."
60
+ end
61
+
62
+ desc "list <board_id> <name>",
63
+ "Add a new list to <board_id> with <name>."
64
+ def list(board_id, name = nil)
65
+ if name.nil?
66
+ name = ask("Please enter a name for this list:")
67
+ end
68
+
69
+ if board = Troo::BoardRetrieval.retrieve(board_id)
70
+ if result = Troo::CreateList.for(board, name)
71
+ say "New list '#{result.name}' created."
72
+ else
73
+ say "List could not be created."
74
+ end
75
+ else
76
+ say "List could not be created, as board was not found."
77
+ end
78
+ rescue Troo::InvalidAccessToken
79
+ say "Your Trello access credentials have expired, please renew and try again."
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,37 @@
1
+ module Troo
2
+ module CLI
3
+ class Default < ThorFixes
4
+ package_name "default"
5
+
6
+ desc "board <board_id>", "Set the board <board_id> to default."
7
+ def board(board_id)
8
+ if board = Troo::BoardRetrieval.retrieve(board_id)
9
+ SetDefault.for(board)
10
+ say "Board '#{board.name}' set to default."
11
+ else
12
+ say "Board cannot be found."
13
+ end
14
+ end
15
+
16
+ desc "card <card_id>", "Set the card <card_id> to default."
17
+ def card(card_id)
18
+ if card = Troo::CardRetrieval.retrieve(card_id)
19
+ SetDefault.for(card)
20
+ say "Card '#{card.name}' set to default."
21
+ else
22
+ say "Card cannot be found."
23
+ end
24
+ end
25
+
26
+ desc "list <list_id>", "Set the list <list_id> to default."
27
+ def list(list_id)
28
+ if list = Troo::ListRetrieval.retrieve(list_id)
29
+ SetDefault.for(list)
30
+ say "List '#{list.name}' set to default."
31
+ else
32
+ say "List cannot be found."
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,130 @@
1
+ module Troo
2
+ module CLI
3
+ class Main < ThorFixes
4
+ default_task :status
5
+
6
+ class_option :debug, type: :boolean, desc: "Enable debugging."
7
+
8
+ desc "status", "Get troo status."
9
+ def status
10
+ board_count = Troo::Board.count
11
+ list_count = Troo::List.count
12
+ card_count = Troo::Card.count
13
+
14
+ if board_count > 0
15
+ if board = Troo::BoardRetrieval.default
16
+ say "Board: #{BoardDecorator.new(board).short}"
17
+ else
18
+ say "Board: No default set."
19
+ end
20
+ else
21
+ say "No local board data."
22
+ end
23
+
24
+ if list_count > 0
25
+ if list = Troo::ListRetrieval.default
26
+ say "List: #{ListDecorator.new(list).short}"
27
+ else
28
+ say "List: No default set."
29
+ end
30
+ else
31
+ say "No local list data."
32
+ end
33
+
34
+ if card_count > 0
35
+ if card = Troo::CardRetrieval.default
36
+ say "Card: #{CardDecorator.new(card).short}"
37
+ else
38
+ say "Card: No default set."
39
+ end
40
+ else
41
+ say "No local card data."
42
+ end
43
+
44
+ puts [plural(board_count, "board"),
45
+ plural(list_count, "list"),
46
+ plural(card_count, "card") ].join(", ")
47
+ puts
48
+
49
+ help
50
+ end
51
+
52
+ private
53
+
54
+ def plural(size, singular)
55
+ (size == 1) ? "#{size} #{singular}" : "#{size} #{singular}s"
56
+ end
57
+
58
+ public
59
+
60
+ desc "refresh", "Refresh all data for default board."
61
+ method_option :all, type: :boolean, desc: "Refresh all boards, lists, cards and comments."
62
+ method_option :lists, type: :boolean, desc: "Refresh all lists for default board."
63
+ method_option :cards, type: :boolean, desc: "Refresh all cards for default board."
64
+ def refresh
65
+ if options["all"]
66
+ RefreshAll.all(nil, options)
67
+ say "All local data has been refreshed."
68
+ else
69
+ if board = Troo::BoardRetrieval.default
70
+ if options["lists"]
71
+ RefreshAll.lists(board, options)
72
+ say "All lists for the default board have been refreshed."
73
+ elsif options["cards"]
74
+ RefreshAll.cards(board, options)
75
+ say "All cards for the default board have been refreshed."
76
+ else
77
+ RefreshAll.default(board, options)
78
+ say "All data for the default board has been refreshed."
79
+ end
80
+ else
81
+ say "Use 'troo default board <board_id>' to set a default board first."
82
+ end
83
+ end
84
+ rescue Troo::InvalidAccessToken
85
+ say "Your Trello access credentials have expired, please renew and try again."
86
+ end
87
+
88
+ desc "cleanup", "Removes all local data."
89
+ def cleanup
90
+ if yes?("This will remove all local data, are you sure?")
91
+ Ohm.redis.flushdb
92
+ say "All local data has been removed."
93
+ end
94
+ end
95
+
96
+ desc "version", "Print the version."
97
+ def version
98
+ say "troo #{Troo::VERSION}"
99
+ end
100
+
101
+ desc "show [board|list|card|comment] <id>", "Show the board, list, card or comment with <id>."
102
+ subcommand :show, Troo::CLI::Show
103
+
104
+ desc "add [board|list|card|comment] <id>", "Add board, list, card or comment."
105
+ subcommand :add, Troo::CLI::Add
106
+
107
+ desc "default [board|list|card] <id>", "Set board, list or card to be default."
108
+ subcommand :default, Troo::CLI::Default
109
+
110
+ desc "move <card_id> <list_id>", "Move a card <card_id> to list <list_id>."
111
+ def move(card_id, list_id)
112
+ if card = Troo::CardRetrieval.retrieve(card_id)
113
+ if list = Troo::ListRetrieval.retrieve(list_id)
114
+ if result = MoveCard.with(card, list)
115
+ say "Card moved from '#{card.list.name}' to '#{list.name}'."
116
+ else
117
+ say "Card could not be moved."
118
+ end
119
+ else
120
+ say "Card could not be moved, as list was not found."
121
+ end
122
+ else
123
+ say "Card could not be moved, as card was not found."
124
+ end
125
+ rescue Troo::InvalidAccessToken
126
+ say "Your Trello access credentials have expired, please renew and try again."
127
+ end
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,83 @@
1
+ module Troo
2
+ module CLI
3
+ class Show < ThorFixes
4
+ package_name "show"
5
+
6
+ desc "boards", "Show all the boards with lists."
7
+ def boards
8
+ boards = Troo::BoardRetrieval.all
9
+ if boards.any?
10
+ boards.map do |board|
11
+ BoardPresenter.render_all(board)
12
+ end
13
+ else
14
+ say "Boards not found."
15
+ end
16
+ end
17
+
18
+ desc "board (<board_id>)", "Show lists and cards for board <board_id> (uses default board if <board_id> not provided)."
19
+ def board(board_id = nil)
20
+ if board = Troo::BoardRetrieval.retrieve(board_id)
21
+ if SetDefault.for(board)
22
+ say "'#{board.name}' set to default."
23
+ end
24
+ BoardPresenter.render_show(board)
25
+ else
26
+ if board_id
27
+ say "Board not found."
28
+ else
29
+ say "Specify a <board_id> or use 'troo default board <board_id>' to set a default board first."
30
+ end
31
+ end
32
+ end
33
+
34
+ desc "list (<list_id>)", "Show all cards for list <list_id> (uses default list if <list_id> not provided)."
35
+ def list(list_id = nil)
36
+ if list = Troo::ListRetrieval.retrieve(list_id)
37
+ if SetDefault.for(list)
38
+ say "'#{list.name}' set to default."
39
+ end
40
+ ListPresenter.render_show(list)
41
+ else
42
+ if list_id
43
+ say "List not found."
44
+ else
45
+ say "Specify a <list_id> or use 'troo default list <list_id>' to set a default list first."
46
+ end
47
+ end
48
+ end
49
+
50
+ desc "card (<card_id>)", "Show a card including latest 3 comments for card <card_id> (uses default card if <card_id> not provided)."
51
+ def card(card_id = nil)
52
+ if card = Troo::CardRetrieval.retrieve(card_id)
53
+ if SetDefault.for(card)
54
+ say "'#{card.name}' set to default."
55
+ end
56
+ CardPresenter.render_show(card)
57
+ else
58
+ if card_id
59
+ say "Card not found."
60
+ else
61
+ say "Specify a <card_id> or use 'troo default card <card_id>' to set a default card first."
62
+ end
63
+ end
64
+ end
65
+
66
+ desc "comments (<card_id>)", "Show all comments for card <card_id> (uses default card if <card_id> not provided)."
67
+ def comments(card_id = nil)
68
+ if card = Troo::CardRetrieval.retrieve(card_id)
69
+ if SetDefault.for(card)
70
+ say "'#{card.name}' set to default."
71
+ end
72
+ CommentPresenter.render_show(card)
73
+ else
74
+ if card_id
75
+ say "Card not found."
76
+ else
77
+ say "Specify a <card_id> or use 'troo default card <card_id>' to set a default card first."
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end