3llo 1.0.0 → 1.1.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8e6ca4c800b73fb0a5514e1a87204547c243045b9e3a0b5842f327513b726073
4
- data.tar.gz: c6bc2f0e09bd27a558c8914d34734863efce9d6b534d2bae38d5d1267d378eb7
3
+ metadata.gz: b821782c50c15268558fee17228bd87e7c1c013c65df510f293701f993f3048e
4
+ data.tar.gz: 1a16571e8eef793329e113aedac17f66e077434ec9d06906e8949c7f57a46f46
5
5
  SHA512:
6
- metadata.gz: 035ff3a48dcfe77e558d5eec4e341dcfc78caf0b6d55fa60c91f8a9d56b32a8d8221634e78ec3f34e26fc13c9d10df130017483fd3b9bcfb5aa0c64ce3d19e0f
7
- data.tar.gz: 152e793d22f7db0ab50d9504c3d2c2d36051dcfa74293931d368a5e58ec9b176fa34f77215498566947fc6851a33bc9eadc3f891fbe43fa0221be13407d1c9b7
6
+ metadata.gz: c93eccf148fa41d4ee1a5aa59cc847b63b4ed6b9a52b0b0ca584effbe403b02b5048df80df398272a23fe5b36e3d983bb2bfefa42c2972dc038281461b1225ed
7
+ data.tar.gz: d1b1c3f133d46ff8f6588899efc9ea29e8db1cacedaf9a113c3384cacba2011cd8f7d7461b096124da592bab8558250c20ad691d358b794174356597cd24b176
@@ -57,8 +57,14 @@ Security/JSONLoad:
57
57
  Style/Alias:
58
58
  EnforcedStyle: prefer_alias
59
59
 
60
- Style/BracesAroundHashParameters:
61
- Enabled: false
60
+ Style/HashEachMethods:
61
+ Enabled: true
62
+
63
+ Style/HashTransformKeys:
64
+ Enabled: true
65
+
66
+ Style/HashTransformValues:
67
+ Enabled: true
62
68
 
63
69
  Style/DefWithParentheses:
64
70
  Enabled: false
@@ -1,5 +1,12 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## v1.1.0
4
+
5
+ * Introduce "list add" command.
6
+ * Introduce "board add" command.
7
+ * Introduce label related command.
8
+ * Support exiting with Ctrl+D.
9
+
3
10
  ## v1.0.0
4
11
 
5
12
  * Support using shortcuts to access entities.
data/Rakefile CHANGED
@@ -1,10 +1,4 @@
1
- require "bundler/gem_tasks"
2
- require "rake/testtask"
1
+ require "rspec/core/rake_task"
2
+ RSpec::Core::RakeTask.new(:spec)
3
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
4
+ task default: :spec
@@ -1,6 +1,7 @@
1
1
  require "3llo/api/board"
2
2
  require "3llo/api/card"
3
3
  require "3llo/api/list"
4
+ require "3llo/api/label"
4
5
  require "3llo/api/user"
5
6
  require "3llo/api/checklist"
6
7
  require "3llo/api/token"
@@ -25,6 +25,18 @@ module Tr3llo
25
25
  make_struct(client.get(req_path, {}))
26
26
  end
27
27
 
28
+ def create(name:, desc:, default_lists: true)
29
+ client = Application.fetch_client!()
30
+ req_path = Utils.build_req_path("/boards", {})
31
+ payload = {
32
+ "name" => name,
33
+ "desc" => desc,
34
+ "defaultLists" => default_lists
35
+ }
36
+
37
+ client.post(req_path, {}, payload)
38
+ end
39
+
28
40
  private
29
41
 
30
42
  def make_struct(payload)
@@ -138,7 +138,7 @@ module Tr3llo
138
138
  label_name = label_payload.fetch("name")
139
139
  label_color = label_payload["color"]
140
140
 
