plz 0.0.1 → 0.0.2

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
  SHA1:
3
- metadata.gz: 488ff35d58b0afabb4dc2ef94aafee3456bec27f
4
- data.tar.gz: db861eecffcf54f36e841e3472ba135522e42190
3
+ metadata.gz: 2f07a8d7d61f673d93630bc76387e45042ecaba6
4
+ data.tar.gz: c1b1b718a3cf09b83b80aca3c783e3c5991f84fd
5
5
  SHA512:
6
- metadata.gz: ae44fcd683b3a0abb5df567df603cc4384ae3ce83adcdd7c0df2fc6d2b83859b226bebbba18dce34e48214806bafa4e53b7578c74e161cd4e47e6bfa0060b8de
7
- data.tar.gz: 9453b228fc5806abb8d50a666aed30f92cd84b97c5436fcd5b8a4e63bea9455f09c66e43d00314bb029c8a1eae53077de2acf7a3fffd4ffd28614673f6f936b7
6
+ metadata.gz: 3485ee06d7409b3a8c15544245947f6fd5121165f7b488de9fd6637142a00bb18e80c7a014399d50e76a6e68f68cf9d25e0459a2cc4aba3388073ebd15b139d6
7
+ data.tar.gz: 406e5b5bd2e6bd055934214adbdb50925703eef87def6633c62eebdf04acd2cc67f0613b6b056e9f082a3954758479712e0914d4836adba00ab1c65e0e4dc5f7
data/CHANGELOG.md ADDED
@@ -0,0 +1,6 @@
1
+ ## 0.0.2
2
+ * cURL-like output
3
+ * Color output
4
+
5
+ ## 0.0.1
6
+ * 1st release
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 schema [Hash]
8
- def initialize(action_name: nil, target_name: nil, headers: nil, params: nil, schema: nil)
9
- @action_name = action_name
10
- @target_name = target_name
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
- @schema = schema
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
- puts client.send(method, path, @params, @headers).body
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
@@ -1,6 +1,6 @@
1
1
  module Plz
2
2
  class CommandBuilder
3
- SCHEMA_FILE_PATH_PATTERN = "{.,config}/schema.{json,yml}"
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
- action_name: action_name,
23
- target_name: target_name,
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 InvalidSchemaFile, schema_file_pathname
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 = <<-EOS.strip_heredoc
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 InvalidSchemaFile < Error
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
- "Failed to parse #{@pathname}"
232
+ "#{@pathname} has no definition for `#{@action_name} #{@target_name}`"
155
233
  end
156
234
  end
157
235
  end
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Plz
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
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.1
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