mudbug 0.6.0.1 → 0.7.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (8) hide show
  1. data/MANIFEST.txt +1 -0
  2. data/README.md +65 -47
  3. data/VERSION +1 -1
  4. data/bin/mb +42 -61
  5. data/lib/mb_config.rb +9 -4
  6. data/lib/mudbug.rb +10 -4
  7. metadata +27 -15
  8. checksums.yaml +0 -15
data/MANIFEST.txt CHANGED
@@ -8,3 +8,4 @@ lib/mudbug.rb
8
8
  lib/mb_config.rb
9
9
  test/mudbug.rb
10
10
  examples/accepts_and_methods.rb
11
+ bin/mb
data/README.md CHANGED
@@ -19,82 +19,105 @@ Install the gem:
19
19
 
20
20
  Or, if using bundler, add to your Gemfile:
21
21
 
22
- gem 'mudbug', '~> 0'
22
+ gem 'mudbug', '~> 0.6'
23
23
 
24
24
  Quick Start
25
25
  -----------
26
26
  Initialize it with a host:
27
27
 
28
- require 'mudbug'
29
- mb = Mudbug.new 'ip.jsontest.com'
28
+ ```ruby
29
+ require 'mudbug'
30
+ mb = Mudbug.new 'ip.jsontest.com'
31
+ ```
30
32
 
31
33
  The convenience methods *#get*, *#post*, *#put*, or *#delete* return the response body. If the response has a *Content-type:* **application/json** header, then JSON parsing will be automatically performed on the response body, with the resulting object returned.
32
34
 
33
- response = mb.get '/'
34
- # => {"ip"=>"12.34.56.78"}
35
+ ```ruby
36
+ response = mb.get '/'
37
+ # => {"ip"=>"12.34.56.78"}
35
38
 
36
- response.class
37
- # => Hash
39
+ response.class
40
+ # => Hash
41
+ ```
38
42
 
39
43
  Usage
40
44
  -----
