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 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