vault-tools 0.0.10 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.yardopts +1 -0
- data/Gemfile +7 -0
- data/Rakefile +10 -0
- data/lib/vault-tools.rb +1 -0
- data/lib/vault-tools/app.rb +16 -3
- data/lib/vault-tools/config.rb +12 -0
- data/lib/vault-tools/core_db_tasks.rb +29 -0
- data/lib/vault-tools/hid.rb +1 -1
- data/lib/vault-tools/user.rb +14 -0
- data/lib/vault-tools/version.rb +1 -1
- data/lib/vault-tools/web.rb +49 -6
- data/test/app_test.rb +16 -1
- data/test/config_test.rb +27 -0
- data/test/helper.rb +2 -2
- data/test/user_test.rb +16 -1
- data/test/web_test.rb +80 -0
- data/vault-tools.gemspec +1 -0
- metadata +23 -13
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
-m markdown
|
data/Gemfile
CHANGED
@@ -3,6 +3,13 @@ source 'https://rubygems.org'
|
|
3
3
|
# Specify your gem's dependencies in vault-tools.gemspec
|
4
4
|
gemspec
|
5
5
|
|
6
|
+
group :development do
|
7
|
+
gem 'rake'
|
8
|
+
gem 'ruby-debug19'
|
9
|
+
gem 'shotgun'
|
10
|
+
gem 'yard-sinatra'
|
11
|
+
end
|
12
|
+
|
6
13
|
group :test do
|
7
14
|
gem 'vault-test-tools', :path => '../vault-test-tools'
|
8
15
|
end
|
data/Rakefile
CHANGED
data/lib/vault-tools.rb
CHANGED
data/lib/vault-tools/app.rb
CHANGED
@@ -2,15 +2,15 @@ require 'uuidtools'
|
|
2
2
|
|
3
3
|
module Vault
|
4
4
|
module App
|
5
|
-
# Convert
|
5
|
+
# Convert a core app ID into a Heroku app ID.
|
6
6
|
#
|
7
|
-
# @param app_id [Fixnum]
|
7
|
+
# @param app_id [Fixnum] A core app ID.
|
8
8
|
# @return [String] A Heroku ID that uniquely represents the app.
|
9
9
|
def self.id_to_hid(app_id)
|
10
10
|
"app#{app_id}@heroku.com"
|
11
11
|
end
|
12
12
|
|
13
|
-
# Convert
|
13
|
+
# Convert a core app ID into a v5 UUID.
|
14
14
|
#
|
15
15
|
# @param app_id [Fixnum] An app ID.
|
16
16
|
# @return [String] A v5 UUID that uniquely represents the app.
|
@@ -19,6 +19,19 @@ module Vault
|
|
19
19
|
UUIDTools::UUID.sha1_create(UUIDTools::UUID_URL_NAMESPACE, url).to_s
|
20
20
|
end
|
21
21
|
|
22
|
+
# Convert a Heroku app ID into a core app ID.
|
23
|
+
#
|
24
|
+
# @param heroku_id [String] A Heroku app ID, such as `app1234@heroku.com`.
|
25
|
+
# @raise [ArgumentError] Raised if a malformed Heroku ID is provided.
|
26
|
+
# @return [Fixnum] The core app ID that uniquely represents the app.
|
27
|
+
def self.hid_to_id(heroku_id)
|
28
|
+
if app_id = heroku_id.slice(/^app(\d+)\@heroku\.com$/, 1)
|
29
|
+
app_id.to_i
|
30
|
+
else
|
31
|
+
raise ArgumentError,"#{heroku_id} is not a valid Heroku app ID."
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
22
35
|
# Convert a Heroku app ID into a v5 UUID.
|
23
36
|
#
|
24
37
|
# @param heroku_id [String] A Heroku app ID, such as `app1234@heroku.com`.
|
data/lib/vault-tools/config.rb
CHANGED
@@ -10,6 +10,14 @@ module Vault
|
|
10
10
|
env(key) || raise("missing #{key}")
|
11
11
|
end
|
12
12
|
|
13
|
+
def production?
|
14
|
+
env('RACK_ENV') == 'production'
|
15
|
+
end
|
16
|
+
|
17
|
+
def test?
|
18
|
+
env('RACK_ENV') == 'test'
|
19
|
+
end
|
20
|
+
|
13
21
|
def app_name; env("APP_NAME"); end
|
14
22
|
def port; env!("PORT").to_i; end
|
15
23
|
|
@@ -17,5 +25,9 @@ module Vault
|
|
17
25
|
kind = "#{kind}_".upcase unless kind.empty?
|
18
26
|
env!("#{kind}DATABASE_URL")
|
19
27
|
end
|
28
|
+
|
29
|
+
def enable_ssl?
|
30
|
+
!env('VAULT_TOOLS_DISABLE_SSL')
|
31
|
+
end
|
20
32
|
end
|
21
33
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# Rake tasks for Core DB
|
2
|
+
#
|
3
|
+
# include in Rakefile via:
|
4
|
+
#
|
5
|
+
# require 'vault-tools/core_db_tasks'
|
6
|
+
|
7
|
+
desc "Pull db/structure.sql from core HEAD"
|
8
|
+
task :pull_core do
|
9
|
+
steps = []
|
10
|
+
steps << 'cd contrib/'
|
11
|
+
if File.exists?('contrib/core')
|
12
|
+
steps << 'rm -rf core'
|
13
|
+
end
|
14
|
+
steps << 'git clone -n git@github.com:heroku/core --depth 1'
|
15
|
+
steps << 'cd core'
|
16
|
+
steps << 'git checkout HEAD db/structure.sql'
|
17
|
+
sh steps.join(' && ')
|
18
|
+
end
|
19
|
+
|
20
|
+
desc "Drop and create vault-usage-test, core-test and shushu-test databases"
|
21
|
+
task :create_core_db => [:drop_core_db, :pull_core] do
|
22
|
+
sh 'createdb core-test'
|
23
|
+
sh 'psql core-test -f contrib/core/db/structure.sql'
|
24
|
+
end
|
25
|
+
|
26
|
+
desc "Drop the vault-usage-test, core-test and shushu-test databases"
|
27
|
+
task :drop_core_db do
|
28
|
+
sh 'dropdb core-test || true'
|
29
|
+
end
|
data/lib/vault-tools/hid.rb
CHANGED
@@ -4,7 +4,7 @@ module Vault
|
|
4
4
|
module HID
|
5
5
|
# Convert a Heroku app ID or user ID into a v5 UUID.
|
6
6
|
#
|
7
|
-
# @param heroku_id [String] A Heroku app ID
|
7
|
+
# @param heroku_id [String] A Heroku app ID or user ID.
|
8
8
|
# @raise [ArgumentError] Raised if a malformed Heroku ID is provided.
|
9
9
|
# @return [String] A v5 UUID that uniquely represents the app.
|
10
10
|
def self.hid_to_uuid(heroku_id)
|
data/lib/vault-tools/user.rb
CHANGED
@@ -19,6 +19,20 @@ module Vault
|
|
19
19
|
UUIDTools::UUID.sha1_create(UUIDTools::UUID_URL_NAMESPACE, url).to_s
|
20
20
|
end
|
21
21
|
|
22
|
+
# Convert a Heroku user ID into a core user ID.
|
23
|
+
#
|
24
|
+
# @param heroku_id [String] A Heroku user ID, such as
|
25
|
+
# `user1234@heroku.com`.
|
26
|
+
# @raise [ArgumentError] Raised if a malformed Heroku ID is provided.
|
27
|
+
# @return [Fixnum] The core user ID that uniquely represents the user.
|
28
|
+
def self.hid_to_id(heroku_id)
|
29
|
+
if user_id = heroku_id.slice(/^user(\d+)\@heroku\.com$/, 1)
|
30
|
+
user_id.to_i
|
31
|
+
else
|
32
|
+
raise ArgumentError,"#{heroku_id} is not a valid Heroku user ID."
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
22
36
|
# Convert a Heroku user ID into a v5 UUID.
|
23
37
|
#
|
24
38
|
# @param heroku_id [String] A Heroku user ID, such as
|
data/lib/vault-tools/version.rb
CHANGED
data/lib/vault-tools/web.rb
CHANGED
@@ -1,28 +1,71 @@
|
|
1
1
|
require 'vault-tools/log'
|
2
2
|
|
3
3
|
module Vault
|
4
|
+
# Base class for HTTP API services.
|
4
5
|
class Web < Sinatra::Base
|
6
|
+
# Store the action for logging purposes.
|
5
7
|
def self.route(verb, action, *)
|
6
8
|
condition { @action = action }
|
7
9
|
super
|
8
10
|
end
|
9
11
|
|
12
|
+
# Start timing the request.
|
10
13
|
before do
|
11
14
|
@start_request = Time.now
|
12
15
|
end
|
13
16
|
|
17
|
+
# Log details about the request including how long it took.
|
14
18
|
after do
|
15
19
|
Log.count_status(response.status)
|
16
20
|
Log.time(@action, Time.now - @start_request)
|
17
21
|
end
|
18
22
|
|
19
|
-
#
|
20
|
-
|
23
|
+
# Make sure error handler blocks are invoked in tests.
|
24
|
+
set :show_exceptions, false
|
25
|
+
set :raise_errors, false
|
21
26
|
|
22
|
-
#
|
23
|
-
|
27
|
+
# Require HTTPS connections when production mode is enabled.
|
28
|
+
use Rack::SslEnforcer if (Config.enable_ssl? && Config.production?)
|
24
29
|
|
25
|
-
#
|
26
|
-
|
30
|
+
# Return an *HTTP 500 Internal Server Error* with a traceback in the
|
31
|
+
# body for easy debugging of errors.
|
32
|
+
error do
|
33
|
+
e = env['sinatra.error']
|
34
|
+
content = "#{e.class}: #{e.message}\n\n"
|
35
|
+
content << e.backtrace.join("\n")
|
36
|
+
[500, content]
|
37
|
+
end
|
38
|
+
|
39
|
+
# Determine if the service is running and responding to requests.
|
40
|
+
#
|
41
|
+
# @method status-check
|
42
|
+
# @return The following responses may be returned by this method:
|
43
|
+
#
|
44
|
+
# - *HTTP 200 OK*: Returned if the request was successful.
|
45
|
+
head '/' do
|
46
|
+
status(200)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Determine if the service is running and responding to requests.
|
50
|
+
#
|
51
|
+
# @method health-check
|
52
|
+
# @return The following responses may be returned by this method:
|
53
|
+
#
|
54
|
+
# - *HTTP 200 OK*: Returned if the request was successful with `OK` in
|
55
|
+
# the body.
|
56
|
+
get '/health' do
|
57
|
+
[200, 'OK']
|
58
|
+
end
|
59
|
+
|
60
|
+
# Trigger an internal server error (to test monitoring and paging tools).
|
61
|
+
#
|
62
|
+
# @method boom
|
63
|
+
# @return The following responses may be returned by this method:
|
64
|
+
#
|
65
|
+
# - *HTTP 500 Internal Server Error*: Returned with a traceback in the
|
66
|
+
# body.
|
67
|
+
get '/boom' do
|
68
|
+
raise "An expected error occurred."
|
69
|
+
end
|
27
70
|
end
|
28
71
|
end
|
data/test/app_test.rb
CHANGED
@@ -14,6 +14,21 @@ class AppTest < Vault::TestCase
|
|
14
14
|
assert_equal(uuid, Vault::App.id_to_uuid(1234))
|
15
15
|
end
|
16
16
|
|
17
|
+
# App.hid_to_id converts a Heroku app ID into a core integer app ID.
|
18
|
+
def test_hid_to_id
|
19
|
+
assert_equal(1234, Vault::App.hid_to_id('app1234@heroku.com'))
|
20
|
+
end
|
21
|
+
|
22
|
+
# App.hid_to_id raises an ArgumentError if the specified ID doesn't match
|
23
|
+
# the expected format.
|
24
|
+
def test_hid_to_id_with_invalid_heroku_id
|
25
|
+
error = assert_raises(ArgumentError) do
|
26
|
+
Vault::App.hid_to_id('invalid1234@heroku.com')
|
27
|
+
end
|
28
|
+
assert_equal('invalid1234@heroku.com is not a valid Heroku app ID.',
|
29
|
+
error.message)
|
30
|
+
end
|
31
|
+
|
17
32
|
# App.hid_to_uuid converts a Heroku app ID to a v5 UUID based on a URL
|
18
33
|
# scheme.
|
19
34
|
def test_hid_to_uuid
|
@@ -22,7 +37,7 @@ class AppTest < Vault::TestCase
|
|
22
37
|
assert_equal(uuid, Vault::App.hid_to_uuid('app1234@heroku.com'))
|
23
38
|
end
|
24
39
|
|
25
|
-
# App.hid_to_uuid raises
|
40
|
+
# App.hid_to_uuid raises an ArgumentError if the specified ID doesn't match
|
26
41
|
# the expected format.
|
27
42
|
def test_hid_to_uuid_with_invalid_heroku_id
|
28
43
|
error = assert_raises(ArgumentError) do
|
data/test/config_test.rb
CHANGED
@@ -2,6 +2,22 @@ require 'helper'
|
|
2
2
|
|
3
3
|
class ConfigTest < Vault::TestCase
|
4
4
|
|
5
|
+
# Config.production? is true when RACK_ENV=production
|
6
|
+
def test_production_mode
|
7
|
+
set_env 'RACK_ENV', nil
|
8
|
+
refute Vault::Config.production?
|
9
|
+
set_env 'RACK_ENV', 'production'
|
10
|
+
assert Vault::Config.production?
|
11
|
+
end
|
12
|
+
|
13
|
+
# Config.test? is true when RACK_ENV=test
|
14
|
+
def test_test_mode
|
15
|
+
set_env 'RACK_ENV', nil
|
16
|
+
refute Vault::Config.test?
|
17
|
+
set_env 'RACK_ENV', 'test'
|
18
|
+
assert Vault::Config.test?
|
19
|
+
end
|
20
|
+
|
5
21
|
# Returns DATABASE_URL with no params
|
6
22
|
def test_database_url
|
7
23
|
set_env 'DATABASE_URL', "postgres:///foo"
|
@@ -36,4 +52,15 @@ class ConfigTest < Vault::TestCase
|
|
36
52
|
set_env 'PORT', "3000"
|
37
53
|
Vault::Config.port.must_equal 3000
|
38
54
|
end
|
55
|
+
|
56
|
+
# Config.enable_ssl? is true unless VAULT_TOOLS_DISABLE_SSL
|
57
|
+
# is set
|
58
|
+
def test_enable_ssl
|
59
|
+
set_env 'VAULT_TOOLS_DISABLE_SSL', nil
|
60
|
+
assert Vault::Config.enable_ssl?
|
61
|
+
set_env 'VAULT_TOOLS_DISABLE_SSL', '1'
|
62
|
+
refute Vault::Config.enable_ssl?
|
63
|
+
set_env 'VAULT_TOOLS_DISABLE_SSL', 'foo'
|
64
|
+
refute Vault::Config.enable_ssl?
|
65
|
+
end
|
39
66
|
end
|
data/test/helper.rb
CHANGED
data/test/user_test.rb
CHANGED
@@ -14,6 +14,21 @@ class UserTest < Vault::TestCase
|
|
14
14
|
assert_equal(uuid, Vault::User.id_to_uuid(1234))
|
15
15
|
end
|
16
16
|
|
17
|
+
# User.hid_to_id converts a Heroku user ID into a core integer user ID.
|
18
|
+
def test_hid_to_id
|
19
|
+
assert_equal(1234, Vault::User.hid_to_id('user1234@heroku.com'))
|
20
|
+
end
|
21
|
+
|
22
|
+
# User.hid_to_id raises an ArgumentError if the specified ID doesn't match
|
23
|
+
# the expected format.
|
24
|
+
def test_hid_to_id_with_invalid_heroku_id
|
25
|
+
error = assert_raises(ArgumentError) do
|
26
|
+
Vault::User.hid_to_id('invalid1234@heroku.com')
|
27
|
+
end
|
28
|
+
assert_equal('invalid1234@heroku.com is not a valid Heroku user ID.',
|
29
|
+
error.message)
|
30
|
+
end
|
31
|
+
|
17
32
|
# User.hid_to_uuid converts a Heroku user ID to a v5 UUID based on a URL
|
18
33
|
# scheme.
|
19
34
|
def test_hid_to_uuid
|
@@ -22,7 +37,7 @@ class UserTest < Vault::TestCase
|
|
22
37
|
assert_equal(uuid, Vault::User.hid_to_uuid('user1234@heroku.com'))
|
23
38
|
end
|
24
39
|
|
25
|
-
# User.hid_to_uuid raises
|
40
|
+
# User.hid_to_uuid raises an ArgumentError if the specified ID doesn't match
|
26
41
|
# the expected format.
|
27
42
|
def test_hid_to_uuid_with_invalid_heroku_id
|
28
43
|
error = assert_raises(ArgumentError) do
|
data/test/web_test.rb
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class WebTest < Vault::TestCase
|
4
|
+
include Rack::Test::Methods
|
5
|
+
|
6
|
+
# Anonymous Web Frontend
|
7
|
+
def app
|
8
|
+
Class.new(Vault::Web)
|
9
|
+
end
|
10
|
+
|
11
|
+
# Always reload the web class to eliminate test leakage
|
12
|
+
def setup
|
13
|
+
super
|
14
|
+
reload_web!
|
15
|
+
end
|
16
|
+
|
17
|
+
# middleware is attached at load time, so we have to
|
18
|
+
# delete the web class and reload it to simulate being
|
19
|
+
# loaded with a given ENV
|
20
|
+
def reload_web!
|
21
|
+
# remove the constant to force a clean reload
|
22
|
+
Vault.send(:remove_const, 'Web')
|
23
|
+
load 'lib/vault-tools/web.rb'
|
24
|
+
end
|
25
|
+
|
26
|
+
# A successful request causes a `web-20` log entry to be written.
|
27
|
+
def test_head_status_check
|
28
|
+
head '/'
|
29
|
+
assert_match(/measure=true/, Scrolls.stream.string)
|
30
|
+
assert_match(/at=web-20/, Scrolls.stream.string)
|
31
|
+
assert_equal(200, last_response.status)
|
32
|
+
end
|
33
|
+
|
34
|
+
# A successful request causes `web-20` log entry to be written and `OK`
|
35
|
+
# content is returned in the response body.
|
36
|
+
def test_get_health_check
|
37
|
+
get '/health'
|
38
|
+
assert_match(/measure=true/, Scrolls.stream.string)
|
39
|
+
assert_match(/at=web-20/, Scrolls.stream.string)
|
40
|
+
assert_equal(200, last_response.status)
|
41
|
+
assert_equal('OK', last_response.body)
|
42
|
+
end
|
43
|
+
|
44
|
+
# A validation error causes a `web-40` log entry to be written.
|
45
|
+
def test_head_with_unknown_endpoint
|
46
|
+
head '/unknown'
|
47
|
+
assert_match(/measure=true/, Scrolls.stream.string)
|
48
|
+
assert_match(/at=web-40/, Scrolls.stream.string)
|
49
|
+
assert_equal(404, last_response.status)
|
50
|
+
end
|
51
|
+
|
52
|
+
# An internal server error causes a `web-50` log entry to be written. A
|
53
|
+
# traceback is also written to the response body to ease debugging.
|
54
|
+
def test_error_logs_500
|
55
|
+
get '/boom'
|
56
|
+
assert_match(/measure=true/, Scrolls.stream.string)
|
57
|
+
assert_match(/at=web-50/, Scrolls.stream.string)
|
58
|
+
assert_match(/^RuntimeError: An expected error occurred.$/m,
|
59
|
+
last_response.body)
|
60
|
+
assert_equal(500, last_response.status)
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
# SSL is enforced when we are in production mode
|
65
|
+
def test_ssl_enforced_in_production_mode
|
66
|
+
set_env 'RACK_ENV', 'production'
|
67
|
+
reload_web!
|
68
|
+
get '/health'
|
69
|
+
assert_equal(301, last_response.status)
|
70
|
+
assert_match(/^https/, last_response.headers['Location'])
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_ssl_can_be_disabled
|
74
|
+
set_env 'RACK_ENV', 'production'
|
75
|
+
set_env 'VAULT_TOOLS_DISABLE_SSL', 'anything'
|
76
|
+
reload_web!
|
77
|
+
get '/health'
|
78
|
+
assert_equal(200, last_response.status)
|
79
|
+
end
|
80
|
+
end
|
data/vault-tools.gemspec
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vault-tools
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-02-
|
13
|
+
date: 2013-02-22 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: scrolls
|
@@ -60,6 +60,22 @@ dependencies:
|
|
60
60
|
- - ! '>='
|
61
61
|
- !ruby/object:Gem::Version
|
62
62
|
version: '0'
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
name: rack-ssl-enforcer
|
65
|
+
requirement: !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ! '>='
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
71
|
+
type: :runtime
|
72
|
+
prerelease: false
|
73
|
+
version_requirements: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ! '>='
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
63
79
|
description: Basic tools for Heroku Vault's Ruby projects
|
64
80
|
email:
|
65
81
|
- christopher.continanza@gmail.com
|
@@ -71,22 +87,15 @@ extensions: []
|
|
71
87
|
extra_rdoc_files: []
|
72
88
|
files:
|
73
89
|
- .gitignore
|
90
|
+
- .yardopts
|
74
91
|
- Gemfile
|
75
92
|
- LICENSE.txt
|
76
93
|
- README.md
|
77
94
|
- Rakefile
|
78
|
-
- bin/d
|
79
|
-
- bin/nokogiri
|
80
|
-
- bin/pprof.rb
|
81
|
-
- bin/rackup
|
82
|
-
- bin/ri
|
83
|
-
- bin/t
|
84
|
-
- bin/tilt
|
85
|
-
- bin/turn
|
86
|
-
- bin/vault-tools
|
87
95
|
- lib/vault-tools.rb
|
88
96
|
- lib/vault-tools/app.rb
|
89
97
|
- lib/vault-tools/config.rb
|
98
|
+
- lib/vault-tools/core_db_tasks.rb
|
90
99
|
- lib/vault-tools/hid.rb
|
91
100
|
- lib/vault-tools/log.rb
|
92
101
|
- lib/vault-tools/pipeline.rb
|
@@ -103,6 +112,7 @@ files:
|
|
103
112
|
- test/product_test.rb
|
104
113
|
- test/test_spec.rb
|
105
114
|
- test/user_test.rb
|
115
|
+
- test/web_test.rb
|
106
116
|
- vault-tools.gemspec
|
107
117
|
homepage: ''
|
108
118
|
licenses: []
|
@@ -118,7 +128,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
118
128
|
version: '0'
|
119
129
|
segments:
|
120
130
|
- 0
|
121
|
-
hash:
|
131
|
+
hash: 29653798075093968
|
122
132
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
123
133
|
none: false
|
124
134
|
requirements:
|
@@ -127,7 +137,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
127
137
|
version: '0'
|
128
138
|
segments:
|
129
139
|
- 0
|
130
|
-
hash:
|
140
|
+
hash: 29653798075093968
|
131
141
|
requirements: []
|
132
142
|
rubyforge_project:
|
133
143
|
rubygems_version: 1.8.23
|