3llo 1.0.0 → 1.1.0

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