capistrano 1.4.2 → 2.0.0

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 (113) hide show
  1. data/CHANGELOG +140 -4
  2. data/MIT-LICENSE +1 -1
  3. data/README +22 -14
  4. data/bin/cap +1 -8
  5. data/bin/capify +77 -0
  6. data/examples/sample.rb +10 -109
  7. data/lib/capistrano.rb +1 -0
  8. data/lib/capistrano/callback.rb +41 -0
  9. data/lib/capistrano/cli.rb +17 -317
  10. data/lib/capistrano/cli/execute.rb +82 -0
  11. data/lib/capistrano/cli/help.rb +102 -0
  12. data/lib/capistrano/cli/help.txt +53 -0
  13. data/lib/capistrano/cli/options.rb +183 -0
  14. data/lib/capistrano/cli/ui.rb +28 -0
  15. data/lib/capistrano/command.rb +62 -29
  16. data/lib/capistrano/configuration.rb +25 -226
  17. data/lib/capistrano/configuration/actions/file_transfer.rb +35 -0
  18. data/lib/capistrano/configuration/actions/inspect.rb +46 -0
  19. data/lib/capistrano/configuration/actions/invocation.rb +127 -0
  20. data/lib/capistrano/configuration/callbacks.rb +148 -0
  21. data/lib/capistrano/configuration/connections.rb +159 -0
  22. data/lib/capistrano/configuration/execution.rb +126 -0
  23. data/lib/capistrano/configuration/loading.rb +112 -0
  24. data/lib/capistrano/configuration/namespaces.rb +190 -0
  25. data/lib/capistrano/configuration/roles.rb +51 -0
  26. data/lib/capistrano/configuration/servers.rb +75 -0
  27. data/lib/capistrano/configuration/variables.rb +127 -0
  28. data/lib/capistrano/errors.rb +15 -0
  29. data/lib/capistrano/extensions.rb +27 -8
  30. data/lib/capistrano/gateway.rb +54 -29
  31. data/lib/capistrano/logger.rb +11 -11
  32. data/lib/capistrano/recipes/compat.rb +32 -0
  33. data/lib/capistrano/recipes/deploy.rb +483 -0
  34. data/lib/capistrano/recipes/deploy/dependencies.rb +44 -0
  35. data/lib/capistrano/recipes/deploy/local_dependency.rb +46 -0
  36. data/lib/capistrano/recipes/deploy/remote_dependency.rb +65 -0
  37. data/lib/capistrano/recipes/deploy/scm.rb +19 -0
  38. data/lib/capistrano/recipes/deploy/scm/base.rb +180 -0
  39. data/lib/capistrano/recipes/deploy/scm/bzr.rb +86 -0
  40. data/lib/capistrano/recipes/deploy/scm/cvs.rb +151 -0
  41. data/lib/capistrano/recipes/deploy/scm/darcs.rb +85 -0
  42. data/lib/capistrano/recipes/deploy/scm/mercurial.rb +129 -0
  43. data/lib/capistrano/recipes/deploy/scm/perforce.rb +126 -0
  44. data/lib/capistrano/recipes/deploy/scm/subversion.rb +103 -0
  45. data/lib/capistrano/recipes/deploy/strategy.rb +19 -0
  46. data/lib/capistrano/recipes/deploy/strategy/base.rb +64 -0
  47. data/lib/capistrano/recipes/deploy/strategy/checkout.rb +20 -0
  48. data/lib/capistrano/recipes/deploy/strategy/copy.rb +143 -0
  49. data/lib/capistrano/recipes/deploy/strategy/export.rb +20 -0
  50. data/lib/capistrano/recipes/deploy/strategy/remote.rb +52 -0
  51. data/lib/capistrano/recipes/deploy/strategy/remote_cache.rb +47 -0
  52. data/lib/capistrano/recipes/deploy/templates/maintenance.rhtml +53 -0
  53. data/lib/capistrano/recipes/standard.rb +26 -276
  54. data/lib/capistrano/recipes/templates/maintenance.rhtml +1 -1
  55. data/lib/capistrano/recipes/upgrade.rb +33 -0
  56. data/lib/capistrano/server_definition.rb +51 -0
  57. data/lib/capistrano/shell.rb +125 -81
  58. data/lib/capistrano/ssh.rb +80 -36
  59. data/lib/capistrano/task_definition.rb +69 -0
  60. data/lib/capistrano/upload.rb +146 -0
  61. data/lib/capistrano/version.rb +13 -17
  62. data/test/cli/execute_test.rb +132 -0
  63. data/test/cli/help_test.rb +139 -0
  64. data/test/cli/options_test.rb +226 -0
  65. data/test/cli/ui_test.rb +28 -0
  66. data/test/cli_test.rb +17 -0
  67. data/test/command_test.rb +284 -25
  68. data/test/configuration/actions/file_transfer_test.rb +40 -0
  69. data/test/configuration/actions/inspect_test.rb +62 -0
  70. data/test/configuration/actions/invocation_test.rb +195 -0
  71. data/test/configuration/callbacks_test.rb +206 -0
  72. data/test/configuration/connections_test.rb +288 -0
  73. data/test/configuration/execution_test.rb +159 -0
  74. data/test/configuration/loading_test.rb +119 -0
  75. data/test/configuration/namespace_dsl_test.rb +283 -0
  76. data/test/configuration/roles_test.rb +47 -0
  77. data/test/configuration/servers_test.rb +90 -0
  78. data/test/configuration/variables_test.rb +180 -0
  79. data/test/configuration_test.rb +60 -212
  80. data/test/deploy/scm/base_test.rb +55 -0
  81. data/test/deploy/strategy/copy_test.rb +146 -0
  82. data/test/extensions_test.rb +69 -0
  83. data/test/fixtures/cli_integration.rb +5 -0
  84. data/test/fixtures/custom.rb +2 -2
  85. data/test/gateway_test.rb +167 -0
  86. data/test/logger_test.rb +123 -0
  87. data/test/server_definition_test.rb +108 -0
  88. data/test/shell_test.rb +64 -0
  89. data/test/ssh_test.rb +67 -154
  90. data/test/task_definition_test.rb +101 -0
  91. data/test/upload_test.rb +131 -0
  92. data/test/utils.rb +31 -39
  93. data/test/version_test.rb +24 -0
  94. metadata +145 -98
  95. data/THANKS +0 -4
  96. data/lib/capistrano/actor.rb +0 -567
  97. data/lib/capistrano/generators/rails/deployment/deployment_generator.rb +0 -25
  98. data/lib/capistrano/generators/rails/deployment/templates/capistrano.rake +0 -49
  99. data/lib/capistrano/generators/rails/deployment/templates/deploy.rb +0 -122
  100. data/lib/capistrano/generators/rails/loader.rb +0 -20
  101. data/lib/capistrano/scm/base.rb +0 -61
  102. data/lib/capistrano/scm/baz.rb +0 -118
  103. data/lib/capistrano/scm/bzr.rb +0 -70
  104. data/lib/capistrano/scm/cvs.rb +0 -129
  105. data/lib/capistrano/scm/darcs.rb +0 -27
  106. data/lib/capistrano/scm/mercurial.rb +0 -83
  107. data/lib/capistrano/scm/perforce.rb +0 -139
  108. data/lib/capistrano/scm/subversion.rb +0 -128
  109. data/lib/capistrano/transfer.rb +0 -97
  110. data/lib/capistrano/utils.rb +0 -26
  111. data/test/actor_test.rb +0 -402
  112. data/test/scm/cvs_test.rb +0 -196
  113. data/test/scm/subversion_test.rb +0 -145
@@ -1,129 +0,0 @@
1
- require 'time'
2
- require 'capistrano/scm/base'
3
-
4
- module Capistrano
5
- module SCM
6
-
7
- # An SCM module for using CVS as your source control tool. You can
8
- # specify it by placing the following line in your configuration:
9
- #
10
- # set :scm, :cvs
11
- #
12
- # Also, this module accepts a <tt>:cvs</tt> configuration variable,
13
- # which (if specified) will be used as the full path to the cvs
14
- # executable on the remote machine:
15
- #
16
- # set :cvs, "/opt/local/bin/cvs"
17
- #
18
- # You can specify the location of your local copy (used to query
19
- # the revisions, etc.) via the <tt>:local</tt> variable, which defaults to
20
- # ".".
21
- #
22
- # You may also specify a <tt>:branch</tt> configuration variable,
23
- # which (if specified) will be used in the '-r' option to the cvs
24
- # check out command. If it is not set, the module will determine if a
25
- # branch is being used in the CVS sandbox relative to
26
- # <tt>:local</tt> and act accordingly.
27
- #
28
- # set :branch, "prod-20060124"
29
- #
30
- # Also, you can specify the CVS_RSH variable to use on the remote machine(s)
31
- # via the <tt>:cvs_rsh</tt> variable. This defaults to the value of the
32
- # CVS_RSH environment variable locally, or if it is not set, to "ssh".
33
- class Cvs < Base
34
- def initialize(configuration)
35
- super(configuration)
36
-
37
- if not @configuration.respond_to?(:local) then
38
- @configuration.set(:local,".")
39
- end
40
-
41
- if not configuration.respond_to?(:branch) then
42
- configuration.set(:branch) { self.current_branch }
43
- else
44
- @current_branch = configuration[:branch]
45
- end
46
- end
47
-
48
- # Return a string representing the date of the last revision (CVS is
49
- # seriously retarded, in that it does not give you a way to query when
50
- # the last revision was made to the repository, so this is a fairly
51
- # expensive operation...)
52
- def latest_revision
53
- return @latest_revision if @latest_revision
54
- configuration.logger.debug "querying latest revision..."
55
- @latest_revision = cvs_log(cvs_local, configuration.branch).
56
- split(/\r?\n/).
57
- grep(/^date: (.*?);/) { Time.parse($1).strftime("%Y-%m-%d %H:%M:%S") }.
58
- sort.
59
- last
60
- end
61
-
62
- # Return a string representing the branch that the sandbox
63
- # relative to <tt>:local</tt> contains.
64
- def current_branch
65
- return @current_branch if @current_branch
66
- configuration.logger.debug "determining current_branch..."
67
- @current_branch = cvs_branch(cvs_local)
68
- end
69
-
70
- # Check out (on all servers associated with the current task) the latest
71
- # revision, using a branch if necessary. Uses the given actor instance
72
- # to execute the command.
73
- def checkout(actor)
74
- cvs = configuration[:cvs] || "cvs"
75
- cvs_rsh = configuration[:cvs_rsh] || ENV['CVS_RSH'] || "ssh"
76
-
77
- if "HEAD" == configuration.branch then
78
- branch_option = ""
79
- else
80
- branch_option = "-r #{configuration.branch}"
81
- end
82
-
83
- command = <<-CMD
84
- cd #{configuration.releases_path};
85
- CVS_RSH="#{cvs_rsh}" #{cvs} -d #{configuration.repository} -Q co -D "#{configuration.revision}" #{branch_option} -d #{File.basename(actor.release_path)} #{actor.application};
86
- CMD
87
-
88
- run_checkout(actor, command) do |ch, stream, out|
89
- prefix = "#{stream} :: #{ch[:host]}"
90
- actor.logger.info out, prefix
91
- if out =~ %r{password:}
92
- actor.logger.info "CVS is asking for a password", prefix
93
- ch.send_data "#{actor.password}\n"
94
- elsif out =~ %r{^Enter passphrase}
95
- message = "CVS needs your key's passphrase and cannot proceed"
96
- actor.logger.info message, prefix
97
- raise message
98
- end
99
- end
100
- end
101
-
102
- private
103
-
104
- # Look for a 'CVS/Tag' file in the path. If this file exists
105
- # and contains a Line starting with 'T' then this CVS sandbox is
106
- # 'tagged' with a branch. In the default case return 'HEAD'
107
- def cvs_branch(path)
108
- branch = "HEAD"
109
- branch_file = File.join(path || ".", "CVS", "Tag")
110
- if File.exists?(branch_file) then
111
- File.open(branch_file) do |f|
112
- possible_branch = f.find { |l| l =~ %r{^T} }
113
- branch = possible_branch.strip[1..-1] if possible_branch
114
- end
115
- end
116
- branch
117
- end
118
-
119
- def cvs_log(path,branch)
120
- `cd #{path || "."} && cvs -d #{configuration.repository} -q log -N -r#{branch}`
121
- end
122
-
123
- def cvs_local
124
- configuration.local || "."
125
- end
126
- end
127
-
128
- end
129
- end
@@ -1,27 +0,0 @@
1
- require 'capistrano/scm/base'
2
-
3
- module Capistrano
4
- module SCM
5
-
6
- # An SCM module for using darcs as your source control tool. Use it by
7
- # specifying the following line in your configuration:
8
- #
9
- # set :scm, :darcs
10
- #
11
- # Also, this module accepts a <tt>:darcs</tt> configuration variable,
12
- # which (if specified) will be used as the full path to the darcs
13
- # executable on the remote machine:
14
- #
15
- # set :darcs, "/opt/local/bin/darcs"
16
- class Darcs < Base
17
- # Check out (on all servers associated with the current task) the latest
18
- # revision. Uses the given actor instance to execute the command.
19
- def checkout(actor)
20
- darcs = configuration[:darcs] ? configuration[:darcs] : "darcs"
21
- revision = configuration[:revision] ? %(--to-match "#{configuration.revision}") : ""
22
- run_checkout(actor, "#{darcs} get -q --set-scripts-executable #{revision} #{configuration.repository} #{actor.release_path};")
23
- end
24
- end
25
-
26
- end
27
- end
@@ -1,83 +0,0 @@
1
- require 'capistrano/scm/base'
2
-
3
- module Capistrano
4
- module SCM
5
-
6
- # An SCM module for using Mercurial as your source control tool.
7
- # You can use it by placing the following line in your configuration:
8
- #
9
- # set :scm, :mercurial
10
- #
11
- # Also, this module accepts a <tt>:mercurial</tt> configuration variable,
12
- # which (if specified) will be used as the full path to the hg
13
- # executable on the remote machine:
14
- #
15
- # set :mercurial, "/usr/local/bin/hg"
16
- class Mercurial < Base
17
- # Return a string identifying the tip changeset in the mercurial
18
- # repository. Note that this fetches the tip changeset from the
19
- # local repository, but capistrano will deploy from your _remote_
20
- # repository. So just make sure your local repository is synchronized
21
- # with your remote one.
22
- def latest_revision
23
- `#{mercurial} tip --template '{node|short}'`
24
- end
25
-
26
- # Return the changeset currently deployed.
27
- def current_revision(actor)
28
- # NOTE:
29
- # copied almost verbatim from svn except its not cast into an int
30
- # this should be the same for almost _every_ scm can we take it out
31
- # of SCM-specific code?
32
- latest = actor.releases.last
33
- grep = %(grep " #{latest}$" #{configuration.deploy_to}/revisions.log)
34
- result = ""
35
- actor.run(grep, :once => true) do |ch, str, out|
36
- result << out if str == :out
37
- raise "could not determine current changeset" if str == :err
38
- end
39
-
40
- date, time, user, changeset, dir = result.split
41
- raise "current changeset not found in revisions.log" unless dir == latest
42
- changeset
43
- end
44
-
45
- # Return a string containing the diff between the two changesets. +from+
46
- # and +to+ may be in any format that mercurial recognizes as a valid
47
- # changeset. If +from+ is +nil+, it defaults to the last deployed
48
- # changeset. If +to+ is +nil+, it defaults to the current working
49
- # directory.
50
- def diff(actor, from = current_revision(actor), to = nil)
51
- cmd = "#{mercurial} diff -r #{from}"
52
- cmd << " -r #{to}" if to
53
- `#{cmd}`
54
- end
55
-
56
- # Check out (on all servers associated with the current task) the latest
57
- # revision. Uses the given actor instance to execute the command. If
58
- # mercurial asks for a password this will automatically provide it
59
- # (assuming the requested password is the same as the password for
60
- # logging into the remote server.) If ssh repository method is used,
61
- # authorized keys must be setup.
62
- def checkout(actor)
63
- command = "#{mercurial} clone -U #{configuration.repository} " +
64
- "#{actor.release_path} && " +
65
- "#{mercurial} -R #{actor.release_path} update " +
66
- "-C #{configuration.revision} &&"
67
- run_checkout(actor, command, &hg_stream_handler(actor))
68
- end
69
-
70
- private
71
- def mercurial
72
- configuration[:mercurial] || "hg"
73
- end
74
-
75
- def hg_stream_handler(actor)
76
- Proc.new do |ch, stream, out|
77
- prefix = "#{stream} :: #{ch[:host]}"
78
- actor.logger.info out, prefix
79
- end
80
- end
81
- end
82
- end
83
- end
@@ -1,139 +0,0 @@
1
- require 'capistrano/scm/base'
2
-
3
- module Capistrano
4
- module SCM
5
-
6
- # An SCM module for using perforce as your source control tool.
7
- # This module can explicitly selected by placing the following line
8
- # in your configuration:
9
- #
10
- # set :scm, :perforce
11
- #
12
- # Also, this module accepts a <tt>:p4</tt> configuration variable,
13
- # which (if specified) will be used as the full path to the p4
14
- # executable on the remote machine:
15
- #
16
- # set :p4, "/usr/local/bin/p4"
17
- #
18
- # This module accepts another <tt>:p4sync_flags</tt> configuration
19
- # variable, which (if specified) can add extra options. This setting
20
- # defaults to the value "-f" which forces resynchronization.
21
- #
22
- # set :p4sync_flags, "-f"
23
- #
24
- # This module accepts another <tt>:p4client_root</tt> configuration
25
- # variable to handle mapping adjustments. Perforce doesn't have the
26
- # ability to sync to a specific directory (e.g. the release_path); the
27
- # location being synced to is defined by the client-spec. As such, we
28
- # sync the client-spec (defined by <tt>p4client</tt> and then copy from
29
- # the determined root of the client-spec mappings to the release_path.
30
- # In the unlikely event that your client-spec mappings introduces
31
- # directory structure above the rails structure, you can override the
32
- # may need to specify the directory
33
- #
34
- # set :p4client_root, "/user/rmcmahon/project1/code"
35
- #
36
- # Finally, the module accepts a <tt>p4diff2_options</tt> configuration
37
- # variable. This can be used to manipulate the output when running a
38
- # diff between what is deployed, and another revision. This option
39
- # defaults to "-u". Run 'p4 help diff2' for other options.
40
- #
41
- class Perforce < Base
42
-
43
- def latest_revision
44
- configuration.logger.debug "querying latest revision..." unless @latest_revision
45
- @latest_revision = `#{local_p4} counter change`.strip
46
- @latest_revision
47
- end
48
-
49
- # Return the number of the revision currently deployed.
50
- def current_revision(actor)
51
- latest = actor.releases.last
52
- grep = %(grep " #{latest}$" #{configuration.deploy_to}/revisions.log)
53
- result = ""
54
- actor.run(grep, :once => true) do |ch, str, out|
55
- result << out if str == :out
56
- raise "could not determine current revision" if str == :err
57
- end
58
-
59
- date, time, user, rev, dir = result.split
60
- raise "current revision not found in revisions.log" unless dir == latest
61
- rev.to_i
62
- end
63
-
64
- # Return a string containing the diff between the two revisions. +from+
65
- # and +to+ may be in any format that p4 recognizes as a valid revision
66
- # identifiers. If +from+ is +nil+, it defaults to the last deployed
67
- # revision. If +to+ is +nil+, it defaults to #head.
68
- def diff(actor, from=nil, to=nil)
69
- from ||= "@#{current_revision(actor)}"
70
- to ||= "#head"
71
- p4client = configuration[:p4client]
72
- p4diff2_options = configuration[:p4diff2_options]||"-u -db"
73
- `#{local_p4} diff2 #{p4diff2_options} //#{p4client}/...#{from} //#{p4client}/...#{to}`
74
- end
75
-
76
- # Syncronizes (on all servers associated with the current task) the head
77
- # revision of the code. Uses the given actor instance to execute the command.
78
- #
79
- def checkout(actor)
80
- p4sync_flags = configuration[:p4sync_flags] || "-f"
81
- p4client_root = configuration[:p4client_root] || "`#{remote_p4} client -o | grep ^Root | cut -f2`"
82
- command = "#{remote_p4} sync #{p4sync_flags} && cp -rf #{p4client_root} #{actor.release_path};"
83
- run_checkout(actor, command, &p4_stream_handler(actor))
84
- end
85
-
86
- def update(actor)
87
- raise "#{self.class} doesn't support update(actor)"
88
- end
89
-
90
- private
91
-
92
- def local_p4
93
- add_standard_p4_options('p4')
94
- end
95
-
96
- def remote_p4
97
- p4_cmd = configuration[:p4] || 'p4'
98
- add_standard_p4_options(p4_cmd)
99
- end
100
-
101
- def add_standard_p4_options(p4_location)
102
- check_settings
103
- p4_cmd = p4_location
104
- p4_cmd = "#{p4_cmd} -p #{configuration[:p4port]}" if configuration[:p4port]
105
- p4_cmd = "#{p4_cmd} -u #{configuration[:p4user]}" if configuration[:p4user]
106
- p4_cmd = "#{p4_cmd} -P #{configuration[:p4passwd]}" if configuration[:p4passwd]
107
- p4_cmd = "#{p4_cmd} -c #{configuration[:p4client]}" if configuration[:p4client]
108
- p4_cmd
109
- end
110
-
111
- def check_settings
112
- check_setting(:p4port, "Add set :p4port, <your perforce server details e.g. my.p4.server:1666> to deploy.rb")
113
- check_setting(:p4user, "Add set :p4user, <your production build username> to deploy.rb")
114
- check_setting(:p4passwd, "Add set :p4passwd, <your build user password> to deploy.rb")
115
- check_setting(:p4client, "Add set :p4client, <your client-spec name> to deploy.rb")
116
- end
117
-
118
- def check_setting(p4setting, message)
119
- raise "#{p4setting} is not configured. #{message}" unless configuration[p4setting]
120
- end
121
-
122
- def p4_stream_handler(actor)
123
- Proc.new do |ch, stream, out|
124
- prefix = "#{stream} :: #{ch[:host]}"
125
- actor.logger.info out, prefix
126
- if out =~ /\(P4PASSWD\) invalid or unset\./i
127
- raise "p4passwd is incorrect or unset"
128
- elsif out =~ /Can.t create a new user.*/i
129
- raise "p4user is incorrect or unset"
130
- elsif out =~ /Perforce client error\:/i
131
- raise "p4port is incorrect or unset"
132
- elsif out =~ /Client \'[\w\-\_\.]+\' unknown.*/i
133
- raise "p4client is incorrect or unset"
134
- end
135
- end
136
- end
137
- end
138
- end
139
- end
@@ -1,128 +0,0 @@
1
- require 'capistrano/scm/base'
2
-
3
- module Capistrano
4
- module SCM
5
-
6
- # An SCM module for using subversion as your source control tool. This
7
- # module is used by default, but you can explicitly specify it by
8
- # placing the following line in your configuration:
9
- #
10
- # set :scm, :subversion
11
- #
12
- # Also, this module accepts a <tt>:svn</tt> configuration variable,
13
- # which (if specified) will be used as the full path to the svn
14
- # executable on the remote machine:
15
- #
16
- # set :svn, "/opt/local/bin/svn"
17
- class Subversion < Base
18
- # Return an integer identifying the last known revision in the svn
19
- # repository. (This integer is currently the revision number.)
20
- def latest_revision
21
- @latest_revision ||= begin
22
- configuration.logger.debug "querying latest revision..."
23
- match = svn_log(configuration.repository).scan(/r(\d+)/).first or
24
- raise "Could not determine latest revision"
25
- match.first
26
- end
27
- end
28
-
29
- # Return the number of the revision currently deployed.
30
- def current_revision(actor)
31
- latest = actor.releases.last
32
- grep = %(grep " #{latest}$" #{configuration.deploy_to}/revisions.log)
33
- result = ""
34
- actor.run(grep, :once => true) do |ch, str, out|
35
- result << out if str == :out
36
- raise "could not determine current revision" if str == :err
37
- end
38
-
39
- date, time, user, rev, dir = result.split
40
- raise "current revision not found in revisions.log" unless dir == latest
41
-
42
- rev.to_i
43
- end
44
-
45
- # Return a string containing the diff between the two revisions. +from+
46
- # and +to+ may be in any format that svn recognizes as a valid revision
47
- # identifier. If +from+ is +nil+, it defaults to the last deployed
48
- # revision. If +to+ is +nil+, it defaults to HEAD.
49
- def diff(actor, from=nil, to=nil)
50
- from ||= current_revision(actor)
51
- to ||= "HEAD"
52
-
53
- `svn diff #{authorization} #{configuration.repository}@#{from} #{configuration.repository}@#{to}`
54
- end
55
-
56
- # Check out (on all servers associated with the current task) the latest
57
- # revision. Uses the given actor instance to execute the command. If
58
- # svn asks for a password this will automatically provide it (assuming
59
- # the requested password is the same as the password for logging into the
60
- # remote server.)
61
- def checkout(actor)
62
- op = configuration[:checkout] || "co"
63
- command = "#{svn} #{op} #{authorization} -q -r#{configuration.revision} #{configuration.repository} #{actor.release_path} &&"
64
- run_checkout(actor, command, &svn_stream_handler(actor))
65
- end
66
-
67
- # Update the current release in-place. This assumes that the original
68
- # deployment was made using checkout, and not something like export.
69
- def update(actor)
70
- command = "cd #{actor.current_path} && #{svn} up -q &&"
71
- run_update(actor, command, &svn_stream_handler(actor))
72
- end
73
-
74
- private
75
-
76
- def svn
77
- configuration[:svn] || "svn"
78
- end
79
-
80
- def authorization
81
- username = configuration[:svn_username] ? "--username #{configuration[:svn_username]}" : ""
82
- password = configuration[:svn_password] ? "--password #{configuration[:svn_password]}" : ""
83
- no_auth_cache = configuration[:svn_username] || configuration[:svn_password] ? "--no-auth-cache" : ""
84
- "#{no_auth_cache} #{username} #{password}"
85
- end
86
-
87
- def svn_log(path)
88
- `svn log #{authorization} -q --limit 1 #{path}`
89
- end
90
-
91
- def svn_password
92
- configuration[:svn_password] || configuration[:password]
93
- end
94
-
95
- def svn_passphrase
96
- configuration[:svn_passphrase] || svn_password
97
- end
98
-
99
- def svn_stream_handler(actor)
100
- Proc.new do |ch, stream, out|
101
- prefix = "#{stream} :: #{ch[:host]}"
102
- actor.logger.info out, prefix
103
- if out =~ /\bpassword.*:/i
104
- actor.logger.info "subversion is asking for a password", prefix
105
- ch.send_data "#{svn_password}\n"
106
- elsif out =~ %r{\(yes/no\)}
107
- actor.logger.info "subversion is asking whether to connect or not",
108
- prefix
109
- ch.send_data "yes\n"
110
- elsif out =~ %r{passphrase}i
111
- message = "subversion needs your key's passphrase"
112
- actor.logger.info message, prefix
113
- ch.send_data "#{svn_passphrase}\n"
114
- elsif out =~ %r{The entry \'(\w+)\' is no longer a directory}
115
- message = "subversion can't update because directory '#{$1}' was replaced. Please add it to svn:ignore."
116
- actor.logger.info message, prefix
117
- raise message
118
- elsif out =~ %r{accept \(t\)emporarily}
119
- message = "accepting certificate temporarily"
120
- actor.logger.info message, prefix
121
- ch.send_data "t\n"
122
- end
123
- end
124
- end
125
- end
126
-
127
- end
128
- end