3llo 0.1.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.travis.yml +5 -0
  4. data/3llo.gemspec +29 -0
  5. data/CODE_OF_CONDUCT.md +49 -0
  6. data/Gemfile +7 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +58 -0
  9. data/Rakefile +10 -0
  10. data/bin/3llo +29 -0
  11. data/lib/3llo/api/board.rb +47 -0
  12. data/lib/3llo/api/card.rb +93 -0
  13. data/lib/3llo/api/list.rb +37 -0
  14. data/lib/3llo/api/user.rb +34 -0
  15. data/lib/3llo/api.rb +4 -0
  16. data/lib/3llo/board_command_factory.rb +29 -0
  17. data/lib/3llo/card_command_factory.rb +49 -0
  18. data/lib/3llo/client.rb +62 -0
  19. data/lib/3llo/command_factory.rb +40 -0
  20. data/lib/3llo/commands/.gitkeep +0 -0
  21. data/lib/3llo/commands/board/invalid.rb +33 -0
  22. data/lib/3llo/commands/board/list.rb +29 -0
  23. data/lib/3llo/commands/board/select.rb +31 -0
  24. data/lib/3llo/commands/card/invalid.rb +36 -0
  25. data/lib/3llo/commands/card/list.rb +37 -0
  26. data/lib/3llo/commands/card/list_mine.rb +30 -0
  27. data/lib/3llo/commands/card/move.rb +43 -0
  28. data/lib/3llo/commands/card/self_assign.rb +31 -0
  29. data/lib/3llo/commands/card/show.rb +29 -0
  30. data/lib/3llo/commands/error.rb +18 -0
  31. data/lib/3llo/commands/exit.rb +16 -0
  32. data/lib/3llo/commands/help.rb +15 -0
  33. data/lib/3llo/commands/invalid.rb +18 -0
  34. data/lib/3llo/commands/list/cards.rb +29 -0
  35. data/lib/3llo/commands/list/invalid.rb +33 -0
  36. data/lib/3llo/commands/list/list.rb +29 -0
  37. data/lib/3llo/configuration.rb +39 -0
  38. data/lib/3llo/controller.rb +35 -0
  39. data/lib/3llo/errors.rb +7 -0
  40. data/lib/3llo/interface.rb +30 -0
  41. data/lib/3llo/list_command_factory.rb +29 -0
  42. data/lib/3llo/presenter/.gitkeep +0 -0
  43. data/lib/3llo/presenter/board/list.rb +25 -0
  44. data/lib/3llo/presenter/card/list.rb +43 -0
  45. data/lib/3llo/presenter/card/list_mine.rb +25 -0
  46. data/lib/3llo/presenter/card/move.rb +25 -0
  47. data/lib/3llo/presenter/card/show.rb +39 -0
  48. data/lib/3llo/presenter/help.rb +38 -0
  49. data/lib/3llo/presenter/list/cards.rb +41 -0
  50. data/lib/3llo/presenter/list/list.rb +25 -0
  51. data/lib/3llo/presenter.rb +8 -0
  52. data/lib/3llo/version.rb +3 -0
  53. data/lib/3llo.rb +14 -0
  54. data/lib/container.rb +24 -0
  55. data/lib/core_ext.rb +41 -0
  56. metadata +100 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 45845f6247206e981300f0213b03d9d5b2e9943b