141
- Entities::Label.new(label_name, label_color)
141
+ Entities::Label.new(id: nil, shortcut: nil, name: label_name, color: label_color)
142
142
  end
143
143
 
144
144
  card =
@@ -0,0 +1,64 @@
1
+ module Tr3llo
2
+ module API
3
+ module Label
4
+ extend self
5
+
6
+ def find_all_by_board(board_id)
7
+ req_path =
8
+ Utils.build_req_path(
9
+ "/boards/#{board_id}/labels"
10
+ )
11
+
12
+ client
13
+ .get(req_path, {})
14
+ .reject { |label| label["name"].empty? }
15
+ .map do |label_payload|
16
+ make_struct(label_payload)
17
+ end
18
+ end
19
+
20
+ def find(label_id)
21
+ req_path = Utils.build_req_path("/labels/#{label_id}")
22
+ label_payload = client.get(req_path, {})
23
+
24
+ make_struct(label_payload)
25
+ end
26
+
27
+ def create(name:, color:, board_id:)
28
+ req_path = Utils.build_req_path("/labels")
29
+ payload = {
30
+ "name" => name,
31
+ "color" => color,
32
+ "idBoard" => board_id
33
+ }
34
+
35
+ client.post(req_path, {}, payload)
36
+ end
37
+
38
+ def update(label_id, data)
39
+ req_path = Utils.build_req_path("/labels/#{label_id}")
40
+
41
+ client.put(req_path, {}, data)
42
+ end
43
+
44
+ def delete(label_id)
45
+ req_path = Utils.build_req_path("/labels/#{label_id}")
46
+
47
+ client.delete(req_path, {}, {})
48
+ end
49
+
50
+ private
51
+
52
+ def make_struct(payload)
53
+ id, name, color = payload.fetch_values("id", "name", "color")
54
+ shortcut = Entities.make_shortcut(:label, id)
55
+
56
+ Entities::Label.new(id: id, shortcut: shortcut, name: name, color: color)
57
+ end
58
+
59
+ def client
60
+ Application.fetch_client!()
61
+ end
62
+ end
63
+ end
64
+ end
@@ -23,6 +23,16 @@ module Tr3llo
23
23
  client.post(req_path, {}, {})
24
24
  end
25
25
 
26
+ def create(name, board_id)
27
+ req_path = Utils.build_req_path("/lists")
28
+ payload = {
29
+ "name" => name,
30
+ "idBoard" => board_id
31
+ }
32
+
33
+ client.post(req_path, {}, payload)
34
+ end
35
+
26
36
  private
27
37
 
28
38
  def make_struct(payload)
@@ -1,6 +1,7 @@
1
1
  require "3llo/command/board"
2
2
  require "3llo/command/card"
3
3
  require "3llo/command/list"
4
+ require "3llo/command/label"
4
5
  require "3llo/command/help"
5
6
  require "3llo/command/exit"
6
7
  require "3llo/command/invalid"
@@ -15,14 +16,15 @@ module Tr3llo
15
16
 
16
17
  def generate_suggestions(buffer, command_buffer)
17
18
  commands = {
18
- "board" => ["list", "select"],
19
- "list" => %w[list cards archive-cards],
19
+ "board" => %w[add list select],
20
+ "list" => %w[list add cards archive-cards],
20
21
  "card" => %w[
21
22
  list show add edit archive list-mine move
22
23
  comment comments self-assign assign
23
24
  add-checklist edit-checklist remove-checklist
24
25
  add-item edit-item remote-item check-item uncheck-item
25
26
  ],
27
+ "label" => %w[list add edit remove],
26
28
  "help" => [],
27
29
  "exit" => []
28
30
  }
@@ -52,6 +54,8 @@ module Tr3llo
52
54
  Command::Card.execute(subcommand, args)
53
55
  when "list"
54
56
  Command::List.execute(subcommand, args)
57
+ when "label"
58
+ Command::Label.execute(subcommand, args)
55
59
  when "help"
