typhoeus 0.4.2 → 0.5.0.pre
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.
- data/CHANGELOG.md +74 -28
- data/README.md +20 -422
- data/Rakefile +21 -12
- data/lib/typhoeus/config.rb +11 -0
- data/lib/typhoeus/hydra.rb +26 -236
- data/lib/typhoeus/hydras/easy_factory.rb +67 -0
- data/lib/typhoeus/hydras/easy_pool.rb +40 -0
- data/lib/typhoeus/hydras/memoizable.rb +53 -0
- data/lib/typhoeus/hydras/queueable.rb +46 -0
- data/lib/typhoeus/hydras/runnable.rb +18 -0
- data/lib/typhoeus/request.rb +56 -241
- data/lib/typhoeus/requests/actions.rb +17 -0
- data/lib/typhoeus/requests/callbacks.rb +48 -0
- data/lib/typhoeus/requests/marshal.rb +21 -0
- data/lib/typhoeus/requests/memoizable.rb +36 -0
- data/lib/typhoeus/requests/operations.rb +51 -0
- data/lib/typhoeus/requests/responseable.rb +29 -0
- data/lib/typhoeus/response.rb +23 -118
- data/lib/typhoeus/responses/header.rb +50 -0
- data/lib/typhoeus/responses/informations.rb +43 -0
- data/lib/typhoeus/responses/legacy.rb +26 -0
- data/lib/typhoeus/responses/status.rb +77 -0
- data/lib/typhoeus/version.rb +3 -1
- data/lib/typhoeus.rb +31 -45
- metadata +45 -48
- data/lib/typhoeus/curl.rb +0 -453
- data/lib/typhoeus/easy/auth.rb +0 -14
- data/lib/typhoeus/easy/callbacks.rb +0 -33
- data/lib/typhoeus/easy/ffi_helper.rb +0 -61
- data/lib/typhoeus/easy/infos.rb +0 -90
- data/lib/typhoeus/easy/options.rb +0 -115
- data/lib/typhoeus/easy/proxy.rb +0 -20
- data/lib/typhoeus/easy/ssl.rb +0 -82
- data/lib/typhoeus/easy.rb +0 -115
- data/lib/typhoeus/filter.rb +0 -28
- data/lib/typhoeus/form.rb +0 -61
- data/lib/typhoeus/header.rb +0 -54
- data/lib/typhoeus/hydra/callbacks.rb +0 -24
- data/lib/typhoeus/hydra/connect_options.rb +0 -61
- data/lib/typhoeus/hydra/stubbing.rb +0 -68
- data/lib/typhoeus/hydra_mock.rb +0 -131
- data/lib/typhoeus/multi.rb +0 -146
- data/lib/typhoeus/param_processor.rb +0 -43
- data/lib/typhoeus/remote.rb +0 -306
- data/lib/typhoeus/remote_method.rb +0 -108
- data/lib/typhoeus/remote_proxy_object.rb +0 -50
- data/lib/typhoeus/utils.rb +0 -50
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
module Typhoeus
|
|
2
|
+
module Responses
|
|
3
|
+
|
|
4
|
+
# This class represents the response header.
|
|
5
|
+
# It can be accessed like a hash.
|
|
6
|
+
class Header < Hash
|
|
7
|
+
# Create a new header.
|
|
8
|
+
#
|
|
9
|
+
# @example Create new header.
|
|
10
|
+
# Header.new(raw)
|
|
11
|
+
#
|
|
12
|
+
# @param [ String ] raw The raw header.
|
|
13
|
+
def initialize(raw)
|
|
14
|
+
@raw = raw
|
|
15
|
+
parse
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Returns the raw header or empty string.
|
|
19
|
+
#
|
|
20
|
+
# @example Return raw header.
|
|
21
|
+
# header.raw
|
|
22
|
+
#
|
|
23
|
+
# @return [ String ] The raw header.
|
|
24
|
+
def raw
|
|
25
|
+
@raw ||= ''
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Parses the raw header.
|
|
29
|
+
#
|
|
30
|
+
# @example Parse header.
|
|
31
|
+
# header.parse
|
|
32
|
+
def parse
|
|
33
|
+
raw.lines.each do |header|
|
|
34
|
+
unless header =~ /^HTTP\/1.[01]/
|
|
35
|
+
parts = header.split(':', 2)
|
|
36
|
+
unless parts.empty?
|
|
37
|
+
parts.map(&:strip!)
|
|
38
|
+
if self.has_key?(parts[0])
|
|
39
|
+
self[parts[0]] = [self[parts[0]]] unless self[parts[0]].kind_of? Array
|
|
40
|
+
self[parts[0]] << parts[1]
|
|
41
|
+
else
|
|
42
|
+
self[parts[0]] = parts[1]
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module Typhoeus
|
|
2
|
+
module Responses
|
|
3
|
+
|
|
4
|
+
# This module contains logic about informations
|
|
5
|
+
# on a response.
|
|
6
|
+
module Informations
|
|
7
|
+
|
|
8
|
+
# All available informations.
|
|
9
|
+
AVAILABLE_INFORMATIONS = Ethon::Easies::Informations::AVAILABLE_INFORMATIONS.keys+
|
|
10
|
+
[:return_code, :response_body, :response_header]
|
|
11
|
+
|
|
12
|
+
AVAILABLE_INFORMATIONS.each do |name|
|
|
13
|
+
define_method(name) do
|
|
14
|
+
options[name.to_sym]
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Returns the response header.
|
|
19
|
+
#
|
|
20
|
+
# @example Return header.
|
|
21
|
+
# response.header
|
|
22
|
+
#
|
|
23
|
+
# @return [ Header ] The response header.
|
|
24
|
+
def header
|
|
25
|
+
return nil unless response_header
|
|
26
|
+
@header ||= Responses::Header.new(response_header.split("\r\n\r\n").last)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Return all redirections in between as multiple
|
|
30
|
+
# responses with header.
|
|
31
|
+
#
|
|
32
|
+
# @example Return redirections.
|
|
33
|
+
# response.redirections
|
|
34
|
+
#
|
|
35
|
+
# @return [ Array ] The redirections
|
|
36
|
+
def redirections
|
|
37
|
+
return [] unless response_header
|
|
38
|
+
response_header.split("\r\n\r\n")[0..-2].map{ |h| Response.new(:response_header => h) }
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module Typhoeus
|
|
2
|
+
module Responses # :nodoc:
|
|
3
|
+
|
|
4
|
+
# This module contains logic for providing the
|
|
5
|
+
# old accessors.
|
|
6
|
+
module Legacy
|
|
7
|
+
|
|
8
|
+
# The legacy mapping.
|
|
9
|
+
MAPPING = {
|
|
10
|
+
:body => :response_body,
|
|
11
|
+
:code => :response_code,
|
|
12
|
+
:curl_return_code => :return_code,
|
|
13
|
+
:time => :total_time,
|
|
14
|
+
:app_connect_time => :appconnect_time,
|
|
15
|
+
:start_transfer_time => :starttransfer_time,
|
|
16
|
+
:name_lookup_time => :namelookup_time
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
MAPPING.each do |old, new|
|
|
20
|
+
define_method(old) do
|
|
21
|
+
options[new]
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
module Typhoeus
|
|
2
|
+
module Responses
|
|
3
|
+
|
|
4
|
+
# This module contains logic about the http
|
|
5
|
+
# status.
|
|
6
|
+
module Status
|
|
7
|
+
|
|
8
|
+
# Return the status message if present.
|
|
9
|
+
#
|
|
10
|
+
# @example Return status message.
|
|
11
|
+
# reesponse.status_message
|
|
12
|
+
#
|
|
13
|
+
# @return [ String ] The message.
|
|
14
|
+
def status_message
|
|
15
|
+
return @status_message if defined?(@status_message) && @status_message
|
|
16
|
+
|
|
17
|
+
# HTTP servers can choose not to include the explanation to HTTP codes. The RFC
|
|
18
|
+
# states this (http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4):
|
|
19
|
+
# Except when responding to a HEAD request, the server SHOULD include an entity containing
|
|
20
|
+
# an explanation of the error situation [...]
|
|
21
|
+
# This means 'HTTP/1.1 404' is as valid as 'HTTP/1.1 404 Not Found' and we have to handle it.
|
|
22
|
+
|
|
23
|
+
# Regexp doc: http://rubular.com/r/eAr1oVYsVa
|
|
24
|
+
if first_header_line != nil and first_header_line[/\d{3} (.*)$/, 1] != nil
|
|
25
|
+
@status_message = first_header_line[/\d{3} (.*)$/, 1].chomp
|
|
26
|
+
else
|
|
27
|
+
@status_message = nil
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Return the http version.
|
|
32
|
+
#
|
|
33
|
+
# @example Return http version.
|
|
34
|
+
# response.http_version
|
|
35
|
+
#
|
|
36
|
+
# @return [ String ] The http version.
|
|
37
|
+
def http_version
|
|
38
|
+
@http_version ||= first_header_line ? first_header_line[/HTTP\/(\S+)/, 1] : nil
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Return wether the response is a success.
|
|
42
|
+
#
|
|
43
|
+
# @example Return if the response was successful.
|
|
44
|
+
# response.success?
|
|
45
|
+
#
|
|
46
|
+
# @return [ Boolean ] Return true if successful, false else.
|
|
47
|
+
def success?
|
|
48
|
+
(200..299).include?(response_code)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Return wether the response is modified.
|
|
52
|
+
#
|
|
53
|
+
# @example Return if the response was modified.
|
|
54
|
+
# response.modified?
|
|
55
|
+
#
|
|
56
|
+
# @return [ Boolean ] Return true if modified, false else.
|
|
57
|
+
def modified?
|
|
58
|
+
response_code != 304
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Return wether the response is timed out.
|
|
62
|
+
#
|
|
63
|
+
# @example Return if the response timed out..
|
|
64
|
+
# response.time_out?
|
|
65
|
+
#
|
|
66
|
+
# @return [ Boolean ] Return true if timed out, false else.
|
|
67
|
+
def timed_out?
|
|
68
|
+
return_code == 28
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# :nodoc:
|
|
72
|
+
def first_header_line
|
|
73
|
+
@first_header_line ||= response_header.to_s.split("\n").first
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
data/lib/typhoeus/version.rb
CHANGED
data/lib/typhoeus.rb
CHANGED
|
@@ -1,56 +1,42 @@
|
|
|
1
1
|
require 'digest/sha2'
|
|
2
|
+
require 'ethon'
|
|
2
3
|
|
|
3
|
-
require 'typhoeus/
|
|
4
|
-
require 'typhoeus/header'
|
|
5
|
-
require 'typhoeus/curl'
|
|
6
|
-
require 'typhoeus/easy'
|
|
7
|
-
require 'typhoeus/form'
|
|
8
|
-
require 'typhoeus/multi'
|
|
9
|
-
require 'typhoeus/filter'
|
|
10
|
-
require 'typhoeus/param_processor'
|
|
11
|
-
require 'typhoeus/remote'
|
|
12
|
-
require 'typhoeus/remote_proxy_object'
|
|
13
|
-
require 'typhoeus/response'
|
|
4
|
+
require 'typhoeus/config'
|
|
14
5
|
require 'typhoeus/request'
|
|
6
|
+
require 'typhoeus/response'
|
|
15
7
|
require 'typhoeus/hydra'
|
|
16
|
-
require 'typhoeus/hydra_mock'
|
|
17
8
|
require 'typhoeus/version'
|
|
18
9
|
|
|
10
|
+
# Typhoeus is a http client library based on Ethon which
|
|
11
|
+
# wraps libcurl.
|
|
12
|
+
#
|
|
13
|
+
# If you want to make a single request, go with:
|
|
14
|
+
# Typhoeus.get("www.example.com")
|
|
15
|
+
#
|
|
16
|
+
# When you looking for firing a bunch of requests automatically
|
|
17
|
+
# choose the hydra:
|
|
18
|
+
#
|
|
19
|
+
# hydra = Typhoeus::Hydra.new
|
|
20
|
+
# requests = (0..9).map{ Typhoeus::Request.new("www.example.com") }
|
|
21
|
+
# requests.each{ |request| hydra.queue(request) }
|
|
22
|
+
# hydra.run
|
|
19
23
|
module Typhoeus
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
def self.init_easy_object_pool
|
|
25
|
-
20.times do
|
|
26
|
-
easy_object_pool << Typhoeus::Easy.new
|
|
27
|
-
end
|
|
28
|
-
end
|
|
24
|
+
extend self
|
|
25
|
+
extend Hydras::EasyPool
|
|
26
|
+
extend Requests::Actions
|
|
29
27
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
easy_object_pool << easy
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def self.get_easy_object
|
|
36
|
-
if easy_object_pool.empty?
|
|
37
|
-
Typhoeus::Easy.new
|
|
38
|
-
else
|
|
39
|
-
easy_object_pool.pop
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def self.add_easy_request(easy_object)
|
|
44
|
-
Thread.current[:curl_multi] ||= Typhoeus::Multi.new
|
|
45
|
-
Thread.current[:curl_multi].add(easy_object)
|
|
46
|
-
end
|
|
28
|
+
# The default typhoeus user agent.
|
|
29
|
+
USER_AGENT = "Typhoeus - https://github.com/typhoeus/typhoeus"
|
|
47
30
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
31
|
+
# Set the Typhoeus configuration options by passing a block.
|
|
32
|
+
#
|
|
33
|
+
# @example Set the configuration options.
|
|
34
|
+
# Typhoeus.configure do |config|
|
|
35
|
+
# config.verbose = true
|
|
36
|
+
# end
|
|
37
|
+
#
|
|
38
|
+
# @return [ Config ] The configuration object.
|
|
39
|
+
def configure
|
|
40
|
+
yield Config
|
|
55
41
|
end
|
|
56
42
|
end
|
metadata
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: typhoeus
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
5
|
-
prerelease:
|
|
4
|
+
version: 0.5.0.pre
|
|
5
|
+
prerelease: 6
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
8
8
|
- David Balatero
|
|
@@ -11,16 +11,16 @@ authors:
|
|
|
11
11
|
autorequire:
|
|
12
12
|
bindir: bin
|
|
13
13
|
cert_chain: []
|
|
14
|
-
date: 2012-
|
|
14
|
+
date: 2012-07-04 00:00:00.000000000 Z
|
|
15
15
|
dependencies:
|
|
16
16
|
- !ruby/object:Gem::Dependency
|
|
17
|
-
name:
|
|
17
|
+
name: ethon
|
|
18
18
|
requirement: !ruby/object:Gem::Requirement
|
|
19
19
|
none: false
|
|
20
20
|
requirements:
|
|
21
21
|
- - ~>
|
|
22
22
|
- !ruby/object:Gem::Version
|
|
23
|
-
version:
|
|
23
|
+
version: 0.3.0
|
|
24
24
|
type: :runtime
|
|
25
25
|
prerelease: false
|
|
26
26
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -28,23 +28,7 @@ dependencies:
|
|
|
28
28
|
requirements:
|
|
29
29
|
- - ~>
|
|
30
30
|
- !ruby/object:Gem::Version
|
|
31
|
-
version:
|
|
32
|
-
- !ruby/object:Gem::Dependency
|
|
33
|
-
name: mime-types
|
|
34
|
-
requirement: !ruby/object:Gem::Requirement
|
|
35
|
-
none: false
|
|
36
|
-
requirements:
|
|
37
|
-
- - ~>
|
|
38
|
-
- !ruby/object:Gem::Version
|
|
39
|
-
version: '1.18'
|
|
40
|
-
type: :runtime
|
|
41
|
-
prerelease: false
|
|
42
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
43
|
-
none: false
|
|
44
|
-
requirements:
|
|
45
|
-
- - ~>
|
|
46
|
-
- !ruby/object:Gem::Version
|
|
47
|
-
version: '1.18'
|
|
31
|
+
version: 0.3.0
|
|
48
32
|
- !ruby/object:Gem::Dependency
|
|
49
33
|
name: sinatra
|
|
50
34
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -100,7 +84,7 @@ dependencies:
|
|
|
100
84
|
requirements:
|
|
101
85
|
- - ~>
|
|
102
86
|
- !ruby/object:Gem::Version
|
|
103
|
-
version:
|
|
87
|
+
version: 0.11.4
|
|
104
88
|
type: :development
|
|
105
89
|
prerelease: false
|
|
106
90
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -108,7 +92,7 @@ dependencies:
|
|
|
108
92
|
requirements:
|
|
109
93
|
- - ~>
|
|
110
94
|
- !ruby/object:Gem::Version
|
|
111
|
-
version:
|
|
95
|
+
version: 0.11.4
|
|
112
96
|
- !ruby/object:Gem::Dependency
|
|
113
97
|
name: rspec
|
|
114
98
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -132,7 +116,23 @@ dependencies:
|
|
|
132
116
|
requirements:
|
|
133
117
|
- - ~>
|
|
134
118
|
- !ruby/object:Gem::Version
|
|
135
|
-
version:
|
|
119
|
+
version: 1.1.0
|
|
120
|
+
type: :development
|
|
121
|
+
prerelease: false
|
|
122
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
123
|
+
none: false
|
|
124
|
+
requirements:
|
|
125
|
+
- - ~>
|
|
126
|
+
- !ruby/object:Gem::Version
|
|
127
|
+
version: 1.1.0
|
|
128
|
+
- !ruby/object:Gem::Dependency
|
|
129
|
+
name: simplecov
|
|
130
|
+
requirement: !ruby/object:Gem::Requirement
|
|
131
|
+
none: false
|
|
132
|
+
requirements:
|
|
133
|
+
- - ~>
|
|
134
|
+
- !ruby/object:Gem::Version
|
|
135
|
+
version: 0.5.3
|
|
136
136
|
type: :development
|
|
137
137
|
prerelease: false
|
|
138
138
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -140,7 +140,7 @@ dependencies:
|
|
|
140
140
|
requirements:
|
|
141
141
|
- - ~>
|
|
142
142
|
- !ruby/object:Gem::Version
|
|
143
|
-
version:
|
|
143
|
+
version: 0.5.3
|
|
144
144
|
description: Like a modern code version of the mythical beast with 100 serpent heads,
|
|
145
145
|
Typhoeus runs HTTP requests in parallel while cleanly encapsulating handling logic.
|
|
146
146
|
email:
|
|
@@ -149,31 +149,25 @@ executables: []
|
|
|
149
149
|
extensions: []
|
|
150
150
|
extra_rdoc_files: []
|
|
151
151
|
files:
|
|
152
|
-
- lib/typhoeus/
|
|
153
|
-
- lib/typhoeus/easy/auth.rb
|
|
154
|
-
- lib/typhoeus/easy/callbacks.rb
|
|
155
|
-
- lib/typhoeus/easy/ffi_helper.rb
|
|
156
|
-
- lib/typhoeus/easy/infos.rb
|
|
157
|
-
- lib/typhoeus/easy/options.rb
|
|
158
|
-
- lib/typhoeus/easy/proxy.rb
|
|
159
|
-
- lib/typhoeus/easy/ssl.rb
|
|
160
|
-
- lib/typhoeus/easy.rb
|
|
161
|
-
- lib/typhoeus/filter.rb
|
|
162
|
-
- lib/typhoeus/form.rb
|
|
163
|
-
- lib/typhoeus/header.rb
|
|
164
|
-
- lib/typhoeus/hydra/callbacks.rb
|
|
165
|
-
- lib/typhoeus/hydra/connect_options.rb
|
|
166
|
-
- lib/typhoeus/hydra/stubbing.rb
|
|
152
|
+
- lib/typhoeus/config.rb
|
|
167
153
|
- lib/typhoeus/hydra.rb
|
|
168
|
-
- lib/typhoeus/
|
|
169
|
-
- lib/typhoeus/
|
|
170
|
-
- lib/typhoeus/
|
|
171
|
-
- lib/typhoeus/
|
|
172
|
-
- lib/typhoeus/
|
|
173
|
-
- lib/typhoeus/remote_proxy_object.rb
|
|
154
|
+
- lib/typhoeus/hydras/easy_factory.rb
|
|
155
|
+
- lib/typhoeus/hydras/easy_pool.rb
|
|
156
|
+
- lib/typhoeus/hydras/memoizable.rb
|
|
157
|
+
- lib/typhoeus/hydras/queueable.rb
|
|
158
|
+
- lib/typhoeus/hydras/runnable.rb
|
|
174
159
|
- lib/typhoeus/request.rb
|
|
160
|
+
- lib/typhoeus/requests/actions.rb
|
|
161
|
+
- lib/typhoeus/requests/callbacks.rb
|
|
162
|
+
- lib/typhoeus/requests/marshal.rb
|
|
163
|
+
- lib/typhoeus/requests/memoizable.rb
|
|
164
|
+
- lib/typhoeus/requests/operations.rb
|
|
165
|
+
- lib/typhoeus/requests/responseable.rb
|
|
175
166
|
- lib/typhoeus/response.rb
|
|
176
|
-
- lib/typhoeus/
|
|
167
|
+
- lib/typhoeus/responses/header.rb
|
|
168
|
+
- lib/typhoeus/responses/informations.rb
|
|
169
|
+
- lib/typhoeus/responses/legacy.rb
|
|
170
|
+
- lib/typhoeus/responses/status.rb
|
|
177
171
|
- lib/typhoeus/version.rb
|
|
178
172
|
- lib/typhoeus.rb
|
|
179
173
|
- CHANGELOG.md
|
|
@@ -193,6 +187,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
193
187
|
- - ! '>='
|
|
194
188
|
- !ruby/object:Gem::Version
|
|
195
189
|
version: '0'
|
|
190
|
+
segments:
|
|
191
|
+
- 0
|
|
192
|
+
hash: -87429564240378902
|
|
196
193
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
197
194
|
none: false
|
|
198
195
|
requirements:
|