mudbug 0.6.0.1 → 0.7.0.1

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