3llo 1.0.0.pre.rc.0 → 1.0.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 +4 -4
- data/.github/workflows/ci.yml +4 -0
- data/.rubocop.yml +113 -0
- data/3llo.gemspec +9 -9
- data/CHANGELOG.md +2 -0
- data/Gemfile +3 -3
- data/Rakefile +2 -2
- data/bin/3llo +4 -4
- data/lib/3llo.rb +14 -14
- data/lib/3llo/api.rb +6 -6
- data/lib/3llo/api/board.rb +13 -29
- data/lib/3llo/api/card.rb +79 -102
- data/lib/3llo/api/checklist.rb +26 -48
- data/lib/3llo/api/list.rb +12 -23
- data/lib/3llo/api/token.rb +2 -2
- data/lib/3llo/api/user.rb +8 -32
- data/lib/3llo/application.rb +32 -22
- data/lib/3llo/command.rb +43 -14
- data/lib/3llo/command/board.rb +6 -6
- data/lib/3llo/command/card.rb +55 -53
- data/lib/3llo/command/card/assign.rb +3 -3
- data/lib/3llo/command/card/edit.rb +33 -0
- data/lib/3llo/command/card/move.rb +3 -3
- data/lib/3llo/command/card/self_assign.rb +2 -2
- data/lib/3llo/command/list.rb +9 -9
- data/lib/3llo/controller.rb +10 -11
- data/lib/3llo/entities.rb +1 -1
- data/lib/3llo/interface.rb +3 -2
- data/lib/3llo/registry.rb +3 -4
- data/lib/3llo/remote_server.rb +97 -0
- data/lib/3llo/utils.rb +10 -0
- data/lib/3llo/version.rb +1 -1
- data/lib/3llo/view.rb +11 -11
- data/lib/3llo/view/board/list.rb +2 -2
- data/lib/3llo/view/card/help.rb +1 -1
- metadata +21 -6
- data/lib/3llo/http/client.rb +0 -95
- data/lib/3llo/http/request_error.rb +0 -18
data/lib/3llo/command/board.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require "3llo/command/board/list"
|
2
|
+
require "3llo/command/board/select"
|
3
|
+
require "3llo/command/board/invalid"
|
4
4
|
|
5
5
|
module Tr3llo
|
6
6
|
module Command
|
@@ -9,12 +9,12 @@ module Tr3llo
|
|
9
9
|
|
10
10
|
def execute(subcommand, args)
|
11
11
|
case subcommand
|
12
|
-
when
|
12
|
+
when "list"
|
13
13
|
user = Application.fetch_user!()
|
14
14
|
|
15
15
|
Command::Board::List.execute(user[:id])
|
16
|
-
when
|
17
|
-
board_key,
|
16
|
+
when "select"
|
17
|
+
board_key, = args
|
18
18
|
Utils.assert_string!(board_key, "board key is missing")
|
19
19
|
|
20
20
|
Command::Board::Select.execute(board_key)
|
data/lib/3llo/command/card.rb
CHANGED
@@ -1,22 +1,23 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
13
|
-
require
|
14
|
-
require
|
15
|
-
require
|
16
|
-
require
|
17
|
-
require
|
18
|
-
require
|
19
|
-
require
|
1
|
+
require "3llo/command/card/list"
|
2
|
+
require "3llo/command/card/list_mine"
|
3
|
+
require "3llo/command/card/edit"
|
4
|
+
require "3llo/command/card/show"
|
5
|
+
require "3llo/command/card/move"
|
6
|
+
require "3llo/command/card/self_assign"
|
7
|
+
require "3llo/command/card/assign"
|
8
|
+
require "3llo/command/card/invalid"
|
9
|
+
require "3llo/command/card/comments"
|
10
|
+
require "3llo/command/card/comment"
|
11
|
+
require "3llo/command/card/add"
|
12
|
+
require "3llo/command/card/archive"
|
13
|
+
require "3llo/command/card/add_checklist"
|
14
|
+
require "3llo/command/card/edit_checklist"
|
15
|
+
require "3llo/command/card/remove_checklist"
|
16
|
+
require "3llo/command/card/add_item"
|
17
|
+
require "3llo/command/card/check_item"
|
18
|
+
require "3llo/command/card/uncheck_item"
|
19
|
+
require "3llo/command/card/edit_item"
|
20
|
+
require "3llo/command/card/remove_item"
|
20
21
|
|
21
22
|
module Tr3llo
|
22
23
|
module Command
|
@@ -25,100 +26,101 @@ module Tr3llo
|
|
25
26
|
|
26
27
|
def execute(subcommand, args)
|
27
28
|
case subcommand
|
28
|
-
when
|
29
|
-
is_mine, _ = *args
|
29
|
+
when "list"
|
30
30
|
board = Application.fetch_board!()
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
raise InvalidArgumentError.new("#{command_string.inspect} is not a valid command")
|
40
|
-
end
|
41
|
-
when 'add'
|
32
|
+
Command::Card::List.execute(board.id)
|
33
|
+
when "list-mine"
|
34
|
+
board = Application.fetch_board!()
|
35
|
+
user = Application.fetch_user!()
|
36
|
+
|
37
|
+
Command::Card::ListMine.execute(board.id, user.id)
|
38
|
+
when "add"
|
42
39
|
board = Application.fetch_board!()
|
43
40
|
Command::Card::Add.execute(board[:id])
|
44
|
-
when
|
45
|
-
card_key,
|
41
|
+
when "show"
|
42
|
+
card_key, = args
|
46
43
|
Utils.assert_string!(card_key, "card key is missing")
|
47
44
|
|
48
45
|
Command::Card::Show.execute(card_key)
|
49
|
-
when
|
50
|
-
card_key,
|
46
|
+
when "edit"
|
47
|
+
card_key, = args
|
48
|
+
Utils.assert_string!(card_key, "card key is missing")
|
49
|
+
|
50
|
+
Command::Card::Edit.execute(card_key)
|
51
|
+
when "comments"
|
52
|
+
card_key, = args
|
51
53
|
Utils.assert_string!(card_key, "card key is missing")
|
52
54
|
|
53
55
|
Command::Card::Comments.execute(card_key)
|
54
|
-
when
|
55
|
-
card_key,
|
56
|
+
when "comment"
|
57
|
+
card_key, = args
|
56
58
|
Utils.assert_string!(card_key, "card key is missing")
|
57
59
|
|
58
60
|
Command::Card::Comment.execute(card_key)
|
59
|
-
when
|
61
|
+
when "move"
|
60
62
|
board = Application.fetch_board!()
|
61
|
-
card_key,
|
63
|
+
card_key, = args
|
62
64
|
Utils.assert_string!(card_key, "card key is missing")
|
63
65
|
|
64
66
|
Command::Card::Move.execute(card_key, board[:id])
|
65
|
-
when
|
67
|
+
when "self-assign"
|
66
68
|
user = Application.fetch_user!()
|
67
|
-
card_key,
|
69
|
+
card_key, = args
|
68
70
|
Utils.assert_string!(card_key, "card key is missing")
|
69
71
|
|
70
72
|
Command::Card::SelfAssign.execute(card_key, user[:id])
|
71
|
-
when
|
73
|
+
when "assign"
|
72
74
|
board = Application.fetch_board!()
|
73
|
-
card_key,
|
75
|
+
card_key, = args
|
74
76
|
Utils.assert_string!(card_key, "card key is missing")
|
75
77
|
|
76
78
|
Command::Card::Assign.execute(card_key, board[:id])
|
77
|
-
when
|
78
|
-
card_key,
|
79
|
+
when "archive"
|
80
|
+
card_key, = args
|
79
81
|
Utils.assert_string!(card_key, "card key is missing")
|
80
82
|
|
81
83
|
Command::Card::Archive.execute(card_key)
|
82
84
|
when "add-checklist"
|
83
|
-
card_key,
|
85
|
+
card_key, = args
|
84
86
|
Utils.assert_string!(card_key, "card key is missing")
|
85
87
|
|
86
88
|
Command::Card::AddChecklist.execute(card_key)
|
87
89
|
when "edit-checklist"
|
88
|
-
checklist_key,
|
90
|
+
checklist_key, = args
|
89
91
|
Utils.assert_string!(checklist_key, "checklist key is missing")
|
90
92
|
|
91
93
|
Command::Card::EditChecklist.execute(checklist_key)
|
92
94
|
when "remove-checklist"
|
93
|
-
checklist_key,
|
95
|
+
checklist_key, = args
|
94
96
|
Utils.assert_string!(checklist_key, "checklist key is missing")
|
95
97
|
|
96
98
|
Command::Card::RemoveChecklist.execute(checklist_key)
|
97
99
|
when "add-item"
|
98
|
-
checklist_key,
|
100
|
+
checklist_key, = args
|
99
101
|
Utils.assert_string!(checklist_key, "checklist key is missing")
|
100
102
|
|
101
103
|
Command::Card::AddItem.execute(checklist_key)
|
102
104
|
when "check-item"
|
103
|
-
card_key, check_item_key,
|
105
|
+
card_key, check_item_key, = args
|
104
106
|
Utils.assert_string!(card_key, "card key is missing")
|
105
107
|
Utils.assert_string!(check_item_key, "item key is missing")
|
106
108
|
|
107
109
|
Command::Card::CheckItem.execute(card_key, check_item_key)
|
108
110
|
when "uncheck-item"
|
109
|
-
card_key, check_item_key,
|
111
|
+
card_key, check_item_key, = args
|
110
112
|
Utils.assert_string!(card_key, "card key is missing")
|
111
113
|
Utils.assert_string!(check_item_key, "item key is missing")
|
112
114
|
|
113
115
|
Command::Card::UncheckItem.execute(card_key, check_item_key)
|
114
116
|
when "edit-item"
|
115
|
-
card_key, check_item_key,
|
117
|
+
card_key, check_item_key, = args
|
116
118
|
Utils.assert_string!(card_key, "card key is missing")
|
117
119
|
Utils.assert_string!(check_item_key, "item key is missing")
|
118
120
|
|
119
121
|
Command::Card::EditItem.execute(card_key, check_item_key)
|
120
122
|
when "remove-item"
|
121
|
-
card_key, check_item_key,
|
123
|
+
card_key, check_item_key, = args
|
122
124
|
Utils.assert_string!(card_key, "card key is missing")
|
123
125
|
Utils.assert_string!(check_item_key, "item key is missing")
|
124
126
|
|
@@ -33,14 +33,14 @@ module Tr3llo
|
|
33
33
|
def select_user(interface, card, board_id)
|
34
34
|
user_options =
|
35
35
|
API::User.find_all_by_board(board_id)
|
36
|
-
|
37
|
-
|
36
|
+
.map { |user| [user.username, user.id] }
|
37
|
+
.to_h()
|
38
38
|
|
39
39
|
member_ids =
|
40
40
|
card.members.flat_map do |member|
|
41
41
|
index = user_options.find_index { |_username, user_id| user_id == member.id }
|
42
42
|
|
43
|
-
|
43
|
+
index ? [index + 1] : []
|
44
44
|
end
|
45
45
|
|
46
46
|
interface.input.multi_select(
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Tr3llo
|
2
|
+
module Command
|
3
|
+
module Card
|
4
|
+
module Edit
|
5
|
+
extend self
|
6
|
+
|
7
|
+
def execute(card_key)
|
8
|
+
card_id = Entities.parse_id(:card, card_key)
|
9
|
+
assert_card_id!(card_id, card_key)
|
10
|
+
|
11
|
+
card = API::Card.find(card_id)
|
12
|
+
|
13
|
+
interface = Application.fetch_interface!()
|
14
|
+
|
15
|
+
interface.print_frame do
|
16
|
+
name = interface.input.ask("Name:", required: true, value: card.name)
|
17
|
+
description = interface.input.ask("Description:", value: card.description)
|
18
|
+
|
19
|
+
API::Card.update(card_id, {"name" => name, "desc" => description})
|
20
|
+
|
21
|
+
interface.puts("Card has been updated.")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def assert_card_id!(card_id, key)
|
28
|
+
raise InvalidArgumentError.new("#{key.inspect} is not a valid list key") unless card_id
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -23,9 +23,9 @@ module Tr3llo
|
|
23
23
|
def select_list(interface, board_id)
|
24
24
|
list_options =
|
25
25
|
API::List
|
26
|
-
|
27
|
-
|
28
|
-
|
26
|
+
.find_all_by_board(board_id)
|
27
|
+
.map { |list| [list.name, list.id] }
|
28
|
+
.to_h()
|
29
29
|
|
30
30
|
interface.input.select(
|
31
31
|
"Choose the list to be moved to",
|
@@ -8,7 +8,7 @@ module Tr3llo
|
|
8
8
|
card_id = Entities.parse_id(:card, key)
|
9
9
|
assert_card_id!(card_id, key)
|
10
10
|
|
11
|
-
|
11
|
+
assign_card(card_id, user_id)
|
12
12
|
|
13
13
|
interface = Application.fetch_interface!()
|
14
14
|
|
@@ -21,7 +21,7 @@ module Tr3llo
|
|
21
21
|
|
22
22
|
def assign_card(card_id, user_id)
|
23
23
|
card = API::Card.find(card_id)
|
24
|
-
members = card.members.map
|
24
|
+
members = card.members.map(&:id) + [user_id]
|
25
25
|
|
26
26
|
API::Card.assign_members(card_id, members)
|
27
27
|
end
|
data/lib/3llo/command/list.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
1
|
+
require "3llo/command/list/list"
|
2
|
+
require "3llo/command/list/cards"
|
3
|
+
require "3llo/command/list/invalid"
|
4
|
+
require "3llo/command/list/archive_cards"
|
5
5
|
|
6
6
|
module Tr3llo
|
7
7
|
module Command
|
@@ -10,17 +10,17 @@ module Tr3llo
|
|
10
10
|
|
11
11
|
def execute(subcommand, args)
|
12
12
|
case subcommand
|
13
|
-
when
|
13
|
+
when "list"
|
14
14
|
board = Application.fetch_board!()
|
15
15
|
|
16
16
|
Command::List::List.execute(board[:id])
|
17
|
-
when
|
18
|
-
list_key,
|
17
|
+
when "cards"
|
18
|
+
list_key, = args
|
19
19
|
Utils.assert_string!(list_key, "list key is missing")
|
20
20
|
|
21
21
|
Command::List::Cards.execute(list_key)
|
22
|
-
when
|
23
|
-
list_key,
|
22
|
+
when "archive-cards"
|
23
|
+
list_key, = args
|
24
24
|
Utils.assert_string!(list_key, "list key is missing")
|
25
25
|
|
26
26
|
Command::List::ArchiveCards.execute(list_key)
|
data/lib/3llo/controller.rb
CHANGED
@@ -1,37 +1,36 @@
|
|
1
|
-
require
|
1
|
+
require "readline"
|
2
2
|
|
3
3
|
module Tr3llo
|
4
4
|
module Controller
|
5
5
|
extend self
|
6
6
|
|
7
7
|
def start(init_command)
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
Readline.completion_proc = auto_completion
|
8
|
+
Readline.completion_append_character = " "
|
9
|
+
Readline.completion_proc = lambda { |buffer|
|
10
|
+
Command.generate_suggestions(buffer, Readline.line_buffer)
|
11
|
+
}
|
13
12
|
|
14
13
|
interface = Application.fetch_interface!()
|
15
14
|
|
16
15
|
if init_command && init_command != ""
|
17
16
|
interface.puts("Executing " + Utils.format_highlight(init_command) + " command")
|
18
17
|
|
19
|
-
execute_command!(init_command
|
18
|
+
execute_command!(init_command)
|
20
19
|
end
|
21
20
|
|
22
21
|
loop do
|
23
22
|
command_buffer = Readline.readline("\e[15;48;5;27m 3llo \e[0m > ", true)
|
24
23
|
|
25
|
-
execute_command!(command_buffer
|
24
|
+
execute_command!(command_buffer)
|
26
25
|
end
|
27
26
|
rescue Interrupt
|
28
27
|
Command::Exit.execute()
|
29
28
|
end
|
30
29
|
|
31
|
-
|
30
|
+
private
|
31
|
+
|
32
|
+
def execute_command!(command_buffer)
|
32
33
|
Tr3llo::Command.execute(command_buffer.strip())
|
33
|
-
rescue Tr3llo::HTTP::Client::RequestError => e
|
34
|
-
interface.print_frame { interface.print_error(e.message) }
|
35
34
|
end
|
36
35
|
end
|
37
36
|
end
|
data/lib/3llo/entities.rb
CHANGED
data/lib/3llo/interface.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
module Tr3llo
|
2
2
|
class Interface
|
3
3
|
def initialize(input, output)
|
4
|
-
@input
|
4
|
+
@input = input
|
5
|
+
@output = output
|
5
6
|
end
|
6
7
|
|
7
8
|
def print_frame
|
@@ -15,7 +16,7 @@ module Tr3llo
|
|
15
16
|
output.puts(str)
|
16
17
|
end
|
17
18
|
|
18
|
-
alias
|
19
|
+
alias puts print_line
|
19
20
|
|
20
21
|
def print(str)
|
21
22
|
output.print(str)
|
data/lib/3llo/registry.rb
CHANGED
@@ -16,11 +16,10 @@ module Tr3llo
|
|
16
16
|
shortcut_to_id: {}
|
17
17
|
})
|
18
18
|
|
19
|
-
|
20
|
-
key_to_id = data[:shortcut_to_id]
|
19
|
+
id_to_shortcut = data[:id_to_shortcut]
|
21
20
|
|
22
|
-
if
|
23
|
-
|
21
|
+
if id_to_shortcut.has_key?(id)
|
22
|
+
id_to_shortcut.fetch(id)
|
24
23
|
else
|
25
24
|
counter = data[:counter] + 1
|
26
25
|
shortcut = counter.to_s
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require "net/http"
|
2
|
+
|
3
|
+
module Tr3llo
|
4
|
+
class RemoteServer
|
5
|
+
attr_reader :endpoint_url
|
6
|
+
|
7
|
+
EXPECTED_CODES = ["200"].freeze
|
8
|
+
|
9
|
+
class RequestError < ::StandardError
|
10
|
+
attr_reader :response
|
11
|
+
|
12
|
+
def initialize(response)
|
13
|
+
@response = response
|
14
|
+
super()
|
15
|
+
end
|
16
|
+
|
17
|
+
def message
|
18
|
+
formatted_response = "status: " + response.code.inspect() + ", body: " + response.body.inspect()
|
19
|
+
|
20
|
+
"Received unexpected response from remote server: " + formatted_response
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def initialize(endpoint_url)
|
25
|
+
@endpoint_url = endpoint_url
|
26
|
+
end
|
27
|
+
|
28
|
+
def get(req_path, req_headers, expected_codes = EXPECTED_CODES)
|
29
|
+
req_uri = build_request_uri(req_path)
|
30
|
+
req_headers = {"accept" => "application/json"}.merge(req_headers)
|
31
|
+
|
32
|
+
dispatch(Net::HTTP::Get.new(req_uri, req_headers), expected_codes)
|
33
|
+
end
|
34
|
+
|
35
|
+
def post(req_path, req_headers, payload, expected_codes = EXPECTED_CODES)
|
36
|
+
req_uri = build_request_uri(req_path)
|
37
|
+
|
38
|
+
req_headers = {
|
39
|
+
"accept" => "application/json",
|
40
|
+
"content-type" => "application/json"
|
41
|
+
}.merge(req_headers)
|
42
|
+
|
43
|
+
request = Net::HTTP::Post.new(req_uri, req_headers)
|
44
|
+
request.body = JSON.dump(payload)
|
45
|
+
|
46
|
+
dispatch(request, expected_codes)
|
47
|
+
end
|
48
|
+
|
49
|
+
def put(req_path, req_headers, payload, expected_codes = EXPECTED_CODES)
|
50
|
+
req_uri = build_request_uri(req_path)
|
51
|
+
|
52
|
+
req_headers = {
|
53
|
+
"Accept" => "application/json",
|
54
|
+
"Content-Type" => "application/json"
|
55
|
+
}.merge(req_headers)
|
56
|
+
|
57
|
+
request = Net::HTTP::Put.new(req_uri, req_headers)
|
58
|
+
request.body = JSON.dump(payload)
|
59
|
+
|
60
|
+
dispatch(request, expected_codes)
|
61
|
+
end
|
62
|
+
|
63
|
+
def delete(req_path, req_headers, payload, expected_codes = EXPECTED_CODES)
|
64
|
+
req_uri = build_request_uri(req_path)
|
65
|
+
|
66
|
+
req_headers = {
|
67
|
+
"Accept" => "application/json",
|
68
|
+
"Content-Type" => "application/json"
|
69
|
+
}.merge(req_headers)
|
70
|
+
|
71
|
+
request = Net::HTTP::Delete.new(req_uri, req_headers)
|
72
|
+
request.body = JSON.dump(payload)
|
73
|
+
|
74
|
+
dispatch(request, expected_codes)
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def build_request_uri(req_path)
|
80
|
+
URI.parse(endpoint_url + req_path)
|
81
|
+
end
|
82
|
+
|
83
|
+
def dispatch(request, expected_status_codes)
|
84
|
+
req_uri = request.uri
|
85
|
+
|
86
|
+
Net::HTTP.start(req_uri.host, req_uri.port, use_ssl: req_uri.scheme == "https") do |http|
|
87
|
+
response = http.request(request)
|
88
|
+
|
89
|
+
if expected_status_codes.include?(response.code)
|
90
|
+
JSON.parse(response.body)
|
91
|
+
else
|
92
|
+
raise RequestError.new(response)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|