capistrano 1.4.2 → 2.0.0

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