56
60
  Command::Help.execute()
57
61
  when "exit"
@@ -1,6 +1,7 @@
1
1
  require "3llo/command/board/list"
2
2
  require "3llo/command/board/select"
3
3
  require "3llo/command/board/invalid"
4
+ require "3llo/command/board/add"
4
5
 
5
6
  module Tr3llo
6
7
  module Command
@@ -18,12 +19,12 @@ module Tr3llo
18
19
  Utils.assert_string!(board_key, "board key is missing")
19
20
 
20
21
  Command::Board::Select.execute(board_key)
22
+ when "add"
23
+ Command::Board::Add.execute()
21
24
  else
22
25
  handle_invalid_subcommand(subcommand, args)
23
26
  end
24
- rescue InvalidCommandError => exception
25
- Command::Board::Invalid.execute(exception.message)
26
- rescue InvalidArgumentError => exception
27
+ rescue InvalidCommandError, InvalidArgumentError => exception
27
28
  Command::Board::Invalid.execute(exception.message)
28
29
  end
29
30
 
@@ -0,0 +1,29 @@
1
+ module Tr3llo
2
+ module Command
3
+ module Board
4
+ module Add
5
+ extend self
6
+
7
+ def execute()
8
+ interface = Application.fetch_interface!()
9
+
10
+ interface.print_frame do
11
+ name = interface.input.ask("Name:", required: true)
12
+ desc = interface.input.ask("Description:")
13
+
14
+ default_lists =
15
+ interface.input.yes?("With default set of lists to the board (To Do, Doing, Done)?") do |question|
16
+ question.default false
17
+ question.positive "Y"
18
+ question.negative "N"
19
+ end
20
+
21
+ API::Board.create(name: name, desc: desc, default_lists: default_lists)
22
+
23
+ interface.puts("Board has been created.")
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -14,17 +14,21 @@ module Tr3llo
14
14
  interface = Application.fetch_interface!()
15
15
 
16
16
  interface.print_frame do
17
- list_id = interface.input.select(
18
- "Choose the list this card should belong to:",
19
- list_options
20
- )
17
+ if list_options.any?
18
+ list_id = interface.input.select(
19
+ "Choose the list this card should belong to:",
20
+ list_options
21
+ )
21
22
 
22
- name = interface.input.ask("Name:", required: true)
23
- description = interface.input.ask("Description:")
23
+ name = interface.input.ask("Name:", required: true)
24
+ description = interface.input.ask("Description:")
24
25
 
25
- API::Card.create(name, description, list_id)
26
+ API::Card.create(name, description, list_id)
26
27
 
27
- interface.puts("Card has been created.")
28
+ interface.puts("Card has been created.")
29
+ else
30
+ interface.puts("There is no list on board.")
31
+ end
28
32
  end
29
33
  end
30
34
  end