4
+ data.tar.gz: 8c373c8ce27298abdf54a083d7c80fb03ae27e84
5
+ SHA512:
6
+ metadata.gz: 3e8e2a1142b5859f1bf699732ae39677375fcda06fc003a296a9c91cfc31067f2d6eb16ccfc0432385843dbd05f5628651319226e3743075b756fd2a181428d8
7
+ data.tar.gz: e95778da4d3df83edbcc99b0e07ab1c1858244c95eb5a61a7ad6c0380a3e29d40f21c5b1b0ae9900f8962e6b3074dbf57553ff6bc96cadb367f6b955d75b8c54
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.gem
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.0
5
+ before_install: gem install bundler -v 1.12.5
data/3llo.gemspec ADDED
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require '3llo/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "3llo"
8
+ spec.version = Tr3llo::VERSION
9
+ spec.authors = ["Cẩm Huỳnh"]
10
+ spec.email = ["huynhquancam@gmail.com"]
11
+
12
+ spec.summary = %q{Trello CLI}
13
+ spec.description = %q{CLI for Trello}
14
+ spec.homepage = "https://github.com/qcam/3llo"
15
+ spec.license = "MIT"
16
+
17
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
18
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
19
+ if spec.respond_to?(:metadata)
20
+ spec.metadata['allowed_push_host'] = "https://rubygems.org"
21
+ else
22
+ raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
23
+ end
24
+
25
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/|intro\.gif}) }
26
+ spec.bindir = "bin"
27
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
28
+ spec.require_paths = ["lib"]
29
+ end
@@ -0,0 +1,49 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, and in the interest of
4
+ fostering an open and welcoming community, we pledge to respect all people who
5
+ contribute through reporting issues, posting feature requests, updating
6
+ documentation, submitting pull requests or patches, and other activities.
7
+
8
+ We are committed to making participation in this project a harassment-free
9
+ experience for everyone, regardless of level of experience, gender, gender
10
+ identity and expression, sexual orientation, disability, personal appearance,
11
+ body size, race, ethnicity, age, religion, or nationality.
12
+
13
+ Examples of unacceptable behavior by participants include:
14
+
15
+ * The use of sexualized language or imagery
16
+ * Personal attacks
17
+ * Trolling or insulting/derogatory comments
18
+ * Public or private harassment
19
+ * Publishing other's private information, such as physical or electronic
20
+ addresses, without explicit permission
21
+ * Other unethical or unprofessional conduct
22
+
23
+ Project maintainers have the right and responsibility to remove, edit, or
24
+ reject comments, commits, code, wiki edits, issues, and other contributions
25
+ that are not aligned to this Code of Conduct, or to ban temporarily or
26
+ permanently any contributor for other behaviors that they deem inappropriate,
27
+ threatening, offensive, or harmful.
28
+
29
+ By adopting this Code of Conduct, project maintainers commit themselves to
30
+ fairly and consistently applying these principles to every aspect of managing
31
+ this project. Project maintainers who do not follow or enforce the Code of
32
+ Conduct may be permanently removed from the project team.
33
+
34
+ This code of conduct applies both within project spaces and in public spaces
35
+ when an individual is representing the project or its community.
36
+
37
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
38
+ reported by contacting a project maintainer at huynhquancam@gmail.com. All
39
+ complaints will be reviewed and investigated and will result in a response that
40
+ is deemed necessary and appropriate to the circumstances. Maintainers are
41
+ obligated to maintain confidentiality with regard to the reporter of an
42
+ incident.
43
+
44
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
45
+ version 1.3.0, available at
46
+ [http://contributor-covenant.org/version/1/3/0/][version]
47
+
48
+ [homepage]: http://contributor-covenant.org
49
+ [version]: http://contributor-covenant.org/version/1/3/0/
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in trecli.gemspec
4
+ gemspec
5
+
6
+ gem 'bundler'
7
+ gem 'rake'
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Cẩm Huỳnh
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,58 @@
1
+ # 3llo - Interactive CLI for Trello
2
+
3
+ 3llo is the terminal client for Trello, which helps you manage Trello cards without
4
+ leaving your awesome terminal.
5
+
6
+ [![video](intro.gif)](https://asciinema.org/a/eu1q5el69kub7si79dubeyfn6)
7
+
8
+ 3llo was inspired by the awesome
9
+ [rainbowstream](https://github.com/DTVD/rainbowstream) and
10
+ [facy](https://github.com/huydx/facy).
11
+
12
+ ## Why this named 3llo?
13
+
14
+ Good to know that `3 == "tre"` in Swedish.
15
+
16
+ ## Installation
17
+
18
+ ```ruby
19
+ [sudo] gem install 3llo
20
+ ```
21
+
22
+ You also need to have these environment variables set in your shell.
23
+
24
+ ```
25
+ export TRELLO_USER=your_username
26
+ export TRELLO_KEY=your_key
27
+ export TRELLO_TOKEN=your_token
28
+ ```
29
+
30
+ ## Usage
31
+
32
+ There are a couple of commands available in 3llo.
33
+
34
+ * `board list`: List your board
35
+ * `board select <board_id>`: Select the active board.
36
+ * `card list`: List all cards of the active board.
37
+ * `card list mine`: List all your cards of the active board.
38
+ * `card show <card_id>`: Show card information.
39
+ * `card move <card_id> <list_id>`: Move card to a specified list.
40
+ * `card self-assign <card_id>`: Self-assign a card.
41
+ * `list list`: List all the lists of the active board.
42
+ * `help`: Show help menu.
43
+ * `exit`: Exit.
44
+
45
+ ## Contributing
46
+
47
+ Bug reports and pull requests are welcome on GitHub at https://github.com/qcam/3llo. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
48
+
49
+ ### Development Roadmap
50
+
51
+ * Add card.
52
+ * Archive card.
53
+ * Show card member.
54
+ * Archive all cards in list.
55
+
56
+ ## License
57
+
58
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList['test/**/*_test.rb']
8
+ end
9
+
10
+ task :default => :test
data/bin/3llo ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.expand_path("../../lib", __FILE__)
4
+ require "3llo"
5
+ require 'container'
6
+
7
+ $container = Container.new
8
+ $container.register(:api_client, Tr3llo::Client)
9
+ $container.register(:interface, Tr3llo::Interface.new($stdin, $stdout))
10
+
11
+ configuration = Tr3llo::Configuration.new
12
+ configuration.user_id = ENV.fetch('TRELLO_USER') { raise "Have you set TRELLO_USER?" }
13
+ configuration.api_key = ENV.fetch('TRELLO_KEY') { raise "Have you set TRELLO_KEY?" }
14
+ configuration.api_token = ENV.fetch('TRELLO_TOKEN') { raise "Have you set TRELLO_TOKEN?" }
15
+ configuration.finalize!
16
+
17
+ $container.register(
18
+ :configuration,
19
+ configuration
20
+ )
21
+
22
+ user = Tr3llo::API::User.find($container.resolve(:configuration).user_id)
23
+ $container.register(:user, user)
24
+
25
+ Tr3llo::Presenter::HelpPresenter
26
+ .new($container.resolve(:interface))
27
+ .print!
28
+
29
+ Tr3llo::Controller.new.start
@@ -0,0 +1,47 @@
1
+ module Tr3llo
2
+ module API
3
+ module Board
4
+ extend self
5
+
6
+ def find_all_by_user(user_id)
7
+ JSON.parse(
8
+ client.get(
9
+ "/members/#{user_id}/boards",
10
+ key: api_key,
11
+ token: api_token,
12
+ ),
13
+ symbolize_names: true
14
+ )
15
+ end
16
+
17
+ def find(board_id)
18
+ JSON.parse(
19
+ client.get(
20
+ "/boards/#{board_id}",
21
+ key: api_key,
22
+ token: api_token,
23
+ ),
24
+ symbolize_names: true
25
+ )
26
+ end
27
+
28
+ private
29
+
30
+ def client
31
+ container.resolve(:api_client)
32
+ end
33
+
34
+ def api_key
35
+ container.resolve(:configuration).api_key
36
+ end
37
+
38
+ def api_token
39
+ container.resolve(:configuration).api_token
40
+ end
41
+
42
+ def container
43
+ $container
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,93 @@
1
+ module Tr3llo
2
+ module API
3
+ module Card
4
+ extend self
5
+
6
+ def find_all_by_board(board_id)
7
+ JSON.parse(
8
+ client.get(
9
+ "/boards/#{board_id}/cards",
10
+ key: api_key,
11
+ token: api_token,
12
+ ),
13
+ symbolize_names: true
14
+ )
15
+ end
16
+
17
+ def find_all_by_list(list_id)
18
+ JSON.parse(
19
+ client.get(
20
+ "/lists/#{list_id}/cards",
21
+ key: api_key,
22
+ token: api_token,
23
+ ),
24
+ symbolize_names: true
25
+ )
26
+ end
27
+
28
+ def find_all_by_user(board_id, user_id)
29
+ JSON.parse(
30
+ client.get(
31
+ "/boards/#{board_id}/members/#{user_id}/cards",
32
+ list: true,
33
+ key: api_key,
34
+ token: api_token,
35
+ ),
36
+ symbolize_names: true
37
+ )
38
+ end
39
+
40
+ def find(card_id)
41
+ JSON.parse(
42
+ client.get(
43
+ "/cards/#{card_id}",
44
+ list: true,
45
+ key: api_key,
46
+ token: api_token,
47
+ ),
48
+ symbolize_names: true
49
+ )
50
+ end
51
+
52
+ def move_to_list(card_id, list_id)
53
+ url = "/cards/#{card_id}/idList"
54
+ JSON.parse(
55
+ client.put(
56
+ url,
57
+ key: api_key,
58
+ token: api_token,
59
+ value: list_id
60
+ ),
61
+ symbolize_names: true
62
+ )
63
+ end
64
+
65
+ def assign_members(card_id, members)
66
+ url = "/cards/#{card_id}/idMembers"
67
+ JSON.parse(
68
+ client.put(
69
+ url,
70
+ key: api_key,
71
+ token: api_token,
72
+ value: members.join(',')
73
+ ),
74
+ symbolize_names: true
75
+ )
76
+ end
77
+
78
+ private
79
+
80
+ def api_key
81
+ $container.resolve(:configuration).api_key
82
+ end
83
+
84
+ def api_token
85
+ $container.resolve(:configuration).api_token
86
+ end
87
+
88
+ def client
89
+ $container.resolve(:api_client)
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,37 @@
1
+ module Tr3llo
2
+ module API
3
+ module List
4
+ extend self
5
+
6
+ def find_all_by_board(board_id)
7
+ JSON.parse(
8
+ client.get(
9
+ "/boards/#{board_id}/lists/",
10
+ list: true,
11
+ key: api_key,
12
+ token: api_token
13
+ ),
14
+ symbolize_names: true
15
+ )
16
+ end
17
+
18
+ private
19
+
20
+ def client
21
+ container.resolve(:api_client)
22
+ end
23
+
24
+ def api_key
25
+ container.resolve(:configuration).api_key
26
+ end
27
+
28
+ def api_token
29
+ container.resolve(:configuration).api_token
30
+ end
31
+
32
+ def container
33
+ $container
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,34 @@
1
+ module Tr3llo
2
+ module API
3
+ module User
4
+ extend self
5
+
6
+ def find(user_id)
7
+ url = "/members/#{user_id}"
8
+
9
+ JSON.parse(
10
+ client.get(
11
+ url,
12
+ key: key,
13
+ token: token
14
+ ),
15
+ symbolize_names: true
16
+ )
17
+ end
18
+
19
+ private
20
+
21
+ def key
22
+ $container.resolve(:configuration).api_key
23
+ end
24
+
25
+ def token
26
+ $container.resolve(:configuration).api_token
27
+ end
28
+
29
+ def client
30
+ $container.resolve(:api_client)
31
+ end
32
+ end
33
+ end
34
+ end
data/lib/3llo/api.rb ADDED
@@ -0,0 +1,4 @@
1
+ require '3llo/api/board'
2
+ require '3llo/api/card'
3
+ require '3llo/api/list'
4
+ require '3llo/api/user'
@@ -0,0 +1,29 @@
1
+ require '3llo/commands/board/list'
2
+ require '3llo/commands/board/select'
3
+ require '3llo/commands/board/invalid'
4
+
5
+ module Tr3llo
6
+ class BoardCommandFactory
7
+ def initialize(subcommand, args)
8
+ @subcommand = subcommand
9
+ @args = args
10
+ end
11
+
12
+ def factory
13
+ case subcommand.to_sym
14
+ when :list
15
+ user_id = $container.resolve(:user)[:id]
16
+ Command::Board::ListCommand.new(user_id)
17
+ when :select
18
+ board_id, _ = args
19
+ Command::Board::SelectCommand.new(board_id)
20
+ else
21
+ Command::Board::InvalidCommand.new
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ attr_reader :subcommand, :args
28
+ end
29
+ end
@@ -0,0 +1,49 @@
1
+ require '3llo/commands/card/list'
2
+ require '3llo/commands/card/list_mine'
3
+ require '3llo/commands/card/show'
4
+ require '3llo/commands/card/move'
5
+ require '3llo/commands/card/self_assign'
6
+ require '3llo/commands/card/invalid'
7
+
8
+ module Tr3llo
9
+ class CardCommandFactory
10
+ def initialize(subcommand, args)
11
+ @subcommand = subcommand
12
+ @args = args
13
+ end
14
+
15
+ def factory
16
+ case subcommand
17
+ when 'list'
18
+ is_mine, _ = *args
19
+ board_id = $container.resolve(:board)[:id]
20
+
21
+ if is_mine == 'mine'
22
+ user_id = $container.resolve(:user)[:id]
23
+ Command::Card::ListMineCommand.new(board_id, user_id)
24
+ else
25
+ Command::Card::ListCommand.new(board_id)
26
+ end
27
+ when 'show'
28
+ card_id, _ = args
29
+ Command::Card::ShowCommand.new(card_id)
30
+ when 'move'
31
+ card_id, list_id = args
32
+ board_id = $container.resolve(:board)[:id]
33
+ Command::Card::MoveCommand.new(card_id, list_id, board_id)
34
+ when 'self-assign'
35
+ card_id, _ = args
36
+ user_id = $container.resolve(:user)[:id]
37
+ Command::Card::SelfAssignCommand.new(card_id, user_id)
38
+ else
39
+ Command::Card::InvalidCommand.new
40
+ end
41
+ rescue Container::KeyNotFoundError
42
+ Command::ErrorCommand.new
43
+ end
44
+
45
+ private
46
+
47
+ attr_reader :subcommand, :args
48
+ end
49
+ end
@@ -0,0 +1,62 @@
1
+ require 'uri'
2
+ require 'net/http'
3
+ require 'openssl'
4
+
5
+ module Tr3llo
6
+ module Client
7
+ extend self
8
+
9
+ BASE_URL = "https://api.trello.com/1"
10
+
11
+ class RequestError < RuntimeError
12
+ attr_reader :response
13
+
14
+ def initialize(response)
15
+ @response = response
16
+ super()
17
+ end
18
+
19
+ def message
20
+ "Request error: #{response}"
21
+ end
22
+ end
23
+
24
+ def get(path, params = {})
25
+ uri = URI("#{BASE_URL}#{path}?#{query_string(params)}")
26
+
27
+ http = Net::HTTP.new(uri.host, uri.port)
28
+ http.use_ssl = true
29
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
30
+ request = Net::HTTP::Get.new(uri.request_uri)
31
+
32
+ res = http.request(request)
33
+
34
+ case res
35
+ when Net::HTTPSuccess then res.body
36
+ else raise(RequestError.new(res.body))
37
+ end
38
+ end
39
+
40
+ def put(path, params)
41
+ uri = URI("#{BASE_URL}#{path}?#{query_string(params)}")
42
+
43
+ http = Net::HTTP.new(uri.host, uri.port)
44
+ http.use_ssl = true
45
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
46
+ request = Net::HTTP::Put.new(uri.request_uri)
47
+
48
+ res = http.request(request)
49
+
50
+ case res
51
+ when Net::HTTPOK then res.body
52
+ else raise(RequestError.new(res.body))
53
+ end
54
+ end
55
+
56
+ private
57
+
58
+ def query_string(params)
59
+ params.keys.map { |key| "#{key}=#{params[key]}" }.join("&")
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,40 @@
1
+ require '3llo/board_command_factory'
2
+ require '3llo/card_command_factory'
3
+ require '3llo/list_command_factory'
4
+ require '3llo/commands/help'
5
+ require '3llo/commands/exit'
6
+ require '3llo/commands/invalid'
7
+ require '3llo/commands/error'
8
+
9
+ module Tr3llo
10
+ class CommandFactory
11
+ def initialize(command_buffer)
12
+ @command_buffer = command_buffer
13
+ end
14
+
15
+ def factory
16
+ command, subcommand, *args = command_buffer.strip.split(' ')
17
+
18
+ case command
19
+ when 'board'
20
+ BoardCommandFactory.new(subcommand, args).factory
21
+ when 'card'
22
+ CardCommandFactory.new(subcommand, args).factory
23
+ when 'list'
24
+ ListCommandFactory.new(subcommand, args).factory
25
+ when 'help', ''
26
+ Command::HelpCommand.new
27
+ when 'exit'
28
+ Command::ExitCommand.new
29
+ else
30
+ Command::InvalidCommand.new
31
+ end
32
+ rescue Container::KeyNotFoundError
33
+ Command::ErrorCommand.new
34
+ end
35
+
36
+ private
37
+
38
+ attr_reader :command_buffer
39
+ end
40
+ end
File without changes
@@ -0,0 +1,33 @@
1
+ module Tr3llo
2
+ module Command
3
+ module Board
4
+ class InvalidCommand
5
+ def execute
6
+ interface.print_frame do
7
+ interface.puts("Invalid command".red)
8
+ interface.puts(menu_text)
9
+ end
10
+ end
11
+
12
+ private
13
+
14
+ def menu_text
15
+ %q{
16
+ Available `board` commands
17
+
18
+ board list - Show list of board
19
+ board select <board_id> - Select board
20
+ }
21
+ end
22
+
23
+ def container
24
+ $container
25
+ end
26
+
27
+ def interface
28
+ container.resolve(:interface)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end