minmb-capistrano 2.15.4

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.
Files changed (119) hide show
  1. data/.gitignore +10 -0
  2. data/.travis.yml +7 -0
  3. data/CHANGELOG +1170 -0
  4. data/Gemfile +13 -0
  5. data/README.md +94 -0
  6. data/Rakefile +11 -0
  7. data/bin/cap +4 -0
  8. data/bin/capify +92 -0
  9. data/capistrano.gemspec +40 -0
  10. data/lib/capistrano.rb +5 -0
  11. data/lib/capistrano/callback.rb +45 -0
  12. data/lib/capistrano/cli.rb +47 -0
  13. data/lib/capistrano/cli/execute.rb +85 -0
  14. data/lib/capistrano/cli/help.rb +125 -0
  15. data/lib/capistrano/cli/help.txt +81 -0
  16. data/lib/capistrano/cli/options.rb +243 -0
  17. data/lib/capistrano/cli/ui.rb +40 -0
  18. data/lib/capistrano/command.rb +303 -0
  19. data/lib/capistrano/configuration.rb +57 -0
  20. data/lib/capistrano/configuration/actions/file_transfer.rb +50 -0
  21. data/lib/capistrano/configuration/actions/inspect.rb +46 -0
  22. data/lib/capistrano/configuration/actions/invocation.rb +329 -0
  23. data/lib/capistrano/configuration/alias_task.rb +26 -0
  24. data/lib/capistrano/configuration/callbacks.rb +147 -0
  25. data/lib/capistrano/configuration/connections.rb +237 -0
  26. data/lib/capistrano/configuration/execution.rb +142 -0
  27. data/lib/capistrano/configuration/loading.rb +205 -0
  28. data/lib/capistrano/configuration/log_formatters.rb +75 -0
  29. data/lib/capistrano/configuration/namespaces.rb +223 -0
  30. data/lib/capistrano/configuration/roles.rb +77 -0
  31. data/lib/capistrano/configuration/servers.rb +116 -0
  32. data/lib/capistrano/configuration/variables.rb +127 -0
  33. data/lib/capistrano/errors.rb +19 -0
  34. data/lib/capistrano/ext/multistage.rb +64 -0
  35. data/lib/capistrano/ext/string.rb +5 -0
  36. data/lib/capistrano/extensions.rb +57 -0
  37. data/lib/capistrano/fix_rake_deprecated_dsl.rb +8 -0
  38. data/lib/capistrano/logger.rb +166 -0
  39. data/lib/capistrano/processable.rb +57 -0
  40. data/lib/capistrano/recipes/compat.rb +32 -0
  41. data/lib/capistrano/recipes/deploy.rb +625 -0
  42. data/lib/capistrano/recipes/deploy/assets.rb +201 -0
  43. data/lib/capistrano/recipes/deploy/dependencies.rb +44 -0
  44. data/lib/capistrano/recipes/deploy/local_dependency.rb +54 -0
  45. data/lib/capistrano/recipes/deploy/remote_dependency.rb +117 -0
  46. data/lib/capistrano/recipes/deploy/scm.rb +19 -0
  47. data/lib/capistrano/recipes/deploy/scm/accurev.rb +169 -0
  48. data/lib/capistrano/recipes/deploy/scm/base.rb +200 -0
  49. data/lib/capistrano/recipes/deploy/scm/bzr.rb +86 -0
  50. data/lib/capistrano/recipes/deploy/scm/cvs.rb +153 -0
  51. data/lib/capistrano/recipes/deploy/scm/darcs.rb +96 -0
  52. data/lib/capistrano/recipes/deploy/scm/git.rb +293 -0
  53. data/lib/capistrano/recipes/deploy/scm/mercurial.rb +137 -0
  54. data/lib/capistrano/recipes/deploy/scm/none.rb +55 -0
  55. data/lib/capistrano/recipes/deploy/scm/perforce.rb +152 -0
  56. data/lib/capistrano/recipes/deploy/scm/subversion.rb +121 -0
  57. data/lib/capistrano/recipes/deploy/strategy.rb +19 -0
  58. data/lib/capistrano/recipes/deploy/strategy/base.rb +92 -0
  59. data/lib/capistrano/recipes/deploy/strategy/checkout.rb +20 -0
  60. data/lib/capistrano/recipes/deploy/strategy/copy.rb +338 -0
  61. data/lib/capistrano/recipes/deploy/strategy/export.rb +20 -0
  62. data/lib/capistrano/recipes/deploy/strategy/remote.rb +52 -0
  63. data/lib/capistrano/recipes/deploy/strategy/remote_cache.rb +57 -0
  64. data/lib/capistrano/recipes/deploy/strategy/unshared_remote_cache.rb +21 -0
  65. data/lib/capistrano/recipes/standard.rb +37 -0
  66. data/lib/capistrano/recipes/templates/maintenance.rhtml +53 -0
  67. data/lib/capistrano/role.rb +102 -0
  68. data/lib/capistrano/server_definition.rb +56 -0
  69. data/lib/capistrano/shell.rb +265 -0
  70. data/lib/capistrano/ssh.rb +95 -0
  71. data/lib/capistrano/task_definition.rb +77 -0
  72. data/lib/capistrano/transfer.rb +218 -0
  73. data/lib/capistrano/version.rb +11 -0
  74. data/test/cli/execute_test.rb +132 -0
  75. data/test/cli/help_test.rb +165 -0
  76. data/test/cli/options_test.rb +329 -0
  77. data/test/cli/ui_test.rb +28 -0
  78. data/test/cli_test.rb +17 -0
  79. data/test/command_test.rb +322 -0
  80. data/test/configuration/actions/file_transfer_test.rb +61 -0
  81. data/test/configuration/actions/inspect_test.rb +76 -0
  82. data/test/configuration/actions/invocation_test.rb +288 -0
  83. data/test/configuration/alias_task_test.rb +118 -0
  84. data/test/configuration/callbacks_test.rb +201 -0
  85. data/test/configuration/connections_test.rb +439 -0
  86. data/test/configuration/execution_test.rb +175 -0
  87. data/test/configuration/loading_test.rb +148 -0
  88. data/test/configuration/namespace_dsl_test.rb +332 -0
  89. data/test/configuration/roles_test.rb +157 -0
  90. data/test/configuration/servers_test.rb +183 -0
  91. data/test/configuration/variables_test.rb +190 -0
  92. data/test/configuration_test.rb +77 -0
  93. data/test/deploy/local_dependency_test.rb +76 -0
  94. data/test/deploy/remote_dependency_test.rb +146 -0
  95. data/test/deploy/scm/accurev_test.rb +23 -0
  96. data/test/deploy/scm/base_test.rb +55 -0
  97. data/test/deploy/scm/bzr_test.rb +51 -0
  98. data/test/deploy/scm/darcs_test.rb +37 -0
  99. data/test/deploy/scm/git_test.rb +221 -0
  100. data/test/deploy/scm/mercurial_test.rb +134 -0
  101. data/test/deploy/scm/none_test.rb +35 -0
  102. data/test/deploy/scm/perforce_test.rb +23 -0
  103. data/test/deploy/scm/subversion_test.rb +40 -0
  104. data/test/deploy/strategy/copy_test.rb +360 -0
  105. data/test/extensions_test.rb +69 -0
  106. data/test/fixtures/cli_integration.rb +5 -0
  107. data/test/fixtures/config.rb +5 -0
  108. data/test/fixtures/custom.rb +3 -0
  109. data/test/logger_formatting_test.rb +149 -0
  110. data/test/logger_test.rb +134 -0
  111. data/test/recipes_test.rb +25 -0
  112. data/test/role_test.rb +11 -0
  113. data/test/server_definition_test.rb +121 -0
  114. data/test/shell_test.rb +96 -0
  115. data/test/ssh_test.rb +113 -0
  116. data/test/task_definition_test.rb +117 -0
  117. data/test/transfer_test.rb +168 -0
  118. data/test/utils.rb +37 -0
  119. metadata +316 -0
