mirror of
https://github.com/capistrano/capistrano
synced 2023-03-27 23:21:18 -04:00
Make SwitchTower easier to invoke programmatically, using SwitchTower::CLI
git-svn-id: http://svn.rubyonrails.org/rails/tools/switchtower@2076 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
parent
824d22bfb8
commit
c8f3edb93d
3 changed files with 134 additions and 115 deletions
|
@ -1,5 +1,7 @@
|
|||
*SVN*
|
||||
|
||||
* Make SwitchTower easier to invoke programmatically via SwitchTower::CLI
|
||||
|
||||
* Specify the revision to release via the :revision variable (defaults to latest revision)
|
||||
|
||||
* Allow variables to be set via the cli using the -s switch
|
||||
|
|
117
bin/switchtower
117
bin/switchtower
|
@ -1,118 +1,5 @@
|
|||
#!/usr/bin/env ruby
|
||||
|
||||
require 'optparse'
|
||||
require 'switchtower'
|
||||
require 'switchtower/cli'
|
||||
|
||||
begin
|
||||
if !defined?(USE_TERMIOS) || USE_TERMIOS
|
||||
require 'termios'
|
||||
else
|
||||
raise LoadError
|
||||
end
|
||||
|
||||
# Enable or disable stdin echoing to the terminal.
|
||||
def echo(enable)
|
||||
term = Termios::getattr(STDIN)
|
||||
|
||||
if enable
|
||||
term.c_lflag |= (Termios::ECHO | Termios::ICANON)
|
||||
else
|
||||
term.c_lflag &= ~Termios::ECHO
|
||||
end
|
||||
|
||||
Termios::setattr(STDIN, Termios::TCSANOW, term)
|
||||
end
|
||||
rescue LoadError
|
||||
def echo(enable)
|
||||
end
|
||||
end
|
||||
|
||||
options = { :verbose => 0, :recipes => [], :actions => [], :vars => {} }
|
||||
|
||||
OptionParser.new do |opts|
|
||||
opts.banner = "Usage: #{$0} [options]"
|
||||
opts.separator ""
|
||||
|
||||
opts.on("-a", "--action ACTION",
|
||||
"An action to execute. Multiple actions may",
|
||||
"be specified, and are loaded in the given order."
|
||||
) { |value| options[:actions] << value }
|
||||
|
||||
opts.on("-p", "--password PASSWORD",
|
||||
"The password to use when connecting.",
|
||||
"(Default: prompt for password)"
|
||||
) { |value| options[:password] = value }
|
||||
|
||||
opts.on("-P", "--[no-]pretend",
|
||||
"Run the task(s), but don't actually connect to or",
|
||||
"execute anything on the servers. (For various reasons",
|
||||
"this will not necessarily be an accurate depiction",
|
||||
"of the work that will actually be performed.",
|
||||
"Default: don't pretend.)"
|
||||
) { |value| options[:pretend] = value }
|
||||
|
||||
opts.on("-r", "--recipe RECIPE",
|
||||
"A recipe file to load. Multiple recipes may",
|
||||
"be specified, and are loaded in the given order."
|
||||
) { |value| options[:recipes] << value }
|
||||
|
||||
opts.on("-s", "--set NAME=VALUE",
|
||||
"Specify a variable and it's value to set. This",
|
||||
"will be set after loading all recipe files."
|
||||
) do |pair|
|
||||
name, value = pair.split(/=/)
|
||||
options[:vars][name.to_sym] = value
|
||||
end
|
||||
|
||||
opts.on("-v", "--verbose",
|
||||
"Specify the verbosity of the output.",
|
||||
"May be given multiple times. (Default: silent)"
|
||||
) { options[:verbose] += 1 }
|
||||
|
||||
opts.separator ""
|
||||
opts.on_tail("-h", "--help", "Display this help message") do
|
||||
puts opts
|
||||
exit
|
||||
end
|
||||
opts.on_tail("-V", "--version",
|
||||
"Display the version info for this utility"
|
||||
) do
|
||||
require 'switchtower/version'
|
||||
puts "SwitchTower v#{SwitchTower::Version::STRING}"
|
||||
exit
|
||||
end
|
||||
|
||||
opts.parse!
|
||||
end
|
||||
|
||||
abort "You must specify at least one recipe" if options[:recipes].empty?
|
||||
abort "You must specify at least one action" if options[:actions].empty?
|
||||
|
||||
unless options.has_key?(:password)
|
||||
options[:password] = Proc.new do
|
||||
sync = STDOUT.sync
|
||||
begin
|
||||
echo false
|
||||
STDOUT.sync = true
|
||||
print "Password: "
|
||||
STDIN.gets.chomp
|
||||
ensure
|
||||
echo true
|
||||
STDOUT.sync = sync
|
||||
puts
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
config = SwitchTower::Configuration.new
|
||||
config.logger.level = options[:verbose]
|
||||
config.set :password, options[:password]
|
||||
config.set :pretend, options[:pretend]
|
||||
|
||||
config.load "standard" # load the standard recipe definition
|
||||
|
||||
options[:recipes].each { |recipe| config.load(recipe) }
|
||||
options[:vars].each { |name, value| config.set(name, value) }
|
||||
|
||||
actor = config.actor
|
||||
options[:actions].each { |action| actor.send action }
|
||||
SwitchTower::CLI.execute!
|
||||
|
|
130
lib/switchtower/cli.rb
Normal file
130
lib/switchtower/cli.rb
Normal file
|
@ -0,0 +1,130 @@
|
|||
require 'optparse'
|
||||
require 'switchtower'
|
||||
|
||||
module SwitchTower
|
||||
class CLI
|
||||
def self.execute!
|
||||
new.execute!
|
||||
end
|
||||
|
||||
begin
|
||||
if !defined?(USE_TERMIOS) || USE_TERMIOS
|
||||
require 'termios'
|
||||
else
|
||||
raise LoadError
|
||||
end
|
||||
|
||||
# Enable or disable stdin echoing to the terminal.
|
||||
def echo(enable)
|
||||
term = Termios::getattr(STDIN)
|
||||
|
||||
if enable
|
||||
term.c_lflag |= (Termios::ECHO | Termios::ICANON)
|
||||
else
|
||||
term.c_lflag &= ~Termios::ECHO
|
||||
end
|
||||
|
||||
Termios::setattr(STDIN, Termios::TCSANOW, term)
|
||||
end
|
||||
rescue LoadError
|
||||
def echo(enable)
|
||||
end
|
||||
end
|
||||
|
||||
attr_reader :options
|
||||
|
||||
def initialize
|
||||
@options = { :verbose => 0, :recipes => [], :actions => [], :vars => {} }
|
||||
|
||||
OptionParser.new do |opts|
|
||||
opts.banner = "Usage: #{$0} [options]"
|
||||
opts.separator ""
|
||||
|
||||
opts.on("-a", "--action ACTION",
|
||||
"An action to execute. Multiple actions may",
|
||||
"be specified, and are loaded in the given order."
|
||||
) { |value| @options[:actions] << value }
|
||||
|
||||
opts.on("-p", "--password PASSWORD",
|
||||
"The password to use when connecting.",
|
||||
"(Default: prompt for password)"
|
||||
) { |value| @options[:password] = value }
|
||||
|
||||
opts.on("-P", "--[no-]pretend",
|
||||
"Run the task(s), but don't actually connect to or",
|
||||
"execute anything on the servers. (For various reasons",
|
||||
"this will not necessarily be an accurate depiction",
|
||||
"of the work that will actually be performed.",
|
||||
"Default: don't pretend.)"
|
||||
) { |value| @options[:pretend] = value }
|
||||
|
||||
opts.on("-r", "--recipe RECIPE",
|
||||
"A recipe file to load. Multiple recipes may",
|
||||
"be specified, and are loaded in the given order."
|
||||
) { |value| @options[:recipes] << value }
|
||||
|
||||
opts.on("-s", "--set NAME=VALUE",
|
||||
"Specify a variable and it's value to set. This",
|
||||
"will be set after loading all recipe files."
|
||||
) do |pair|
|
||||
name, value = pair.split(/=/)
|
||||
@options[:vars][name.to_sym] = value
|
||||
end
|
||||
|
||||
opts.on("-v", "--verbose",
|
||||
"Specify the verbosity of the output.",
|
||||
"May be given multiple times. (Default: silent)"
|
||||
) { @options[:verbose] += 1 }
|
||||
|
||||
opts.separator ""
|
||||
opts.on_tail("-h", "--help", "Display this help message") do
|
||||
puts opts
|
||||
exit
|
||||
end
|
||||
opts.on_tail("-V", "--version",
|
||||
"Display the version info for this utility"
|
||||
) do
|
||||
require 'switchtower/version'
|
||||
puts "SwitchTower v#{SwitchTower::Version::STRING}"
|
||||
exit
|
||||
end
|
||||
|
||||
opts.parse!
|
||||
end
|
||||
|
||||
abort "You must specify at least one recipe" if @options[:recipes].empty?
|
||||
abort "You must specify at least one action" if @options[:actions].empty?
|
||||
|
||||
unless @options.has_key?(:password)
|
||||
@options[:password] = Proc.new do
|
||||
sync = STDOUT.sync
|
||||
begin
|
||||
echo false
|
||||
STDOUT.sync = true
|
||||
print "Password: "
|
||||
STDIN.gets.chomp
|
||||
ensure
|
||||
echo true
|
||||
STDOUT.sync = sync
|
||||
puts
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def execute!
|
||||
config = SwitchTower::Configuration.new
|
||||
config.logger.level = options[:verbose]
|
||||
config.set :password, options[:password]
|
||||
config.set :pretend, options[:pretend]
|
||||
|
||||
config.load "standard" # load the standard recipe definition
|
||||
|
||||
options[:recipes].each { |recipe| config.load(recipe) }
|
||||
options[:vars].each { |name, value| config.set(name, value) }
|
||||
|
||||
actor = config.actor
|
||||
options[:actions].each { |action| actor.send action }
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue