json-rigs 1.0.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 +7 -0
- data/bin/jrigs +16 -0
- data/lib/json-rigs.rb +0 -0
- data/lib/json-rigs/client.rb +72 -0
- data/lib/json-rigs/fixture-templates.rb +22 -0
- data/lib/json-rigs/fixture.rb +51 -0
- data/lib/json-rigs/fixtures.rb +72 -0
- data/lib/json-rigs/server.rb +205 -0
- metadata +125 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b948986d7f1dda5f386391f83ce52c3d342a8194
|
4
|
+
data.tar.gz: b51936d4af268f96f9e406765ceee41e3ad6853b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5cc7e5c4611ea393849553308c28f2d4aea01a7b9ffa2bed214d984325db825f6c2cf249a99ea2c280aba04510a4ead2881a6e4b94b05215b32522728510297f
|
7
|
+
data.tar.gz: aecb7b4a6f6f41317b14ad83bcafc86e0abc12d75822ee29e534012a66a29af5c24def2d6662943dfc9b2e9b56288ef0caff984ef00004500e9c13a134cc00b5
|
data/bin/jrigs
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
require 'daemons'
|
4
|
+
require 'json-rigs/server'
|
5
|
+
|
6
|
+
OPTIONS = {
|
7
|
+
app_name: 'json-rigs',
|
8
|
+
dir: '/tmp/',
|
9
|
+
dir_mode: :normal
|
10
|
+
}
|
11
|
+
cwd = File.join(Dir.pwd, 'fixtures')
|
12
|
+
|
13
|
+
Daemons.run_proc('json-rigs', OPTIONS) do
|
14
|
+
JsonRigs::FixtureServerRunner.start(cwd)
|
15
|
+
end
|
16
|
+
|
data/lib/json-rigs.rb
ADDED
File without changes
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'spec/fixture_server/constants'
|
3
|
+
|
4
|
+
module JsonRigs
|
5
|
+
module FixtureClient
|
6
|
+
class << self
|
7
|
+
FIXTURE_URI = '/fixtures'
|
8
|
+
|
9
|
+
def clear_active_fixtures
|
10
|
+
data = {
|
11
|
+
:fixture_action => 'clear'
|
12
|
+
}
|
13
|
+
post_fixture(data)
|
14
|
+
end
|
15
|
+
|
16
|
+
def set_fixture url, method, action, fixture
|
17
|
+
data = {
|
18
|
+
:url => url,
|
19
|
+
:method => method,
|
20
|
+
:action => action,
|
21
|
+
:fixture => fixture,
|
22
|
+
:fixture_action => 'set'
|
23
|
+
}
|
24
|
+
response = post_fixture(data)
|
25
|
+
|
26
|
+
if response.body.length > 0
|
27
|
+
puts "Fixture server error: #{response.body}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def fixtures
|
32
|
+
data = {
|
33
|
+
:fixture_action => 'get'
|
34
|
+
}
|
35
|
+
response = get_fixture(data)
|
36
|
+
|
37
|
+
if response.body.length > 0
|
38
|
+
puts "Fixture server error: #{response.body}"
|
39
|
+
end
|
40
|
+
|
41
|
+
puts response.body
|
42
|
+
|
43
|
+
JSON.parse(response.body)
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def get_conn
|
49
|
+
begin
|
50
|
+
Net::HTTP.new('localhost', File.read(JsonRigs::PORT_FILE).to_i)
|
51
|
+
rescue Errno::ENOENT
|
52
|
+
fail "Failed to find fixture server port file #{JsonRigs::PORT_FILE}. Maybe your fixture server is down."
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def get_fixture(data)
|
57
|
+
path = FIXTURE_URI.dup
|
58
|
+
path << '?' << data.map { |k, v| "#{k}=#{CGI::escape(v.to_s)}" }.join('&')
|
59
|
+
request = Net::HTTP::Get.new(path)
|
60
|
+
|
61
|
+
get_conn.request(request)
|
62
|
+
end
|
63
|
+
|
64
|
+
def post_fixture(data)
|
65
|
+
request = Net::HTTP::Post.new(FIXTURE_URI)
|
66
|
+
request.set_form_data(data)
|
67
|
+
|
68
|
+
get_conn.request(request)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module JsonRigs
|
2
|
+
module FixtureTemplates
|
3
|
+
def basic_post_fixture
|
4
|
+
fixture :success do
|
5
|
+
respond_with %q(
|
6
|
+
{
|
7
|
+
"success": true
|
8
|
+
}
|
9
|
+
)
|
10
|
+
end
|
11
|
+
|
12
|
+
fixture :failure do
|
13
|
+
respond_with %q(
|
14
|
+
{
|
15
|
+
"error_code": 0,
|
16
|
+
"success": false
|
17
|
+
}
|
18
|
+
)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'json-rigs/fixture-templates'
|
2
|
+
|
3
|
+
module JsonRigs
|
4
|
+
class Fixture
|
5
|
+
|
6
|
+
attr_accessor :pause_time
|
7
|
+
attr_reader :response
|
8
|
+
|
9
|
+
def respond_with response
|
10
|
+
JSON.parse(response)
|
11
|
+
@response = response
|
12
|
+
end
|
13
|
+
|
14
|
+
alias_method :delay, :pause_time=
|
15
|
+
end
|
16
|
+
|
17
|
+
class FixturedAction
|
18
|
+
include JsonRigs::FixtureTemplates
|
19
|
+
|
20
|
+
attr_reader :fixtures, :url
|
21
|
+
attr_accessor :active_fixture_name
|
22
|
+
|
23
|
+
def initialize(url, method)
|
24
|
+
@active_fixture_name = nil
|
25
|
+
@url = url
|
26
|
+
@method = method
|
27
|
+
@fixtures = {}
|
28
|
+
end
|
29
|
+
|
30
|
+
def fixture fixture_name, &block
|
31
|
+
fixture = Fixture.new
|
32
|
+
@fixtures[fixture_name.to_s] = fixture
|
33
|
+
fixture.instance_eval &block
|
34
|
+
@active_fixture_name = ''
|
35
|
+
end
|
36
|
+
|
37
|
+
def active_fixture; @fixtures[@active_fixture_name] end
|
38
|
+
def active_fixture?; !@active_fixture_name.empty? end
|
39
|
+
|
40
|
+
def to_hash
|
41
|
+
fixture_hash = @fixtures.keys.each_with_object({}) do |fixture_name, hash|
|
42
|
+
hash[fixture_name] = @active_fixture_name == fixture_name
|
43
|
+
end
|
44
|
+
|
45
|
+
{
|
46
|
+
method: @method,
|
47
|
+
fixtures: fixture_hash
|
48
|
+
}
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
require 'json-rigs/fixture'
|
4
|
+
|
5
|
+
module JsonRigs
|
6
|
+
module Fixtures
|
7
|
+
FixturedActionKey = Struct.new(:url, :method)
|
8
|
+
ACTIVE_FIXTURE_FILE = 'tmp/active_fixtures.json'
|
9
|
+
|
10
|
+
def self.fixture_action(url, method, &block)
|
11
|
+
method = method.to_s
|
12
|
+
@actions ||= {}
|
13
|
+
|
14
|
+
key = _key(url, method)
|
15
|
+
fixture_action = @actions[key] || FixturedAction.new(url, method)
|
16
|
+
@actions[key] = fixture_action
|
17
|
+
fixture_action.instance_eval &block
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.find_action(url, method)
|
21
|
+
method = method.to_s
|
22
|
+
@actions ||= {}
|
23
|
+
@actions[_key(url, method)]
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.clear_active_fixtures
|
27
|
+
@actions.values.each do |action|
|
28
|
+
action.active_fixture_name = ''
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.save_active_fixtures
|
33
|
+
active_fixtures = @actions.map { |key, action|
|
34
|
+
[ key.url, key.method, action.active_fixture_name ]
|
35
|
+
}
|
36
|
+
FileUtils.mkdir_p(File.dirname(ACTIVE_FIXTURE_FILE))
|
37
|
+
File.open(ACTIVE_FIXTURE_FILE, 'w') { |io| io.write(active_fixtures.to_json) }
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.load_active_fixtures
|
41
|
+
begin
|
42
|
+
active_fixtures = JSON.parse(File.read(ACTIVE_FIXTURE_FILE))
|
43
|
+
rescue Errno::ENOENT, Errno::ESRCH
|
44
|
+
return
|
45
|
+
end
|
46
|
+
|
47
|
+
active_fixtures.each do |fixture|
|
48
|
+
url, method, active_fixture = fixture
|
49
|
+
action = find_action(url, method)
|
50
|
+
if action
|
51
|
+
action.active_fixture_name = active_fixture
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.clear_all!
|
57
|
+
@actions = {}
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.fixtures
|
61
|
+
json = @actions.values.group_by(&:url)
|
62
|
+
json.each do |url, actions|
|
63
|
+
json[url] = actions.map(&:to_hash)
|
64
|
+
end
|
65
|
+
json
|
66
|
+
end
|
67
|
+
|
68
|
+
def self._key(url, method)
|
69
|
+
FixturedActionKey.new(url, method)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,205 @@
|
|
1
|
+
require 'listen'
|
2
|
+
require 'sinatra/base'
|
3
|
+
require 'socket'
|
4
|
+
require 'haml'
|
5
|
+
require 'pathname'
|
6
|
+
|
7
|
+
require 'json-rigs/fixture'
|
8
|
+
require 'json-rigs/fixtures'
|
9
|
+
|
10
|
+
module JsonRigs
|
11
|
+
class FixtureServer < Sinatra::Base
|
12
|
+
configure :production, :development do
|
13
|
+
enable :logging
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.load_fixtures
|
17
|
+
puts "Loading fixtures from #{settings.fixture_path}..."
|
18
|
+
Dir[File.join(settings.fixture_path, '**/*.json')].each do |f|
|
19
|
+
load_fixture(f)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.load_fixture(f)
|
24
|
+
puts "Loading #{f}..."
|
25
|
+
relevant_path = f.sub(/\A#{settings.fixture_path}/, '')
|
26
|
+
pieces = Pathname(relevant_path).each_filename.to_a
|
27
|
+
|
28
|
+
unless pieces.length >= 2
|
29
|
+
error_message = %Q(
|
30
|
+
Fixtures are not structured correctly.
|
31
|
+
Please place .json files inside #{settings.fixture_path} as /[url]/[HTTP method]/[response type].json, e.g. /users/GET/success.json
|
32
|
+
)
|
33
|
+
logger.error error_message
|
34
|
+
halt error_message
|
35
|
+
end
|
36
|
+
|
37
|
+
url = pieces[0...-2].join('/')
|
38
|
+
method = pieces[-2]
|
39
|
+
response_name = File.basename(pieces[-1], ".*")
|
40
|
+
contents = File.read(f)
|
41
|
+
JsonRigs::Fixtures::fixture_action url, method do
|
42
|
+
fixture response_name.to_sym do
|
43
|
+
respond_with(contents)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
helpers do
|
49
|
+
def serve_request(servlet_url, method)
|
50
|
+
action = JsonRigs::Fixtures::find_action(servlet_url, method)
|
51
|
+
halt "unknown action '#{servlet_url} #{method}'" unless action
|
52
|
+
|
53
|
+
logger.info "Responding to #{servlet_url} #{method}"
|
54
|
+
|
55
|
+
if action.active_fixture?
|
56
|
+
logger.info "Using fixture #{action.active_fixture_name.inspect}"
|
57
|
+
|
58
|
+
fixture = action.active_fixture
|
59
|
+
halt 'action has no associated fixture' unless fixture
|
60
|
+
|
61
|
+
if fixture.pause_time
|
62
|
+
logger.info "Sleeping #{fixture.pause_time} seconds.."
|
63
|
+
sleep(fixture.pause_time)
|
64
|
+
end
|
65
|
+
|
66
|
+
content_type 'application/json'
|
67
|
+
return fixture.response
|
68
|
+
else
|
69
|
+
logger.info 'No fixture specified, using stub response.'
|
70
|
+
return '{ "success": false, "error_code": 0 }'
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def clear_fixtures
|
75
|
+
JsonRigs::Fixtures::clear_active_fixtures
|
76
|
+
logger.info 'Fixture clear successful.'
|
77
|
+
return 200
|
78
|
+
end
|
79
|
+
|
80
|
+
def get_fixtures
|
81
|
+
JsonRigs::Fixtures::fixtures.to_json
|
82
|
+
end
|
83
|
+
|
84
|
+
def set_active_fixture
|
85
|
+
%w{url method fixture}.each do |arg|
|
86
|
+
value = params[arg]
|
87
|
+
unless value
|
88
|
+
logger.error "missing #{arg} param"
|
89
|
+
halt "missing #{arg} param"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
action = JsonRigs::Fixtures::find_action(params[:url], params[:method])
|
94
|
+
|
95
|
+
action_str = "#{params[:url]} #{params[:method]}"
|
96
|
+
unless action
|
97
|
+
logger.error "unknown action #{action_str}"
|
98
|
+
halt "unknown action #{action_str}"
|
99
|
+
end
|
100
|
+
action.active_fixture_name = params[:fixture]
|
101
|
+
|
102
|
+
JsonRigs::Fixtures::save_active_fixtures
|
103
|
+
|
104
|
+
logger.info "Setting fixture for #{action_str} to #{params[:fixture]}"
|
105
|
+
|
106
|
+
return 200
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
get '/test-panel' do
|
111
|
+
@fixtures = JsonRigs::Fixtures::fixtures
|
112
|
+
haml :test_panel, locals: {fixtures: @fixtures}
|
113
|
+
end
|
114
|
+
|
115
|
+
get '/test-fixtures' do
|
116
|
+
fixture_action = params[:fixture_action]
|
117
|
+
case fixture_action
|
118
|
+
when 'get', nil
|
119
|
+
get_fixtures
|
120
|
+
else
|
121
|
+
halt "unknown fixture action #{fixture_action.inspect}"
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
post '/test-fixtures' do
|
126
|
+
fixture_action = params[:fixture_action]
|
127
|
+
case fixture_action
|
128
|
+
when 'clear'
|
129
|
+
clear_fixtures
|
130
|
+
when 'set'
|
131
|
+
set_active_fixture
|
132
|
+
else
|
133
|
+
halt "unknown fixture action #{fixture_action.inspect}"
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
get '/*' do |servlet_url|
|
138
|
+
serve_request(servlet_url, :GET)
|
139
|
+
end
|
140
|
+
|
141
|
+
post '/*' do |servlet_url|
|
142
|
+
serve_request(servlet_url, :POST)
|
143
|
+
end
|
144
|
+
|
145
|
+
put '/*' do |servlet_url|
|
146
|
+
serve_request(servlet_url, :PUT)
|
147
|
+
end
|
148
|
+
|
149
|
+
delete '/*' do |servlet_url|
|
150
|
+
serve_request(servlet_url, :DELETE)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
module FixtureServerRunner
|
155
|
+
class << self
|
156
|
+
STARTING_PORT = 3000
|
157
|
+
|
158
|
+
def start(fixture_path)
|
159
|
+
puts 'Starting fixture server...'
|
160
|
+
|
161
|
+
port = choose_port()
|
162
|
+
|
163
|
+
FixtureServer.set(:port, port)
|
164
|
+
FixtureServer.set(:fixture_path, fixture_path)
|
165
|
+
FixtureServer::load_fixtures
|
166
|
+
JsonRigs::Fixtures::load_active_fixtures
|
167
|
+
|
168
|
+
# Start listener on fixture path to reload fixtures if necessary.
|
169
|
+
listener = Listen.to(fixture_path, only: /\.json$/) { |modified, added, removed|
|
170
|
+
on_fixture_change(modified, added, removed)
|
171
|
+
}
|
172
|
+
listener.start
|
173
|
+
|
174
|
+
FixtureServer.run!
|
175
|
+
end
|
176
|
+
|
177
|
+
private
|
178
|
+
|
179
|
+
def on_fixture_change(modified, added, removed)
|
180
|
+
puts 'Reloading fixtures...'
|
181
|
+
|
182
|
+
JsonRigs::Fixtures::clear_all!
|
183
|
+
FixtureServer::load_fixtures
|
184
|
+
JsonRigs::Fixtures::load_active_fixtures
|
185
|
+
|
186
|
+
puts 'Fixtures reloaded.'
|
187
|
+
end
|
188
|
+
|
189
|
+
def choose_port
|
190
|
+
port = STARTING_PORT
|
191
|
+
|
192
|
+
begin
|
193
|
+
server = TCPServer.new(port)
|
194
|
+
rescue Errno::EADDRINUSE
|
195
|
+
port += 1
|
196
|
+
retry
|
197
|
+
ensure
|
198
|
+
server.close if server
|
199
|
+
end
|
200
|
+
|
201
|
+
port
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
metadata
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: json-rigs
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Clinkle
|
8
|
+
- David Kettler
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-09-01 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: daemons
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '1.2'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '1.2'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: json
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '1.8'
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '1.8'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: listen
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - "~>"
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '2.9'
|
49
|
+
type: :runtime
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - "~>"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '2.9'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: sinatra
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - "~>"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '1.4'
|
63
|
+
type: :runtime
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '1.4'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: haml
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - "~>"
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '4.0'
|
77
|
+
type: :runtime
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - "~>"
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '4.0'
|
84
|
+
description: An easy way to serve fixtures in response to web requests.Use a handy
|
85
|
+
panel to choose which fixtures to serve. Great for QA and fast prototyping.
|
86
|
+
email:
|
87
|
+
- alex@clinkle.com
|
88
|
+
- 21echoes@gmail.com
|
89
|
+
executables:
|
90
|
+
- jrigs
|
91
|
+
extensions: []
|
92
|
+
extra_rdoc_files: []
|
93
|
+
files:
|
94
|
+
- bin/jrigs
|
95
|
+
- lib/json-rigs.rb
|
96
|
+
- lib/json-rigs/client.rb
|
97
|
+
- lib/json-rigs/fixture-templates.rb
|
98
|
+
- lib/json-rigs/fixture.rb
|
99
|
+
- lib/json-rigs/fixtures.rb
|
100
|
+
- lib/json-rigs/server.rb
|
101
|
+
homepage: https://github.com/21echoes/json-rigs
|
102
|
+
licenses:
|
103
|
+
- MIT
|
104
|
+
metadata: {}
|
105
|
+
post_install_message:
|
106
|
+
rdoc_options: []
|
107
|
+
require_paths:
|
108
|
+
- lib
|
109
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
110
|
+
requirements:
|
111
|
+
- - ">="
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '0'
|
114
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - ">="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
requirements: []
|
120
|
+
rubyforge_project:
|
121
|
+
rubygems_version: 2.2.2
|
122
|
+
signing_key:
|
123
|
+
specification_version: 4
|
124
|
+
summary: "~~ set sail with json-rigs ~~"
|
125
|
+
test_files: []
|