@@ -0,0 +1,127 @@
1
+ require 'thread'
2
+
3
+ module Capistrano
4
+ class Configuration
5
+ module Variables
6
+ def self.included(base) #:nodoc:
7
+ %w(initialize respond_to? method_missing).each do |m|
8
+ base_name = m[/^\w+/]
9
+ punct = m[/\W+$/]
10
+ base.send :alias_method, "#{base_name}_without_variables#{punct}", m
11
+ base.send :alias_method, m, "#{base_name}_with_variables#{punct}"
12
+ end
13
+ end
14
+
15
+ # The hash of variables that have been defined in this configuration
16
+ # instance.
17
+ attr_reader :variables
18
+
19
+ # Set a variable to the given value.
20
+ def set(variable, *args, &block)
21
+ if variable.to_s !~ /^[_a-z]/
22
+ raise ArgumentError, "invalid variable `#{variable}' (variables must begin with an underscore, or a lower-case letter)"
23
+ end
24
+
25
+ if !block_given? && args.empty? || block_given? && !args.empty?
26
+ raise ArgumentError, "you must specify exactly one of either a value or a block"
27
+ end
28
+
29
+ if args.length > 1
30
+ raise ArgumentError, "wrong number of arguments (#{args.length} for 1)"
31
+ end
32
+
33
+ value = args.empty? ? block : args.first
34
+ sym = variable.to_sym
35
+ protect(sym) { @variables[sym] = value }
36
+ end
37
+
38
+ alias :[]= :set
39
+
40
+ # Removes any trace of the given variable.
41
+ def unset(variable)
42
+ sym = variable.to_sym
43
+ protect(sym) do
44
+ @original_procs.delete(sym)
45
+ @variables.delete(sym)
46
+ end
47
+ end
48
+
49
+ # Returns true if the variable has been defined, and false otherwise.
50
+ def exists?(variable)
51
+ @variables.key?(variable.to_sym)
52
+ end
53
+
54
+ # If the variable was originally a proc value, it will be reset to it's
55
+ # original proc value. Otherwise, this method does nothing. It returns
56
+ # true if the variable was actually reset.
57
+ def reset!(variable)
58
+ sym = variable.to_sym
59
+ protect(sym) do
60
+ if @original_procs.key?(sym)
61
+ @variables[sym] = @original_procs.delete(sym)
62
+ true
63
+ else
64
+ false
65
+ end
66
+ end
67
+ end
68
+
69
+ # Access a named variable. If the value of the variable responds_to? :call,
70
+ # #call will be invoked (without parameters) and the return value cached
71
+ # and returned.
72
+ def fetch(variable, *args)
73
+ if !args.empty? && block_given?
74
+ raise ArgumentError, "you must specify either a default value or a block, but not both"
75
+ end
76
+
77
+ sym = variable.to_sym
78
+ protect(sym) do
79
+ if !@variables.key?(sym)
80
+ return args.first unless args.empty?
81
+ return yield(variable) if block_given?
82
+ raise IndexError, "`#{variable}' not found"
83
+ end
84
+
85
+ if @variables[sym].respond_to?(:call)
86
+ @original_procs[sym] = @variables[sym]
87
+ @variables[sym] = @variables[sym].call
88
+ end
89
+ end
90
+
91
+ @variables[sym]
92
+ end
93
+
94
+ def [](variable)
95
+ fetch(variable, nil)
96
+ end
97
+
98
+ def initialize_with_variables(*args) #:nodoc:
99
+ initialize_without_variables(*args)
100
+ @variables = {}
101
+ @original_procs = {}
102
+ @variable_locks = Hash.new { |h,k| h[k] = Mutex.new }
103
+
104
+ set :ssh_options, {}
105
+ set :logger, logger
106
+ end
107
+ private :initialize_with_variables
108
+
109
+ def protect(variable)
110
+ @variable_locks[variable.to_sym].synchronize { yield }
111
+ end
112
+ private :protect
113
+
114
+ def respond_to_with_variables?(sym, include_priv=false) #:nodoc:
115
+ @variables.has_key?(sym.to_sym) || respond_to_without_variables?(sym, include_priv)
116
+ end
117
+
118
+ def method_missing_with_variables(sym, *args, &block) #:nodoc:
119
+ if args.length == 0 && block.nil? && @variables.has_key?(sym)
120
+ self[sym]
121
+ else
122
+ method_missing_without_variables(sym, *args, &block)
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,19 @@
1
+ module Capistrano
2
+
3
+ Error = Class.new(RuntimeError)
4
+
5
+ CaptureError = Class.new(Capistrano::Error)
6
+ NoSuchTaskError = Class.new(Capistrano::Error)
7
+ NoMatchingServersError = Class.new(Capistrano::Error)
8
+
9
+ class RemoteError < Error
10
+ attr_accessor :hosts
11
+ end
12
+
13
+ ConnectionError = Class.new(Capistrano::RemoteError)
14
+ TransferError = Class.new(Capistrano::RemoteError)
15
+ CommandError = Class.new(Capistrano::RemoteError)
16
+
17
+ LocalArgumentError = Class.new(Capistrano::Error)
18
+
19
+ end
@@ -0,0 +1,64 @@
1
+ require 'fileutils'
2
+
3
+ unless Capistrano::Configuration.respond_to?(:instance)
4
+ abort "capistrano/ext/multistage requires Capistrano 2"
5
+ end
6
+
7
+ Capistrano::Configuration.instance.load do
8
+ location = fetch(:stage_dir, "config/deploy")
9
+
10
+ unless exists?(:stages)
11
+ set :stages, Dir["#{location}/*.rb"].map { |f| File.basename(f, ".rb") }
12
+ end
13
+
14
+ stages.each do |name|
15
+ desc "Set the target stage to `#{name}'."
16
+ task(name) do
17
+ set :stage, name.to_sym
18
+
19
+ file = "#{location}/#{stage}"
20
+ load file if file_in_load_path?(file)
21
+ end
22
+ end
23
+
24
+ on :load do
25
+ if stages.include?(ARGV.first)
26
+ # Execute the specified stage so that recipes required in stage can contribute to task list
27
+ find_and_execute_task(ARGV.first) if ARGV.any?{ |option| option =~ /-T|--tasks|-e|--explain/ }
28
+ else
29
+ # Execute the default stage so that recipes required in stage can contribute tasks
30
+ find_and_execute_task(default_stage) if exists?(:default_stage)
31
+ end
32
+ end
33
+
34
+ namespace :multistage do
35
+ desc "[internal] Ensure that a stage has been selected."
36
+ task :ensure do
37
+ if !exists?(:stage)
38
+ if exists?(:default_stage)
39
+ logger.important "Defaulting to `#{default_stage}'"
40
+ find_and_execute_task(default_stage)
41
+ else
42
+ abort "No stage specified. Please specify one of: #{stages.join(', ')} (e.g. `cap #{stages.first} #{ARGV.last}')"
43
+ end
44
+ end
45
+ end
46
+
47
+ desc "Stub out the staging config files."
48
+ task :prepare do
49
+ FileUtils.mkdir_p(location)
50
+ stages.each do |name|
51
+ file = File.join(location, name + ".rb")
52
+ unless File.exists?(file)
53
+ File.open(file, "w") do |f|
54
+ f.puts "# #{name.upcase}-specific deployment configuration"
55
+ f.puts "# please put general deployment config in config/deploy.rb"
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+
62
+ on :start, "multistage:ensure", :except => stages + ['multistage:prepare']
63
+
64
+ end
@@ -0,0 +1,5 @@
1
+ class String
2
+ def compact
3
+ self.gsub(/\s+/, ' ')
4
+ end
5
+ end
@@ -0,0 +1,57 @@
1
+ module Capistrano
2
+ class ExtensionProxy #:nodoc:
3
+ def initialize(config, mod)
4
+ @config = config
5
+ extend(mod)
6
+ end
7
+
8
+ def method_missing(sym, *args, &block)
9
+ @config.send(sym, *args, &block)
10
+ end
11
+ end
12
+
13
+ # Holds the set of registered plugins, keyed by name (where the name is a
14
+ # symbol).
15
+ EXTENSIONS = {}
16
+
17
+ # Register the given module as a plugin with the given name. It will henceforth
18
+ # be available via a proxy object on Configuration instances, accessible by
19
+ # a method with the given name.
20
+ def self.plugin(name, mod)
21
+ name = name.to_sym
22
+ return false if EXTENSIONS.has_key?(name)
23
+
24
+ methods = Capistrano::Configuration.public_instance_methods +
25
+ Capistrano::Configuration.protected_instance_methods +
26
+ Capistrano::Configuration.private_instance_methods
27
+
28
+ if methods.any? { |m| m.to_sym == name }
29
+ raise Capistrano::Error, "registering a plugin named `#{name}' would shadow a method on Capistrano::Configuration with the same name"
30
+ end
31
+
32
+ Capistrano::Configuration.class_eval <<-STR, __FILE__, __LINE__+1
33
+ def #{name}
34
+ @__#{name}_proxy ||= Capistrano::ExtensionProxy.new(self, Capistrano::EXTENSIONS[#{name.inspect}])
35
+ end
36
+ STR
37
+
38
+ EXTENSIONS[name] = mod
39
+ return true
40
+ end
41
+
42
+ # Unregister the plugin with the given name.
43
+ def self.remove_plugin(name)
44
+ name = name.to_sym
45
+ if EXTENSIONS.delete(name)
46
+ Capistrano::Configuration.send(:remove_method, name)
47
+ return true
48
+ end
49
+
50
+ return false
51
+ end
52
+
53
+ def self.configuration(*args) #:nodoc:
54
+ warn "[DEPRECATION] Capistrano.configuration is deprecated. Use Capistrano::Configuration.instance instead"
55
+ Capistrano::Configuration.instance(*args)
56
+ end
57
+ end
@@ -0,0 +1,8 @@
1
+ #
2
+ # See https://github.com/jimweirich/rake/issues/81
3
+ #
4
+ if defined?(Rake::DeprecatedObjectDSL)
5
+ Rake::DeprecatedObjectDSL.private_instance_methods.each do |m|
6
+ Rake::DeprecatedObjectDSL.send("undef_method", m)
7
+ end
8
+ end
@@ -0,0 +1,166 @@
1
+ module Capistrano
2
+ class Logger #:nodoc:
3
+ attr_accessor :level, :device, :disable_formatters
4
+
5
+ IMPORTANT = 0
6
+ INFO = 1
7
+ DEBUG = 2
8
+ TRACE = 3
9
+
10
+ MAX_LEVEL = 3
11
+
12
+ COLORS = {
13
+ :none => "0",
14
+ :black => "30",
15
+ :red => "31",
16
+ :green => "32",
17
+ :yellow => "33",
18
+ :blue => "34",
19
+ :magenta => "35",
20
+ :cyan => "36",
21
+ :white => "37"
22
+ }
23
+
24
+ STYLES = {
25
+ :bright => 1,
26
+ :dim => 2,
27
+ :underscore => 4,
28
+ :blink => 5,
29
+ :reverse => 7,
30
+ :hidden => 8
31
+ }
32
+
33
+ # Set up default formatters
34
+ @default_formatters = [
35
+ # TRACE
36
+ { :match => /command finished/, :color => :white, :style => :dim, :level => 3, :priority => -10 },
37
+ { :match => /executing locally/, :color => :yellow, :level => 3, :priority => -20 },
38
+
39
+ # DEBUG
40
+ { :match => /executing `.*/, :color => :green, :level => 2, :priority => -10, :timestamp => true },
41
+ { :match => /.*/, :color => :yellow, :level => 2, :priority => -30 },
42
+
43
+ # INFO
44
+ { :match => /.*out\] (fatal:|ERROR:).*/, :color => :red, :level => 1, :priority => -10 },
45
+ { :match => /Permission denied/, :color => :red, :level => 1, :priority => -20 },
46
+ { :match => /sh: .+: command not found/, :color => :magenta, :level => 1, :priority => -30 },
47
+
48
+ # IMPORTANT
49
+ { :match => /^err ::/, :color => :red, :level => 0, :priority => -10 },
50
+ { :match => /.*/, :color => :blue, :level => 0, :priority => -20 }
51
+ ]
52
+ @formatters = @default_formatters
53
+
54
+ class << self
55
+ def default_formatters
56
+ @default_formatters
57
+ end
58
+
59
+ def default_formatters=(defaults=nil)
60
+ @default_formatters = [defaults].flatten
61
+
62
+ # reset the formatters
63
+ @formatters = @default_formatters
64
+ @sorted_formatters = nil
65
+ end
66
+
67
+ def add_formatter(options) #:nodoc:
68
+ @formatters.push(options)
69
+ @sorted_formatters = nil
70
+ end
71
+
72
+ def sorted_formatters
73
+ # Sort matchers in reverse order so we can break if we found a match.
74
+ @sorted_formatters ||= @formatters.sort_by { |i| -(i[:priority] || i[:prio] || 0) }
75
+ end
76
+ end
77
+
78
+ def initialize(options={})
79
+ output = options[:output] || $stderr
80
+ if output.respond_to?(:puts)
81
+ @device = output
82
+ else
83
+ @device = File.open(output.to_str, "a")
84
+ @needs_close = true
85
+ end
86
+
87
+ @options = options
88
+ @level = options[:level] || 0
89
+ @disable_formatters = options[:disable_formatters]
90
+ end
91
+
92
+ def close
93
+ device.close if @needs_close
94
+ end
95
+
96
+ def log(level, message, line_prefix=nil)
97
+ if level <= self.level
98
+ # Only format output if device is a TTY or formatters are not disabled
99
+ if device.tty? && !@disable_formatters
100
+ color = :none
101
+ style = nil
102
+
103
+ Logger.sorted_formatters.each do |formatter|
104
+ if (formatter[:level] == level || formatter[:level].nil?)
105
+ if message =~ formatter[:match] || line_prefix =~ formatter[:match]
106
+ color = formatter[:color] if formatter[:color]
107
+ style = formatter[:style] || formatter[:attribute] # (support original cap colors)
108
+ message.gsub!(formatter[:match], formatter[:replace]) if formatter[:replace]
109
+ message = formatter[:prepend] + message unless formatter[:prepend].nil?
110
+ message = message + formatter[:append] unless formatter[:append].nil?
111
+ message = Time.now.strftime('%Y-%m-%d %T') + ' ' + message if formatter[:timestamp]
112
+ break unless formatter[:replace]
113
+ end
114
+ end
115
+ end
116
+
117
+ if color == :hide
118
+ # Don't do anything if color is set to :hide
119
+ return false
120
+ end
121
+
122
+ term_color = COLORS[color]
123
+ term_style = STYLES[style]
124
+
125
+ # Don't format message if no color or style
126
+ unless color == :none and style.nil?
127
+ unless line_prefix.nil?
128
+ line_prefix = format(line_prefix, term_color, term_style, nil)
129
+ end
130
+ message = format(message, term_color, term_style)
131
+ end
132
+ end
133
+
134
+ indent = "%*s" % [MAX_LEVEL, "*" * (MAX_LEVEL - level)]
135
+ (RUBY_VERSION >= "1.9" ? message.lines : message).each do |line|
136
+ if line_prefix
137
+ device.puts "#{indent} [#{line_prefix}] #{line.strip}\n"
138
+ else
139
+ device.puts "#{indent} #{line.strip}\n"
140
+ end
141
+ end
142
+ end
143
+ end
144
+
145
+ def important(message, line_prefix=nil)
146
+ log(IMPORTANT, message, line_prefix)
147
+ end
148
+
149
+ def info(message, line_prefix=nil)
150
+ log(INFO, message, line_prefix)
151
+ end
152
+
153
+ def debug(message, line_prefix=nil)
154
+ log(DEBUG, message, line_prefix)
155
+ end
156
+
157
+ def trace(message, line_prefix=nil)
158
+ log(TRACE, message, line_prefix)
159
+ end
160
+
161
+ def format(message, color, style, nl = "\n")
162
+ style = "#{style};" if style
163
+ "\e[#{style}#{color}m" + message.to_s.strip + "\e[0m#{nl}"
164
+ end
165
+ end
166
+ end