foreman 0.40.0 → 0.42.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.
- data/data/export/supervisord/app.conf.erb +27 -0
- data/lib/foreman/color.rb +40 -0
- data/lib/foreman/engine.rb +27 -35
- data/lib/foreman/export/supervisord.rb +26 -0
- data/lib/foreman/export.rb +2 -0
- data/lib/foreman/version.rb +1 -1
- data/spec/foreman/color_spec.rb +31 -0
- data/spec/foreman/export/supervisord_spec.rb +75 -0
- data/spec/resources/export/supervisord/app-alpha-2.conf +24 -0
- data/spec/resources/export/supervisord/app.conf +24 -0
- metadata +11 -21
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<%
|
|
2
|
+
app_names = []
|
|
3
|
+
engine.procfile.entries.each do |process|
|
|
4
|
+
next if (conc = self.concurrency[process.name]) < 1
|
|
5
|
+
1.upto(self.concurrency[process.name]) do |num|
|
|
6
|
+
port = engine.port_for(process, num, self.port)
|
|
7
|
+
name = if (conc > 1); "#{process.name}-#{num}" else process.name; end
|
|
8
|
+
environment = (engine.environment.map{ |var,env| "#{var.upcase}=#{env}" } + ["PORT=#{port}"])
|
|
9
|
+
app_name = "#{app}-#{name}"
|
|
10
|
+
app_names << app_name
|
|
11
|
+
%>
|
|
12
|
+
[program:<%= app_name %>]
|
|
13
|
+
command=<%= process.command %>
|
|
14
|
+
autostart=true
|
|
15
|
+
autorestart=true
|
|
16
|
+
stopsignal=QUIT
|
|
17
|
+
stdout_logfile=<%= log_root %>/<%=process.name%>-<%=num%>-out.log
|
|
18
|
+
stderr_logfile=<%= log_root %>/<%=process.name%>-<%=num%>-err.log
|
|
19
|
+
user=<%= user %>
|
|
20
|
+
directory=<%= engine.directory %>
|
|
21
|
+
environment=<%= environment.join(',') %><%
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
%>
|
|
25
|
+
|
|
26
|
+
[group:<%= app %>]
|
|
27
|
+
programs=<%= app_names.join(',') %>
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require "foreman"
|
|
2
|
+
|
|
3
|
+
module Foreman::Color
|
|
4
|
+
|
|
5
|
+
ANSI = {
|
|
6
|
+
:reset => 0,
|
|
7
|
+
:black => 30,
|
|
8
|
+
:red => 31,
|
|
9
|
+
:green => 32,
|
|
10
|
+
:yellow => 33,
|
|
11
|
+
:blue => 34,
|
|
12
|
+
:magenta => 35,
|
|
13
|
+
:cyan => 36,
|
|
14
|
+
:white => 37,
|
|
15
|
+
:bright_black => 30,
|
|
16
|
+
:bright_red => 31,
|
|
17
|
+
:bright_green => 32,
|
|
18
|
+
:bright_yellow => 33,
|
|
19
|
+
:bright_blue => 34,
|
|
20
|
+
:bright_magenta => 35,
|
|
21
|
+
:bright_cyan => 36,
|
|
22
|
+
:bright_white => 37,
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
def self.enable(io)
|
|
26
|
+
io.extend(self)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def color?
|
|
30
|
+
return false unless self.respond_to?(:isatty)
|
|
31
|
+
self.isatty && ENV["TERM"]
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def color(name)
|
|
35
|
+
return "" unless color?
|
|
36
|
+
return "" unless ansi = ANSI[name.to_sym]
|
|
37
|
+
"\e[#{ansi}m"
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
end
|
data/lib/foreman/engine.rb
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
require "foreman"
|
|
2
|
+
require "foreman/color"
|
|
2
3
|
require "foreman/process"
|
|
3
4
|
require "foreman/procfile"
|
|
4
5
|
require "foreman/utils"
|
|
5
6
|
require "tempfile"
|
|
6
7
|
require "timeout"
|
|
7
|
-
require "term/ansicolor"
|
|
8
8
|
require "fileutils"
|
|
9
9
|
require "thread"
|
|
10
10
|
|
|
@@ -15,11 +15,10 @@ class Foreman::Engine
|
|
|
15
15
|
attr_reader :directory
|
|
16
16
|
attr_reader :options
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
COLORS = %w( cyan yellow green magenta red blue intense_cyan intense_yellow
|
|
19
|
+
intense_green intense_magenta intense_red, intense_blue )
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
intense_cyan, intense_yellow, intense_green, intense_magenta,
|
|
22
|
-
intense_red, intense_blue ]
|
|
21
|
+
Foreman::Color.enable($stdout)
|
|
23
22
|
|
|
24
23
|
def initialize(procfile, options={})
|
|
25
24
|
@procfile = Foreman::Procfile.new(procfile)
|
|
@@ -52,6 +51,22 @@ class Foreman::Engine
|
|
|
52
51
|
environment.each { |k,v| ENV[k] = v }
|
|
53
52
|
end
|
|
54
53
|
|
|
54
|
+
def self.read_environment(filename)
|
|
55
|
+
return {} unless File.exists?(filename)
|
|
56
|
+
|
|
57
|
+
File.read(filename).split("\n").inject({}) do |hash, line|
|
|
58
|
+
if line =~ /\A([A-Za-z_0-9]+)=(.*)\z/
|
|
59
|
+
key, val = [$1, $2]
|
|
60
|
+
case val
|
|
61
|
+
when /\A'(.*)'\z/ then hash[key] = $1
|
|
62
|
+
when /\A"(.*)"\z/ then hash[key] = $1.gsub(/\\(.)/, '\1')
|
|
63
|
+
else hash[key] = val
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
hash
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
55
70
|
private ######################################################################
|
|
56
71
|
|
|
57
72
|
def spawn_processes
|
|
@@ -128,11 +143,11 @@ private ######################################################################
|
|
|
128
143
|
rescue Errno::ECHILD
|
|
129
144
|
end
|
|
130
145
|
|
|
131
|
-
def info(message, name="system", color
|
|
146
|
+
def info(message, name="system", color=:white)
|
|
132
147
|
output = ""
|
|
133
|
-
output += color
|
|
148
|
+
output += $stdout.color(color)
|
|
134
149
|
output += "#{Time.now.strftime("%H:%M:%S")} #{pad_process_name(name)} | "
|
|
135
|
-
output +=
|
|
150
|
+
output += $stdout.color(:reset)
|
|
136
151
|
output += message.chomp
|
|
137
152
|
puts output
|
|
138
153
|
end
|
|
@@ -182,8 +197,8 @@ private ######################################################################
|
|
|
182
197
|
end
|
|
183
198
|
|
|
184
199
|
def assign_colors
|
|
185
|
-
procfile.entries.
|
|
186
|
-
colors[entry.name] =
|
|
200
|
+
procfile.entries.each_with_index do |entry, idx|
|
|
201
|
+
colors[entry.name] = COLORS[idx % COLORS.length]
|
|
187
202
|
end
|
|
188
203
|
end
|
|
189
204
|
|
|
@@ -191,38 +206,15 @@ private ######################################################################
|
|
|
191
206
|
readers.invert[reader]
|
|
192
207
|
end
|
|
193
208
|
|
|
194
|
-
def next_color
|
|
195
|
-
@current_color ||= -1
|
|
196
|
-
@current_color += 1
|
|
197
|
-
@current_color = 0 if COLORS.length < @current_color
|
|
198
|
-
COLORS[@current_color]
|
|
199
|
-
end
|
|
200
|
-
|
|
201
209
|
def read_environment_files(filenames)
|
|
202
210
|
environment = {}
|
|
203
211
|
|
|
204
212
|
(filenames || "").split(",").map(&:strip).each do |filename|
|
|
205
213
|
error "No such file: #{filename}" unless File.exists?(filename)
|
|
206
|
-
environment.merge!(read_environment(filename))
|
|
214
|
+
environment.merge!(Foreman::Engine.read_environment(filename))
|
|
207
215
|
end
|
|
208
216
|
|
|
209
|
-
environment.merge!(read_environment(".env")) unless filenames
|
|
217
|
+
environment.merge!(Foreman::Engine.read_environment(".env")) unless filenames
|
|
210
218
|
environment
|
|
211
219
|
end
|
|
212
|
-
|
|
213
|
-
def read_environment(filename)
|
|
214
|
-
return {} unless File.exists?(filename)
|
|
215
|
-
|
|
216
|
-
File.read(filename).split("\n").inject({}) do |hash, line|
|
|
217
|
-
if line =~ /\A([A-Za-z_0-9]+)=(.*)\z/
|
|
218
|
-
key, val = [$1, $2]
|
|
219
|
-
case val
|
|
220
|
-
when /\A'(.*)'\z/ then hash[key] = $1
|
|
221
|
-
when /\A"(.*)"\z/ then hash[key] = $1.gsub(/\\(.)/, '\1')
|
|
222
|
-
else hash[key] = val
|
|
223
|
-
end
|
|
224
|
-
end
|
|
225
|
-
hash
|
|
226
|
-
end
|
|
227
|
-
end
|
|
228
220
|
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require "erb"
|
|
2
|
+
require "foreman/export"
|
|
3
|
+
|
|
4
|
+
class Foreman::Export::Supervisord < Foreman::Export::Base
|
|
5
|
+
|
|
6
|
+
def export
|
|
7
|
+
error("Must specify a location") unless location
|
|
8
|
+
|
|
9
|
+
FileUtils.mkdir_p location
|
|
10
|
+
|
|
11
|
+
app = self.app || File.basename(engine.directory)
|
|
12
|
+
user = self.user || app
|
|
13
|
+
log_root = self.log || "/var/log/#{app}"
|
|
14
|
+
template_root = self.template
|
|
15
|
+
|
|
16
|
+
Dir["#{location}/#{app}*.conf"].each do |file|
|
|
17
|
+
say "cleaning up: #{file}"
|
|
18
|
+
FileUtils.rm(file)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
app_template = export_template("supervisord", "app.conf.erb", template_root)
|
|
22
|
+
app_config = ERB.new(app_template, 0, '<').result(binding)
|
|
23
|
+
write_file "#{location}/#{app}.conf", app_config
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
end
|
data/lib/foreman/export.rb
CHANGED
data/lib/foreman/version.rb
CHANGED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
require "foreman/color"
|
|
3
|
+
|
|
4
|
+
describe Foreman::Color do
|
|
5
|
+
|
|
6
|
+
let(:io) { Object.new }
|
|
7
|
+
|
|
8
|
+
it "should extend an object with colorization" do
|
|
9
|
+
Foreman::Color.enable(io)
|
|
10
|
+
io.should respond_to(:color)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "should not colorize if the object does not respond to isatty" do
|
|
14
|
+
mock(io).respond_to?(:isatty) { false }
|
|
15
|
+
Foreman::Color.enable(io)
|
|
16
|
+
io.color(:white).should == ""
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "should not colorize if the object is not a tty" do
|
|
20
|
+
mock(io).isatty { false }
|
|
21
|
+
Foreman::Color.enable(io)
|
|
22
|
+
io.color(:white).should == ""
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "should colorize if the object is a tty" do
|
|
26
|
+
mock(io).isatty { true }
|
|
27
|
+
Foreman::Color.enable(io)
|
|
28
|
+
io.color(:white).should == "\e[37m"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
require "foreman/engine"
|
|
3
|
+
require "foreman/export/supervisord"
|
|
4
|
+
require "tmpdir"
|
|
5
|
+
|
|
6
|
+
describe Foreman::Export::Supervisord, :fakefs do
|
|
7
|
+
let(:procfile) { FileUtils.mkdir_p("/tmp/app"); write_procfile("/tmp/app/Procfile") }
|
|
8
|
+
let(:engine) { Foreman::Engine.new(procfile) }
|
|
9
|
+
let(:options) { Hash.new }
|
|
10
|
+
let(:supervisord) { Foreman::Export::Supervisord.new("/tmp/init", engine, options) }
|
|
11
|
+
|
|
12
|
+
before(:each) { load_export_templates_into_fakefs("supervisord") }
|
|
13
|
+
before(:each) { stub(supervisord).say }
|
|
14
|
+
|
|
15
|
+
it "exports to the filesystem" do
|
|
16
|
+
supervisord.export
|
|
17
|
+
|
|
18
|
+
File.read("/tmp/init/app.conf").should == example_export_file("supervisord/app.conf")
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "cleans up if exporting into an existing dir" do
|
|
22
|
+
mock(FileUtils).rm("/tmp/init/app.conf")
|
|
23
|
+
|
|
24
|
+
supervisord.export
|
|
25
|
+
supervisord.export
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
context "with concurrency" do
|
|
29
|
+
let(:options) { Hash[:concurrency => "alpha=2"] }
|
|
30
|
+
|
|
31
|
+
it "exports to the filesystem with concurrency" do
|
|
32
|
+
supervisord.export
|
|
33
|
+
|
|
34
|
+
File.read("/tmp/init/app.conf").should == example_export_file("supervisord/app-alpha-2.conf")
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
context "with alternate templates" do
|
|
39
|
+
let(:template_root) { "/tmp/alternate" }
|
|
40
|
+
let(:supervisord) { Foreman::Export::Supervisord.new("/tmp/init", engine, :template => template_root) }
|
|
41
|
+
|
|
42
|
+
before do
|
|
43
|
+
FileUtils.mkdir_p template_root
|
|
44
|
+
File.open("#{template_root}/app.conf.erb", "w") { |f| f.puts "alternate_template" }
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "can export with alternate template files" do
|
|
48
|
+
supervisord.export
|
|
49
|
+
|
|
50
|
+
File.read("/tmp/init/app.conf").should == "alternate_template\n"
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
context "with alternate templates from home dir" do
|
|
55
|
+
let(:default_template_root) {File.expand_path("#{ENV['HOME']}/.foreman/templates")}
|
|
56
|
+
|
|
57
|
+
before do
|
|
58
|
+
ENV['_FOREMAN_SPEC_HOME'] = ENV['HOME']
|
|
59
|
+
ENV['HOME'] = "/home/appuser"
|
|
60
|
+
FileUtils.mkdir_p default_template_root
|
|
61
|
+
File.open("#{default_template_root}/app.conf.erb", "w") { |f| f.puts "default_alternate_template" }
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
after do
|
|
65
|
+
ENV['HOME'] = ENV.delete('_FOREMAN_SPEC_HOME')
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it "can export with alternate template files" do
|
|
69
|
+
supervisord.export
|
|
70
|
+
|
|
71
|
+
File.read("/tmp/init/app.conf").should == "default_alternate_template\n"
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
|
|
2
|
+
[program:app-alpha-1]
|
|
3
|
+
command=./alpha
|
|
4
|
+
autostart=true
|
|
5
|
+
autorestart=true
|
|
6
|
+
stopsignal=QUIT
|
|
7
|
+
stdout_logfile=/var/log/app/alpha-1-out.log
|
|
8
|
+
stderr_logfile=/var/log/app/alpha-1-err.log
|
|
9
|
+
user=app
|
|
10
|
+
directory=/tmp/app
|
|
11
|
+
environment=PORT=5000
|
|
12
|
+
[program:app-alpha-2]
|
|
13
|
+
command=./alpha
|
|
14
|
+
autostart=true
|
|
15
|
+
autorestart=true
|
|
16
|
+
stopsignal=QUIT
|
|
17
|
+
stdout_logfile=/var/log/app/alpha-2-out.log
|
|
18
|
+
stderr_logfile=/var/log/app/alpha-2-err.log
|
|
19
|
+
user=app
|
|
20
|
+
directory=/tmp/app
|
|
21
|
+
environment=PORT=5001
|
|
22
|
+
|
|
23
|
+
[group:app]
|
|
24
|
+
programs=app-alpha-1,app-alpha-2
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
|
|
2
|
+
[program:app-alpha]
|
|
3
|
+
command=./alpha
|
|
4
|
+
autostart=true
|
|
5
|
+
autorestart=true
|
|
6
|
+
stopsignal=QUIT
|
|
7
|
+
stdout_logfile=/var/log/app/alpha-1-out.log
|
|
8
|
+
stderr_logfile=/var/log/app/alpha-1-err.log
|
|
9
|
+
user=app
|
|
10
|
+
directory=/tmp/app
|
|
11
|
+
environment=PORT=5000
|
|
12
|
+
[program:app-bravo]
|
|
13
|
+
command=./bravo
|
|
14
|
+
autostart=true
|
|
15
|
+
autorestart=true
|
|
16
|
+
stopsignal=QUIT
|
|
17
|
+
stdout_logfile=/var/log/app/bravo-1-out.log
|
|
18
|
+
stderr_logfile=/var/log/app/bravo-1-err.log
|
|
19
|
+
user=app
|
|
20
|
+
directory=/tmp/app
|
|
21
|
+
environment=PORT=5100
|
|
22
|
+
|
|
23
|
+
[group:app]
|
|
24
|
+
programs=app-alpha,app-bravo
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: foreman
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.42.0
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -9,22 +9,11 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2012-
|
|
12
|
+
date: 2012-04-18 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
|
-
- !ruby/object:Gem::Dependency
|
|
15
|
-
name: term-ansicolor
|
|
16
|
-
requirement: &70330442658940 !ruby/object:Gem::Requirement
|
|
17
|
-
none: false
|
|
18
|
-
requirements:
|
|
19
|
-
- - ~>
|
|
20
|
-
- !ruby/object:Gem::Version
|
|
21
|
-
version: 1.0.7
|
|
22
|
-
type: :runtime
|
|
23
|
-
prerelease: false
|
|
24
|
-
version_requirements: *70330442658940
|
|
25
14
|
- !ruby/object:Gem::Dependency
|
|
26
15
|
name: thor
|
|
27
|
-
requirement: &
|
|
16
|
+
requirement: &70264218748020 !ruby/object:Gem::Requirement
|
|
28
17
|
none: false
|
|
29
18
|
requirements:
|
|
30
19
|
- - ! '>='
|
|
@@ -32,7 +21,7 @@ dependencies:
|
|
|
32
21
|
version: 0.13.6
|
|
33
22
|
type: :runtime
|
|
34
23
|
prerelease: false
|
|
35
|
-
version_requirements: *
|
|
24
|
+
version_requirements: *70264218748020
|
|
36
25
|
description: Process manager for applications with multiple components
|
|
37
26
|
email: ddollar@gmail.com
|
|
38
27
|
executables:
|
|
@@ -51,16 +40,19 @@ files:
|
|
|
51
40
|
- data/export/bluepill/master.pill.erb
|
|
52
41
|
- data/export/runit/log_run.erb
|
|
53
42
|
- data/export/runit/run.erb
|
|
43
|
+
- data/export/supervisord/app.conf.erb
|
|
54
44
|
- data/export/upstart/master.conf.erb
|
|
55
45
|
- data/export/upstart/process.conf.erb
|
|
56
46
|
- data/export/upstart/process_master.conf.erb
|
|
57
47
|
- lib/foreman/cli.rb
|
|
48
|
+
- lib/foreman/color.rb
|
|
58
49
|
- lib/foreman/distribution.rb
|
|
59
50
|
- lib/foreman/engine.rb
|
|
60
51
|
- lib/foreman/export/base.rb
|
|
61
52
|
- lib/foreman/export/bluepill.rb
|
|
62
53
|
- lib/foreman/export/inittab.rb
|
|
63
54
|
- lib/foreman/export/runit.rb
|
|
55
|
+
- lib/foreman/export/supervisord.rb
|
|
64
56
|
- lib/foreman/export/upstart.rb
|
|
65
57
|
- lib/foreman/export.rb
|
|
66
58
|
- lib/foreman/helpers.rb
|
|
@@ -72,11 +64,13 @@ files:
|
|
|
72
64
|
- lib/foreman.rb
|
|
73
65
|
- README.md
|
|
74
66
|
- spec/foreman/cli_spec.rb
|
|
67
|
+
- spec/foreman/color_spec.rb
|
|
75
68
|
- spec/foreman/engine_spec.rb
|
|
76
69
|
- spec/foreman/export/base_spec.rb
|
|
77
70
|
- spec/foreman/export/bluepill_spec.rb
|
|
78
71
|
- spec/foreman/export/inittab_spec.rb
|
|
79
72
|
- spec/foreman/export/runit_spec.rb
|
|
73
|
+
- spec/foreman/export/supervisord_spec.rb
|
|
80
74
|
- spec/foreman/export/upstart_spec.rb
|
|
81
75
|
- spec/foreman/export_spec.rb
|
|
82
76
|
- spec/foreman/helpers_spec.rb
|
|
@@ -94,6 +88,8 @@ files:
|
|
|
94
88
|
- spec/resources/export/runit/app-alpha-2-run
|
|
95
89
|
- spec/resources/export/runit/app-bravo-1-log-run
|
|
96
90
|
- spec/resources/export/runit/app-bravo-1-run
|
|
91
|
+
- spec/resources/export/supervisord/app-alpha-2.conf
|
|
92
|
+
- spec/resources/export/supervisord/app.conf
|
|
97
93
|
- spec/resources/export/upstart/app-alpha-1.conf
|
|
98
94
|
- spec/resources/export/upstart/app-alpha-2.conf
|
|
99
95
|
- spec/resources/export/upstart/app-alpha.conf
|
|
@@ -114,18 +110,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
114
110
|
- - ! '>='
|
|
115
111
|
- !ruby/object:Gem::Version
|
|
116
112
|
version: '0'
|
|
117
|
-
segments:
|
|
118
|
-
- 0
|
|
119
|
-
hash: 4516446218853691019
|
|
120
113
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
121
114
|
none: false
|
|
122
115
|
requirements:
|
|
123
116
|
- - ! '>='
|
|
124
117
|
- !ruby/object:Gem::Version
|
|
125
118
|
version: '0'
|
|
126
|
-
segments:
|
|
127
|
-
- 0
|
|
128
|
-
hash: 4516446218853691019
|
|
129
119
|
requirements: []
|
|
130
120
|
rubyforge_project:
|
|
131
121
|
rubygems_version: 1.8.11
|