fezzik 0.7.4 → 0.8.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/fez +50 -11
- data/completions/_fez.bash +14 -0
- data/completions/_fez.zsh +7 -0
- data/example/Gemfile +3 -0
- data/example/Rakefile +67 -0
- data/fezzik.gemspec +6 -3
- data/lib/fezzik.rb +4 -3
- data/lib/fezzik/base.rb +48 -2
- data/lib/fezzik/dsl.rb +5 -6
- data/lib/fezzik/environment.rb +1 -1
- data/lib/fezzik/host_task.rb +49 -0
- data/lib/fezzik/role.rb +3 -16
- data/lib/fezzik/util.rb +0 -16
- data/lib/fezzik/version.rb +1 -1
- data/tasks/command.rake +3 -1
- data/tasks/environment.rake +6 -3
- data/weave_todo.md +13 -0
- metadata +32 -15
- data/lib/fezzik/io.rb +0 -11
- data/lib/fezzik/thread_local_io.rb +0 -47
data/bin/fez
CHANGED
@@ -4,8 +4,14 @@ require "rubygems"
|
|
4
4
|
require "rake"
|
5
5
|
require "fezzik"
|
6
6
|
|
7
|
+
module Fezzik
|
8
|
+
RAKE_AT_LEAST_090 = defined?(Rake::VERSION) &&
|
9
|
+
Gem.loaded_specs["rake"].version >= Gem::Version.create("0.9.0")
|
10
|
+
end
|
11
|
+
|
7
12
|
# Required for using rake/remote-task with rake >= 0.9.x
|
8
|
-
|
13
|
+
# TODO(caleb): Still necessary w/out RRT?
|
14
|
+
include Rake::DSL if Fezzik::RAKE_AT_LEAST_090
|
9
15
|
|
10
16
|
Fezzik.activated = true
|
11
17
|
|
@@ -13,7 +19,11 @@ USAGE = <<EOF
|
|
13
19
|
Version #{Fezzik::VERSION}
|
14
20
|
fez <destination> <tasks> # Run deployment tasks on destination servers
|
15
21
|
fez get <tasks> # Download tasks to use in your project
|
16
|
-
fez -
|
22
|
+
fez -v, --version # Print version number
|
23
|
+
fez -h, --help # Print this help message
|
24
|
+
fez -T # Print all tasks with descriptions
|
25
|
+
fez --task-names # Print all tasks names
|
26
|
+
fez --destinations # Print all destinations
|
17
27
|
EOF
|
18
28
|
|
19
29
|
def print_usage_and_exit
|
@@ -26,19 +36,31 @@ def print_version_and_exit
|
|
26
36
|
exit
|
27
37
|
end
|
28
38
|
|
29
|
-
def
|
39
|
+
def print_destinations_and_exit
|
40
|
+
Rake.application.init
|
41
|
+
Rake.application.load_rakefile
|
42
|
+
puts Fezzik.destinations.to_a.join("\n")
|
43
|
+
exit 0
|
44
|
+
end
|
45
|
+
|
46
|
+
def display_tasks_and_exit(hide_descriptions = false)
|
47
|
+
if Fezzik::RAKE_AT_LEAST_090
|
48
|
+
Rake::TaskManager.record_task_metadata = true
|
49
|
+
Rake::application.options.show_tasks = :tasks
|
50
|
+
end
|
30
51
|
Rake.application.init
|
31
52
|
Rake.application.load_rakefile
|
32
53
|
Rake.application.options.show_task_pattern = /^fezzik:/
|
33
54
|
output = Fezzik::Util.capture_output { Rake.application.display_tasks_and_comments }
|
34
55
|
output.gsub!(/^rake fezzik:/, "fez <destination> ")
|
35
|
-
|
56
|
+
output.gsub!(/^fez <destination> (\S+).*$/, "\\1") if hide_descriptions
|
57
|
+
output.strip.empty? ? $stderr.puts("(No Fezzik tasks with descriptions are defined.)") : puts(output)
|
36
58
|
exit 0
|
37
59
|
end
|
38
60
|
|
39
61
|
TASKS_URL = "https://raw.github.com/dmacdougall/fezzik/master/tasks"
|
40
62
|
def download_tasks_and_exit
|
41
|
-
|
63
|
+
OPTIONS[1..-1].each do |task|
|
42
64
|
task += ".rake" unless task =~ /\.rake$/
|
43
65
|
system("curl -f #{TASKS_URL}/#{task} -o #{task} > /dev/null 2>&1")
|
44
66
|
if $? == 0
|
@@ -51,7 +73,7 @@ def download_tasks_and_exit
|
|
51
73
|
end
|
52
74
|
|
53
75
|
def run_fezzik_tasks
|
54
|
-
ENV["fezzik_destination"] =
|
76
|
+
ENV["fezzik_destination"] = OPTIONS[0]
|
55
77
|
Fezzik.init
|
56
78
|
Rake.application.init
|
57
79
|
Rake.application.load_rakefile
|
@@ -60,20 +82,27 @@ def run_fezzik_tasks
|
|
60
82
|
host_list = Array(domain).join("\n ")
|
61
83
|
puts "Targeting hosts:"
|
62
84
|
puts " #{host_list}"
|
63
|
-
rescue
|
85
|
+
rescue NameError => e
|
64
86
|
puts "Invalid destination: #{Fezzik.target_destination}"
|
65
87
|
puts "Make sure this destination is configured and includes `set :domain, \"yourdomain.com\"`"
|
66
88
|
puts Fezzik.color_string("[fail]", :red)
|
67
89
|
exit 1
|
68
90
|
end
|
69
91
|
begin
|
70
|
-
tasks =
|
92
|
+
tasks = OPTIONS[1..-1]
|
71
93
|
tasks.each do |task_with_params|
|
72
94
|
task_name, params = Fezzik::Util.split_task_and_params(task_with_params)
|
73
|
-
Rake::Task["fezzik:#{task_name}"].invoke(params)
|
95
|
+
Rake::Task["fezzik:#{task_name}"].invoke(*params)
|
74
96
|
end
|
75
97
|
puts Fezzik.color_string("[success]", :green)
|
76
|
-
rescue SystemExit
|
98
|
+
rescue SystemExit => e
|
99
|
+
if e.status == 0
|
100
|
+
puts Fezzik.color_string("[success]", :green)
|
101
|
+
else
|
102
|
+
puts Fezzik.color_string("[fail]", :red)
|
103
|
+
exit e.status
|
104
|
+
end
|
105
|
+
rescue Fezzik::CommandFailedError => e
|
77
106
|
puts Fezzik.color_string("[fail]", :red)
|
78
107
|
exit 1
|
79
108
|
rescue StandardError => e
|
@@ -84,11 +113,21 @@ def run_fezzik_tasks
|
|
84
113
|
end
|
85
114
|
end
|
86
115
|
|
87
|
-
|
116
|
+
# Rake directly inspects ARGV and will crash if it doesn't recognize a flag that was passed to fez.
|
117
|
+
OPTIONS = ARGV.dup
|
118
|
+
ARGV.clear
|
119
|
+
|
120
|
+
# Pass these options through to Rake.
|
121
|
+
ARGV << "--trace" if OPTIONS.delete("--trace")
|
122
|
+
ARGV << "--dry-run" if OPTIONS.delete("--dry-run")
|
123
|
+
|
124
|
+
case OPTIONS[0]
|
88
125
|
when nil then abort USAGE
|
89
126
|
when "-h", "--help" then print_usage_and_exit
|
90
127
|
when "-v", "--version" then print_version_and_exit
|
91
128
|
when "-T", "--tasks" then display_tasks_and_exit
|
92
129
|
when "get" then download_tasks_and_exit
|
130
|
+
when "--task-names" then display_tasks_and_exit(hide_descriptions = true)
|
131
|
+
when "--destinations" then print_destinations_and_exit
|
93
132
|
else run_fezzik_tasks
|
94
133
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
_fez()
|
2
|
+
{
|
3
|
+
local cur prev completion
|
4
|
+
cur="${COMP_WORDS[COMP_CWORD]}"
|
5
|
+
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
6
|
+
if [ $prev == "fez" ]; then
|
7
|
+
completion="--destinations"
|
8
|
+
else
|
9
|
+
completion="--task-names"
|
10
|
+
fi
|
11
|
+
COMPREPLY=( $(compgen -W "$(fez ${completion} 2> /dev/null | GREP_OPTIONS='' grep -v '(in')" -- ${cur}) )
|
12
|
+
return 0
|
13
|
+
}
|
14
|
+
complete -F _fez fez
|
data/example/Gemfile
ADDED
data/example/Rakefile
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
require "fezzik"
|
2
|
+
include Fezzik::DSL
|
3
|
+
|
4
|
+
Fezzik.init(:tasks => "../tasks")
|
5
|
+
|
6
|
+
set :app, "test"
|
7
|
+
set :deploy_to, "/opt/#{app}"
|
8
|
+
set :release_path, "#{deploy_to}/releases/#{Time.now.strftime("%Y%m%d%H%M")}"
|
9
|
+
set :local_path, Dir.pwd
|
10
|
+
set :user, "root"
|
11
|
+
|
12
|
+
destination :vagrant do
|
13
|
+
set :user, "vagrant"
|
14
|
+
set :domain, "fezzik-vagrant"
|
15
|
+
|
16
|
+
env :foo, "bar"
|
17
|
+
env :baz, "baz"
|
18
|
+
env :baz, "qux", :hosts => "localhost"
|
19
|
+
|
20
|
+
set :role_var, nil
|
21
|
+
role :role1, :role_var => "apple"
|
22
|
+
role :role2, :role_var => "banana"
|
23
|
+
end
|
24
|
+
|
25
|
+
namespace :fezzik do
|
26
|
+
desc "Print information on the destination and environment"
|
27
|
+
remote_task :info do
|
28
|
+
puts "Destination: #{Fezzik.target_destination.inspect}"
|
29
|
+
puts "Environment: #{Fezzik.environments.inspect}"
|
30
|
+
end
|
31
|
+
|
32
|
+
desc "An example of appending..."
|
33
|
+
remote_task :append do
|
34
|
+
run "echo hi"
|
35
|
+
end
|
36
|
+
|
37
|
+
desc "...new actions to an existing task"
|
38
|
+
remote_task :append do
|
39
|
+
run "echo bye"
|
40
|
+
end
|
41
|
+
|
42
|
+
desc "Tasks can take arguments"
|
43
|
+
remote_task :args, :arg1, :arg2 do |t, args|
|
44
|
+
puts "args: #{args.inspect}"
|
45
|
+
end
|
46
|
+
|
47
|
+
desc "Tasks may print out the host and user."
|
48
|
+
remote_task :host do
|
49
|
+
puts "#{user}@#{host}"
|
50
|
+
end
|
51
|
+
|
52
|
+
desc "Tasks can depend on other tasks"
|
53
|
+
remote_task :deps => :append do
|
54
|
+
puts "some other task just ran"
|
55
|
+
end
|
56
|
+
|
57
|
+
desc "If a server command fails the block should exist and fezzik should indicate failure"
|
58
|
+
remote_task :fails do
|
59
|
+
run "cd i-dont-exist"
|
60
|
+
run "echo 'should not print'"
|
61
|
+
end
|
62
|
+
|
63
|
+
desc "Use roles to override settings"
|
64
|
+
remote_task :roles, :roles => [:role1, :role2] do
|
65
|
+
puts "role_var: #{get :role_var}"
|
66
|
+
end
|
67
|
+
end
|
data/fezzik.gemspec
CHANGED
@@ -13,15 +13,18 @@ Gem::Specification.new do |s|
|
|
13
13
|
s.email = "dmacdougall@gmail.com"
|
14
14
|
|
15
15
|
s.description = "A light deployment system that gets out of your way"
|
16
|
-
s.summary
|
17
|
-
|
16
|
+
s.summary =<<EOS
|
17
|
+
Fezzik adds remote ssh capabilities to Rake. It simplifies running commands on remote servers and can be used
|
18
|
+
for anything from deploying code to installing libraries remotely.
|
19
|
+
EOS
|
18
20
|
s.homepage = "http://github.com/dmacdougall/fezzik"
|
19
21
|
s.rubyforge_project = "fezzik"
|
20
22
|
|
21
23
|
s.executables = %w(fez)
|
22
24
|
s.files = `git ls-files`.split("\n")
|
23
25
|
|
24
|
-
s.add_dependency
|
26
|
+
s.add_dependency "rake"
|
27
|
+
s.add_dependency "weave", "=0.1.0"
|
25
28
|
|
26
29
|
s.add_development_dependency("scope", "~>0.2.3")
|
27
30
|
s.add_development_dependency("vagrant", "~>1.0.5")
|
data/lib/fezzik.rb
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
require "stringio"
|
2
2
|
require "thread"
|
3
3
|
require "rake"
|
4
|
-
require "
|
4
|
+
require "weave"
|
5
|
+
require "set"
|
6
|
+
|
7
|
+
require "fezzik/host_task"
|
5
8
|
require "fezzik/base"
|
6
9
|
require "fezzik/colors"
|
7
10
|
require "fezzik/dsl"
|
8
11
|
require "fezzik/environment"
|
9
12
|
require "fezzik/role"
|
10
|
-
require "fezzik/io"
|
11
|
-
require "fezzik/thread_local_io"
|
12
13
|
require "fezzik/util"
|
13
14
|
require "fezzik/version"
|
data/lib/fezzik/base.rb
CHANGED
@@ -2,20 +2,66 @@ module Fezzik
|
|
2
2
|
def self.activated=(value) @activated = value end
|
3
3
|
def self.activated?() @activated || false end
|
4
4
|
|
5
|
+
def self.set(name, value)
|
6
|
+
@@settings ||= {}
|
7
|
+
|
8
|
+
value = Array(value) if name == :domain
|
9
|
+
|
10
|
+
@@settings[name] = value
|
11
|
+
|
12
|
+
if Object.public_instance_methods.include? name.to_sym
|
13
|
+
Object.send :alias_method, :"old_#{name}", name
|
14
|
+
end
|
15
|
+
|
16
|
+
Object.send :define_method, name do
|
17
|
+
# TODO: Add deprecation note for setting/accessing global settings
|
18
|
+
Fezzik.get name
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.get(name)
|
23
|
+
raise "Fezzik: No such setting: #{name}" unless @@settings.has_key?(name)
|
24
|
+
@@settings[name]
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.remote_task(*args, &block)
|
28
|
+
roles = (Hash === args.last && args.last[:roles]) ? args.pop[:roles] : []
|
29
|
+
name, args, deps = Rake.application.resolve_args(args)
|
30
|
+
host_task(name, { :args => Array(args), :deps => Array(deps), :roles => Array(roles) }, &block)
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.host_task(name, options = {}, &block)
|
34
|
+
options = {
|
35
|
+
:args => [],
|
36
|
+
:deps => [],
|
37
|
+
:roles => []
|
38
|
+
}.merge(options)
|
39
|
+
t = HostTask.define_task(name, { options[:args] => options[:deps] }, &block)
|
40
|
+
t.roles += options[:roles]
|
41
|
+
end
|
42
|
+
|
5
43
|
def self.init(options={})
|
6
44
|
@options = options
|
7
45
|
@target_destination = ENV["fezzik_destination"].to_sym rescue nil
|
8
46
|
unless options[:tasks].nil?
|
9
|
-
puts "Loading Fezzik tasks from #{@options[:tasks]}"
|
10
|
-
Dir[File.join(
|
47
|
+
$stderr.puts "Loading Fezzik tasks from #{@options[:tasks]}"
|
48
|
+
Dir[File.join(File.expand_path(@options[:tasks]), "**", "*.rake")].sort.each { |lib| import lib }
|
11
49
|
end
|
12
50
|
end
|
13
51
|
|
14
52
|
def self.destination(*names, &block)
|
53
|
+
@destinations ||= Set.new
|
54
|
+
@destinations.merge(names)
|
15
55
|
block.call if names.include?(@target_destination)
|
16
56
|
end
|
17
57
|
|
18
58
|
def self.target_destination
|
19
59
|
@target_destination ||= nil
|
20
60
|
end
|
61
|
+
|
62
|
+
def self.destinations
|
63
|
+
@destinations ||= Set.new
|
64
|
+
end
|
65
|
+
|
66
|
+
class CommandFailedError < StandardError; end
|
21
67
|
end
|
data/lib/fezzik/dsl.rb
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
module Fezzik
|
2
2
|
module DSL
|
3
|
-
# This is necessary to override Rake::RemoteTask's globally eval'ed method definitions.
|
4
|
-
def self.included(klass)
|
5
|
-
klass.class_eval do
|
6
|
-
def role(*args) Fezzik.role(*args) end
|
7
|
-
end
|
8
|
-
end
|
9
3
|
def destination(*names, &block) Fezzik.destination(*names, &block) end
|
10
4
|
def env(*args) Fezzik.env(*args) end
|
11
5
|
def capture_output(&block) Fezzik::Util.capture_output(&block) end
|
6
|
+
def set(name, value) Fezzik.set(name, value) end
|
7
|
+
def get(name) Fezzik.get(name) end
|
8
|
+
def remote_task(*args, &block) Fezzik.remote_task(*args, &block) end
|
9
|
+
def host_task(name, options = {}, &block) Fezzik.host_task(name, options, &block) end
|
10
|
+
def role(*args) Fezzik.role(*args) end
|
12
11
|
end
|
13
12
|
end
|
data/lib/fezzik/environment.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Fezzik
|
2
2
|
def self.env(key, value, options={})
|
3
3
|
options = {
|
4
|
-
:hosts =>
|
4
|
+
:hosts => Fezzik.get(:domain)
|
5
5
|
}.merge(options)
|
6
6
|
options[:hosts] = Array(options[:hosts])
|
7
7
|
@environments ||= Hash.new { |h, k| h[k] = {} }
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Fezzik
|
2
|
+
class HostTask < Rake::Task
|
3
|
+
attr_accessor :roles
|
4
|
+
|
5
|
+
def initialize(task_name, app)
|
6
|
+
super
|
7
|
+
@roles = []
|
8
|
+
@host_actions = []
|
9
|
+
end
|
10
|
+
|
11
|
+
def enhance(deps = nil, &block)
|
12
|
+
@host_actions << block if block_given?
|
13
|
+
super(deps)
|
14
|
+
end
|
15
|
+
|
16
|
+
def execute(args = nil)
|
17
|
+
return if Rake.application.options.dryrun
|
18
|
+
|
19
|
+
if @roles.empty?
|
20
|
+
hosts = Fezzik.get(:domain).map { |domain| "#{Fezzik.get(:user)}@#{domain}" }
|
21
|
+
@@connection_pool ||= Weave.connect(hosts)
|
22
|
+
@host_actions.each do |action|
|
23
|
+
begin
|
24
|
+
@@connection_pool.execute(:args => [self, args], &action)
|
25
|
+
rescue Weave::Error => e
|
26
|
+
STDERR.puts "Error running command in HostTask '#{@name}':"
|
27
|
+
abort e.message
|
28
|
+
end
|
29
|
+
end
|
30
|
+
else
|
31
|
+
@roles.each do |role|
|
32
|
+
Fezzik.with_role(role) do
|
33
|
+
hosts = Fezzik.get(:domain).map { |domain| "#{Fezzik.get(:user)}@#{domain}" }
|
34
|
+
@@role_connection_pools ||= {}
|
35
|
+
@@role_connection_pools[role] ||= Weave.connect(hosts)
|
36
|
+
@host_actions.each do |action|
|
37
|
+
begin
|
38
|
+
@@role_connection_pools[role].execute(:args => [self, args], &action)
|
39
|
+
rescue Weave::Error => e
|
40
|
+
STDERR.puts "Error running command in HostTask '#{@name}' with role '#{role}':"
|
41
|
+
abort e.message
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/fezzik/role.rb
CHANGED
@@ -6,6 +6,8 @@ module Fezzik
|
|
6
6
|
|
7
7
|
def self.roles() @roles ||= {} end
|
8
8
|
|
9
|
+
# TODO: Consider allowing roles that don't override an existing setting.
|
10
|
+
# Right now you have to do: set :foo nil; role :foo_role {:foo => :bar}
|
9
11
|
def self.with_role(role_name, &block)
|
10
12
|
return block.call if roles[role_name].nil?
|
11
13
|
|
@@ -19,21 +21,6 @@ module Fezzik
|
|
19
21
|
end
|
20
22
|
|
21
23
|
def self.override_settings(settings)
|
22
|
-
settings.each { |setting, value|
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
module Rake
|
27
|
-
class RemoteTask
|
28
|
-
def defined_target_hosts?() true end
|
29
|
-
def target_hosts() domain end
|
30
|
-
|
31
|
-
alias remote_task_execute execute
|
32
|
-
def execute(args = nil)
|
33
|
-
return Fezzik::Util.with_prepended_user { remote_task_execute(args) } if options[:roles].empty?
|
34
|
-
options[:roles].each do |role|
|
35
|
-
Fezzik.with_role(role) { Fezzik::Util.with_prepended_user { remote_task_execute(args) } }
|
36
|
-
end
|
37
|
-
end
|
24
|
+
settings.each { |setting, value| Fezzik.set setting, value }
|
38
25
|
end
|
39
26
|
end
|
data/lib/fezzik/util.rb
CHANGED
@@ -20,21 +20,5 @@ module Fezzik
|
|
20
20
|
end
|
21
21
|
[task, params]
|
22
22
|
end
|
23
|
-
|
24
|
-
# Blocks passed to this function will ensure `domain` is always an Array. In addition, if `user` is set it
|
25
|
-
# will automatically prepend the value of `user` to the front of any domains missing a username. This allows a
|
26
|
-
# fezzik user to write the following in their configuration and have it "just work":
|
27
|
-
# set :domain, ["example.com", "test@example2.com"]
|
28
|
-
# set :user, "root"
|
29
|
-
# `domain` will be equal to ["root@example.com", "test@example2.com"]
|
30
|
-
def self.with_prepended_user(&block)
|
31
|
-
old_domain = domain
|
32
|
-
begin
|
33
|
-
set :domain, Array(domain).map { |d| (defined?(user) && !d.include?("@")) ? "#{user}@#{d}" : d }
|
34
|
-
block.call
|
35
|
-
ensure
|
36
|
-
set :domain, old_domain
|
37
|
-
end
|
38
|
-
end
|
39
23
|
end
|
40
24
|
end
|
data/lib/fezzik/version.rb
CHANGED
data/tasks/command.rake
CHANGED
@@ -23,7 +23,9 @@ namespace :fezzik do
|
|
23
23
|
else
|
24
24
|
begin
|
25
25
|
Rake::Task["fezzik:command_execute"].invoke command
|
26
|
-
rescue
|
26
|
+
rescue Fezzik::CommandFailedError => e
|
27
|
+
puts e.message
|
28
|
+
puts e.backtrace
|
27
29
|
ensure
|
28
30
|
Rake::Task["fezzik:command_execute"].reenable
|
29
31
|
end
|
data/tasks/environment.rake
CHANGED
@@ -34,9 +34,12 @@ namespace :fezzik do
|
|
34
34
|
task :push do
|
35
35
|
# Copy over the appropriate configs for the target
|
36
36
|
server = target_host.gsub(/^.*@/, "")
|
37
|
-
|
38
|
-
|
39
|
-
|
37
|
+
config_directory = "/tmp/#{app}/#{server}_config"
|
38
|
+
if File.directory?(config_directory)
|
39
|
+
["environment.rb", "environment.sh"].each do |config_file|
|
40
|
+
rsync "-q", "#{config_directory}/#{config_file}",
|
41
|
+
"#{target_host}:#{release_path}/#{config_file}"
|
42
|
+
end
|
40
43
|
end
|
41
44
|
end
|
42
45
|
end
|
data/weave_todo.md
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
## Breaking changes in the weave branch
|
2
|
+
|
3
|
+
* `target_host` is gone
|
4
|
+
* `host` is now an alias for `target_host`, not a method
|
5
|
+
* `rsync` no longer exists (unless we write a new helper function)
|
6
|
+
|
7
|
+
## Other docs to write
|
8
|
+
|
9
|
+
* Call `warn` for deprecation notices
|
10
|
+
* document --trace and --dry-run passthrough flags
|
11
|
+
* puts is not thread-safe; instead, use print "" + "\n"
|
12
|
+
* capture_output captures the host prefix on each line. Instead pass :capture => :output to `run`.
|
13
|
+
You can also use capture_output and pass :capture => raw
|
metadata
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fezzik
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.8.0.beta1
|
5
|
+
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Daniel MacDougall
|
@@ -10,24 +10,40 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2013-02-10 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
|
-
name: rake
|
16
|
+
name: rake
|
17
17
|
requirement: !ruby/object:Gem::Requirement
|
18
18
|
none: false
|
19
19
|
requirements:
|
20
|
-
- -
|
20
|
+
- - ! '>='
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version:
|
22
|
+
version: '0'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
none: false
|
27
27
|
requirements:
|
28
|
-
- -
|
28
|
+
- - ! '>='
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: '0'
|
31
|
+
- !ruby/object:Gem::Dependency
|
32
|
+
name: weave
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
34
|
+
none: false
|
35
|
+
requirements:
|
36
|
+
- - '='
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: 0.1.0
|
39
|
+
type: :runtime
|
40
|
+
prerelease: false
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - '='
|
29
45
|
- !ruby/object:Gem::Version
|
30
|
-
version:
|
46
|
+
version: 0.1.0
|
31
47
|
- !ruby/object:Gem::Dependency
|
32
48
|
name: scope
|
33
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -73,15 +89,18 @@ files:
|
|
73
89
|
- Rakefile
|
74
90
|
- Vagrantfile
|
75
91
|
- bin/fez
|
92
|
+
- completions/_fez.bash
|
93
|
+
- completions/_fez.zsh
|
94
|
+
- example/Gemfile
|
95
|
+
- example/Rakefile
|
76
96
|
- fezzik.gemspec
|
77
97
|
- lib/fezzik.rb
|
78
98
|
- lib/fezzik/base.rb
|
79
99
|
- lib/fezzik/colors.rb
|
80
100
|
- lib/fezzik/dsl.rb
|
81
101
|
- lib/fezzik/environment.rb
|
82
|
-
- lib/fezzik/
|
102
|
+
- lib/fezzik/host_task.rb
|
83
103
|
- lib/fezzik/role.rb
|
84
|
-
- lib/fezzik/thread_local_io.rb
|
85
104
|
- lib/fezzik/util.rb
|
86
105
|
- lib/fezzik/version.rb
|
87
106
|
- tasks/command.rake
|
@@ -91,6 +110,7 @@ files:
|
|
91
110
|
- test/integration/base_test.rb
|
92
111
|
- test/integration/environment_test.rb
|
93
112
|
- test/integration_test_helper.rb
|
113
|
+
- weave_todo.md
|
94
114
|
homepage: http://github.com/dmacdougall/fezzik
|
95
115
|
licenses: []
|
96
116
|
post_install_message:
|
@@ -103,9 +123,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
103
123
|
- - ! '>='
|
104
124
|
- !ruby/object:Gem::Version
|
105
125
|
version: '0'
|
106
|
-
segments:
|
107
|
-
- 0
|
108
|
-
hash: 3198673685344171649
|
109
126
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
110
127
|
none: false
|
111
128
|
requirements:
|
@@ -117,7 +134,7 @@ rubyforge_project: fezzik
|
|
117
134
|
rubygems_version: 1.8.23
|
118
135
|
signing_key:
|
119
136
|
specification_version: 2
|
120
|
-
summary: Fezzik
|
121
|
-
|
137
|
+
summary: Fezzik adds remote ssh capabilities to Rake. It simplifies running commands
|
138
|
+
on remote servers and can be used for anything from deploying code to installing
|
122
139
|
libraries remotely.
|
123
140
|
test_files: []
|
data/lib/fezzik/io.rb
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
# Synchronize 'puts' because it's annoying to have interleaved output when rake remote task is running
|
2
|
-
# several things at once in multiple threads (for instance: commands on multiple servers or commands as
|
3
|
-
# multiple users).
|
4
|
-
#
|
5
|
-
# TODO(dmac): Is this made obsolete by thread_local_io.rb?
|
6
|
-
class IO
|
7
|
-
@@print_mutex = Mutex.new
|
8
|
-
alias :old_puts :puts
|
9
|
-
def puts(*args) @@print_mutex.synchronize { old_puts(*args) } end
|
10
|
-
end
|
11
|
-
|
@@ -1,47 +0,0 @@
|
|
1
|
-
# Overrides $stdout and allows it to be overridden by the thread-local variable Thread.current[:stdout].
|
2
|
-
#
|
3
|
-
# If Thread.current[:stdout] is set, the thread will write all output there. Otherwise the thread will
|
4
|
-
# use $stdout as normal.
|
5
|
-
#
|
6
|
-
# Example usage:
|
7
|
-
#
|
8
|
-
# out = StringIO.new
|
9
|
-
#
|
10
|
-
# Thread.start do
|
11
|
-
# Thread.current[:stdout] = out
|
12
|
-
# puts "thread1"
|
13
|
-
# end.join
|
14
|
-
#
|
15
|
-
# Thread.start do
|
16
|
-
# puts "thread2"
|
17
|
-
# end.join
|
18
|
-
#
|
19
|
-
# puts out.string
|
20
|
-
#
|
21
|
-
# Output:
|
22
|
-
# thread2
|
23
|
-
# thread1
|
24
|
-
|
25
|
-
module Fezzik
|
26
|
-
class ThreadLocalIO < IO
|
27
|
-
@@former_stdout = $stdout
|
28
|
-
|
29
|
-
def self.write(*args)
|
30
|
-
if Thread.current[:stdout]
|
31
|
-
Thread.current[:stdout].write(*args)
|
32
|
-
else
|
33
|
-
@@former_stdout.write(*args)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def self.flush
|
38
|
-
if Thread.current[:stdout]
|
39
|
-
Thread.current[:stdout].flush
|
40
|
-
else
|
41
|
-
@@former_stdout.flush
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
$stdout = Fezzik::ThreadLocalIO
|