41
45
  You can pass through persistent [options to rest-client](https://github.com/rest-client/rest-client/blob/master/lib/restclient/request.rb):
42
46
 
43
- require 'mudbug'
44
- mb = Mudbug.new 'google.com', max_redirects: 3
47
+ ```ruby
48
+ require 'mudbug'
49
+ mb = Mudbug.new 'google.com', max_redirects: 3
50
+ ```
45
51
 
46
52
  Declare what you accept: (optional, default shown)
47
53
 
48
- mb.accept :json, :html, :text
54
+ ```ruby
55
+ mb.accept :json, :html, :text
56
+ ```
49
57
 
50
58
  You can pass through per-request [options to rest-client](https://github.com/rest-client/rest-client/blob/master/lib/restclient/request.rb)
51
59
 
52
- mb.get '/', max_redirects: 3
53
- # => "<!doctype html><html ... <head><meta content=\"Search the world's information ... "
60
+ ```ruby
61
+ mb.get '/', max_redirects: 3
62
+ # => "<!doctype html><html ... <head><meta content=\"Search the world's information ... "
63
+ ```
54
64
 
55
65
  [RestClient exceptions](https://github.com/rest-client/rest-client/blob/master/lib/restclient/exceptions.rb) will be passed through. POST and PUT payloads will be sent as strings. Non-string payloads will be converted to JSON by calling #to_json.
56
66
 
57
- mb = Mudbug.new 'plus.google.com'
58
- mb.post '/', { 'hi' => 'mom' }, max_redirects: 3
67
+ ```ruby
68
+ mb = Mudbug.new 'plus.google.com'
69
+ mb.post '/', { 'hi' => 'mom' }, max_redirects: 3
59
70
 
60
- /path/to/lib/restclient/abstract_response.rb:48:in `return!': 405 Method Not Allowed (RestClient::MethodNotAllowed)
71
+ # /path/to/lib/restclient/abstract_response.rb:48:in `return!': 405 Method Not Allowed (RestClient::MethodNotAllowed)
61
72
 
62
- # lawyer up
63
- # hit gym
64
- Mudbug.new('facebook.com').delete '/'
73
+ # lawyer up
74
+ # hit gym
75
+ Mudbug.new('facebook.com').delete '/'
65
76
 
66
- /path/to/lib/restclient/abstract_response.rb:39:in `return!': 301 Moved Permanently (RestClient::MovedPermanently)
77
+ # /path/to/lib/restclient/abstract_response.rb:39:in `return!': 301 Moved Permanently (RestClient::MovedPermanently)
78
+ ```
67
79
 
68
80
  Digging Deeper
69
81
  --------------
70
82
  Call Mudbug#resource directly for finer-grained response handling:
71
83
 
72
- resp = Mudbug.new('google.com').resource('/').get
73
- # check resp.code
74
- # check resp.headers
75
- # process resp.body
76
- # etc.
84
+ ```ruby
85
+ resp = Mudbug.new('google.com').resource('/').get
86
+ # check resp.code
87
+ # check resp.headers
88
+ # process resp.body
89
+ # etc.
90
+ ```
77
91
 
78
92
  Here is the heart of Mudbug's [response processing](https://github.com/rickhull/mudbug/blob/master/lib/mudbug.rb#L45):
79
93
 
80
- # this structure declares what we support in the request Accept: header
81
- # and defines automatic processing of the response based on the
82
- # response Content-type: header
83
- #
84
- CONTENT = {
85
- json: {
86
- type: 'application/json',
87
- proc: proc { |text| JSON.parse(text, symobolize_names: true) },
88
- },
89
- html: {
90
- type: 'text/html',
91
- proc: proc { |text| text },
92
- },
93
- text: {
94
- type: 'text/plain',
95
- proc: proc { |text| text },
96
- },
97
- }
94
+ ```ruby
95
+ # this structure declares what we support in the request Accept: header
96
+ # and defines automatic processing of the response based on the
97
+ # response Content-type: header
98
+ #
99
+ CONTENT = {
100
+ json: {
101
+ type: 'application/json',
102
+ proc: proc { |text| JSON.parse(text, symobolize_names: true) },
103
+ },
104
+ html: {
105
+ type: 'text/html',
106
+ proc: proc { |text| text },
107
+ },
108
+ text: {
109
+ type: 'text/plain',
110
+ proc: proc { |text| text },
111
+ },
112
+ }
113
+ ```
114
+
115
+ Careful with that axe, Eugene.
116
+
117
+ Examples
118
+ --------
119
+ * accepts_and_methods [sample script](https://github.com/rickhull/mudbug/blob/master/examples/accepts_and_methods.rb)
120
+ * accepts_and_methods [sample output](https://github.com/rickhull/mudbug/blob/master/examples/accepts_and_methods.txt)
98
121
 
99
122
  Funny, that
100
123
  -----------
@@ -103,8 +126,3 @@ Mudbug works best with webservers that respect the *Accept:* request header and
103
126
  [RFC 2616](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html)
104
127
 
105
128
  > If no Accept header field is present, then it is assumed that the client accepts all media types. If an Accept header field is present, and if the server cannot send a response which is acceptable according to the combined Accept field value, then the server SHOULD send a 406 (not acceptable) response.
106
-
107
- Examples
108
- --------
109
- * accepts_and_methods [sample script](https://github.com/rickhull/mudbug/blob/master/examples/accepts_and_methods.rb)
110
- * accepts_and_methods [sample output](https://github.com/rickhull/mudbug/blob/master/examples/accepts_and_methods.txt)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.6.0.1
1
+ 0.7.0.1
data/bin/mb CHANGED
@@ -1,8 +1,10 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
+ require 'mb_config'
4
+
3
5
  def usage(msg = nil)
4
6
  puts "ERROR: #{msg}" if msg
5
- puts <<USAGE
7
+ puts <<EOF
6
8
  USAGE:
7
9
  mb [get|delete] [PATH] - GET or DELETE PATH
8
10
  mb [post|put] [PATH] - - POST or PUT payload (STDIN) to PATH
@@ -12,10 +14,11 @@ USAGE:
12
14
  mb payload [-] - Set (from STDIN) or display payload config
13
15
  mb config - Display current config
14
16
 
15
- * A host must be configured for mb to operate
16
- * method, path, and payload, if configured, can be omitted as CLI arguments
17
- * accept is optional; valid values include json, html, text
18
- USAGE
17
+ * A `host` must be configured for mb to operate
18
+ * `method`, `path`, and `payload`, if configured, are not required arguments
19
+ * Set a config item to nil in order to remove it
20
+ * `accept` is optional; valid values include json, html, text
21
+ EOF
19
22
  puts
20
23
  puts "CONFIG: #{MbConfig.dump}"
21
24
 
@@ -27,8 +30,6 @@ def conclude(msg)
27
30
  exit 0
28
31
  end
29
32
 
30
- require 'mb_config'
31
-
32
33
  #
33
34
  # Config section: handle commands that manipulate MbConfig
34
35
  # Should exit in all cases with conclude()
@@ -96,9 +97,7 @@ if cfg_cmd
96
97
  end
97
98
  when 1
98
99
  # did they provide a quoted or CSV list? or pseudo-symbols with colons?
99
- accepts = accepts.first.split(/[ ,:]+/).map { |s|
100
- s.empty? ? nil : s
101
- }.compact
100
+ accepts = accepts.first.split(/[ ,:]+/).select { |s| !s.empty? }
102
101
  else
103
102
  accepts.map! { |s| s.gsub %r{[ ,:]+}, '' }
104
103
  end
@@ -112,87 +111,69 @@ if cfg_cmd
112
111
  end
113
112
 
114
113
  #
115
- # Done with manipulating MbConfig
116
- #
117
-
118
- #
119
- # Stage 2: create Mudbug based on MbConfig and command line options
114
+ # OK, we're not manipulating MbConfig
115
+ # Create Mudbug, determine method and path - from MbConfig and cmd line args
120
116
  #
121
117
 
122
118
  # set the host, always from MbConfig
119
+ #
123
120
  usage "no host is set" unless MbConfig['host']
124
121
  mb = Mudbug.new MbConfig['host']
125
122
 
126
123
  mb.accept MbConfig['accept'].map(&:to_sym) if MbConfig['accept']
127
124
 
128
125
  # set the method, possibly from CLI args
129
- meth_cmd = ARGV.first
130
- case meth_cmd
131
- when 'get', 'post', 'put', 'delete', 'del'
132
- ARGV.shift # confirmed meth_cmd, go ahead and shift
133
- method = meth_cmd
126
+ #
127
+ case ARGV.first
128
+ when 'get', 'post', 'put', 'delete'# , 'patch' # Soon(tm)
129
+ method = ARGV.shift
134
130
  else
135
131
  method = MbConfig['method'] or usage "no method provided"
136
132
  end
137
133
 
138
134
  # set the path, possibly from CLI args
139
- path_cmd = ARGV.first
140
- case path_cmd
135
+ #
136
+ case ARGV.first
141
137
  when %r{^\/} # starts with a slash
142
- ARGV.shift # confirmed path_cmd, go ahead and shift
143
- path = path_cmd
138
+ path = ARGV.shift
144
139
  else
145
140
  path = MbConfig['path'] or usage "no path provided"
146
141
  end
147
142
 
143
+ # determine method
144
+ # gather payload as required
145
+ # create args for sending the request
148
146
  #
149
- # no payload yet; run GET and DELETE
150
- #
151
-
152
147
  case method
153
- when 'get'
154
- begin
155
- data = mb.get path
156
- rescue RuntimeError => e
157
- puts "#{e} - #{e.class}"
158
- exit 1
159
- end
160
- conclude JSON.pretty_generate data
161
- when 'del', 'delete'
162
- begin
163
- data = mb.delete path
164
- rescue RuntimeError => e
165
- puts "#{e} - #{e.class}"
166
- exit 1
167
- end
168
- conclude JSON.pretty_generate data
148
+ when 'get', 'delete'
149
+ args = [method, path]
169
150
  when 'post', 'put', 'patch'
170
- # do nothing for now
151
+ # get payload
152
+ case ARGV.first
153
+ when nil
154
+ payload = MbConfig['payload'] or usage "no payload provided"
155
+ when '-'
156
+ begin
157
+ payload = JSON.parse $stdin.read
158
+ rescue
159
+ usage "could not parse payload:\n#{payload.inspect}"
160
+ end
161
+ end
162
+ args = [method, path, payload]
171
163
  else
172
164
  usage "Bad HTTP method #{method}"
173
165
  end
174
166
 
175
- # to get here, we must be doing POST, PUT, or PATCH
176
- # we need a payload
177
-
178
- payload = ARGV.first
179
- case payload
180
- when nil
181
- payload = MbConfig['payload'] or usage "no payload provided"
182
- when '-'
183
- payload = $stdin.read
184
- begin
185
- JSON.parse payload
186
- rescue
187
- usage "could not parse payload:\n#{payload.inspect}"
188
- end
189
- end
167
+ #
168
+ # finally!
169
+ #
190
170
 
191
171
  begin
192
- data = mb.send(method, path, payload)
172
+ data = mb.send(*args)
193
173
  rescue RuntimeError => e
194
174
  puts "#{e} - #{e.class}"
195
175
  exit 1
196
176
  end
197
177
 
198
- conclude JSON.pretty_generate data
178
+ data = JSON.pretty_generate data unless data.is_a? String
179
+ conclude data
data/lib/mb_config.rb CHANGED
@@ -26,16 +26,21 @@ module MbConfig
26
26
  #
27
27
  def self.load
28
28
  reset unless File.exists?(FILE)
29
+ rescues = 0
29
30
  begin
30
31
  File.open(FILE, 'r') { |f|
31
32
  CFG.merge! JSON.parse f.read
32
33
  }
33
34
  rescue JSON::ParserError => e
35
+ rescues += 1
34
36
  puts "#{e} (#{e.class})"
35
- puts "Resetting #{FILE}"
36
- reset
37
- # recursion; depends on .reset writing parseable JSON to stop
38
- load
37
+ if rescues < 2
38
+ puts "Resetting #{FILE}"
39
+ reset
40
+ retry
41
+ end
42
+ Mudbug.lager.fatal { "MbConfig.load failed!" }
43
+ raise e
39
44
  end
40
45
  end
41
46
 
data/lib/mudbug.rb CHANGED
@@ -84,8 +84,6 @@ class Mudbug
84
84
  attr_accessor :host
85
85
 
86
86
  def initialize(host, options = {})
87
- # note, not yet logging at instance layer
88
- # @lager = self.class.lager
89
87
  @host = host
90
88
  @options = options
91
89
  accept :json, :html, :text
@@ -107,10 +105,18 @@ class Mudbug
107
105
 
108
106
  # use this method directly if you want finer-grained request and response
109
107
  # handling
108
+ # supports /path/to/res, path/to/res, http://host.com/path/to/res
110
109
  #
111
110
  def resource(path, options = {})
112
- path = "/#{path}" unless path[0,1] == '/'
113
- RestClient::Resource.new "http://#{@host}#{path}", @options.merge(options)
111
+ uri = URI.parse(path)
112
+ if uri.host # a full URL was passed in
113
+ @host = uri.host
114
+ url = uri.to_s
115
+ else
116
+ path = "/#{path}" unless path[0,1] == '/'
117
+ url = "http://#{@host}#{path}"
118
+ end
119
+ RestClient::Resource.new url, @options.merge(options)
114
120
  end
115
121
 
116
122
  # no payload
metadata CHANGED
@@ -1,85 +1,96 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mudbug
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0.1
4
+ version: 0.7.0.1
5
+ prerelease:
5
6
  platform: ruby
6
7
  authors:
7
8
  - Rick Hull
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2013-07-12 00:00:00.000000000 Z
12
+ date: 2013-07-19 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: rest-client
15
16
  requirement: !ruby/object:Gem::Requirement
17
+ none: false
16
18
  requirements:
17
19
  - - ~>
18
20
  - !ruby/object:Gem::Version
19
21
  version: '1'
22
+ type: :runtime
23
+ prerelease: false
20
24
  version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
21
26
  requirements:
22
27
  - - ~>
23
28
  - !ruby/object:Gem::Version
24
29
  version: '1'
25
- type: :runtime
26
- prerelease: false
27
30
  - !ruby/object:Gem::Dependency
28
31
  name: json
29
32
  requirement: !ruby/object:Gem::Requirement
33
+ none: false
30
34
  requirements:
31
35
  - - ~>
32
36
  - !ruby/object:Gem::Version
33
37
  version: '1'
38
+ type: :runtime
39
+ prerelease: false
34
40
  version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
35
42
  requirements:
36
43
  - - ~>
37
44
  - !ruby/object:Gem::Version
38
45
  version: '1'
39
- type: :runtime
40
- prerelease: false
41
46
  - !ruby/object:Gem::Dependency
42
47
  name: lager
43
48
  requirement: !ruby/object:Gem::Requirement
49
+ none: false
44
50
  requirements:
45
51
  - - ! '>='
46
52
  - !ruby/object:Gem::Version
47
53
  version: '0.2'
54
+ type: :runtime
55
+ prerelease: false
48
56
  version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
49
58
  requirements:
50
59
  - - ! '>='
51
60
  - !ruby/object:Gem::Version
52
61
  version: '0.2'
53
- type: :runtime
54
- prerelease: false
55
62
  - !ruby/object:Gem::Dependency
56
63
  name: minitest
57
64
  requirement: !ruby/object:Gem::Requirement
65
+ none: false
58
66
  requirements:
59
67
  - - ! '>='
60
68
  - !ruby/object:Gem::Version
61
69
  version: '0'
70
+ type: :development
71
+ prerelease: false
62
72
  version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
63
74
  requirements:
64
75
  - - ! '>='
65
76
  - !ruby/object:Gem::Version
66
77
  version: '0'
67
- type: :development
68
- prerelease: false
69
78
  - !ruby/object:Gem::Dependency
70
79
  name: buildar
71
80
  requirement: !ruby/object:Gem::Requirement
81
+ none: false
72
82
  requirements:
73
83
  - - ~>
74
84
  - !ruby/object:Gem::Version
75
85
  version: '1.4'
86
+ type: :development
87
+ prerelease: false
76
88
  version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
77
90
  requirements:
78
91
  - - ~>
79
92
  - !ruby/object:Gem::Version
80
93
  version: '1.4'
81
- type: :development
82
- prerelease: false
83
94
  description: GET, POST, PUT, and DELETE JSON payloads. Easy Accept headers. Fine-grained
84
95
  response handling using Mudbug#resource.
85
96
  email:
@@ -102,25 +113,26 @@ files:
102
113
  homepage: http://github.com/rickhull/mudbug
103
114
  licenses:
104
115
  - LGPL
105
- metadata: {}
106
116
  post_install_message:
107
117
  rdoc_options: []
108
118
  require_paths:
109
119
  - lib
110
120
  required_ruby_version: !ruby/object:Gem::Requirement
121
+ none: false
111
122
  requirements:
112
123
  - - ! '>='
113
124
  - !ruby/object:Gem::Version
114
125
  version: '0'
115
126
  required_rubygems_version: !ruby/object:Gem::Requirement
127
+ none: false
116
128
  requirements:
117
129
  - - ! '>='
118
130
  - !ruby/object:Gem::Version
119
131
  version: '0'
120
132
  requirements: []
121
133
  rubyforge_project:
122
- rubygems_version: 2.0.3
134
+ rubygems_version: 1.8.23
123
135
  signing_key:
124
- specification_version: 4
136
+ specification_version: 3
125
137
  summary: This hardy creature consumes JSON / REST APIs
126
138
  test_files: []
checksums.yaml DELETED
@@ -1,15 +0,0 @@
1
- ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- YmI3NzE0NGE5MmVjZGQ5NDgwNzRmZmZjOTdkNjVmMGQ1NGJjYmRkZQ==
5
- data.tar.gz: !binary |-
6
- MDQ5NGFhZTVkZTEyMzU4NjVjY2Y3NjI0YjAyNjEzNDEyNDdhNzdhMw==
7
- !binary "U0hBNTEy":
8
- metadata.gz: !binary |-
9
- MTAwMzFjZThlNWFkMTczNzM5YTFhMDQ2M2UxNzg3ZGU3OGE5MjYxMjYyYTNl
10
- ZDIwMGU3MmNhMGQzOWFlNWY4NzdmMDBmZTFhNWZiZjM2YmRiNDk3NWI2OTI1
11
- OWFhNDJlNWQwNGQwYjAyNTdhMDJmN2E1NjdiMTkzMmIwNDgzODc=
12
- data.tar.gz: !binary |-
13
- MjMyZTljZTNjMzMzM2M3YzhhNThiYjhmNDM1MTM0NTY2ZWMzZGY2N2NjMWVh
14
- YjM3N2QyYjYxOTMyNDcyY2JiMTBhYTY5MTlmOWE3NDBmMGE1OTUzZjM5ZjMx
15
- ZTJmMzMyMTI3MGYwMDc3NzlhMTczM2Y0ZDhlOTI2YzYxYWFkNDc=