goodread 0.1.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e5a293ce19c1885ff9c90422f79721f1f0842374
4
+ data.tar.gz: a2756e32cc34d605cfdd730ee39e2e08938b5276
5
+ SHA512:
6
+ metadata.gz: bfa940e289ac827d87c095f9ca4a3452ae458b5029d75d35a64e607982b3366ed0054022ec39b1f16cce961565f62c2a9042166fed0dd0fb3f258f6ee949fc7f
7
+ data.tar.gz: c0c93672822cb4b2579b63e2ae8f4066a5f3c20b2c6549b009ec185b1d9aac2b287a70d7249a22df542d69e9d771e18adac6023d34a60308a4f962534976baf3
data/.gitignore ADDED
@@ -0,0 +1,54 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /spec/examples.txt
9
+ /test/tmp/
10
+ /test/version_tmp/
11
+ /tmp/
12
+
13
+ # Used by dotenv library to load environment variables.
14
+ # .env
15
+
16
+ ## Specific to RubyMotion:
17
+ .dat*
18
+ .repl_history
19
+ build/
20
+ *.bridgesupport
21
+ build-iPhoneOS/
22
+ build-iPhoneSimulator/
23
+
24
+ ## Specific to RubyMotion (use of CocoaPods):
25
+ #
26
+ # We recommend against adding the Pods directory to your .gitignore. However
27
+ # you should judge for yourself, the pros and cons are mentioned at:
28
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
29
+ #
30
+ # vendor/Pods/
31
+
32
+ ## Documentation cache and generated files:
33
+ /.yardoc/
34
+ /_yardoc/
35
+ /doc/
36
+ /rdoc/
37
+
38
+ ## Environment normalization:
39
+ /.bundle/
40
+ /vendor/bundle
41
+ /lib/bundler/man/
42
+
43
+ # for a library or gem, you might want to ignore these files since the code is
44
+ # intended to run in multiple environments; otherwise, check them in:
45
+ # Gemfile.lock
46
+ # .ruby-version
47
+ # .ruby-gemset
48
+
49
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
50
+ .rvmrc
51
+
52
+ # Extra
53
+ Gemfile.lock
54
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,19 @@
1
+ sudo:
2
+ false
3
+
4
+ language:
5
+ ruby
6
+
7
+ rvm:
8
+ - 2.1.2
9
+
10
+ before_install:
11
+ gem install bundler -v 1.14.6
12
+
13
+ deploy:
14
+ provider: rubygems
15
+ gem: goodread
16
+ on:
17
+ tags: true
18
+ api_key:
19
+ secure: 1Sip+AvVHYYcr+AwH8fysiDTm8a0E2jZZjk7raNGuX17vllz+q3vWLRIX+qsBcdLyY5nKwwn6UokXrWzEjtxFNJ7BO9j/lK9LFYeMDthfNQz0gZygJAmaJaAaPZ8saBe+SoLd+sTrXB26eNJQ8qkY1yz/uj03/f3FS+3S+Pwe5Gf95uMd3pAOxUJZaCVypKXiOpLq67pD8D6j+AbUUKr5VlQAw9+A6ddXFlLAVstJyApgxXlunaViHmCl396fFuE7CQIgKmcScJzl6wpQQ/KbqY4OyVXgB9relUxdiE7LRQeUGkwZ9R6UpPv7+LMTTZOMWXWc1gVLLRoWax4M8zQ7lhoK7Bsi6+0NqDJsg16q0+zBaFLQSRbI91ig8DaE4bQbC1BzlcZdw3bHE8YP6IjrP9v0EIEasgklKD4wwa3d+ltKFAtuoLM1jMNN7X85B5InQHGXl3Gf12QdKhBJDHJXF6elLj7q4S2yaGziHhtQukA8B6AtCt9efvnBJgQgLR1DFEnYbnbL42+fM3YKchfjWuk/el6Pz+ThiDPFGy3agDhaf9vV/ju5bBF1muok6XlKXs37sUcPAe5Kp7EU7IfqkJzAqG8ci3mJT3dxDSzxWa3kzL3UKZd6yh/ccukOLj4U38oySDYzlInBE76Apc2GTK7Vk9bAgGgOuCkFQCmAaY=
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in goodread.gemspec
4
+ gemspec
data/LICENSE.md ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Evgeny Karev
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
data/README.md ADDED
@@ -0,0 +1,41 @@
1
+ # Goodread::Rb
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/goodread/rb`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'goodread'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install goodread
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/goodread-rb.
36
+
37
+
38
+ ## License
39
+
40
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
41
+
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "goodread/rb"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/goodread-rb ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'cli'
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/goodread.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "goodread"
7
+ spec.version = "0.1.0"
8
+ spec.authors = ["Evgeny Karev\n"]
9
+ spec.email = ["eskarev@gmail.com"]
10
+
11
+ spec.summary = %q{goodread}
12
+ spec.description = %q{goodread}
13
+ spec.homepage = "https://github.com/goodread/goodread-rb"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
+ f.match(%r{^(test|spec|features)/})
18
+ end
19
+
20
+ spec.bindir = "bin"
21
+ spec.executables = ["goodread-rb"]
22
+ spec.require_paths = ["lib"]
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.14"
25
+ spec.add_development_dependency "rake", "~> 10.0"
26
+ spec.add_development_dependency "rspec", "~> 3.0"
27
+
28
+ spec.add_dependency "colorize", "~> 0.8"
29
+ spec.add_dependency "gemoji", "~> 3.0"
30
+ end
data/lib/cli.rb ADDED
@@ -0,0 +1,416 @@
1
+ require 'json'
2
+ require 'yaml'
3
+ require 'emoji'
4
+ require 'colorize'
5
+
6
+
7
+ # Helpers
8
+
9
+ def parse_specs(path)
10
+
11
+ # Paths
12
+ paths = []
13
+ if !path
14
+ paths = Dir.glob('package.*')
15
+ if paths.empty?
16
+ path = 'packspec'
17
+ end
18
+ end
19
+ if File.file?(path)
20
+ paths = [path]
21
+ elsif File.directory?(path)
22
+ for path in Dir.glob("#{path}/*.*")
23
+ paths.push(path)
24
+ end
25
+ end
26
+
27
+ # Specs
28
+ specs = []
29
+ for path in paths
30
+ spec = parse_spec(path)
31
+ if spec
32
+ specs.push(spec)
33
+ end
34
+ end
35
+
36
+ return specs
37
+
38
+ end
39
+
40
+
41
+ def parse_spec(path)
42
+
43
+ # Documents
44
+ documents = []
45
+ if !path.end_with?('.yml')
46
+ return nil
47
+ end
48
+ contents = File.read(path)
49
+ YAML.load_stream(contents) do |document|
50
+ documents.push(document)
51
+ end
52
+
53
+ # Package
54
+ feature = parse_feature(documents[0][0])
55
+ if feature['skip']
56
+ return nil
57
+ end
58
+ package = feature['comment']
59
+
60
+ # Features
61
+ skip = false
62
+ features = []
63
+ for feature in documents[0]
64
+ feature = parse_feature(feature)
65
+ features.push(feature)
66
+ if feature['comment']
67
+ skip = feature['skip']
68
+ end
69
+ feature['skip'] = skip || feature['skip']
70
+ end
71
+
72
+ # Scope
73
+ scope = {}
74
+ scope['$import'] = BuiltinFunctions.new().public_method(:builtin_import)
75
+ if documents.length > 1 && documents[1]['rb']
76
+ eval(documents[1]['rb'])
77
+ hook_scope = Functions.new()
78
+ for name in hook_scope.public_methods
79
+ # TODO: filter ruby builtin methods
80
+ scope["$#{name}"] = hook_scope.public_method(name)
81
+ end
82
+ end
83
+
84
+ # Stats
85
+ stats = {'features' => 0, 'comments' => 0, 'skipped' => 0, 'tests' => 0}
86
+ for feature in features
87
+ stats['features'] += 1
88
+ if feature['comment']
89
+ stats['comments'] += 1
90
+ else
91
+ stats['tests'] += 1
92
+ if feature['skip']
93
+ stats['skipped'] += 1
94
+ end
95
+ end
96
+ end
97
+
98
+ return {
99
+ 'package' => package,
100
+ 'features' => features,
101
+ 'scope' => scope,
102
+ 'stats' => stats,
103
+ }
104
+
105
+ end
106
+
107
+
108
+ def parse_feature(feature)
109
+
110
+ # General
111
+ if feature.is_a?(String)
112
+ match = /^(?:\((.*)\))?(\w.*)$/.match(feature)
113
+ skip, comment = match[1], match[2]
114
+ if !!skip
115
+ skip = !skip.split(':').include?('rb')
116
+ end
117
+ return {'assign' => nil, 'comment' => comment, 'skip' => skip}
118
+ end
119
+ left, right = Array(feature.each_pair)[0]
120
+
121
+ # Left side
122
+ call = false
123
+ match = /^(?:\((.*)\))?(?:([^=]*)=)?([^=].*)?$/.match(left)
124
+ skip, assign, property = match[1], match[2], match[3]
125
+ if !!skip
126
+ skip = !skip.split(':').include?('rb')
127
+ end
128
+ if !assign && !property
129
+ raise Exception.new('Non-valid feature')
130
+ end
131
+ if !!property
132
+ call = true
133
+ if property.end_with?('==')
134
+ property = property[0..-3]
135
+ call = false
136
+ end
137
+ end
138
+
139
+ # Right side
140
+ args = []
141
+ kwargs = {}
142
+ result = right
143
+ if !!call
144
+ result = nil
145
+ for item in right
146
+ if item.is_a?(Hash) && item.length == 1
147
+ item_left, item_right = Array(item.each_pair)[0]
148
+ if item_left == '=='
149
+ result = item_right
150
+ next
151
+ end
152
+ if item_left.end_with?('=')
153
+ kwargs[item_left[0..-2]] = item_right
154
+ next
155
+ end
156
+ end
157
+ args.push(item)
158
+ end
159
+ end
160
+
161
+ # Text repr
162
+ text = property
163
+ if !!assign
164
+ text = "#{assign} = #{property || JSON.generate(result)}"
165
+ end
166
+ if !!call
167
+ items = []
168
+ for item in args
169
+ items.push(JSON.generate(item))
170
+ end
171
+ for name, item in kwargs.each_pair
172
+ items.push("#{name}=#{JSON.generate(item)}")
173
+ end
174
+ text = "#{text}(#{items.join(', ')})"
175
+ end
176
+ if !!result && !assign
177
+ text = "#{text} == #{result == 'ERROR' ? result : JSON.generate(result)}"
178
+ end
179
+ text = text.gsub(/{"([^{}]*?)": null}/, '\1')
180
+
181
+ return {
182
+ 'comment' => nil,
183
+ 'skip' => skip,
184
+ 'call' => call,
185
+ 'assign' => assign,
186
+ 'property' => property,
187
+ 'args' => args,
188
+ 'kwargs' => kwargs,
189
+ 'result' => result,
190
+ 'text' => text,
191
+ }
192
+
193
+ end
194
+
195
+
196
+ def test_specs(specs)
197
+
198
+ # Message
199
+ message = "\n # Ruby\n".bold
200
+ puts(message)
201
+
202
+ # Test specs
203
+ success = true
204
+ for spec in specs
205
+ spec_success = test_spec(spec)
206
+ success = success && spec_success
207
+ end
208
+
209
+ return success
210
+
211
+ end
212
+
213
+
214
+ def test_spec(spec)
215
+
216
+ # Message
217
+ message = Emoji.find_by_alias('heavy_minus_sign').raw * 3 + "\n\n"
218
+ puts(message)
219
+
220
+ # Test spec
221
+ passed = 0
222
+ for feature in spec['features']
223
+ result = test_feature(feature, spec['scope'])
224
+ if result
225
+ passed += 1
226
+ end
227
+ end
228
+ success = (passed == spec['stats']['features'])
229
+
230
+ # Message
231
+ color = 'green'
232
+ message = ("\n " + Emoji.find_by_alias('heavy_check_mark').raw + ' ').green.bold
233
+ if !success
234
+ color = 'red'
235
+ message = ("\n " + Emoji.find_by_alias('x').raw + ' ').red.bold
236
+ end
237
+ message += "#{spec['package']}: #{passed - spec['stats']['comments'] - spec['stats']['skipped']}/#{spec['stats']['tests'] - spec['stats']['skipped']}\n".colorize(color).bold
238
+ puts(message)
239
+
240
+ return success
241
+
242
+ end
243
+
244
+
245
+ def test_feature(feature, scope)
246
+
247
+ # Comment
248
+ if !!feature['comment']
249
+ message = "\n # #{feature['comment']}\n".bold
250
+ puts(message)
251
+ return true
252
+ end
253
+
254
+ # Skip
255
+ if !!feature['skip']
256
+ message = " #{Emoji.find_by_alias('heavy_minus_sign').raw} ".yellow
257
+ message += feature['text']
258
+ puts(message)
259
+ return true
260
+ end
261
+
262
+ # Dereference
263
+ # TODO: deepcopy feature
264
+ if !!feature['call']
265
+ feature['args'] = dereference_value(feature['args'], scope)
266
+ feature['kwargs'] = dereference_value(feature['kwargs'], scope)
267
+ end
268
+ feature['result'] = dereference_value(feature['result'], scope)
269
+
270
+ # Execute
271
+ exception = nil
272
+ result = feature['result']
273
+ if !!feature['property']
274
+ begin
275
+ property = scope
276
+ for name in feature['property'].split('.')
277
+ property = get_property(property, name)
278
+ end
279
+ if !!feature['call']
280
+ args = feature['args'].dup
281
+ if !feature['kwargs'].empty?
282
+ args.push(Hash[feature['kwargs'].map{|k, v| [k.to_sym, v]}])
283
+ end
284
+ if property.respond_to?('new')
285
+ result = property.new(*args)
286
+ else
287
+ result = property.call(*args)
288
+ end
289
+ else
290
+ result = property
291
+ if result.is_a?(Method)
292
+ result = result.call()
293
+ end
294
+ end
295
+ rescue Exception => exc
296
+ exception = exc
297
+ result = 'ERROR'
298
+ end
299
+ end
300
+
301
+ # Assign
302
+ if !!feature['assign']
303
+ owner = scope
304
+ names = feature['assign'].split('.')
305
+ for name in names[0..-2]
306
+ owner = get_property(owner, name)
307
+ end
308
+ # TODO: ensure constants are immutable
309
+ set_property(owner, names[-1], result)
310
+ end
311
+
312
+ # Compare
313
+ if feature['result'] != nil
314
+ success = result == feature['result']
315
+ else
316
+ success = result != 'ERROR'
317
+ end
318
+ if success
319
+ message = " #{Emoji.find_by_alias('heavy_check_mark').raw} ".green
320
+ message += feature['text']
321
+ puts(message)
322
+ else
323
+ begin
324
+ result_text = JSON.generate(result)
325
+ rescue Exception
326
+ result_text = result.to_s
327
+ end
328
+ message = " #{Emoji.find_by_alias('x').raw} ".red
329
+ message += "#{feature['text']}\n"
330
+ if exception
331
+ message += "Exception: #{exception}".red.bold
332
+ else
333
+ message += "Assertion: #{result_text} != #{JSON.generate(feature['result'])}".red.bold
334
+ end
335
+ puts(message)
336
+ end
337
+
338
+ return success
339
+
340
+ end
341
+
342
+
343
+ class BuiltinFunctions
344
+ def builtin_import(package)
345
+ attributes = {}
346
+ require(package)
347
+ for item in ObjectSpace.each_object
348
+ if package == String(item).downcase
349
+ begin
350
+ scope = Kernel.const_get(item)
351
+ rescue Exception
352
+ next
353
+ end
354
+ for name in scope.constants
355
+ attributes[String(name)] = scope.const_get(name)
356
+ end
357
+ end
358
+ end
359
+ return attributes
360
+ end
361
+ end
362
+
363
+
364
+ def dereference_value(value, scope)
365
+ if value.is_a?(Hash) && value.length == 1 && Array(value.each_value)[0] == nil
366
+ result = scope
367
+ for name in Array(value.each_key)[0].split('.')
368
+ result = get_property(result, name)
369
+ end
370
+ value = result
371
+ elsif value.is_a?(Hash)
372
+ for key, item in value
373
+ value[key] = dereference_value(item, scope)
374
+ end
375
+ elsif value.is_a?(Array)
376
+ for item, index in value.each_with_index
377
+ value[index] = dereference_value(item, scope)
378
+ end
379
+ end
380
+ return value
381
+ end
382
+
383
+
384
+ def get_property(owner, name)
385
+ if owner.is_a?(Method)
386
+ owner = owner.call()
387
+ end
388
+ if owner.class == Hash
389
+ return owner[name]
390
+ elsif owner.class == Array
391
+ return owner[name.to_i]
392
+ end
393
+ return owner.method(name)
394
+ end
395
+
396
+
397
+ def set_property(owner, name, value)
398
+ if owner.class == Hash
399
+ owner[name] = value
400
+ return
401
+ elsif owner.class == Array
402
+ owner[name.to_i] = value
403
+ return
404
+ end
405
+ return owner.const_set(name, value)
406
+ end
407
+
408
+
409
+ # Main program
410
+
411
+ path = ARGV[0] || nil
412
+ specs = parse_specs(path)
413
+ success = test_specs(specs)
414
+ if !success
415
+ exit(1)
416
+ end
metadata ADDED
@@ -0,0 +1,129 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: goodread
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - 'Evgeny Karev
8
+
9
+ '
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2017-08-14 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: bundler
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - "~>"
20
+ - !ruby/object:Gem::Version
21
+ version: '1.14'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - "~>"
27
+ - !ruby/object:Gem::Version
28
+ version: '1.14'
29
+ - !ruby/object:Gem::Dependency
30
+ name: rake
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - "~>"
34
+ - !ruby/object:Gem::Version
35
+ version: '10.0'
36
+ type: :development
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - "~>"
41
+ - !ruby/object:Gem::Version
42
+ version: '10.0'
43
+ - !ruby/object:Gem::Dependency
44
+ name: rspec
45
+ requirement: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '3.0'
50
+ type: :development
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - "~>"
55
+ - !ruby/object:Gem::Version
56
+ version: '3.0'
57
+ - !ruby/object:Gem::Dependency
58
+ name: colorize
59
+ requirement: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - "~>"
62
+ - !ruby/object:Gem::Version
63
+ version: '0.8'
64
+ type: :runtime
65
+ prerelease: false
66
+ version_requirements: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - "~>"
69
+ - !ruby/object:Gem::Version
70
+ version: '0.8'
71
+ - !ruby/object:Gem::Dependency
72
+ name: gemoji
73
+ requirement: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - "~>"
76
+ - !ruby/object:Gem::Version
77
+ version: '3.0'
78
+ type: :runtime
79
+ prerelease: false
80
+ version_requirements: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - "~>"
83
+ - !ruby/object:Gem::Version
84
+ version: '3.0'
85
+ description: goodread
86
+ email:
87
+ - eskarev@gmail.com
88
+ executables:
89
+ - goodread-rb
90
+ extensions: []
91
+ extra_rdoc_files: []
92
+ files:
93
+ - ".gitignore"
94
+ - ".rspec"
95
+ - ".travis.yml"
96
+ - Gemfile
97
+ - LICENSE.md
98
+ - README.md
99
+ - Rakefile
100
+ - bin/console
101
+ - bin/goodread-rb
102
+ - bin/setup
103
+ - goodread.gemspec
104
+ - lib/cli.rb
105
+ homepage: https://github.com/goodread/goodread-rb
106
+ licenses:
107
+ - MIT
108
+ metadata: {}
109
+ post_install_message:
110
+ rdoc_options: []
111
+ require_paths:
112
+ - lib
113
+ required_ruby_version: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ required_rubygems_version: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: '0'
123
+ requirements: []
124
+ rubyforge_project:
125
+ rubygems_version: 2.6.12
126
+ signing_key:
127
+ specification_version: 4
128
+ summary: goodread
129
+ test_files: []