brightbox 0.22
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/bin/brightbox +38 -0
- data/bin/brightbox-apache +73 -0
- data/bin/brightbox-monit +68 -0
- data/lib/brightbox/generators/brightbox/brightbox_generator.rb +26 -0
- data/lib/brightbox/generators/brightbox/brightboxapache_generator.rb +27 -0
- data/lib/brightbox/generators/brightbox/templates/deploy.rb +41 -0
- data/lib/brightbox/generators/loader.rb +40 -0
- data/lib/brightbox/recipes.rb +104 -0
- metadata +85 -0
data/bin/brightbox
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'rubygems'
|
5
|
+
rescue LoadError
|
6
|
+
# no rubygems to load, so we fail silently
|
7
|
+
end
|
8
|
+
|
9
|
+
require 'optparse'
|
10
|
+
|
11
|
+
@options = {}
|
12
|
+
OptionParser.new do |opts|
|
13
|
+
opts.banner = "Usage: #{$0} [options] [args]"
|
14
|
+
|
15
|
+
opts.on("-A", "--apply-to DIRECTORY",
|
16
|
+
"Create a minimal set of scripts and recipes",
|
17
|
+
"for use with capistrano to configure servers."
|
18
|
+
) { |value| @options[:apply_to] = value }
|
19
|
+
opts.on("-n", "--name APPLICATION_NAME",
|
20
|
+
"Name of application."
|
21
|
+
) { |value| @options[:application] = value }
|
22
|
+
opts.on("-d", "--domain DOMAIN_NAME",
|
23
|
+
"Domain name for application."
|
24
|
+
) { |value| @options[:domain] = value }
|
25
|
+
opts.on("-i", "--server SERVER_NAME",
|
26
|
+
"Hostname or IP address of your Brightbox virtual server"
|
27
|
+
) { |value| @options[:server] = value }
|
28
|
+
|
29
|
+
if ARGV.empty?
|
30
|
+
puts opts
|
31
|
+
exit
|
32
|
+
else
|
33
|
+
opts.parse!(ARGV)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
require 'brightbox/generators/loader'
|
38
|
+
Brightbox::Generators::RailsLoader.load! @options
|
@@ -0,0 +1,73 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'optparse'
|
5
|
+
require 'erb'
|
6
|
+
require 'fileutils'
|
7
|
+
|
8
|
+
@mongrelhost = "127.0.0.1"
|
9
|
+
@port = 9200
|
10
|
+
@mongrels = 2
|
11
|
+
|
12
|
+
OptionParser.new do |opts|
|
13
|
+
opts.banner = "Usage: #{$0} [options] [args]"
|
14
|
+
|
15
|
+
opts.on("-n", "--name APPLICATION_NAME",
|
16
|
+
"Name of application."
|
17
|
+
) { |value| @application = value }
|
18
|
+
opts.on("-w", "--webroot WEB_ROOT",
|
19
|
+
"path to web root"
|
20
|
+
) { |value| @webroot = value }
|
21
|
+
opts.on("-d", "--domain DOMAIN_NAME",
|
22
|
+
"Domain name for application."
|
23
|
+
) { |value| @domain = value }
|
24
|
+
opts.on("-p", "--port MONGREL_PORT",
|
25
|
+
"Port of the first mongrel sevuce"
|
26
|
+
) { |value| @port = value.to_i }
|
27
|
+
opts.on("-s", "--servers MONGRELS",
|
28
|
+
"Number of mongrel servers running"
|
29
|
+
) { |value| @mongrels = value.to_i }
|
30
|
+
opts.on("-h", "--mongrelhost MONGREL_HOST",
|
31
|
+
"ip/host where mongrel is running"
|
32
|
+
) { |value| @mongrelhost = value }
|
33
|
+
|
34
|
+
if ARGV.empty?
|
35
|
+
puts opts
|
36
|
+
exit
|
37
|
+
else
|
38
|
+
opts.parse!(ARGV)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
@balancer_members = (@port..@port+@mongrels-1).collect {|i| " BalancerMember http://#{@mongrelhost}:#{i}" }.join("\n")
|
43
|
+
|
44
|
+
TEMPLATE = <<EOT
|
45
|
+
<VirtualHost *:80>
|
46
|
+
ServerName <%= @domain %>
|
47
|
+
DocumentRoot <%= @webroot %>
|
48
|
+
|
49
|
+
<Directory "<%= @webroot %>">
|
50
|
+
Options FollowSymLinks
|
51
|
+
AllowOverride None
|
52
|
+
Order allow,deny
|
53
|
+
Allow from all
|
54
|
+
</Directory>
|
55
|
+
|
56
|
+
# Configure mongrel_cluster
|
57
|
+
<Proxy balancer://mongrel_cluster>
|
58
|
+
<%= @balancer_members %>
|
59
|
+
</Proxy>
|
60
|
+
|
61
|
+
ErrorLog /var/log/apache2/<%= @application %>_error_log
|
62
|
+
CustomLog /var/log/apache2/<%= @application %>_log combined
|
63
|
+
|
64
|
+
# Rails specific rewrite rules
|
65
|
+
Include /etc/apache2/brightbox-common
|
66
|
+
</VirtualHost>
|
67
|
+
EOT
|
68
|
+
|
69
|
+
template = ERB.new(TEMPLATE)
|
70
|
+
config = template.result
|
71
|
+
|
72
|
+
File.open("/etc/apache2/sites-available/rails-#{@application}", "w") { |f| f.write config }
|
73
|
+
FileUtils.ln_s("/etc/apache2/sites-available/rails-#{@application}", "/etc/apache2/sites-enabled/rails-#{@application}", :force => true)
|
data/bin/brightbox-monit
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'optparse'
|
5
|
+
require 'erb'
|
6
|
+
|
7
|
+
@mongrelhost = "127.0.0.1"
|
8
|
+
@port = 9200
|
9
|
+
@mongrels = 2
|
10
|
+
@railsenv = "production"
|
11
|
+
|
12
|
+
OptionParser.new do |opts|
|
13
|
+
opts.banner = "Usage: #{$0} [options] [args]"
|
14
|
+
|
15
|
+
opts.on("-n", "--name APPLICATION_NAME",
|
16
|
+
"Name of application."
|
17
|
+
) { |value| @application = value }
|
18
|
+
opts.on("-r", "--railsroot RAILS_ROOT",
|
19
|
+
"path to rails root"
|
20
|
+
) { |value| @railsroot = value }
|
21
|
+
opts.on("-e", "--railsenv RAILS_ENV",
|
22
|
+
"rails environment"
|
23
|
+
) { |value| @railsroot = value }
|
24
|
+
opts.on("-p", "--port MONGREL_PORT",
|
25
|
+
"Port of the first mongrel sevuce"
|
26
|
+
) { |value| @port = value.to_i }
|
27
|
+
opts.on("-s", "--servers MONGRELS",
|
28
|
+
"Number of mongrel servers running"
|
29
|
+
) { |value| @mongrels = value.to_i }
|
30
|
+
opts.on("-h", "--mongrelhost MONGREL_HOST",
|
31
|
+
"ip/host where mongrel is running"
|
32
|
+
) { |value| @mongrelhost = value }
|
33
|
+
|
34
|
+
if ARGV.empty?
|
35
|
+
puts opts
|
36
|
+
exit
|
37
|
+
else
|
38
|
+
opts.parse!(ARGV)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
@mongrel_instances = (@port..@port+@mongrels-1).collect { |port| [port, "#{@railsroot}/log/mongrel.#{port}.pid"] }
|
43
|
+
|
44
|
+
TEMPLATE = <<EOT
|
45
|
+
<% @mongrel_instances.each do |port, pidfile| %>
|
46
|
+
check process mongrel_<%= @application %>_<%= port %> with pidfile <%= pidfile %>
|
47
|
+
group <%= @application %>
|
48
|
+
start program = "/usr/bin/mongrel_rails start -d -c <%= @railsroot %> -p <%= port %> -e <%= @railsenv %> -P <%= pidfile %>"
|
49
|
+
as uid rails and gid rails
|
50
|
+
stop program = "/usr/bin/mongrel_rails stop -c <%= @railsroot %> -P <%= pidfile %> -w 20"
|
51
|
+
as uid rails and gid rails
|
52
|
+
|
53
|
+
if failed host <%= @mongrelhost %> port <%= port %> protocol http
|
54
|
+
with timeout 30 seconds
|
55
|
+
then restart
|
56
|
+
|
57
|
+
if totalmem > 110 Mb then restart
|
58
|
+
#if cpu is greater than 60% for 2 cycles then alert
|
59
|
+
if cpu > 90% for 5 cycles then restart
|
60
|
+
#if loadavg(5min) greater than 10 for 8 cycles then restart
|
61
|
+
if 3 restarts within 5 cycles then timeout
|
62
|
+
<% end %>
|
63
|
+
EOT
|
64
|
+
|
65
|
+
template = ERB.new(TEMPLATE)
|
66
|
+
config = template.result
|
67
|
+
|
68
|
+
File.open("/etc/monit/conf.d/rails-#{@application}.monitrc", "w") { |f| f.write config }
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class BrightboxGenerator < Rails::Generator::NamedBase
|
2
|
+
attr_reader :application_name
|
3
|
+
attr_reader :domain_name
|
4
|
+
attr_reader :server
|
5
|
+
|
6
|
+
def initialize(runtime_args, runtime_options = {})
|
7
|
+
super
|
8
|
+
@application_name = self.file_name
|
9
|
+
@domain_name = @args[0]
|
10
|
+
@server = @args[1]
|
11
|
+
end
|
12
|
+
|
13
|
+
def manifest
|
14
|
+
record do |m|
|
15
|
+
m.directory "config"
|
16
|
+
m.template "deploy.rb", File.join("config", "deploy.rb")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
protected
|
21
|
+
|
22
|
+
# Override with your own usage banner.
|
23
|
+
def banner
|
24
|
+
"Usage: #{$0} brightbox ApplicationName DomainName BrightboxServer"
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class BrightboxapacheGenerator < Rails::Generator::NamedBase
|
2
|
+
attr_reader :application_name
|
3
|
+
attr_reader :domain_name
|
4
|
+
attr_reader :port
|
5
|
+
attr_reader :mongrels
|
6
|
+
|
7
|
+
def initialize(runtime_args, runtime_options = {})
|
8
|
+
super
|
9
|
+
@application_name = self.file_name
|
10
|
+
@domain_name = @args[0]
|
11
|
+
@port = @args[1]
|
12
|
+
@mongrels = @args[2]
|
13
|
+
end
|
14
|
+
|
15
|
+
def manifest
|
16
|
+
record do |m|
|
17
|
+
m.template "apache_config", @application_name
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
protected
|
22
|
+
|
23
|
+
# Override with your own usage banner.
|
24
|
+
def banner
|
25
|
+
"Usage: #{$0} brightbox_apache ApplicationName DomainName MongrelPort NumberOfMongrels"
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'brightbox/recipes'
|
2
|
+
|
3
|
+
# The name of your application. Used for deployment directory and filenames
|
4
|
+
# and apache configs
|
5
|
+
set :application, "<%= singular_name %>"
|
6
|
+
|
7
|
+
# Target directory for the application on the web and app servers.
|
8
|
+
set :deploy_to, "/home/rails/#{application}"
|
9
|
+
|
10
|
+
# Primary domain name of your application. Used in the Apache configs
|
11
|
+
set :domain, "<%= domain_name %>"
|
12
|
+
|
13
|
+
# Login user for ssh on your Brightbox server
|
14
|
+
set :user, "rails"
|
15
|
+
|
16
|
+
# URL of your source repository - there i
|
17
|
+
set :repository, "svn+ssh://rails@<%= server %>/home/rails/subversion/<%= singular_name %>/trunk"
|
18
|
+
|
19
|
+
role :web, "<%= server %>"
|
20
|
+
role :app, "<%= server %>"
|
21
|
+
role :db, "<%= server %>", :primary => true
|
22
|
+
|
23
|
+
set :use_sudo, false
|
24
|
+
|
25
|
+
set :mongrel_host, "127.0.0.1"
|
26
|
+
set :mongrel_port, 9200
|
27
|
+
set :mongrel_servers, 2
|
28
|
+
set :mongrel_conf, "#{current_path}/config/mongrel_cluster.yml"
|
29
|
+
|
30
|
+
# set :scm, :darcs # defaults to :subversion
|
31
|
+
# set :svn, "/path/to/svn" # defaults to searching the PATH
|
32
|
+
# set :darcs, "/path/to/darcs" # defaults to searching the PATH
|
33
|
+
# set :cvs, "/path/to/cvs" # defaults to searching the PATH
|
34
|
+
# set :gateway, "gate.host.com" # default to no gateway
|
35
|
+
|
36
|
+
# =============================================================================
|
37
|
+
# SSH OPTIONS
|
38
|
+
# =============================================================================
|
39
|
+
# ssh_options[:keys] = %w(/path/to/my/key /path/to/another/key)
|
40
|
+
# ssh_options[:port] = 25
|
41
|
+
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Brightbox
|
2
|
+
module Generators
|
3
|
+
class RailsLoader
|
4
|
+
def self.load!(options)
|
5
|
+
require "#{options[:apply_to]}/config/environment"
|
6
|
+
require "rails_generator"
|
7
|
+
require "rails_generator/scripts/generate"
|
8
|
+
|
9
|
+
Rails::Generator::Base.sources << Rails::Generator::PathSource.new(
|
10
|
+
:brightbox, File.dirname(__FILE__))
|
11
|
+
|
12
|
+
args = ["brightbox"]
|
13
|
+
args << (options[:application] || "Application")
|
14
|
+
args << (options[:domain] || "application.boxname.username.brightbox.co.uk")
|
15
|
+
args << (options[:server] || "87.237.63.??")
|
16
|
+
|
17
|
+
Rails::Generator::Scripts::Generate.new.run(args)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
class ApacheLoader
|
21
|
+
def self.load!(options)
|
22
|
+
require "/home/john/devel/reflex/capistrano-setup/cap-test2/config/environment"
|
23
|
+
require "rails_generator"
|
24
|
+
require "rails_generator/scripts/generate"
|
25
|
+
|
26
|
+
Rails::Generator::Base.sources << Rails::Generator::PathSource.new(
|
27
|
+
:brightboxapache, "/etc/apache2/sites-available")
|
28
|
+
|
29
|
+
args = ["brightboxapache"]
|
30
|
+
args << (options[:application] || "application").downcase
|
31
|
+
args << (options[:web_root] || "/home/rails/#{options[:application]}/current/public")
|
32
|
+
args << (options[:domain] || "application.boxname.username.brightbox.co.uk")
|
33
|
+
args << (options[:port] || 9200)
|
34
|
+
args << (options[:mongrels] || 2)
|
35
|
+
|
36
|
+
Rails::Generator::Scripts::Generate.new.run(args)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'mongrel_cluster/recipes'
|
2
|
+
|
3
|
+
Capistrano.configuration(:must_exist).load do
|
4
|
+
|
5
|
+
desc "Create apache config for this app on your Brightbox web servers"
|
6
|
+
task :setup_apache, :roles => :web do
|
7
|
+
sudo "/usr/bin/brightbox-apache -n #{application} -d #{domain} -w #{current_path}/public -h #{mongrel_host} -p #{mongrel_port} -s #{mongrel_servers}"
|
8
|
+
sudo "/usr/sbin/apache2ctl -t"
|
9
|
+
end
|
10
|
+
|
11
|
+
desc "Reload apache on your Brightbox web servers"
|
12
|
+
task :reload_apache, :roles => :web do
|
13
|
+
sudo "/usr/sbin/apache2ctl -t"
|
14
|
+
sudo "/usr/sbin/apache2ctl graceful"
|
15
|
+
end
|
16
|
+
|
17
|
+
desc "Load the rails db schema on the primary db server"
|
18
|
+
task :load_schema, :roles => :db, :primary => true do
|
19
|
+
run "cd #{current_path} && #{rake} RAILS_ENV=#{rails_env} db:schema:load"
|
20
|
+
end
|
21
|
+
|
22
|
+
desc "Configure monit to handle the mongrel servers for this app"
|
23
|
+
task :configure_mongrel_cluster, :roles => :app do
|
24
|
+
sudo "/usr/bin/brightbox-monit -n #{application} -r #{current_path} -p #{mongrel_port} -s #{mongrel_servers} -h #{mongrel_host}"
|
25
|
+
end
|
26
|
+
|
27
|
+
desc "Restart the mongrel servers using monit"
|
28
|
+
task :restart_mongrel_cluster, :roles => :app do
|
29
|
+
sudo "/usr/sbin/monit -g #{application} restart all"
|
30
|
+
end
|
31
|
+
|
32
|
+
desc "Start the mongrel servers using monit"
|
33
|
+
task :start_mongrel_cluster, :roles => :app do
|
34
|
+
sudo "/usr/sbin/monit -g #{application} start all"
|
35
|
+
end
|
36
|
+
|
37
|
+
desc "Stop the mongrel servers using monit"
|
38
|
+
task :stop_mongrel_cluster, :roles => :app do
|
39
|
+
sudo "/usr/sbin/monit -g #{application} stop all"
|
40
|
+
end
|
41
|
+
|
42
|
+
desc "Display the monit status for this app"
|
43
|
+
task :monit_status, :roles => :app do
|
44
|
+
sudo "/usr/sbin/monit -g #{application} status"
|
45
|
+
end
|
46
|
+
|
47
|
+
desc "Reload the monit daemon"
|
48
|
+
task :monit_reload, :roles => :app do
|
49
|
+
sudo "/usr/sbin/monit reload"
|
50
|
+
end
|
51
|
+
|
52
|
+
desc "Deploy the app to your Brightbox servers for the FIRST TIME. Sets up apache config starts mongrel."
|
53
|
+
task :cold_deploy do
|
54
|
+
transaction do
|
55
|
+
update_code
|
56
|
+
symlink
|
57
|
+
end
|
58
|
+
|
59
|
+
create_mysql_database
|
60
|
+
load_schema
|
61
|
+
migrate
|
62
|
+
configure_mongrel_cluster
|
63
|
+
monit_reload
|
64
|
+
start_mongrel_cluster
|
65
|
+
setup_apache
|
66
|
+
reload_apache
|
67
|
+
end
|
68
|
+
|
69
|
+
desc "Deploy the app to your Brightbox servers"
|
70
|
+
task :deploy do
|
71
|
+
transaction do
|
72
|
+
update_code
|
73
|
+
disable_web
|
74
|
+
stop_mongrel_cluster
|
75
|
+
symlink
|
76
|
+
start_mongrel_cluster
|
77
|
+
end
|
78
|
+
|
79
|
+
enable_web
|
80
|
+
end
|
81
|
+
|
82
|
+
desc "Create the mysql database named in the database.yml on the primary db server"
|
83
|
+
task :create_mysql_database, :roles => :db, :primary => true do
|
84
|
+
read_db_config
|
85
|
+
if db_adapter == 'mysql'
|
86
|
+
run "mysql -h #{db_host} --user=#{db_user} -p --execute=\"CREATE DATABASE #{db_name}\" || true" do |channel, stream, data|
|
87
|
+
if data =~ /^Enter password:/
|
88
|
+
logger.info data, "[database on #{channel[:host]} asked for password]"
|
89
|
+
channel.send_data "#{db_password}\n"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def read_db_config
|
96
|
+
db_config = YAML.load_file('config/database.yml')
|
97
|
+
set :db_adapter, db_config["production"]["adapter"]
|
98
|
+
set :db_user, db_config["production"]["username"]
|
99
|
+
set :db_password, db_config["production"]["password"]
|
100
|
+
set :db_name, db_config["production"]["database"]
|
101
|
+
set :db_host, db_config["production"]["host"]
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
metadata
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.4
|
3
|
+
specification_version: 1
|
4
|
+
name: brightbox
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: "0.22"
|
7
|
+
date: 2007-06-28 00:00:00 +01:00
|
8
|
+
summary: Brightbox rails deployment scripts for Capistrano
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: john@brightbox.co.uk
|
12
|
+
homepage: http://rubyforge.org/projects/brightbox/
|
13
|
+
rubyforge_project:
|
14
|
+
description:
|
15
|
+
autorequire: name
|
16
|
+
default_executable: brightbox
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: false
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
post_install_message:
|
29
|
+
authors:
|
30
|
+
- John Leach
|
31
|
+
files:
|
32
|
+
- bin/brightbox
|
33
|
+
- bin/brightbox-apache
|
34
|
+
- bin/brightbox-monit
|
35
|
+
- lib/brightbox
|
36
|
+
- lib/brightbox/generators
|
37
|
+
- lib/brightbox/recipes.rb
|
38
|
+
- lib/brightbox/generators/brightbox
|
39
|
+
- lib/brightbox/generators/loader.rb
|
40
|
+
- lib/brightbox/generators/brightbox/brightboxapache_generator.rb
|
41
|
+
- lib/brightbox/generators/brightbox/brightbox_generator.rb
|
42
|
+
- lib/brightbox/generators/brightbox/templates
|
43
|
+
- lib/brightbox/generators/brightbox/templates/deploy.rb
|
44
|
+
test_files: []
|
45
|
+
|
46
|
+
rdoc_options: []
|
47
|
+
|
48
|
+
extra_rdoc_files: []
|
49
|
+
|
50
|
+
executables:
|
51
|
+
- brightbox
|
52
|
+
- brightbox-apache
|
53
|
+
- brightbox-monit
|
54
|
+
extensions: []
|
55
|
+
|
56
|
+
requirements: []
|
57
|
+
|
58
|
+
dependencies:
|
59
|
+
- !ruby/object:Gem::Dependency
|
60
|
+
name: capistrano
|
61
|
+
version_requirement:
|
62
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: "1.4"
|
67
|
+
version:
|
68
|
+
- !ruby/object:Gem::Dependency
|
69
|
+
name: mongrel_cluster
|
70
|
+
version_requirement:
|
71
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.2.1
|
76
|
+
version:
|
77
|
+
- !ruby/object:Gem::Dependency
|
78
|
+
name: termios
|
79
|
+
version_requirement:
|
80
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">"
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: 0.0.0
|
85
|
+
version:
|