brightbox 0.22
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|