@@ -0,0 +1,51 @@
1
+ require "3llo/command/label/list"
2
+ require "3llo/command/label/add"
3
+ require "3llo/command/label/edit"
4
+ require "3llo/command/label/remove"
5
+ require "3llo/command/label/invalid"
6
+
7
+ module Tr3llo
8
+ module Command
9
+ module Label
10
+ extend self
11
+
12
+ def execute(subcommand, args)
13
+ case subcommand
14
+ when "list"
15
+ board = Application.fetch_board!()
16
+
17
+ Command::Label::List.execute(board[:id])
18
+ when "add"
19
+ board = Application.fetch_board!()
20
+
21
+ Command::Label::Add.execute(board[:id])
22
+ when "edit"
23
+ label_key, = args
24
+ Utils.assert_string!(label_key, "label key is missing")
25
+
26
+ Command::Label::Edit.execute(label_key)
27
+ when "remove"
28
+ label_key, = args
29
+ Utils.assert_string!(label_key, "label key is missing")
30
+
31
+ Command::Label::Remove.execute(label_key)
32
+ else
33
+ handle_invalid_subcommand(subcommand, args)
34
+ end
35
+ rescue InvalidArgumentError, InvalidCommandError, BoardNotSelectedError => exception
36
+ Command::Label::Invalid.execute(exception.message)
37
+ end
38
+
39
+ private
40
+
41
+ def handle_invalid_subcommand(subcommand, _args)
42
+ case subcommand
43
+ when String
44
+ raise InvalidCommandError.new("#{subcommand.inspect} is not a valid command")
45
+ when NilClass
46
+ raise InvalidCommandError.new("command is missing")
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,22 @@
1
+ module Tr3llo
2
+ module Command
3
+ module Label
4
+ module Add
5
+ extend self
6
+
7
+ def execute(board_id)
8
+ interface = Application.fetch_interface!()
9
+
10
+ interface.print_frame do
11
+ name = interface.input.ask("Name:", required: true)
12
+ color = interface.input.select("Choose the color:", Utils::TRELLO_LABEL_COLOR)
13
+
14
+ API::Label.create(name: name, color: color, board_id: board_id)
15
+
16
+ interface.puts("Label has been created.")
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,37 @@
1
+ module Tr3llo
2
+ module Command
3
+ module Label
4
+ module Edit
5
+ extend self
6
+
7
+ def execute(label_key)
8
+ label_id = Entities.parse_id(:label, label_key)
9
+ assert_label_id!(label_id, label_key)
10
+
11
+ label = API::Label.find(label_id)
12
+
13
+ interface = Application.fetch_interface!()
14
+
15
+ interface.print_frame do
16
+ name = interface.input.ask("Name:", required: true, value: label.name)
17
+ color = interface.input.select(
18
+ "Choose the color:",
19
+ Utils::TRELLO_LABEL_COLOR,
20
+ default: Utils::TRELLO_LABEL_COLOR.index(label.color)
21
+ )
22
+
23
+ API::Label.update(label_id, {"name" => name, "color" => color})
24
+
25
+ interface.puts("Label has been updated.")
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ def assert_label_id!(label_id, key)
32
+ raise InvalidArgumentError.new("#{key.inspect} is not a valid label key") unless label_id
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,18 @@
1
+ module Tr3llo
2
+ module Command
3
+ module Label
4
+ module Invalid
5
+ extend self
6
+
7
+ def execute(message)
8
+ interface = Application.fetch_interface!()
9
+
10
+ interface.print_frame do
11
+ interface.print_error(message)
12
+ interface.puts(View::Label::Help.render())
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ module Tr3llo
2
+ module Command
3
+ module Label
4
+ module List
5
+ extend self
6
+
7
+ def execute(board_id)
8
+ interface = Application.fetch_interface!()
9
+ labels = API::Label.find_all_by_board(board_id)
10
+
11
+ interface.print_frame do
12
+ interface.puts(View::Label::List.render(labels))
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,28 @@
1
+ module Tr3llo
2
+ module Command
3
+ module Label
4
+ module Remove
5
+ extend self
6
+
7
+ def execute(label_key)
8
+ label_id = Entities.parse_id(:label, label_key)
9
+ assert_label_id!(label_id, label_key)
10
+
11
+ interface = Application.fetch_interface!()
12
+
13
+ interface.print_frame do
14
+ API::Label.delete(label_id)
15
+
16
+ interface.puts("Label has been deleted.")
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def assert_label_id!(label_id, key)
23
+ raise InvalidArgumentError.new("#{key.inspect} is not a valid label key") unless label_id
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -1,4 +1,5 @@
1
1
  require "3llo/command/list/list"
2
+ require "3llo/command/list/add"
2
3
  require "3llo/command/list/cards"
3
4
  require "3llo/command/list/invalid"
4
5
  require "3llo/command/list/archive_cards"
@@ -14,6 +15,10 @@ module Tr3llo
14
15
  board = Application.fetch_board!()
