brightbox-cli 0.13.0 → 0.13.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.
@@ -24,7 +24,6 @@ Gem::Specification.new do |s|
24
24
  s.add_dependency 'excon', '~> 0.6.1'
25
25
  s.add_dependency 'builder'
26
26
  s.add_dependency 'mime-types'
27
- s.add_dependency 'multi_json', '~> 1.0.3'
28
27
  s.add_dependency 'net-scp', '~> 1.0.4'
29
28
  s.add_dependency 'net-ssh', '~> 2.2.1'
30
29
  s.add_dependency 'nokogiri', '~> 1.5.0'
@@ -0,0 +1,5 @@
1
+ LICENSE.md
2
+ README.md
3
+ bin/*
4
+ features/**/*.feature
5
+ lib/**/*.rb
@@ -0,0 +1,34 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ doc
19
+ rdoc
20
+ log
21
+
22
+ ## BUNDLER
23
+ *.gem
24
+ .bundle
25
+ pkg
26
+ Gemfile.lock
27
+
28
+ ## RCOV
29
+ coverage.data
30
+
31
+ ## RUBINIUS
32
+ *.rbc
33
+
34
+ ## PROJECT::SPECIFIC
@@ -0,0 +1,3 @@
1
+ --color
2
+ --format=nested
3
+ --backtrace
@@ -0,0 +1,9 @@
1
+ rvm:
2
+ - 1.8.6
3
+ - 1.8.7
4
+ - 1.9.1
5
+ - 1.9.2
6
+ - jruby
7
+ - rbx
8
+ - ree
9
+ - ruby-head
@@ -0,0 +1,7 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'json', '~> 1.4', :require => nil
4
+ gem 'json_pure', '~> 1.4', :require => nil
5
+ gem 'yajl-ruby', '~> 0.7', :require => nil
6
+
7
+ gemspec
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Michael Bleigh, Josh Kalderimis, Erik Michaels-Ober, and Intridea, Inc.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,70 @@
1
+ MultiJSON
2
+ =========
3
+
4
+ Lots of Ruby libraries utilize JSON parsing in some form, and everyone has
5
+ their favorite JSON library. In order to best support multiple JSON parsers and
6
+ libraries, <tt>multi_json</tt> is a general-purpose swappable JSON backend
7
+ library. You use it like so:
8
+
9
+ require 'multi_json'
10
+
11
+ MultiJson.engine = :yajl
12
+ MultiJson.decode('{"abc":"def"}') # decoded using Yajl
13
+
14
+ MultiJson.engine = :json_gem
15
+ MultiJson.engine = MultiJson::Engines::JsonGem # equivalent to previous line
16
+ MultiJson.encode({:abc => 'def'}) # encoded using the JSON gem
17
+
18
+ The <tt>engine</tt> setter takes either a symbol or a class (to allow for
19
+ custom JSON parsers) that responds to both <tt>.decode</tt> and
20
+ <tt>.encode</tt> at the class level.
21
+
22
+ MultiJSON tries to have intelligent defaulting. That is, if you have any of the
23
+ supported engines already loaded, it will utilize them before attempting to
24
+ load any. When loading, libraries are ordered by speed. First Yajl-Ruby, then
25
+ the JSON gem, then JSON pure. If no JSON library is available, MultiJSON falls
26
+ back to a bundled version of [OkJson](https://github.com/kr/okjson).
27
+
28
+ Continuous Integration
29
+ ----------------------
30
+ [![Build Status](http://travis-ci.org/intridea/multi_json.png)](http://travis-ci.org/intridea/multi_json)
31
+
32
+ Contributing
33
+ ------------
34
+ In the spirit of [free software](http://www.fsf.org/licensing/essays/free-sw.html), **everyone** is encouraged to help improve this project.
35
+
36
+ Here are some ways *you* can contribute:
37
+
38
+ * by using alpha, beta, and prerelease versions
39
+ * by reporting bugs
40
+ * by suggesting new features
41
+ * by writing or editing documentation
42
+ * by writing specifications
43
+ * by writing code (**no patch is too small**: fix typos, add comments, clean up inconsistent whitespace)
44
+ * by refactoring code
45
+ * by closing [issues](https://github.com/intridea/multi_json/issues)
46
+ * by reviewing patches
47
+
48
+ Submitting an Issue
49
+ -------------------
50
+ We use the [GitHub issue tracker](https://github.com/intridea/multi_json/issues) to track bugs and
51
+ features. Before submitting a bug report or feature request, check to make sure it hasn't already
52
+ been submitted. You can indicate support for an existing issuse by voting it up. When submitting a
53
+ bug report, please include a [Gist](https://gist.github.com/) that includes a stack trace and any
54
+ details that may be necessary to reproduce the bug, including your gem version, Ruby version, and
55
+ operating system. Ideally, a bug report should include a pull request with failing specs.
56
+
57
+ Submitting a Pull Request
58
+ -------------------------
59
+ 1. Fork the project.
60
+ 2. Create a topic branch.
61
+ 3. Implement your feature or bug fix.
62
+ 4. Add specs for your feature or bug fix.
63
+ 5. Run <tt>bundle exec rake spec</tt>. If your changes are not 100% covered, go back to step 4.
64
+ 6. Commit and push your changes.
65
+ 7. Submit a pull request. Please do not include changes to the gemspec, version, or history file. (If you want to create your own version for some reason, please do so in a separate commit.)
66
+
67
+ Copyright
68
+ ---------
69
+ Copyright (c) 2010 Michael Bleigh, Josh Kalderimis, Erik Michaels-Ober, and Intridea, Inc.
70
+ See [LICENSE](https://github.com/intridea/multi_json/blob/master/LICENSE.md) for details.
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler'
4
+ Bundler::GemHelper.install_tasks
5
+ rescue LoadError => e
6
+ warn "[WARNING]: It is recommended that you use bundler during development: gem install bundler"
7
+ end
8
+
9
+ require 'rspec/core/rake_task'
10
+ desc "Run all examples"
11
+ RSpec::Core::RakeTask.new(:spec)
12
+
13
+ task :default => :spec
14
+ task :test => :spec
15
+
16
+ require 'rdoc/task'
17
+ Rake::RDocTask.new do |rdoc|
18
+ rdoc.rdoc_dir = 'rdoc'
19
+ rdoc.title = "multi_json #{MultiJson::VERSION}"
20
+ rdoc.rdoc_files.include('README.md')
21
+ rdoc.rdoc_files.include('LICENSE.md')
22
+ rdoc.rdoc_files.include('lib/**/*.rb')
23
+ end
@@ -0,0 +1,74 @@
1
+ module MultiJson
2
+ class DecodeError < StandardError; end
3
+ module_function
4
+
5
+ @engine = nil
6
+
7
+ # Get the current engine class.
8
+ def engine
9
+ return @engine if @engine
10
+ self.engine = self.default_engine
11
+ @engine
12
+ end
13
+
14
+ REQUIREMENT_MAP = [
15
+ ["yajl", :yajl],
16
+ ["json", :json_gem],
17
+ ["json/pure", :json_pure]
18
+ ]
19
+
20
+ # The default engine based on what you currently
21
+ # have loaded and installed. First checks to see
22
+ # if any engines are already loaded, then checks
23
+ # to see which are installed if none are loaded.
24
+ def default_engine
25
+ return :yajl if defined?(::Yajl)
26
+ return :json_gem if defined?(::JSON)
27
+
28
+ REQUIREMENT_MAP.each do |(library, engine)|
29
+ begin
30
+ require library
31
+ return engine
32
+ rescue LoadError
33
+ next
34
+ end
35
+ end
36
+
37
+ :ok_json
38
+ end
39
+
40
+ # Set the JSON parser utilizing a symbol, string, or class.
41
+ # Supported by default are:
42
+ #
43
+ # * <tt>:json_gem</tt>
44
+ # * <tt>:json_pure</tt>
45
+ # * <tt>:ok_json</tt>
46
+ # * <tt>:yajl</tt>
47
+ def engine=(new_engine)
48
+ case new_engine
49
+ when String, Symbol
50
+ require "multi_json/engines/#{new_engine}"
51
+ @engine = MultiJson::Engines.const_get("#{new_engine.to_s.split('_').map{|s| s.capitalize}.join('')}")
52
+ when Class
53
+ @engine = new_engine
54
+ else
55
+ raise "Did not recognize your engine specification. Please specify either a symbol or a class."
56
+ end
57
+ end
58
+
59
+ # Decode a JSON string into Ruby.
60
+ #
61
+ # <b>Options</b>
62
+ #
63
+ # <tt>:symbolize_keys</tt> :: If true, will use symbols instead of strings for the keys.
64
+ def decode(string, options = {})
65
+ engine.decode(string, options)
66
+ rescue engine::ParseError => exception
67
+ raise DecodeError, exception.message, exception.backtrace
68
+ end
69
+
70
+ # Encodes a Ruby object as JSON.
71
+ def encode(object)
72
+ engine.encode(object)
73
+ end
74
+ end
@@ -0,0 +1,21 @@
1
+ require 'json' unless defined?(::JSON)
2
+
3
+ module MultiJson
4
+ module Engines
5
+ # Use the JSON gem to encode/decode.
6
+ class JsonGem
7
+ ParseError = ::JSON::ParserError
8
+
9
+ def self.decode(string, options = {}) #:nodoc:
10
+ opts = {}
11
+ opts[:symbolize_names] = options[:symbolize_keys]
12
+ string = string.read if string.respond_to?(:read)
13
+ ::JSON.parse(string, opts)
14
+ end
15
+
16
+ def self.encode(object) #:nodoc:
17
+ object.to_json
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ require 'json/pure' unless defined?(::JSON)
2
+
3
+ module MultiJson
4
+ module Engines
5
+ # Use JSON pure to encode/decode.
6
+ class JsonPure
7
+ ParseError = ::JSON::ParserError
8
+
9
+ def self.decode(string, options = {}) #:nodoc:
10
+ opts = {}
11
+ opts[:symbolize_names] = options[:symbolize_keys]
12
+ string = string.read if string.respond_to?(:read)
13
+ ::JSON.parse(string, opts)
14
+ end
15
+
16
+ def self.encode(object) #:nodoc:
17
+ object.to_json
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,48 @@
1
+ require "multi_json/vendor/ok_json" unless defined?(::OkJson)
2
+
3
+ module MultiJson
4
+ module Engines
5
+ class OkJson
6
+ ParseError = ::OkJson::Error
7
+
8
+ def self.decode(string, options = {}) #:nodoc:
9
+ string = string.read if string.respond_to?(:read)
10
+ result = ::OkJson.decode(string)
11
+ options[:symbolize_keys] ? symbolize_keys(result) : result
12
+ end
13
+
14
+ def self.encode(object) #:nodoc:
15
+ ::OkJson.valenc(stringify_keys(object))
16
+ end
17
+
18
+ def self.symbolize_keys(object) #:nodoc:
19
+ modify_keys(object) do |key|
20
+ key.is_a?(String) ? key.to_sym : key
21
+ end
22
+ end
23
+
24
+ def self.stringify_keys(object) #:nodoc:
25
+ modify_keys(object) do |key|
26
+ key.is_a?(Symbol) ? key.to_s : key
27
+ end
28
+ end
29
+
30
+ def self.modify_keys(object, &modifier) #:nodoc:
31
+ case object
32
+ when Array
33
+ object.map do |value|
34
+ modify_keys(value, &modifier)
35
+ end
36
+ when Hash
37
+ object.inject({}) do |result, (key, value)|
38
+ new_key = modifier.call(key)
39
+ new_value = modify_keys(value, &modifier)
40
+ result.merge! new_key => new_value
41
+ end
42
+ else
43
+ object
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,18 @@
1
+ require 'yajl' unless defined?(Yajl)
2
+
3
+ module MultiJson
4
+ module Engines
5
+ # Use the Yajl-Ruby library to encode/decode.
6
+ class Yajl
7
+ ParseError = ::Yajl::ParseError
8
+
9
+ def self.decode(string, options = {}) #:nodoc:
10
+ ::Yajl::Parser.new(:symbolize_keys => options[:symbolize_keys]).parse(string)
11
+ end
12
+
13
+ def self.encode(object) #:nodoc:
14
+ ::Yajl::Encoder.new.encode(object)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,581 @@
1
+ # Copyright 2011 Keith Rarick
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ # See https://github.com/kr/okjson for updates.
22
+
23
+ require 'stringio'
24
+
25
+ # Some parts adapted from
26
+ # http://golang.org/src/pkg/json/decode.go and
27
+ # http://golang.org/src/pkg/utf8/utf8.go
28
+ module OkJson
29
+ extend self
30
+
31
+
32
+ # Decodes a json document in string s and
33
+ # returns the corresponding ruby value.
34
+ # String s must be valid UTF-8. If you have
35
+ # a string in some other encoding, convert
36
+ # it first.
37
+ #
38
+ # String values in the resulting structure
39
+ # will be UTF-8.
40
+ def decode(s)
41
+ ts = lex(s)
42
+ v, ts = textparse(ts)
43
+ if ts.length > 0
44
+ raise Error, 'trailing garbage'
45
+ end
46
+ v
47
+ end
48
+
49
+
50
+ # Parses a "json text" in the sense of RFC 4627.
51
+ # Returns the parsed value and any trailing tokens.
52
+ # Note: this is almost the same as valparse,
53
+ # except that it does not accept atomic values.
54
+ def textparse(ts)
55
+ if ts.length < 0
56
+ raise Error, 'empty'
57
+ end
58
+
59
+ typ, _, val = ts[0]
60
+ case typ
61
+ when '{' then objparse(ts)
62
+ when '[' then arrparse(ts)
63
+ else
64
+ raise Error, "unexpected #{val.inspect}"
65
+ end
66
+ end
67
+
68
+
69
+ # Parses a "value" in the sense of RFC 4627.
70
+ # Returns the parsed value and any trailing tokens.
71
+ def valparse(ts)
72
+ if ts.length < 0
73
+ raise Error, 'empty'
74
+ end
75
+
76
+ typ, _, val = ts[0]
77
+ case typ
78
+ when '{' then objparse(ts)
79
+ when '[' then arrparse(ts)
80
+ when :val,:str then [val, ts[1..-1]]
81
+ else
82
+ raise Error, "unexpected #{val.inspect}"
83
+ end
84
+ end
85
+
86
+
87
+ # Parses an "object" in the sense of RFC 4627.
88
+ # Returns the parsed value and any trailing tokens.
89
+ def objparse(ts)
90
+ ts = eat('{', ts)
91
+ obj = {}
92
+
93
+ if ts[0][0] == '}'
94
+ return obj, ts[1..-1]
95
+ end
96
+
97
+ k, v, ts = pairparse(ts)
98
+ obj[k] = v
99
+
100
+ if ts[0][0] == '}'
101
+ return obj, ts[1..-1]
102
+ end
103
+
104
+ loop do
105
+ ts = eat(',', ts)
106
+
107
+ k, v, ts = pairparse(ts)
108
+ obj[k] = v
109
+
110
+ if ts[0][0] == '}'
111
+ return obj, ts[1..-1]
112
+ end
113
+ end
114
+ end
115
+
116
+
117
+ # Parses a "member" in the sense of RFC 4627.
118
+ # Returns the parsed values and any trailing tokens.
119
+ def pairparse(ts)
120
+ (typ, _, k), ts = ts[0], ts[1..-1]
121
+ if typ != :str
122
+ raise Error, "unexpected #{k.inspect}"
123
+ end
124
+ ts = eat(':', ts)
125
+ v, ts = valparse(ts)
126
+ [k, v, ts]
127
+ end
128
+
129
+
130
+ # Parses an "array" in the sense of RFC 4627.
131
+ # Returns the parsed value and any trailing tokens.
132
+ def arrparse(ts)
133
+ ts = eat('[', ts)
134
+ arr = []
135
+
136
+ if ts[0][0] == ']'
137
+ return arr, ts[1..-1]
138
+ end
139
+
140
+ v, ts = valparse(ts)
141
+ arr << v
142
+
143
+ if ts[0][0] == ']'
144
+ return arr, ts[1..-1]
145
+ end
146
+
147
+ loop do
148
+ ts = eat(',', ts)
149
+
150
+ v, ts = valparse(ts)
151
+ arr << v
152
+
153
+ if ts[0][0] == ']'
154
+ return arr, ts[1..-1]
155
+ end
156
+ end
157
+ end
158
+
159
+
160
+ def eat(typ, ts)
161
+ if ts[0][0] != typ
162
+ raise Error, "expected #{typ} (got #{ts[0].inspect})"
163
+ end
164
+ ts[1..-1]
165
+ end
166
+
167
+
168
+ # Sans s and returns a list of json tokens,
169
+ # excluding white space (as defined in RFC 4627).
170
+ def lex(s)
171
+ ts = []
172
+ while s.length > 0
173
+ typ, lexeme, val = tok(s)
174
+ if typ == nil
175
+ raise Error, "invalid character at #{s[0,10].inspect}"
176
+ end
177
+ if typ != :space
178
+ ts << [typ, lexeme, val]
179
+ end
180
+ s = s[lexeme.length..-1]
181
+ end
182
+ ts
183
+ end
184
+
185
+
186
+ # Scans the first token in s and
187
+ # returns a 3-element list, or nil
188
+ # if no such token exists.
189
+ #
190
+ # The first list element is one of
191
+ # '{', '}', ':', ',', '[', ']',
192
+ # :val, :str, and :space.
193
+ #
194
+ # The second element is the lexeme.
195
+ #
196
+ # The third element is the value of the
197
+ # token for :val and :str, otherwise
198
+ # it is the lexeme.
199
+ def tok(s)
200
+ case s[0]
201
+ when ?{ then ['{', s[0,1], s[0,1]]
202
+ when ?} then ['}', s[0,1], s[0,1]]
203
+ when ?: then [':', s[0,1], s[0,1]]
204
+ when ?, then [',', s[0,1], s[0,1]]
205
+ when ?[ then ['[', s[0,1], s[0,1]]
206
+ when ?] then [']', s[0,1], s[0,1]]
207
+ when ?n then nulltok(s)
208
+ when ?t then truetok(s)
209
+ when ?f then falsetok(s)
210
+ when ?" then strtok(s)
211
+ when Spc then [:space, s[0,1], s[0,1]]
212
+ when ?\t then [:space, s[0,1], s[0,1]]
213
+ when ?\n then [:space, s[0,1], s[0,1]]
214
+ when ?\r then [:space, s[0,1], s[0,1]]
215
+ else numtok(s)
216
+ end
217
+ end
218
+
219
+
220
+ def nulltok(s); s[0,4] == 'null' && [:val, 'null', nil] end
221
+ def truetok(s); s[0,4] == 'true' && [:val, 'true', true] end
222
+ def falsetok(s); s[0,5] == 'false' && [:val, 'false', false] end
223
+
224
+
225
+ def numtok(s)
226
+ m = /-?([1-9][0-9]+|[0-9])([.][0-9]+)?([eE][+-]?[0-9]+)?/.match(s)
227
+ if m && m.begin(0) == 0
228
+ if m[3] && !m[2]
229
+ [:val, m[0], Integer(m[1])*(10**Integer(m[3][1..-1]))]
230
+ elsif m[2]
231
+ [:val, m[0], Float(m[0])]
232
+ else
233
+ [:val, m[0], Integer(m[0])]
234
+ end
235
+ end
236
+ end
237
+
238
+
239
+ def strtok(s)
240
+ m = /"([^"\\]|\\["\/\\bfnrt]|\\u[0-9a-fA-F]{4})*"/.match(s)
241
+ if ! m
242
+ raise Error, "invalid string literal at #{abbrev(s)}"
243
+ end
244
+ [:str, m[0], unquote(m[0])]
245
+ end
246
+
247
+
248
+ def abbrev(s)
249
+ t = s[0,10]
250
+ p = t['`']
251
+ t = t[0,p] if p
252
+ t = t + '...' if t.length < s.length
253
+ '`' + t + '`'
254
+ end
255
+
256
+
257
+ # Converts a quoted json string literal q into a UTF-8-encoded string.
258
+ # The rules are different than for Ruby, so we cannot use eval.
259
+ # Unquote will raise an error if q contains control characters.
260
+ def unquote(q)
261
+ q = q[1...-1]
262
+ a = q.dup # allocate a big enough string
263
+ r, w = 0, 0
264
+ while r < q.length
265
+ c = q[r]
266
+ case true
267
+ when c == ?\\
268
+ r += 1
269
+ if r >= q.length
270
+ raise Error, "string literal ends with a \"\\\": \"#{q}\""
271
+ end
272
+
273
+ case q[r]
274
+ when ?",?\\,?/,?'
275
+ a[w] = q[r]
276
+ r += 1
277
+ w += 1
278
+ when ?b,?f,?n,?r,?t
279
+ a[w] = Unesc[q[r]]
280
+ r += 1
281
+ w += 1
282
+ when ?u
283
+ r += 1
284
+ uchar = begin
285
+ hexdec4(q[r,4])
286
+ rescue RuntimeError => e
287
+ raise Error, "invalid escape sequence \\u#{q[r,4]}: #{e}"
288
+ end
289
+ r += 4
290
+ if surrogate? uchar
291
+ if q.length >= r+6
292
+ uchar1 = hexdec4(q[r+2,4])
293
+ uchar = subst(uchar, uchar1)
294
+ if uchar != Ucharerr
295
+ # A valid pair; consume.
296
+ r += 6
297
+ end
298
+ end
299
+ end
300
+ w += ucharenc(a, w, uchar)
301
+ else
302
+ raise Error, "invalid escape char #{q[r]} in \"#{q}\""
303
+ end
304
+ when c == ?", c < Spc
305
+ raise Error, "invalid character in string literal \"#{q}\""
306
+ else
307
+ # Copy anything else byte-for-byte.
308
+ # Valid UTF-8 will remain valid UTF-8.
309
+ # Invalid UTF-8 will remain invalid UTF-8.
310
+ a[w] = c
311
+ r += 1
312
+ w += 1
313
+ end
314
+ end
315
+ a[0,w]
316
+ end
317
+
318
+
319
+ # Encodes unicode character u as UTF-8
320
+ # bytes in string a at position i.
321
+ # Returns the number of bytes written.
322
+ def ucharenc(a, i, u)
323
+ case true
324
+ when u <= Uchar1max
325
+ a[i] = (u & 0xff).chr
326
+ 1
327
+ when u <= Uchar2max
328
+ a[i+0] = (Utag2 | ((u>>6)&0xff)).chr
329
+ a[i+1] = (Utagx | (u&Umaskx)).chr
330
+ 2
331
+ when u <= Uchar3max
332
+ a[i+0] = (Utag3 | ((u>>12)&0xff)).chr
333
+ a[i+1] = (Utagx | ((u>>6)&Umaskx)).chr
334
+ a[i+2] = (Utagx | (u&Umaskx)).chr
335
+ 3
336
+ else
337
+ a[i+0] = (Utag4 | ((u>>18)&0xff)).chr
338
+ a[i+1] = (Utagx | ((u>>12)&Umaskx)).chr
339
+ a[i+2] = (Utagx | ((u>>6)&Umaskx)).chr
340
+ a[i+3] = (Utagx | (u&Umaskx)).chr
341
+ 4
342
+ end
343
+ end
344
+
345
+
346
+ def hexdec4(s)
347
+ if s.length != 4
348
+ raise Error, 'short'
349
+ end
350
+ (nibble(s[0])<<12) | (nibble(s[1])<<8) | (nibble(s[2])<<4) | nibble(s[3])
351
+ end
352
+
353
+
354
+ def subst(u1, u2)
355
+ if Usurr1 <= u1 && u1 < Usurr2 && Usurr2 <= u2 && u2 < Usurr3
356
+ return ((u1-Usurr1)<<10) | (u2-Usurr2) + Usurrself
357
+ end
358
+ return Ucharerr
359
+ end
360
+
361
+
362
+ def unsubst(u)
363
+ if u < Usurrself || u > Umax || surrogate?(u)
364
+ return Ucharerr, Ucharerr
365
+ end
366
+ u -= Usurrself
367
+ [Usurr1 + ((u>>10)&0x3ff), Usurr2 + (u&0x3ff)]
368
+ end
369
+
370
+
371
+ def surrogate?(u)
372
+ Usurr1 <= u && u < Usurr3
373
+ end
374
+
375
+
376
+ def nibble(c)
377
+ case true
378
+ when ?0 <= c && c <= ?9 then c.ord - ?0.ord
379
+ when ?a <= c && c <= ?z then c.ord - ?a.ord + 10
380
+ when ?A <= c && c <= ?Z then c.ord - ?A.ord + 10
381
+ else
382
+ raise Error, "invalid hex code #{c}"
383
+ end
384
+ end
385
+
386
+
387
+ # Encodes x into a json text. It may contain only
388
+ # Array, Hash, String, Numeric, true, false, nil.
389
+ # (Note, this list excludes Symbol.)
390
+ # X itself must be an Array or a Hash.
391
+ # No other value can be encoded, and an error will
392
+ # be raised if x contains any other value, such as
393
+ # Nan, Infinity, Symbol, and Proc, or if a Hash key
394
+ # is not a String.
395
+ # Strings contained in x must be valid UTF-8.
396
+ def encode(x)
397
+ case x
398
+ when Hash then objenc(x)
399
+ when Array then arrenc(x)
400
+ else
401
+ raise Error, 'root value must be an Array or a Hash'
402
+ end
403
+ end
404
+
405
+
406
+ def valenc(x)
407
+ case x
408
+ when Hash then objenc(x)
409
+ when Array then arrenc(x)
410
+ when String then strenc(x)
411
+ when Numeric then numenc(x)
412
+ when true then "true"
413
+ when false then "false"
414
+ when nil then "null"
415
+ else
416
+ raise Error, "cannot encode #{x.class}: #{x.inspect}"
417
+ end
418
+ end
419
+
420
+
421
+ def objenc(x)
422
+ '{' + x.map{|k,v| keyenc(k) + ':' + valenc(v)}.join(',') + '}'
423
+ end
424
+
425
+
426
+ def arrenc(a)
427
+ '[' + a.map{|x| valenc(x)}.join(',') + ']'
428
+ end
429
+
430
+
431
+ def keyenc(k)
432
+ case k
433
+ when String then strenc(k)
434
+ else
435
+ raise Error, "Hash key is not a string: #{k.inspect}"
436
+ end
437
+ end
438
+
439
+
440
+ def strenc(s)
441
+ t = StringIO.new
442
+ t.putc(?")
443
+ r = 0
444
+ while r < s.length
445
+ case s[r]
446
+ when ?" then t.print('\\"')
447
+ when ?\\ then t.print('\\\\')
448
+ when ?\b then t.print('\\b')
449
+ when ?\f then t.print('\\f')
450
+ when ?\n then t.print('\\n')
451
+ when ?\r then t.print('\\r')
452
+ when ?\t then t.print('\\t')
453
+ else
454
+ c = s[r]
455
+ case true
456
+ when Spc <= c && c <= ?~
457
+ t.putc(c)
458
+ when true
459
+ u, size = uchardec(s, r)
460
+ r += size - 1 # we add one more at the bottom of the loop
461
+ if u < 0x10000
462
+ t.print('\\u')
463
+ hexenc4(t, u)
464
+ else
465
+ u1, u2 = unsubst(u)
466
+ t.print('\\u')
467
+ hexenc4(t, u1)
468
+ t.print('\\u')
469
+ hexenc4(t, u2)
470
+ end
471
+ else
472
+ # invalid byte; skip it
473
+ end
474
+ end
475
+ r += 1
476
+ end
477
+ t.putc(?")
478
+ t.string
479
+ end
480
+
481
+
482
+ def hexenc4(t, u)
483
+ t.putc(Hex[(u>>12)&0xf])
484
+ t.putc(Hex[(u>>8)&0xf])
485
+ t.putc(Hex[(u>>4)&0xf])
486
+ t.putc(Hex[u&0xf])
487
+ end
488
+
489
+
490
+ def numenc(x)
491
+ if x.nan? || x.infinite?
492
+ return 'null'
493
+ end rescue nil
494
+ "#{x}"
495
+ end
496
+
497
+
498
+ # Decodes unicode character u from UTF-8
499
+ # bytes in string s at position i.
500
+ # Returns u and the number of bytes read.
501
+ def uchardec(s, i)
502
+ n = s.length - i
503
+ return [Ucharerr, 1] if n < 1
504
+
505
+ c0 = s[i].ord
506
+
507
+ # 1-byte, 7-bit sequence?
508
+ if c0 < Utagx
509
+ return [c0, 1]
510
+ end
511
+
512
+ # unexpected continuation byte?
513
+ return [Ucharerr, 1] if c0 < Utag2
514
+
515
+ # need continuation byte
516
+ return [Ucharerr, 1] if n < 2
517
+ c1 = s[i+1].ord
518
+ return [Ucharerr, 1] if c1 < Utagx || Utag2 <= c1
519
+
520
+ # 2-byte, 11-bit sequence?
521
+ if c0 < Utag3
522
+ u = (c0&Umask2)<<6 | (c1&Umaskx)
523
+ return [Ucharerr, 1] if u <= Uchar1max
524
+ return [u, 2]
525
+ end
526
+
527
+ # need second continuation byte
528
+ return [Ucharerr, 1] if n < 3
529
+ c2 = s[i+2].ord
530
+ return [Ucharerr, 1] if c2 < Utagx || Utag2 <= c2
531
+
532
+ # 3-byte, 16-bit sequence?
533
+ if c0 < Utag4
534
+ u = (c0&Umask3)<<12 | (c1&Umaskx)<<6 | (c2&Umaskx)
535
+ return [Ucharerr, 1] if u <= Uchar2max
536
+ return [u, 3]
537
+ end
538
+
539
+ # need third continuation byte
540
+ return [Ucharerr, 1] if n < 4
541
+ c3 = s[i+3].ord
542
+ return [Ucharerr, 1] if c3 < Utagx || Utag2 <= c3
543
+
544
+ # 4-byte, 21-bit sequence?
545
+ if c0 < Utag5
546
+ u = (c0&Umask4)<<18 | (c1&Umaskx)<<12 | (c2&Umaskx)<<6 | (c3&Umaskx)
547
+ return [Ucharerr, 1] if u <= Uchar3max
548
+ return [u, 4]
549
+ end
550
+
551
+ return [Ucharerr, 1]
552
+ end
553
+
554
+
555
+ class Error < ::StandardError
556
+ end
557
+
558
+
559
+ Utagx = 0x80 # 1000 0000
560
+ Utag2 = 0xc0 # 1100 0000
561
+ Utag3 = 0xe0 # 1110 0000
562
+ Utag4 = 0xf0 # 1111 0000
563
+ Utag5 = 0xF8 # 1111 1000
564
+ Umaskx = 0x3f # 0011 1111
565
+ Umask2 = 0x1f # 0001 1111
566
+ Umask3 = 0x0f # 0000 1111
567
+ Umask4 = 0x07 # 0000 0111
568
+ Uchar1max = (1<<7) - 1
569
+ Uchar2max = (1<<11) - 1
570
+ Uchar3max = (1<<16) - 1
571
+ Ucharerr = 0xFFFD # unicode "replacement char"
572
+ Usurrself = 0x10000
573
+ Usurr1 = 0xd800
574
+ Usurr2 = 0xdc00
575
+ Usurr3 = 0xe000
576
+ Umax = 0x10ffff
577
+
578
+ Spc = ' '[0]
579
+ Unesc = {?b=>?\b, ?f=>?\f, ?n=>?\n, ?r=>?\r, ?t=>?\t}
580
+ Hex = '0123456789abcdef'
581
+ end
@@ -0,0 +1,3 @@
1
+ module MultiJson
2
+ VERSION = "1.0.3"
3
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path("../lib/multi_json/version", __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.add_development_dependency 'rake', '~> 0.9'
6
+ gem.add_development_dependency 'rdoc', '3.5.1'
7
+ gem.add_development_dependency 'rspec', '~> 2.6'
8
+ gem.add_development_dependency 'simplecov', '~> 0.4'
9
+ gem.authors = ["Michael Bleigh", "Josh Kalderimis", "Erik Michaels-Ober"]
10
+ gem.description = %q{A gem to provide swappable JSON backends utilizing Yajl::Ruby, the JSON gem, JSON pure, or a vendored version of okjson.}
11
+ gem.email = ['michael@intridea.com', 'josh.kalderimis@gmail.com', 'sferik@gmail.com']
12
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{|f| File.basename(f)}
13
+ gem.extra_rdoc_files = ['LICENSE.md', 'README.md']
14
+ gem.files = `git ls-files`.split("\n")
15
+ gem.homepage = 'http://github.com/intridea/multi_json'
16
+ gem.name = 'multi_json'
17
+ gem.rdoc_options = ["--charset=UTF-8"]
18
+ gem.require_paths = ['lib']
19
+ gem.required_rubygems_version = Gem::Requirement.new(">= 1.3.6")
20
+ gem.summary = %q{A gem to provide swappable JSON backends.}
21
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
22
+ gem.version = MultiJson::VERSION
23
+ end
@@ -0,0 +1,11 @@
1
+ begin
2
+ require 'bundler'
3
+ Bundler.setup
4
+ rescue LoadError
5
+ warn "[WARNING]: It is recommended that you use bundler during development: gem install bundler"
6
+ end
7
+
8
+ require 'simplecov'
9
+ SimpleCov.start
10
+ require 'rspec'
11
+ require 'multi_json'
@@ -0,0 +1,134 @@
1
+ require 'helper'
2
+ require 'stringio'
3
+
4
+ class MockDecoder
5
+ def self.decode(string, options = {})
6
+ {'abc' => 'def'}
7
+ end
8
+
9
+ def self.encode(string)
10
+ '{"abc":"def"}'
11
+ end
12
+ end
13
+
14
+ describe "MultiJson" do
15
+ context 'engines' do
16
+ it 'defaults to ok_json if no other json implementions are available' do
17
+ old_map = MultiJson::REQUIREMENT_MAP
18
+ begin
19
+ MultiJson::REQUIREMENT_MAP.each_with_index do |(library, engine), index|
20
+ MultiJson::REQUIREMENT_MAP[index] = ["foo/#{library}", engine]
21
+ end
22
+ MultiJson.default_engine.should == :ok_json
23
+ ensure
24
+ old_map.each_with_index do |(library, engine), index|
25
+ MultiJson::REQUIREMENT_MAP[index] = [library, engine]
26
+ end
27
+ end
28
+ end
29
+
30
+ it 'defaults to the best available gem' do
31
+ require 'yajl'
32
+ MultiJson.engine.name.should == 'MultiJson::Engines::Yajl'
33
+ end
34
+
35
+ it 'is settable via a symbol' do
36
+ MultiJson.engine = :json_gem
37
+ MultiJson.engine.name.should == 'MultiJson::Engines::JsonGem'
38
+ end
39
+
40
+ it 'is settable via a class' do
41
+ MultiJson.engine = MockDecoder
42
+ MultiJson.engine.name.should == 'MockDecoder'
43
+ end
44
+ end
45
+
46
+ %w(json_gem json_pure ok_json yajl).each do |engine|
47
+ context engine do
48
+ before do
49
+ begin
50
+ MultiJson.engine = engine
51
+ rescue LoadError
52
+ pending "Engine #{engine} couldn't be loaded (not installed?)"
53
+ end
54
+ end
55
+
56
+ describe '.encode' do
57
+ it 'writes decodable JSON' do
58
+ [
59
+ { 'abc' => 'def' },
60
+ [1, 2, 3, "4"]
61
+ ].each do |example|
62
+ MultiJson.decode(MultiJson.encode(example)).should == example
63
+ end
64
+ end
65
+
66
+ it 'encodes symbol keys as strings' do
67
+ [
68
+ [
69
+ { :foo => { :bar => 'baz' } },
70
+ { 'foo' => { 'bar' => 'baz' } }
71
+ ],
72
+ [
73
+ [ { :foo => { :bar => 'baz' } } ],
74
+ [ { 'foo' => { 'bar' => 'baz' } } ],
75
+ ],
76
+ [
77
+ { :foo => [ { :bar => 'baz' } ] },
78
+ { 'foo' => [ { 'bar' => 'baz' } ] },
79
+ ]
80
+ ].each do |example, expected|
81
+ encoded_json = MultiJson.encode(example)
82
+ MultiJson.decode(encoded_json).should == expected
83
+ end
84
+ end
85
+
86
+ it 'encodes rootless JSON' do
87
+ MultiJson.encode("random rootless string").should == "\"random rootless string\""
88
+ MultiJson.encode(123).should == "123"
89
+ end
90
+ end
91
+
92
+ describe '.decode' do
93
+ it 'properly decodes valid JSON' do
94
+ MultiJson.decode('{"abc":"def"}').should == { 'abc' => 'def' }
95
+ end
96
+
97
+ it 'raises MultiJson::DecodeError on invalid JSON' do
98
+ lambda do
99
+ MultiJson.decode('{"abc"}')
100
+ end.should raise_error(MultiJson::DecodeError)
101
+ end
102
+
103
+ it 'stringifys symbol keys when encoding' do
104
+ encoded_json = MultiJson.encode(:a => 1, :b => {:c => 2})
105
+ MultiJson.decode(encoded_json).should == { "a" => 1, "b" => { "c" => 2 } }
106
+ end
107
+
108
+ it "properly decodes valid JSON in StringIOs" do
109
+ json = StringIO.new('{"abc":"def"}')
110
+ MultiJson.decode(json).should == { 'abc' => 'def' }
111
+ end
112
+
113
+ it 'allows for symbolization of keys' do
114
+ [
115
+ [
116
+ '{"abc":{"def":"hgi"}}',
117
+ { :abc => { :def => 'hgi' } }
118
+ ],
119
+ [
120
+ '[{"abc":{"def":"hgi"}}]',
121
+ [ { :abc => { :def => 'hgi' } } ]
122
+ ],
123
+ [
124
+ '{"abc":[{"def":"hgi"}]}',
125
+ { :abc => [ { :def => 'hgi' } ] }
126
+ ],
127
+ ].each do |example, expected|
128
+ MultiJson.decode(example, :symbolize_keys => true).should == expected
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
134
+ end
@@ -1,3 +1,3 @@
1
1
  module Brightbox
2
- VERSION = "0.13.0"
2
+ VERSION = "0.13.1"
3
3
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brightbox-cli
3
3
  version: !ruby/object:Gem::Version
4
- hash: 43
4
+ hash: 41
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 13
9
- - 0
10
- version: 0.13.0
9
+ - 1
10
+ version: 0.13.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - John Leach
@@ -109,26 +109,10 @@ dependencies:
109
109
  version: "0"
110
110
  type: :runtime
111
111
  version_requirements: *id006
112
- - !ruby/object:Gem::Dependency
113
- name: multi_json
114
- prerelease: false
115
- requirement: &id007 !ruby/object:Gem::Requirement
116
- none: false
117
- requirements:
118
- - - ~>
119
- - !ruby/object:Gem::Version
120
- hash: 17
121
- segments:
122
- - 1
123
- - 0
124
- - 3
125
- version: 1.0.3
126
- type: :runtime
127
- version_requirements: *id007
128
112
  - !ruby/object:Gem::Dependency
129
113
  name: net-scp
130
114
  prerelease: false
131
- requirement: &id008 !ruby/object:Gem::Requirement
115
+ requirement: &id007 !ruby/object:Gem::Requirement
132
116
  none: false
133
117
  requirements:
134
118
  - - ~>
@@ -140,11 +124,11 @@ dependencies:
140
124
  - 4
141
125
  version: 1.0.4
142
126
  type: :runtime
143
- version_requirements: *id008
127
+ version_requirements: *id007
144
128
  - !ruby/object:Gem::Dependency
145
129
  name: net-ssh
146
130
  prerelease: false
147
- requirement: &id009 !ruby/object:Gem::Requirement
131
+ requirement: &id008 !ruby/object:Gem::Requirement
148
132
  none: false
149
133
  requirements:
150
134
  - - ~>
@@ -156,11 +140,11 @@ dependencies:
156
140
  - 1
157
141
  version: 2.2.1
158
142
  type: :runtime
159
- version_requirements: *id009
143
+ version_requirements: *id008
160
144
  - !ruby/object:Gem::Dependency
161
145
  name: nokogiri
162
146
  prerelease: false
163
- requirement: &id010 !ruby/object:Gem::Requirement
147
+ requirement: &id009 !ruby/object:Gem::Requirement
164
148
  none: false
165
149
  requirements:
166
150
  - - ~>
@@ -172,11 +156,11 @@ dependencies:
172
156
  - 0
173
157
  version: 1.5.0
174
158
  type: :runtime
175
- version_requirements: *id010
159
+ version_requirements: *id009
176
160
  - !ruby/object:Gem::Dependency
177
161
  name: ruby-hmac
178
162
  prerelease: false
179
- requirement: &id011 !ruby/object:Gem::Requirement
163
+ requirement: &id010 !ruby/object:Gem::Requirement
180
164
  none: false
181
165
  requirements:
182
166
  - - ">="
@@ -186,11 +170,11 @@ dependencies:
186
170
  - 0
187
171
  version: "0"
188
172
  type: :runtime
189
- version_requirements: *id011
173
+ version_requirements: *id010
190
174
  - !ruby/object:Gem::Dependency
191
175
  name: rake
192
176
  prerelease: false
193
- requirement: &id012 !ruby/object:Gem::Requirement
177
+ requirement: &id011 !ruby/object:Gem::Requirement
194
178
  none: false
195
179
  requirements:
196
180
  - - ~>
@@ -202,11 +186,11 @@ dependencies:
202
186
  - 0
203
187
  version: 0.8.0
204
188
  type: :development
205
- version_requirements: *id012
189
+ version_requirements: *id011
206
190
  - !ruby/object:Gem::Dependency
207
191
  name: vcr
208
192
  prerelease: false
209
- requirement: &id013 !ruby/object:Gem::Requirement
193
+ requirement: &id012 !ruby/object:Gem::Requirement
210
194
  none: false
211
195
  requirements:
212
196
  - - ">="
@@ -216,11 +200,11 @@ dependencies:
216
200
  - 0
217
201
  version: "0"
218
202
  type: :development
219
- version_requirements: *id013
203
+ version_requirements: *id012
220
204
  - !ruby/object:Gem::Dependency
221
205
  name: rspec
222
206
  prerelease: false
223
- requirement: &id014 !ruby/object:Gem::Requirement
207
+ requirement: &id013 !ruby/object:Gem::Requirement
224
208
  none: false
225
209
  requirements:
226
210
  - - ">="
@@ -230,11 +214,11 @@ dependencies:
230
214
  - 0
231
215
  version: "0"
232
216
  type: :development
233
- version_requirements: *id014
217
+ version_requirements: *id013
234
218
  - !ruby/object:Gem::Dependency
235
219
  name: mocha
236
220
  prerelease: false
237
- requirement: &id015 !ruby/object:Gem::Requirement
221
+ requirement: &id014 !ruby/object:Gem::Requirement
238
222
  none: false
239
223
  requirements:
240
224
  - - ">="
@@ -244,7 +228,7 @@ dependencies:
244
228
  - 0
245
229
  version: "0"
246
230
  type: :development
247
- version_requirements: *id015
231
+ version_requirements: *id014
248
232
  description: Scripts to interact with the Brightbox cloud API
249
233
  email:
250
234
  - john@brightbox.co.uk
@@ -1969,6 +1953,25 @@ files:
1969
1953
  - lib/brightbox-cli/vendor/gli/test/tc_parsing.rb
1970
1954
  - lib/brightbox-cli/vendor/gli/test/tc_switch.rb
1971
1955
  - lib/brightbox-cli/vendor/gli/test/tc_terminal.rb
1956
+ - lib/brightbox-cli/vendor/multi_json/.document
1957
+ - lib/brightbox-cli/vendor/multi_json/.gemtest
1958
+ - lib/brightbox-cli/vendor/multi_json/.gitignore
1959
+ - lib/brightbox-cli/vendor/multi_json/.rspec
1960
+ - lib/brightbox-cli/vendor/multi_json/.travis.yml
1961
+ - lib/brightbox-cli/vendor/multi_json/Gemfile
1962
+ - lib/brightbox-cli/vendor/multi_json/LICENSE.md
1963
+ - lib/brightbox-cli/vendor/multi_json/README.md
1964
+ - lib/brightbox-cli/vendor/multi_json/Rakefile
1965
+ - lib/brightbox-cli/vendor/multi_json/lib/multi_json.rb
1966
+ - lib/brightbox-cli/vendor/multi_json/lib/multi_json/engines/json_gem.rb
1967
+ - lib/brightbox-cli/vendor/multi_json/lib/multi_json/engines/json_pure.rb
1968
+ - lib/brightbox-cli/vendor/multi_json/lib/multi_json/engines/ok_json.rb
1969
+ - lib/brightbox-cli/vendor/multi_json/lib/multi_json/engines/yajl.rb
1970
+ - lib/brightbox-cli/vendor/multi_json/lib/multi_json/vendor/ok_json.rb
1971
+ - lib/brightbox-cli/vendor/multi_json/lib/multi_json/version.rb
1972
+ - lib/brightbox-cli/vendor/multi_json/multi_json.gemspec
1973
+ - lib/brightbox-cli/vendor/multi_json/spec/helper.rb
1974
+ - lib/brightbox-cli/vendor/multi_json/spec/multi_json_spec.rb
1972
1975
  - lib/brightbox-cli/version.rb
1973
1976
  - lib/brightbox-cli/zones.rb
1974
1977
  - lib/brightbox_cli.rb