plz 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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/lib/plz.rb +4 -0
- data/lib/plz/command.rb +11 -49
- data/lib/plz/command_builder.rb +102 -24
- data/lib/plz/response.rb +66 -0
- data/lib/plz/version.rb +1 -1
- data/plz.gemspec +3 -0
- metadata +45 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2f07a8d7d61f673d93630bc76387e45042ecaba6
|
4
|
+
data.tar.gz: c1b1b718a3cf09b83b80aca3c783e3c5991f84fd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3485ee06d7409b3a8c15544245947f6fd5121165f7b488de9fd6637142a00bb18e80c7a014399d50e76a6e68f68cf9d25e0459a2cc4aba3388073ebd15b139d6
|
7
|
+
data.tar.gz: 406e5b5bd2e6bd055934214adbdb50925703eef87def6633c62eebdf04acd2cc67f0613b6b056e9f082a3954758479712e0914d4836adba00ab1c65e0e4dc5f7
|
data/CHANGELOG.md
ADDED
data/lib/plz.rb
CHANGED
@@ -5,10 +5,14 @@ require "faraday_middleware"
|
|
5
5
|
require "json"
|
6
6
|
require "json_schema"
|
7
7
|
require "pathname"
|
8
|
+
require "rack"
|
9
|
+
require "rainbow"
|
10
|
+
require "rouge"
|
8
11
|
require "yaml"
|
9
12
|
|
10
13
|
require "plz/error"
|
11
14
|
require "plz/command"
|
12
15
|
require "plz/command_builder"
|
13
16
|
require "plz/error_command"
|
17
|
+
require "plz/response"
|
14
18
|
require "plz/version"
|
data/lib/plz/command.rb
CHANGED
@@ -1,71 +1,33 @@
|
|
1
1
|
module Plz
|
2
2
|
class Command
|
3
|
-
# @param action_name [String]
|
4
|
-
# @param target_name [String]
|
5
3
|
# @param headers [Hash]
|
6
4
|
# @param params [Hash]
|
7
|
-
# @param
|
8
|
-
|
9
|
-
|
10
|
-
|
5
|
+
# @param method [String]
|
6
|
+
# @param base_url [String]
|
7
|
+
# @param path [String]
|
8
|
+
def initialize(headers: nil, params: nil, method: nil, base_url: nil, path: nil)
|
11
9
|
@headers = headers
|
12
10
|
@params = params
|
13
|
-
@
|
11
|
+
@method = method
|
12
|
+
@base_url = base_url
|
13
|
+
@path = path
|
14
14
|
end
|
15
15
|
|
16
|
-
# TODO
|
17
16
|
# Sends an HTTP request and logs out the response
|
18
17
|
def call
|
19
|
-
|
18
|
+
raw = client.send(@method.downcase, @path, @params, @headers)
|
19
|
+
puts Response.new(raw).render
|
20
20
|
end
|
21
21
|
|
22
22
|
private
|
23
23
|
|
24
|
-
# @return [String]
|
25
|
-
def path
|
26
|
-
current_link.href
|
27
|
-
end
|
28
|
-
|
29
|
-
# @return [Symbol]
|
30
|
-
def method
|
31
|
-
current_link.method
|
32
|
-
end
|
33
|
-
|
34
|
-
# @return [JsonSchema::Schema::Link, nil]
|
35
|
-
def current_link
|
36
|
-
@current_link ||= json_schema.properties.find do |key, schema|
|
37
|
-
if key == @target_name
|
38
|
-
schema.links.find do |link|
|
39
|
-
if link.href && link.method && link.title.underscore == @action_name
|
40
|
-
return link
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
# @return JsonSchema::Schema
|
48
|
-
# @raise [JsonSchema::SchemaError]
|
49
|
-
def json_schema
|
50
|
-
@json_schema ||= JsonSchema.parse!(@schema).tap(&:expand_references!)
|
51
|
-
end
|
52
|
-
|
53
24
|
# @return [Faraday::Connection]
|
54
25
|
def client
|
55
|
-
Faraday.new(url: base_url) do |connection|
|
26
|
+
Faraday.new(url: @base_url) do |connection|
|
56
27
|
connection.request :json
|
28
|
+
connection.response :json
|
57
29
|
connection.adapter :net_http
|
58
30
|
end
|
59
31
|
end
|
60
|
-
|
61
|
-
# Extracts the base url of the API
|
62
|
-
# @return [String, nil]
|
63
|
-
def base_url
|
64
|
-
json_schema.links.find do |link|
|
65
|
-
if link.href && link.rel == "self"
|
66
|
-
return link.href
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
32
|
end
|
71
33
|
end
|
data/lib/plz/command_builder.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Plz
|
2
2
|
class CommandBuilder
|
3
|
-
SCHEMA_FILE_PATH_PATTERN = "
|
3
|
+
SCHEMA_FILE_PATH_PATTERN = "schema.{json,yml}"
|
4
4
|
|
5
5
|
# Builds callable command object from given ARGV
|
6
6
|
# @return [Plz::Command]
|
@@ -19,11 +19,11 @@ module Plz
|
|
19
19
|
def call
|
20
20
|
validate!
|
21
21
|
Command.new(
|
22
|
-
|
23
|
-
|
22
|
+
method: method,
|
23
|
+
base_url: base_url,
|
24
|
+
path: path,
|
24
25
|
headers: headers,
|
25
26
|
params: params,
|
26
|
-
schema: schema,
|
27
27
|
)
|
28
28
|
rescue Error => error
|
29
29
|
ErrorCommand.new(error)
|
@@ -40,8 +40,14 @@ module Plz
|
|
40
40
|
raise NoTargetName
|
41
41
|
when !has_schema_file?
|
42
42
|
raise SchemaFileNotFound
|
43
|
+
when !has_decodable_schema_file?
|
44
|
+
raise UndecodableSchemaFile, pathname: schema_file_pathname
|
43
45
|
when !has_valid_schema_file?
|
44
|
-
raise
|
46
|
+
raise InvalidSchema, pathname: schema_file_pathname
|
47
|
+
when !has_base_url?
|
48
|
+
raise BaseUrlNotFound, pathname: schema_file_pathname
|
49
|
+
when !has_link?
|
50
|
+
raise LinkNotFound, pathname: schema_file_pathname, action_name: action_name, target_name: target_name
|
45
51
|
end
|
46
52
|
end
|
47
53
|
|
@@ -60,11 +66,26 @@ module Plz
|
|
60
66
|
!!schema_file_pathname
|
61
67
|
end
|
62
68
|
|
63
|
-
# @return [true, false] True if no error occured in parsing schema file
|
69
|
+
# @return [true, false] True if no error occured in parsing schema file as JSON Schema
|
64
70
|
def has_valid_schema_file?
|
71
|
+
!!json_schema
|
72
|
+
end
|
73
|
+
|
74
|
+
# @return [true, false] True if no error occured in decoding schema file
|
75
|
+
def has_decodable_schema_file?
|
65
76
|
!!schema
|
66
77
|
end
|
67
78
|
|
79
|
+
# @return [true, false] True if given JSON Schema has a link of base URL of API
|
80
|
+
def has_base_url?
|
81
|
+
!!base_url
|
82
|
+
end
|
83
|
+
|
84
|
+
# @return [true, false] True if any link for given action and target found
|
85
|
+
def has_link?
|
86
|
+
!!link
|
87
|
+
end
|
88
|
+
|
68
89
|
# @return [Hash]
|
69
90
|
def schema
|
70
91
|
@schema ||= begin
|
@@ -109,22 +130,53 @@ module Plz
|
|
109
130
|
def headers
|
110
131
|
end
|
111
132
|
|
133
|
+
# @return [String]
|
134
|
+
# @example
|
135
|
+
# path #=> "/users"
|
136
|
+
def path
|
137
|
+
link.href
|
138
|
+
end
|
139
|
+
|
140
|
+
# @return [String]
|
141
|
+
# @example
|
142
|
+
# method #=> "GET"
|
143
|
+
def method
|
144
|
+
link.method.to_s.upcase
|
145
|
+
end
|
146
|
+
|
147
|
+
# Extracts the base url of the API
|
148
|
+
# @return [String, nil]
|
149
|
+
# @example
|
150
|
+
# base_url #=> "https://api.example.com/"
|
151
|
+
def base_url
|
152
|
+
@base_url ||= json_schema.links.find do |link|
|
153
|
+
if link.href && link.rel == "self"
|
154
|
+
return link.href
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
# @return [JsonSchema::Schema::Link, nil]
|
160
|
+
def link
|
161
|
+
@link ||= json_schema.properties.find do |key, schema|
|
162
|
+
if key == target_name
|
163
|
+
schema.links.find do |link|
|
164
|
+
if link.href && link.method && link.title.underscore == action_name
|
165
|
+
return link
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
# @return [JsonSchema::Schema, nil]
|
173
|
+
def json_schema
|
174
|
+
@json_schema ||= JsonSchema.parse!(@schema).tap(&:expand_references!)
|
175
|
+
rescue JsonSchema::SchemaError
|
176
|
+
end
|
177
|
+
|
112
178
|
class Error < Error
|
113
|
-
USAGE =
|
114
|
-
$ plz <action> <target> [headers|params]
|
115
|
-
| | | |
|
116
|
-
| | | `---- key=value ({"key":"value"}) or key:=value ({"key":value})
|
117
|
-
| | | params can be:
|
118
|
-
| | | * URI Template variable
|
119
|
-
| | | * Query string in GET method
|
120
|
-
| | | * Request body in other methods
|
121
|
-
| | |
|
122
|
-
| | `----------- Key:value
|
123
|
-
| |
|
124
|
-
| `--------------------- target resource name (e.g. user, recipe, etc.)
|
125
|
-
|
|
126
|
-
`------------------------------ action name (e.g. show, list, create, delete, etc.)
|
127
|
-
EOS
|
179
|
+
USAGE = "Usage: plz <action> <target> [headers|params]"
|
128
180
|
end
|
129
181
|
|
130
182
|
class NoActionName < Error
|
@@ -145,13 +197,39 @@ module Plz
|
|
145
197
|
end
|
146
198
|
end
|
147
199
|
|
148
|
-
class
|
149
|
-
def initialize(pathname)
|
200
|
+
class InvalidSchema < Error
|
201
|
+
def initialize(pathname: pathname)
|
150
202
|
@pathname = pathname
|
151
203
|
end
|
204
|
+
end
|
205
|
+
|
206
|
+
class UndecodableSchemaFile < InvalidSchema
|
207
|
+
def to_s
|
208
|
+
"Failed to decode #{@pathname}"
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
class InvalidSchemaFile < InvalidSchema
|
213
|
+
def to_s
|
214
|
+
"#{@pathname} was invalid JSON Schema"
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
class BaseUrlNotFound < InvalidSchema
|
219
|
+
def to_s
|
220
|
+
"#{@pathname} has no base URL at top-level links property"
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
class LinkNotFound < InvalidSchema
|
225
|
+
def initialize(action_name: action_name, target_name: target_name, **args)
|
226
|
+
super(**args)
|
227
|
+
@action_name = action_name
|
228
|
+
@target_name = target_name
|
229
|
+
end
|
152
230
|
|
153
231
|
def to_s
|
154
|
-
"
|
232
|
+
"#{@pathname} has no definition for `#{@action_name} #{@target_name}`"
|
155
233
|
end
|
156
234
|
end
|
157
235
|
end
|
data/lib/plz/response.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
module Plz
|
2
|
+
class Response
|
3
|
+
TEMPLATE = <<-EOS.strip_heredoc
|
4
|
+
HTTP/1.1 %{status}
|
5
|
+
%{headers}
|
6
|
+
|
7
|
+
%{body}
|
8
|
+
EOS
|
9
|
+
|
10
|
+
# @param [Faraday::Response]
|
11
|
+
def initialize(raw)
|
12
|
+
@raw = raw
|
13
|
+
end
|
14
|
+
|
15
|
+
# @return [String]
|
16
|
+
def render
|
17
|
+
TEMPLATE % {
|
18
|
+
status: status,
|
19
|
+
headers: headers.join("\n"),
|
20
|
+
body: body,
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
# @return [Array<String>]
|
27
|
+
def headers
|
28
|
+
@raw.headers.sort_by do |key, value|
|
29
|
+
key
|
30
|
+
end.map do |key, value|
|
31
|
+
"%{key}: %{value}" % {
|
32
|
+
key: Rainbow(key.split("-").map(&:camelize).join("-")).underline,
|
33
|
+
value: value,
|
34
|
+
}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# @return [String]
|
39
|
+
def status
|
40
|
+
Rainbow("#{status_code} #{status_in_words}").bright
|
41
|
+
end
|
42
|
+
|
43
|
+
# @return [Fixnum]
|
44
|
+
def status_code
|
45
|
+
@raw.status
|
46
|
+
end
|
47
|
+
|
48
|
+
# @return [String] Words for its status code
|
49
|
+
def status_in_words
|
50
|
+
Rack::Utils::HTTP_STATUS_CODES[@raw.status]
|
51
|
+
end
|
52
|
+
|
53
|
+
# @return [String]
|
54
|
+
def body
|
55
|
+
Rouge::Formatters::Terminal256.format(
|
56
|
+
Rouge::Lexers::Javascript.new.lex(plain_body),
|
57
|
+
theme: "github"
|
58
|
+
)
|
59
|
+
end
|
60
|
+
|
61
|
+
# @return [String] Pretty-printed JSON body
|
62
|
+
def plain_body
|
63
|
+
JSON.pretty_generate(@raw.body)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
data/lib/plz/version.rb
CHANGED
data/plz.gemspec
CHANGED
@@ -20,6 +20,9 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.add_dependency "faraday"
|
21
21
|
spec.add_dependency "faraday_middleware"
|
22
22
|
spec.add_dependency "json_schema"
|
23
|
+
spec.add_dependency "rack"
|
24
|
+
spec.add_dependency "rainbow"
|
25
|
+
spec.add_dependency "rouge"
|
23
26
|
spec.add_development_dependency "bundler", "~> 1.6"
|
24
27
|
spec.add_development_dependency "rake"
|
25
28
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: plz
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryo Nakamura
|
@@ -66,6 +66,48 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rack
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rainbow
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rouge
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
69
111
|
- !ruby/object:Gem::Dependency
|
70
112
|
name: bundler
|
71
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -103,6 +145,7 @@ extensions: []
|
|
103
145
|
extra_rdoc_files: []
|
104
146
|
files:
|
105
147
|
- ".gitignore"
|
148
|
+
- CHANGELOG.md
|
106
149
|
- Gemfile
|
107
150
|
- LICENSE.txt
|
108
151
|
- README.md
|
@@ -113,6 +156,7 @@ files:
|
|
113
156
|
- lib/plz/command_builder.rb
|
114
157
|
- lib/plz/error.rb
|
115
158
|
- lib/plz/error_command.rb
|
159
|
+
- lib/plz/response.rb
|
116
160
|
- lib/plz/version.rb
|
117
161
|
- plz.gemspec
|
118
162
|
- schema.yml
|