15
16
 
16
17
  Command::List::List.execute(board[:id])
18
+ when "add"
19
+ board = Application.fetch_board!()
20
+
21
+ Command::List::Add.execute(board[:id])
17
22
  when "cards"
18
23
  list_key, = args
19
24
  Utils.assert_string!(list_key, "list key is missing")
@@ -0,0 +1,21 @@
1
+ module Tr3llo
2
+ module Command
3
+ module List
4
+ module Add
5
+ extend self
6
+
7
+ def execute(board_id)
8
+ interface = Application.fetch_interface!()
9
+
10
+ interface.print_frame do
11
+ name = interface.input.ask("Name:", required: true)
12
+
13
+ API::List.create(name, board_id)
14
+
15
+ interface.puts("List has been created.")
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -5,7 +5,7 @@ module Tr3llo
5
5
  extend self
6
6
 
7
7
  def start(init_command)
8
- Readline.completion_append_character = " "
8
+ Readline.completion_append_character = " "
9
9
  Readline.completion_proc = lambda { |buffer|
10
10
  Command.generate_suggestions(buffer, Readline.line_buffer)
11
11
  }
@@ -21,6 +21,8 @@ module Tr3llo
21
21
  loop do
22
22
  command_buffer = Readline.readline("\e[15;48;5;27m 3llo \e[0m > ", true)
23
23
 
24
+ Command::Exit.execute() if command_buffer.nil?
25
+
24
26
  execute_command!(command_buffer)
25
27
  end
26
28
  rescue Interrupt
@@ -11,7 +11,7 @@ module Tr3llo
11
11
  Board = Struct.new(:id, :shortcut, :name)
12
12
  List = Struct.new(:id, :shortcut, :name)
13
13
  Card = Struct.new(:id, :shortcut, :name, :description, :short_url, :labels, :members, :list, keyword_init: true)
14
- Label = Struct.new(:name, :color)
14
+ Label = Struct.new(:id, :shortcut, :name, :color, keyword_init: true)
15
15
  Comment = Struct.new(:id, :text, :creator, :created_at, keyword_init: true)
16
16
  Checklist = Struct.new(:id, :shortcut, :name, :items, keyword_init: true)
17
17
  Checklist::Item = Struct.new(:id, :shortcut, :name, :state, keyword_init: true)
@@ -78,6 +78,8 @@ module Tr3llo
78
78
 
79
79
  def build_request_uri(req_path)
80
80
  URI.parse(endpoint_url + req_path)
81
+ rescue URI::Error
82
+ raise InvalidArgumentError.new("invalid command arguments")
81
83
  end
82
84
 
83
85
  def dispatch(request, expected_status_codes)
@@ -17,6 +17,8 @@ module Tr3llo
17
17
  "sky" => 36
18
18
  }.freeze()
19
19
 
20
+ TRELLO_LABEL_COLOR = %w[red pink blue green purple yellow orange sky].freeze()
21
+
20
22
  def format_key_tag(id, shortcut)
21
23
  formatted_shortcut = Utils.format_highlight(Entities::SHORTCUT_PREFIX + shortcut)
22
24
  formatted_id = Utils.paint(id, "blue")
@@ -1,3 +1,3 @@
1
1
  module Tr3llo
2
- VERSION = "1.0.0".freeze
2
+ VERSION = "1.1.0".freeze
3
3
  end
@@ -9,3 +9,5 @@ require "3llo/view/card/comments"
9
9
  require "3llo/view/list/help"
10
10
  require "3llo/view/list/list"
11
11
  require "3llo/view/list/cards"
12
+ require "3llo/view/label/list"
13
+ require "3llo/view/label/help"
@@ -10,6 +10,7 @@ module Tr3llo
10
10
 
11
11
  board list - Show list of boards
12
12
  board select <board_key> - Select board
13
+ board add - Create a board
13
14
  TEMPLATE
