capistrano 2.15.11 → 3.0.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (158) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +17 -8
  3. data/Gemfile +1 -12
  4. data/LICENSE.txt +18 -0
  5. data/README.md +65 -68
  6. data/Rakefile +4 -10
  7. data/bin/cap +2 -3
  8. data/bin/capify +7 -91
  9. data/capistrano.gemspec +20 -34
  10. data/lib/Capfile +2 -0
  11. data/lib/capistrano/application.rb +28 -0
  12. data/lib/capistrano/bundler.rb +1 -0
  13. data/lib/capistrano/configuration/question.rb +42 -0
  14. data/lib/capistrano/configuration/server.rb +24 -0
  15. data/lib/capistrano/configuration/servers.rb +43 -95
  16. data/lib/capistrano/configuration.rb +81 -44
  17. data/lib/capistrano/console.rb +1 -0
  18. data/lib/capistrano/defaults.rb +11 -0
  19. data/lib/capistrano/deploy.rb +3 -0
  20. data/lib/capistrano/dotfile.rb +3 -0
  21. data/lib/capistrano/dsl/env.rb +57 -0
  22. data/lib/capistrano/dsl/paths.rb +74 -0
  23. data/lib/capistrano/dsl/stages.rb +15 -0
  24. data/lib/capistrano/dsl/task_enhancements.rb +15 -0
  25. data/lib/capistrano/dsl.rb +38 -0
  26. data/lib/capistrano/git.rb +1 -0
  27. data/lib/capistrano/i18n.rb +33 -0
  28. data/lib/capistrano/install.rb +1 -0
  29. data/lib/capistrano/setup.rb +17 -0
  30. data/lib/capistrano/tasks/bundler.rake +13 -0
  31. data/lib/capistrano/tasks/console.rake +21 -0
  32. data/lib/capistrano/tasks/deploy.rake +153 -0
  33. data/lib/capistrano/tasks/framework.rake +45 -0
  34. data/lib/capistrano/tasks/git.rake +65 -0
  35. data/lib/capistrano/tasks/install.rake +39 -0
  36. data/lib/capistrano/templates/Capfile +43 -0
  37. data/lib/capistrano/templates/deploy.rb.erb +17 -0
  38. data/lib/capistrano/templates/stage.rb.erb +20 -0
  39. data/lib/capistrano/version.rb +1 -11
  40. data/lib/capistrano.rb +9 -3
  41. data/spec/lib/capistrano/configuration/question_spec.rb +54 -0
  42. data/spec/lib/capistrano/configuration/server_spec.rb +48 -0
  43. data/spec/lib/capistrano/configuration/servers_spec.rb +79 -0
  44. data/spec/lib/capistrano/configuration_spec.rb +80 -0
  45. data/spec/lib/capistrano/dsl/env_spec.rb +83 -0
  46. data/spec/lib/capistrano/dsl/paths_spec.rb +69 -0
  47. data/spec/lib/capistrano/dsl_spec.rb +51 -0
  48. data/spec/lib/capistrano_spec.rb +8 -0
  49. data/spec/spec_helper.rb +14 -0
  50. metadata +89 -215
  51. data/.travis.yml +0 -9
  52. data/CHANGELOG +0 -1203
  53. data/lib/capistrano/callback.rb +0 -45
  54. data/lib/capistrano/cli/execute.rb +0 -85
  55. data/lib/capistrano/cli/help.rb +0 -125
  56. data/lib/capistrano/cli/help.txt +0 -81
  57. data/lib/capistrano/cli/options.rb +0 -243
  58. data/lib/capistrano/cli/ui.rb +0 -40
  59. data/lib/capistrano/cli.rb +0 -47
  60. data/lib/capistrano/command.rb +0 -303
  61. data/lib/capistrano/configuration/actions/file_transfer.rb +0 -50
  62. data/lib/capistrano/configuration/actions/inspect.rb +0 -46
  63. data/lib/capistrano/configuration/actions/invocation.rb +0 -329
  64. data/lib/capistrano/configuration/alias_task.rb +0 -26
  65. data/lib/capistrano/configuration/callbacks.rb +0 -147
  66. data/lib/capistrano/configuration/connections.rb +0 -237
  67. data/lib/capistrano/configuration/execution.rb +0 -142
  68. data/lib/capistrano/configuration/loading.rb +0 -205
  69. data/lib/capistrano/configuration/log_formatters.rb +0 -75
  70. data/lib/capistrano/configuration/namespaces.rb +0 -223
  71. data/lib/capistrano/configuration/roles.rb +0 -83
  72. data/lib/capistrano/configuration/variables.rb +0 -127
  73. data/lib/capistrano/errors.rb +0 -19
  74. data/lib/capistrano/ext/multistage.rb +0 -67
  75. data/lib/capistrano/ext/string.rb +0 -5
  76. data/lib/capistrano/extensions.rb +0 -57
  77. data/lib/capistrano/fix_rake_deprecated_dsl.rb +0 -8
  78. data/lib/capistrano/logger.rb +0 -166
  79. data/lib/capistrano/processable.rb +0 -55
  80. data/lib/capistrano/recipes/compat.rb +0 -32
  81. data/lib/capistrano/recipes/deploy/assets.rb +0 -202
  82. data/lib/capistrano/recipes/deploy/dependencies.rb +0 -44
  83. data/lib/capistrano/recipes/deploy/local_dependency.rb +0 -54
  84. data/lib/capistrano/recipes/deploy/remote_dependency.rb +0 -117
  85. data/lib/capistrano/recipes/deploy/scm/accurev.rb +0 -169
  86. data/lib/capistrano/recipes/deploy/scm/base.rb +0 -200
  87. data/lib/capistrano/recipes/deploy/scm/bzr.rb +0 -86
  88. data/lib/capistrano/recipes/deploy/scm/cvs.rb +0 -153
  89. data/lib/capistrano/recipes/deploy/scm/darcs.rb +0 -96
  90. data/lib/capistrano/recipes/deploy/scm/git.rb +0 -299
  91. data/lib/capistrano/recipes/deploy/scm/mercurial.rb +0 -137
  92. data/lib/capistrano/recipes/deploy/scm/none.rb +0 -55
  93. data/lib/capistrano/recipes/deploy/scm/perforce.rb +0 -152
  94. data/lib/capistrano/recipes/deploy/scm/subversion.rb +0 -121
  95. data/lib/capistrano/recipes/deploy/scm.rb +0 -19
  96. data/lib/capistrano/recipes/deploy/strategy/base.rb +0 -92
  97. data/lib/capistrano/recipes/deploy/strategy/checkout.rb +0 -20
  98. data/lib/capistrano/recipes/deploy/strategy/copy.rb +0 -338
  99. data/lib/capistrano/recipes/deploy/strategy/export.rb +0 -20
  100. data/lib/capistrano/recipes/deploy/strategy/remote.rb +0 -52
  101. data/lib/capistrano/recipes/deploy/strategy/remote_cache.rb +0 -57
  102. data/lib/capistrano/recipes/deploy/strategy/unshared_remote_cache.rb +0 -21
  103. data/lib/capistrano/recipes/deploy/strategy.rb +0 -20
  104. data/lib/capistrano/recipes/deploy.rb +0 -625
  105. data/lib/capistrano/recipes/standard.rb +0 -37
  106. data/lib/capistrano/recipes/templates/maintenance.rhtml +0 -53
  107. data/lib/capistrano/role.rb +0 -102
  108. data/lib/capistrano/server_definition.rb +0 -56
  109. data/lib/capistrano/shell.rb +0 -265
  110. data/lib/capistrano/ssh.rb +0 -95
  111. data/lib/capistrano/task_definition.rb +0 -77
  112. data/lib/capistrano/transfer.rb +0 -218
  113. data/test/cli/execute_test.rb +0 -132
  114. data/test/cli/help_test.rb +0 -165
  115. data/test/cli/options_test.rb +0 -329
  116. data/test/cli/ui_test.rb +0 -28
  117. data/test/cli_test.rb +0 -17
  118. data/test/command_test.rb +0 -322
  119. data/test/configuration/actions/file_transfer_test.rb +0 -61
  120. data/test/configuration/actions/inspect_test.rb +0 -76
  121. data/test/configuration/actions/invocation_test.rb +0 -306
  122. data/test/configuration/alias_task_test.rb +0 -118
  123. data/test/configuration/callbacks_test.rb +0 -201
  124. data/test/configuration/connections_test.rb +0 -439
  125. data/test/configuration/execution_test.rb +0 -175
  126. data/test/configuration/loading_test.rb +0 -148
  127. data/test/configuration/namespace_dsl_test.rb +0 -332
  128. data/test/configuration/roles_test.rb +0 -157
  129. data/test/configuration/servers_test.rb +0 -183
  130. data/test/configuration/variables_test.rb +0 -190
  131. data/test/configuration_test.rb +0 -77
  132. data/test/deploy/local_dependency_test.rb +0 -76
  133. data/test/deploy/remote_dependency_test.rb +0 -146
  134. data/test/deploy/scm/accurev_test.rb +0 -23
  135. data/test/deploy/scm/base_test.rb +0 -55
  136. data/test/deploy/scm/bzr_test.rb +0 -51
  137. data/test/deploy/scm/darcs_test.rb +0 -37
  138. data/test/deploy/scm/git_test.rb +0 -274
  139. data/test/deploy/scm/mercurial_test.rb +0 -134
  140. data/test/deploy/scm/none_test.rb +0 -35
  141. data/test/deploy/scm/perforce_test.rb +0 -23
  142. data/test/deploy/scm/subversion_test.rb +0 -68
  143. data/test/deploy/strategy/copy_test.rb +0 -360
  144. data/test/extensions_test.rb +0 -69
  145. data/test/fixtures/cli_integration.rb +0 -5
  146. data/test/fixtures/config.rb +0 -5
  147. data/test/fixtures/custom.rb +0 -3
  148. data/test/logger_formatting_test.rb +0 -149
  149. data/test/logger_test.rb +0 -134
  150. data/test/recipes_test.rb +0 -25
  151. data/test/role_test.rb +0 -11
  152. data/test/server_definition_test.rb +0 -121
  153. data/test/shell_test.rb +0 -96
  154. data/test/ssh_test.rb +0 -113
  155. data/test/task_definition_test.rb +0 -117
  156. data/test/transfer_test.rb +0 -168
  157. data/test/utils.rb +0 -37
  158. data/test/version_test.rb +0 -11
@@ -1,169 +0,0 @@
1
- require 'capistrano/recipes/deploy/scm/base'
2
- require 'rexml/xpath'
3
- require 'rexml/document'
4
-
5
- module Capistrano
6
- module Deploy
7
- module SCM
8
- # Accurev bridge for use by Capistrano. This implementation does not
9
- # implement all features of a Capistrano SCM module. The ones that are
10
- # left out are either exceedingly difficult to implement with Accurev
11
- # or are considered bad form.
12
- #
13
- # When using this module in a project, the following variables are used:
14
- # * :repository - This should match the depot that code lives in. If your code
15
- # exists in a subdirectory, you can append the path depot.
16
- # eg. foo-depot/bar_dir
17
- # * :stream - The stream in the depot that code should be pulled from. If
18
- # left blank, the depot stream will be used
19
- # * :revision - Should be in the form 'stream/transaction'.
20
- class Accurev < Base
21
- include REXML
22
- default_command 'accurev'
23
-
24
- # Defines pseudo-revision value for the most recent changes to be deployed.
25
- def head
26
- "#{stream}/highest"
27
- end
28
-
29
- # Given an Accurev revision identifier, this method returns an identifier that
30
- # can be used for later SCM calls. This returned identifier will not
31
- # change as a result of further SCM activity.
32
- def query_revision(revision)
33
- internal_revision = InternalRevision.parse(revision)
34
- return revision unless internal_revision.psuedo_revision?
35
-
36
- logger.debug("Querying for real revision for #{internal_revision}")
37
- rev_stream = internal_revision.stream
38
-
39
- logger.debug("Determining what type of stream #{rev_stream} is...")
40
- stream_xml = yield show_streams_for(rev_stream)
41
- stream_doc = Document.new(stream_xml)
42
- type = XPath.first(stream_doc, '//streams/stream/@type').value
43
-
44
- case type
45
- when 'snapshot'
46
- InternalRevision.new(rev_stream, 'highest').to_s
47
- else
48
- logger.debug("Getting latest transaction id in #{rev_stream}")
49
- # Doing another yield for a second Accurev call. Hopefully this is ok.
50
- hist_xml = yield scm(:hist, '-ftx', '-s', rev_stream, '-t', 'now.1')
51
- hist_doc = Document.new(hist_xml)
52
- transaction_id = XPath.first(hist_doc, '//AcResponse/transaction/@id').value
53
- InternalRevision.new(stream, transaction_id).to_s
54
- end
55
- end
56
-
57
- # Pops a copy of the code for the specified Accurev revision identifier.
58
- # The revision identifier is represented as a stream & transaction ID combo.
59
- # Accurev can only pop a particular transaction if a stream is created on the server
60
- # with a time basis of that transaction id. Therefore, we will create a stream with
61
- # the required criteria and pop that.
62
- def export(revision_id, destination)
63
- revision = InternalRevision.parse(revision_id)
64
- logger.debug("Exporting #{revision.stream}/#{revision.transaction_id} to #{destination}")
65
-
66
- commands = [
67
- change_or_create_stream("#{revision.stream}-capistrano-deploy", revision),
68
- "mkdir -p #{destination}",
69
- scm_quiet(:pop, "-Rv #{stream}", "-L #{destination}", "'/./#{subdir}'")
70
- ]
71
- if subdir
72
- commands.push(
73
- "mv #{destination}/#{subdir}/* #{destination}",
74
- "rm -rf #{File.join(destination, subdir)}"
75
- )
76
- end
77
- commands.join(' && ')
78
- end
79
-
80
- # Returns the command needed to show the changes that exist between the two revisions.
81
- def log(from, to=head)
82
- logger.info("Getting transactions between #{from} and #{to}")
83
- from_rev = InternalRevision.parse(from)
84
- to_rev = InternalRevision.parse(to)
85
-
86
- [
87
- scm(:hist, '-s', from_rev.stream, '-t', "#{to_rev.transaction_id}-#{from_rev.transaction_id}"),
88
- "sed -e '/transaction #{from_rev.transaction_id}/ { Q }'"
89
- ].join(' | ')
90
- end
91
-
92
- # Returns the command needed to show the diff between what is deployed and what is
93
- # pending. Because Accurev can not do this task without creating some streams,
94
- # two time basis streams will be created for the purposes of doing the diff.
95
- def diff(from, to=head)
96
- from = InternalRevision.parse(from)
97
- to = InternalRevision.parse(to)
98
-
99
- from_stream = "#{from.stream}-capistrano-diff-from"
100
- to_stream = "#{to.stream}-capistrano-diff-to"
101
-
102
- [
103
- change_or_create_stream(from_stream, from),
104
- change_or_create_stream(to_stream, to),
105
- scm(:diff, '-v', from_stream, '-V', to_stream, '-a')
106
- ].join(' && ')
107
- end
108
-
109
- private
110
- def depot
111
- repository.split('/')[0]
112
- end
113
-
114
- def stream
115
- variable(:stream) || depot
116
- end
117
-
118
- def subdir
119
- repository.split('/')[1..-1].join('/') unless repository.index('/').nil?
120
- end
121
-
122
- def change_or_create_stream(name, revision)
123
- [
124
- scm_quiet(:mkstream, '-b', revision.stream, '-s', name, '-t', revision.transaction_id),
125
- scm_quiet(:chstream, '-b', revision.stream, '-s', name, '-t', revision.transaction_id)
126
- ].join('; ')
127
- end
128
-
129
- def show_streams_for(stream)
130
- scm :show, '-fx', '-s', stream, :streams
131
- end
132
-
133
- def scm_quiet(*args)
134
- scm(*args) + (variable(:scm_verbose) ? '' : '&> /dev/null')
135
- end
136
-
137
- class InternalRevision
138
- attr_reader :stream, :transaction_id
139
-
140
- def self.parse(string)
141
- match = /([^\/]+)(\/(.+)){0,1}/.match(string)
142
- raise "Unrecognized revision identifier: #{string}" unless match
143
-
144
- stream = match[1]
145
- transaction_id = match[3] || 'highest'
146
- InternalRevision.new(stream, transaction_id)
147
- end
148
-
149
- def initialize(stream, transaction_id)
150
- @stream = stream
151
- @transaction_id = transaction_id
152
- end
153
-
154
- def psuedo_revision?
155
- @transaction_id == 'highest'
156
- end
157
-
158
- def to_s
159
- "#{stream}/#{transaction_id}"
160
- end
161
-
162
- def ==(other)
163
- (stream == other.stream) && (transaction_id == other.transaction_id)
164
- end
165
- end
166
- end
167
- end
168
- end
169
- end
@@ -1,200 +0,0 @@
1
- module Capistrano
2
- module Deploy
3
- module SCM
4
-
5
- # The ancestor class for all Capistrano SCM implementations. It provides
6
- # minimal infrastructure for subclasses to build upon and override.
7
- #
8
- # Note that subclasses that implement this abstract class only return
9
- # the commands that need to be executed--they do not execute the commands
10
- # themselves. In this way, the deployment method may execute the commands
11
- # either locally or remotely, as necessary.
12
- class Base
13
- class << self
14
- # If no parameters are given, it returns the current configured
15
- # name of the command-line utility of this SCM. If a parameter is
16
- # given, the defeault command is set to that value.
17
- def default_command(value=nil)
18
- if value
19
- @default_command = value
20
- else
21
- @default_command
22
- end
23
- end
24
- end
25
-
26
- # Wraps an SCM instance and forces all messages sent to it to be
27
- # relayed to the underlying SCM instance, in "local" mode. See
28
- # Base#local.
29
- class LocalProxy
30
- def initialize(scm)
31
- @scm = scm
32
- end
33
-
34
- def method_missing(sym, *args, &block)
35
- @scm.local { return @scm.send(sym, *args, &block) }
36
- end
37
- end
38
-
39
- # The options available for this SCM instance to reference. Should be
40
- # treated like a hash.
41
- attr_reader :configuration
42
-
43
- # Creates a new SCM instance with the given configuration options.
44
- def initialize(configuration={})
45
- @configuration = configuration
46
- end
47
-
48
- # Returns a proxy that wraps the SCM instance and forces it to operate
49
- # in "local" mode, which changes how variables are looked up in the
50
- # configuration. Normally, if the value of a variable "foo" is needed,
51
- # it is queried for in the configuration as "foo". However, in "local"
52
- # mode, first "local_foo" would be looked for, and only if it is not
53
- # found would "foo" be used. This allows for both (e.g.) "scm_command"
54
- # and "local_scm_command" to be set, if the two differ.
55
- #
56
- # Alternatively, it may be called with a block, and for the duration of
57
- # the block, all requests on this configuration object will be
58
- # considered local.
59
- def local
60
- if block_given?
61
- begin
62
- saved, @local_mode = @local_mode, true
63
- yield
64
- ensure
65
- @local_mode = saved
66
- end
67
- else
68
- LocalProxy.new(self)
69
- end
70
- end
71
-
72
- # Returns true if running in "local" mode. See #local.
73
- def local?
74
- @local_mode
75
- end
76
-
77
- # Returns the string used to identify the latest revision in the
78
- # repository. This will be passed as the "revision" parameter of
79
- # the methods below.
80
- def head
81
- raise NotImplementedError, "`head' is not implemented by #{self.class.name}"
82
- end
83
-
84
- # Checkout a copy of the repository, at the given +revision+, to the
85
- # given +destination+. The checkout is suitable for doing development
86
- # work in, e.g. allowing subsequent commits and updates.
87
- def checkout(revision, destination)
88
- raise NotImplementedError, "`checkout' is not implemented by #{self.class.name}"
89
- end
90
-
91
- # Resynchronize the working copy in +destination+ to the specified
92
- # +revision+.
93
- def sync(revision, destination)
94
- raise NotImplementedError, "`sync' is not implemented by #{self.class.name}"
95
- end
96
-
97
- # Compute the difference between the two revisions, +from+ and +to+.
98
- def diff(from, to=nil)
99
- raise NotImplementedError, "`diff' is not implemented by #{self.class.name}"
100
- end
101
-
102
- # Return a log of all changes between the two specified revisions,
103
- # +from+ and +to+, inclusive.
104
- def log(from, to=nil)
105
- raise NotImplementedError, "`log' is not implemented by #{self.class.name}"
106
- end
107
-
108
- # If the given revision represents a "real" revision, this should
109
- # simply return the revision value. If it represends a pseudo-revision
110
- # (like Subversions "HEAD" identifier), it should yield a string
111
- # containing the commands that, when executed will return a string
112
- # that this method can then extract the real revision from.
113
- def query_revision(revision)
114
- raise NotImplementedError, "`query_revision' is not implemented by #{self.class.name}"
115
- end
116
-
117
- # Returns the revision number immediately following revision, if at
118
- # all possible. A block should always be passed to this method, which
119
- # accepts a command to invoke and returns the result, although a
120
- # particular SCM's implementation is not required to invoke the block.
121
- #
122
- # By default, this method simply returns the revision itself. If a
123
- # particular SCM is able to determine a subsequent revision given a
124
- # revision identifier, it should override this method.
125
- def next_revision(revision)
126
- revision
127
- end
128
-
129
- # Should analyze the given text and determine whether or not a
130
- # response is expected, and if so, return the appropriate response.
131
- # If no response is expected, return nil. The +state+ parameter is a
132
- # hash that may be used to preserve state between calls. This method
133
- # is used to define how Capistrano should respond to common prompts
134
- # and messages from the SCM, like password prompts and such. By
135
- # default, the output is simply displayed.
136
- def handle_data(state, stream, text)
137
- logger.info "[#{stream}] #{text}"
138
- nil
139
- end
140
-
141
- # Returns the name of the command-line utility for this SCM. It first
142
- # looks at the :scm_command variable, and if it does not exist, it
143
- # then falls back to whatever was defined by +default_command+.
144
- #
145
- # If scm_command is set to :default, the default_command will be
146
- # returned.
147
- def command
148
- command = variable(:scm_command)
149
- command = nil if command == :default
150
- command || default_command
151
- end
152
-
153
- # A helper method that can be used to define SCM commands naturally.
154
- # It returns a single string with all arguments joined by spaces,
155
- # with the scm command prefixed onto it.
156
- def scm(*args)
157
- [command, *args].compact.join(" ")
158
- end
159
-
160
- private
161
-
162
- # A helper for accessing variable values, which takes into
163
- # consideration the current mode ("normal" vs. "local").
164
- def variable(name, default = nil)
165
- if local? && configuration.exists?("local_#{name}".to_sym)
166
- return configuration["local_#{name}".to_sym].nil? ? default : configuration["local_#{name}".to_sym]
167
- else
168
- configuration[name].nil? ? default : configuration[name]
169
- end
170
- end
171
-
172
- # A reference to a Logger instance that the SCM can use to log
173
- # activity.
174
- def logger
175
- @logger ||= variable(:logger) || Capistrano::Logger.new(:output => STDOUT)
176
- end
177
-
178
- # A helper for accessing the default command name for this SCM. It
179
- # simply delegates to the class' +default_command+ method.
180
- def default_command
181
- self.class.default_command
182
- end
183
-
184
- # A convenience method for accessing the declared repository value.
185
- def repository
186
- variable(:repository)
187
- end
188
-
189
- def arguments(command = :all)
190
- value = variable(:scm_arguments)
191
- if value.is_a?(Hash)
192
- value = value[command]
193
- end
194
- value
195
- end
196
- end
197
-
198
- end
199
- end
200
- end
@@ -1,86 +0,0 @@
1
- require 'capistrano/recipes/deploy/scm/base'
2
-
3
- module Capistrano
4
- module Deploy
5
- module SCM
6
-
7
- # Implements the Capistrano SCM interface for the Bazaar-NG revision
8
- # control system (http://bazaar-vcs.org/).
9
- class Bzr < Base
10
- # Sets the default command name for this SCM. Users may override this
11
- # by setting the :scm_command variable.
12
- default_command "bzr"
13
-
14
- # Bazaar-NG doesn't support any pseudo-id's, so we'll use the convention
15
- # in this adapter that the :head symbol means the most recently
16
- # committed revision.
17
- def head
18
- :head
19
- end
20
-
21
- # Returns the command that will check out the given revision to the
22
- # given destination.
23
- def checkout(revision, destination)
24
- scm :checkout, "--lightweight", revswitch(revision), repository, destination
25
- end
26
-
27
- # The bzr 'update' command does not support updating to a specific
28
- # revision, so this just does update, followed by revert (unless
29
- # updating to head).
30
- def sync(revision, destination)
31
- commands = [scm(:update, destination)]
32
- commands << [scm(:revert, revswitch(revision), destination)] if revision != head
33
- commands.join(" && ")
34
- end
35
-
36
- # The bzr 'export' does an export similar to other SCM systems
37
- def export(revision, destination)
38
- scm :export, revswitch(revision), destination, repository
39
- end
40
-
41
- # The bzr "diff" command doesn't accept a repository argument, so it
42
- # must be run from within a working tree.
43
- def diff(from, to=nil)
44
- switch = "-r#{from}"
45
- switch << "..#{to}" if to
46
-
47
- scm :diff, switch
48
- end
49
-
50
- # Returns a log of changes between the two revisions (inclusive).
51
- def log(from, to=nil)
52
- scm :log, "--short", "-r#{from}..#{to}", repository
53
- end
54
-
55
- # Attempts to translate the given revision identifier to a "real"
56
- # revision. If the identifier is :head, the "bzr revno" command will
57
- # be yielded, and the block must execute the command and return the
58
- # output. The revision will be extracted from the output and returned.
59
- # If the 'revision' argument, on the other hand, is not :head, it is
60
- # simply returned.
61
- def query_revision(revision)
62
- return revision unless :head == revision
63
-
64
- command = scm('revno', repository)
65
- result = yield(command)
66
- end
67
-
68
- # Increments the given revision number and returns it.
69
- def next_revision(revision)
70
- revision.to_i + 1
71
- end
72
-
73
- private
74
-
75
- def revswitch(revision)
76
- if revision == :head || revision.nil?
77
- nil
78
- else
79
- "-r #{revision}".chomp
80
- end
81
- end
82
- end
83
-
84
- end
85
- end
86
- end
@@ -1,153 +0,0 @@
1
- require 'capistrano/recipes/deploy/scm/base'
2
-
3
- module Capistrano
4
- module Deploy
5
- module SCM
6
-
7
- # Implements the Capistrano SCM interface for the CVS revision
8
- # control system.
9
- class Cvs < Base
10
- # Sets the default command name for this SCM. Users may override this
11
- # by setting the :scm_command variable.
12
- default_command "cvs"
13
-
14
- # CVS understands 'HEAD' to refer to the latest revision in the
15
- # repository.
16
- def head
17
- "HEAD"
18
- end
19
-
20
- # Returns the command that will check out the given revision to the
21
- # given destination.
22
- def checkout(revision, destination)
23
- [ prep_destination(destination),
24
- scm(verbose, cvs_root, :checkout, cvs_revision(revision), cvs_destination(destination), variable(:scm_module))
25
- ].join(' && ')
26
- end
27
-
28
- # Returns the command that will do an "cvs update" to the given
29
- # revision, for the working copy at the given destination.
30
- def sync(revision, destination)
31
- [ prep_destination(destination),
32
- scm(verbose, cvs_root, :update, cvs_revision(revision), cvs_destination(destination))
33
- ].join(' && ')
34
- end
35
-
36
- # Returns the command that will do an "cvs export" of the given revision
37
- # to the given destination.
38
- def export(revision, destination)
39
- [ prep_destination(destination),
40
- scm(verbose, cvs_root, :export, cvs_revision(revision), cvs_destination(destination), variable(:scm_module))
41
- ].join(' && ')
42
- end
43
-
44
- # Returns the command that will do an "cvs diff" for the two revisions.
45
- def diff(from, to=nil)
46
- rev_type = revision_type(from)
47
- if rev_type == :date
48
- range_args = "-D '#{from}' -D '#{to || 'now'}'"
49
- else
50
- range_args = "-r '#{from}' -r '#{to || head}'"
51
- end
52
- scm cvs_root, :diff, range_args
53
- end
54
-
55
- # Returns an "cvs log" command for the two revisions.
56
- def log(from, to=nil)
57
- rev_type = revision_type(from)
58
- if rev_type == :date
59
- range_arg = "-d '#{from}<#{to || 'now'}'"
60
- else
61
- range_arg = "-r '#{from}:#{to || head}'"
62
- end
63
- scm cvs_root, :log, range_arg
64
- end
65
-
66
- # Unfortunately, cvs doesn't support the concept of a revision number like
67
- # subversion and other SCM's do. For now, we'll rely on getting the timestamp
68
- # of the latest checkin under the revision that's passed to us.
69
- def query_revision(revision)
70
- return revision if revision_type(revision) == :date
71
- revision = yield(scm(cvs_root, :log, "-r#{revision}")).
72
- split("\n").
73
- select { |line| line =~ /^date:/ }.
74
- map { |line| line[/^date: (.*?);/, 1] }.
75
- sort.last + " UTC"
76
- return revision
77
- end
78
-
79
- # Determines what the response should be for a particular bit of text
80
- # from the SCM. Password prompts, connection requests, passphrases,
81
- # etc. are handled here.
82
- def handle_data(state, stream, text)
83
- logger.info "[#{stream}] #{text}"
84
- case text
85
- when /\bpassword.*:/i
86
- # prompting for a password
87
- %("#{variable(:scm_password) || variable(:password)}"\n)
88
- when %r{\(yes/no\)}
89
- # let's be agreeable...
90
- "yes\n"
91
- end
92
- end
93
-
94
- private
95
-
96
- # Constructs the CVSROOT command-line option
97
- def cvs_root
98
- root = ""
99
- root << "-d #{repository} " if repository
100
- root
101
- end
102
-
103
- # Constructs the destination dir command-line option
104
- def cvs_destination(destination)
105
- dest = ""
106
- if destination
107
- dest_parts = destination.split(/\//);
108
- dest << "-d #{dest_parts.pop}"
109
- end
110
- dest
111
- end
112
-
113
- # attempts to guess what type of revision we're working with
114
- def revision_type(rev)
115
- return :date if rev =~ /^\d{4}\/\d{2}\/\d{2} \d{2}:\d{2}:\d{2} UTC$/ # i.e 2007-05-15 08:13:25 UTC
116
- return :date if rev =~ /^\d{4}\/\d{2}\/\d{2} \d{2}:\d{2}:\d{2}$/ # i.e 2007-05-15 08:13:25
117
- return :revision if rev =~ /^\d/ # i.e. 1.2.1
118
- return :tag # i.e. RELEASE_1_2
119
- end
120
-
121
- # constructs the appropriate command-line switch for specifying a
122
- # "revision" in CVS. This could be a tag, branch, revision (i.e. 1.3)
123
- # or a date (to be used with -d)
124
- def cvs_revision(rev)
125
- revision = ""
126
- revision << case revision_type(rev)
127
- when :date
128
- "-D \"#{rev}\"" if revision_type(rev) == :date
129
- when :revision
130
- "-r #{rev}"
131
- else
132
- "-r #{head}"
133
- end
134
- return revision
135
- end
136
-
137
- # If verbose output is requested, return nil, otherwise return the
138
- # command-line switch for "quiet" ("-Q").
139
- def verbose
140
- variable(:scm_verbose) ? nil : "-Q"
141
- end
142
-
143
- def prep_destination(destination)
144
- dest_parts = destination.split(/\//);
145
- checkout_dir = dest_parts.pop
146
- dest = dest_parts.join('/')
147
- "mkdir -p #{ dest } && cd #{ dest }"
148
- end
149
- end
150
-
151
- end
152
- end
153
- end