14
15
  end
15
16
  end
@@ -14,6 +14,8 @@ module Tr3llo
14
14
 
15
15
  #{View::List::Help.render()}
16
16
 
17
+ #{View::Label::Help.render()}
18
+
17
19
  #{miscellaneous_help()}
18
20
  TEMPLATE
19
21
  end
@@ -0,0 +1,20 @@
1
+ module Tr3llo
2
+ module View
3
+ module Label
4
+ module Help
5
+ extend self
6
+
7
+ def render()
8
+ <<~TEMPLATE.strip
9
+ #{Utils.format_bold("# Available label commands:")}
10
+
11
+ label list - Show all labels
12
+ label add - Create a label
13
+ label edit <key> - Edit a label
14
+ list remove <key> - Remove a label
15
+ TEMPLATE
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,21 @@
1
+ module Tr3llo
2
+ module View
3
+ module Label
4
+ module List
5
+ extend self
6
+
7
+ def render(labels)
8
+ labels
9
+ .map { |label| render_label(label) }
10
+ .join("\n")
11
+ end
12
+
13
+ private
14
+
15
+ def render_label(label)
16
+ "#{Utils.format_key_tag(label.id, label.shortcut)} #{Utils.paint("#" + label.name, label.color)}"
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -9,6 +9,7 @@ module Tr3llo
9
9
  #{Utils.format_bold("# Available list commands:")}
10
10
 
11
11
  list list - Show all lists
12
+ list add - Create a list
12
13
  list cards <key> - Show all cards in list
13
14
  list archive-cards <key> - Archive all cards in list
14
15
  TEMPLATE
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: 3llo
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cẩm Huỳnh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-01-23 00:00:00.000000000 Z
11
+ date: 2020-04-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tty-prompt
@@ -75,6 +75,7 @@ files:
75
75
  - lib/3llo/api/board.rb
76
76
  - lib/3llo/api/card.rb
77
77
  - lib/3llo/api/checklist.rb
78
+ - lib/3llo/api/label.rb
78
79
  - lib/3llo/api/list.rb
79
80
  - lib/3llo/api/token.rb
80
81
  - lib/3llo/api/user.rb
@@ -82,6 +83,7 @@ files:
82
83
  - lib/3llo/command.rb
83
84
  - lib/3llo/command/.gitkeep
84
85
  - lib/3llo/command/board.rb
86
+ - lib/3llo/command/board/add.rb
85
87
  - lib/3llo/command/board/invalid.rb
86
88
  - lib/3llo/command/board/list.rb
87
89
  - lib/3llo/command/board/select.rb
@@ -109,7 +111,14 @@ files:
109
111
  - lib/3llo/command/exit.rb
110
112
  - lib/3llo/command/help.rb
111
113
  - lib/3llo/command/invalid.rb
114
+ - lib/3llo/command/label.rb
115
+ - lib/3llo/command/label/add.rb
116
+ - lib/3llo/command/label/edit.rb
117
+ - lib/3llo/command/label/invalid.rb
118
+ - lib/3llo/command/label/list.rb
119
+ - lib/3llo/command/label/remove.rb
112
120
  - lib/3llo/command/list.rb
121
+ - lib/3llo/command/list/add.rb
113
122
  - lib/3llo/command/list/archive_cards.rb
114
123
  - lib/3llo/command/list/cards.rb
115
124
  - lib/3llo/command/list/invalid.rb
@@ -133,6 +142,8 @@ files:
133
142
  - lib/3llo/view/card/list_mine.rb
134
143
  - lib/3llo/view/card/show.rb
135
144
  - lib/3llo/view/help.rb
145
+ - lib/3llo/view/label/help.rb
146
+ - lib/3llo/view/label/list.rb
136
147
  - lib/3llo/view/list/cards.rb
137
148
  - lib/3llo/view/list/help.rb
138
149
  - lib/3llo/view/list/list.rb