rscm 0.4.5 → 0.5.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.
- data/CHANGES +12 -0
- data/README +14 -0
- data/Rakefile +4 -24
- data/lib/rscm.rb +1 -2
- data/lib/rscm/base.rb +289 -281
- data/lib/rscm/command_line.rb +135 -112
- data/lib/rscm/revision.rb +63 -166
- data/lib/rscm/revision_file.rb +8 -2
- data/lib/rscm/revision_poller.rb +78 -67
- data/lib/rscm/revisions.rb +79 -0
- data/lib/rscm/scm/clearcase.rb +11 -9
- data/lib/rscm/scm/cvs.rb +374 -352
- data/lib/rscm/scm/cvs_log_parser.rb +1 -0
- data/lib/rscm/scm/darcs.rb +9 -0
- data/lib/rscm/scm/perforce.rb +216 -149
- data/lib/rscm/scm/subversion.rb +44 -24
- data/lib/rscm/scm/subversion_log_parser.rb +37 -51
- data/lib/rscm/time_ext.rb +0 -1
- data/lib/rscm/version.rb +2 -2
- data/test/rscm/command_line_test.rb +7 -5
- data/test/rscm/compatibility/config.yml +4 -4
- data/test/rscm/compatibility/cvs_metaproject/diff.txt +52 -0
- data/test/rscm/compatibility/cvs_metaproject/file.txt +48 -0
- data/test/rscm/compatibility/cvs_metaproject/old.yml +13 -0
- data/test/rscm/compatibility/full.rb +2 -223
- data/test/rscm/compatibility/p4_gfx/files_0.yml +10 -0
- data/test/rscm/compatibility/p4_gfx/old.yml +26 -0
- data/test/rscm/compatibility/p4_gfx/revisions.yml +24 -0
- data/test/rscm/compatibility/p4_gfx/scm.yml +4 -0
- data/test/rscm/compatibility/rscm_engine.rb +197 -0
- data/test/rscm/compatibility/subversion_rscm/diff.txt +12 -0
- data/test/rscm/compatibility/subversion_rscm/file.txt +567 -0
- data/test/rscm/compatibility/subversion_rscm/old.yml +14 -0
- data/test/rscm/compatibility/subversion_rscm/revisions.yml +17 -0
- data/test/rscm/compatibility/subversion_rscm/scm.yml +1 -0
- data/test/rscm/revision_file_test.rb +10 -0
- data/test/rscm/revision_poller_test.rb +91 -0
- data/test/rscm/revision_test.rb +22 -117
- data/test/rscm/revisions_test.rb +80 -0
- data/test/rscm/scm/cvs_log_parser_test.rb +569 -567
- data/test/rscm/scm/cvs_test.rb +6 -3
- data/test/rscm/scm/darcs_test.rb +4 -7
- data/test/rscm/scm/perforce_test.rb +6 -2
- data/test/rscm/scm/star_team_test.rb +10 -0
- data/test/rscm/scm/subversion_log_parser_test.rb +38 -5
- data/test/rscm/scm/subversion_test.rb +2 -3
- data/test/rscm/test_helper.rb +41 -2
- data/testproject/damagecontrolled/build.xml +154 -154
- data/testproject/damagecontrolled/src/java/com/thoughtworks/damagecontrolled/Thingy.java +6 -6
- metadata +19 -7
- data/lib/rscm/historic_file.rb +0 -30
- data/test/rscm/compatibility/damage_control_minimal.rb +0 -104
- data/test/rscm/revision_fixture.rb +0 -20
- data/test/rscm/revisions.yaml +0 -42
- data/test/rscm/scm/star_team.rb +0 -36
data/CHANGES
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
= RSCM Changelog
|
2
2
|
|
3
|
+
== 0.5.0
|
4
|
+
This release improves command line and logging, as well as improved support for slurping all historic revisions incrementally (to save memory). The latter will be improved in upcoming versions.
|
5
|
+
|
6
|
+
* Diffing and opening specific files is now part of the rscm_engine/damagecontrol compatibility test
|
7
|
+
* The interface of RSCM::Base.diff has changed to take a path and two revision identifiers.
|
8
|
+
* Different timezones for client and server are now (hopefully) properly handled for Perforce.
|
9
|
+
* Made RSCM::Base.execute not do a chdir unless it's needed (makes direct usage from a Rails app more feasable).
|
10
|
+
* Fixed broken pipe error for CVS triggers.
|
11
|
+
* Store the commandline used to retrieve revisions in the Revisions object (useful for debugging).
|
12
|
+
* New RSCM::Base.poll method that yields revisions incrementally from a start date (backwards or forwards in time).
|
13
|
+
* Removed RSCM::Base.file and RSCM::HistoricFile - too hard to implement correctly across SCMs and too little value.
|
14
|
+
|
3
15
|
== 0.4.5
|
4
16
|
This is a minor bugfix release that corrects the tests for command_line.rb to work on win32
|
5
17
|
|
data/README
CHANGED
@@ -173,6 +173,20 @@ in modification time, commit message and developer.
|
|
173
173
|
This file should contain the files that will be in the working copy after a checkout of the 1st revision in revisions.yml,
|
174
174
|
sorted by their path.
|
175
175
|
|
176
|
+
=== Create old.yml
|
177
|
+
This file should contain a start time and all the revision identifiers before that time.
|
178
|
+
The start time should be a carefully selected timestamp close to the start of the scm.
|
179
|
+
"identifiers" should be a list of all identifiers from the beginning of time up until
|
180
|
+
the start identifier.
|
181
|
+
|
182
|
+
=== Create diff.txt
|
183
|
+
This file should contain a diff. It should be the diff of the first revision file in revisions.yml -
|
184
|
+
between its native_revision_identifier and the previous_revision_identifier.
|
185
|
+
|
186
|
+
=== Create file.txt
|
187
|
+
This file should contain the contents of the first revision file in revisions.yml (at the revision
|
188
|
+
specified by native_revision_identifier).
|
189
|
+
|
176
190
|
== Implement the methods
|
177
191
|
Now that we have set up everything needed for the tests, we can run the tests again:
|
178
192
|
|
data/Rakefile
CHANGED
@@ -13,23 +13,16 @@ PKG_NAME = 'rscm'
|
|
13
13
|
PKG_VERSION = RSCM::VERSION::STRING + PKG_BUILD
|
14
14
|
PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
|
15
15
|
|
16
|
-
desc "Default Task"
|
17
16
|
task :default => [:test, :gem]
|
18
|
-
#task :gem => [:test]
|
19
|
-
task :test => [:starteam]
|
20
17
|
|
21
18
|
# Run the unit tests
|
22
19
|
# To run a specific test: rake test TEST=path/to/test
|
23
20
|
fl = FileList.new('test/**/*_test.rb')
|
24
21
|
fl.exclude('test/**/mooky*.rb')
|
25
|
-
fl.exclude('test/**/monotone*.rb')
|
26
|
-
fl.exclude('test/**/clearcase*.rb')
|
27
|
-
fl.exclude('test/**/
|
28
|
-
|
29
|
-
#fl.exclude('test/**/subversion*.rb') # Incomplete/unsupported for now - reactivate when more complete!
|
30
|
-
fl.exclude('test/**/perforce*.rb') # Incomplete/unsupported for now - reactivate when more complete!
|
31
|
-
fl.exclude('test/**/p4client*.rb') # Incomplete/unsupported for now - reactivate when more complete!
|
32
|
-
fl.exclude('test/**/starteam*.rb') # Too bloody hard to test without a StarTeam server license! Tested ad-hoc.
|
22
|
+
fl.exclude('test/**/monotone*.rb')
|
23
|
+
fl.exclude('test/**/clearcase*.rb')
|
24
|
+
fl.exclude('test/**/p4client*.rb')
|
25
|
+
fl.exclude('test/**/darcs*.rb')
|
33
26
|
Rake::TestTask.new { |t|
|
34
27
|
t.libs << "test"
|
35
28
|
t.test_files = fl
|
@@ -48,19 +41,6 @@ rd = Rake::RDocTask.new { |rdoc|
|
|
48
41
|
rdoc.rdoc_files.include('docs/**/*.rd')
|
49
42
|
}
|
50
43
|
|
51
|
-
task :starteam do |t|
|
52
|
-
if(!ENV['RSCM_STARTEAM'])
|
53
|
-
puts "WARNING - NOT BUILDING STARTEAM SUPPORT SINCE 'RSCM_STARTEAM' IS NOT DEFINED. It should point to the StarTeam SDK directory"
|
54
|
-
else
|
55
|
-
ant = RUBY_PLATFORM == "i386-mswin32" ? "ant.bat" : system("which ant.sh") ? "ant.sh" : "ant"
|
56
|
-
IO.popen("#{ant} -f ext/java/build.xml clean jar") do |io|
|
57
|
-
io.each_line do |line|
|
58
|
-
puts line
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
44
|
PKG_FILES = FileList[
|
65
45
|
'[A-Z]*',
|
66
46
|
'lib/**/*',
|
data/lib/rscm.rb
CHANGED
@@ -1,12 +1,11 @@
|
|
1
|
+
require 'rscm/revision_poller'
|
1
2
|
require 'rscm/path_converter'
|
2
3
|
require 'rscm/difftool'
|
3
4
|
require 'rscm/platform'
|
4
5
|
require 'rscm/command_line'
|
5
6
|
require 'rscm/base'
|
6
7
|
require 'rscm/revision'
|
7
|
-
require 'rscm/revision_poller'
|
8
8
|
require 'rscm/revision_file'
|
9
|
-
require 'rscm/historic_file'
|
10
9
|
require 'rscm/time_ext'
|
11
10
|
# Load all sources under scm
|
12
11
|
Dir[File.dirname(__FILE__) + "/rscm/scm/*.rb"].each do |src|
|
data/lib/rscm/base.rb
CHANGED
@@ -1,281 +1,289 @@
|
|
1
|
-
require 'fileutils'
|
2
|
-
require 'rscm/revision'
|
3
|
-
require 'rscm/path_converter'
|
4
|
-
|
5
|
-
module RSCM
|
6
|
-
# This class defines the RSCM API, which offers access to an SCM working copy
|
7
|
-
# as well as a 'central' repository.
|
8
|
-
#
|
9
|
-
# Concrete subclasses of this class (concrete adapters) implement the integration
|
10
|
-
# with the respective SCMs.
|
11
|
-
#
|
12
|
-
# Most of the methods take an optional +options+ Hash (named parameters), allowing
|
13
|
-
# the following options:
|
14
|
-
#
|
15
|
-
# * <tt>:stdout</tt>: Path to file name where stdout of SCM operations are written.
|
16
|
-
# * <tt>:stdout</tt>: Path to file name where stderr of SCM operations are written.
|
17
|
-
#
|
18
|
-
# In stead of specifying the +options+ parameters for every API method, it's possible
|
19
|
-
# to assign default options via the +default_options+ attribute.
|
20
|
-
#
|
21
|
-
# Some of the methods in this API use +from_identifier+ and +to_identifier+.
|
22
|
-
# These identifiers can be either a UTC Time (according to the SCM's clock)
|
23
|
-
# or a String or Integer representing a label/revision
|
24
|
-
# (according to the SCM's native label/revision scheme).
|
25
|
-
#
|
26
|
-
# If +from_identifier+ or +to_identifier+ are +nil+ they should respectively default to
|
27
|
-
# Time.epoch or Time.infinite.
|
28
|
-
#
|
29
|
-
class Base
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
def
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
#
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
#
|
90
|
-
#
|
91
|
-
# it
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
#
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
#
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
#
|
137
|
-
#
|
138
|
-
#
|
139
|
-
#
|
140
|
-
#
|
141
|
-
#
|
142
|
-
#
|
143
|
-
#
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
#
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
#
|
190
|
-
#
|
191
|
-
#
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
#
|
198
|
-
#
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
#
|
205
|
-
|
206
|
-
|
207
|
-
#
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
#
|
219
|
-
#
|
220
|
-
#
|
221
|
-
#
|
222
|
-
#
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
#
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
#
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
#
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
#
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
#
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
self.
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
1
|
+
require 'fileutils'
|
2
|
+
require 'rscm/revision'
|
3
|
+
require 'rscm/path_converter'
|
4
|
+
|
5
|
+
module RSCM
|
6
|
+
# This class defines the RSCM API, which offers access to an SCM working copy
|
7
|
+
# as well as a 'central' repository.
|
8
|
+
#
|
9
|
+
# Concrete subclasses of this class (concrete adapters) implement the integration
|
10
|
+
# with the respective SCMs.
|
11
|
+
#
|
12
|
+
# Most of the methods take an optional +options+ Hash (named parameters), allowing
|
13
|
+
# the following options:
|
14
|
+
#
|
15
|
+
# * <tt>:stdout</tt>: Path to file name where stdout of SCM operations are written.
|
16
|
+
# * <tt>:stdout</tt>: Path to file name where stderr of SCM operations are written.
|
17
|
+
#
|
18
|
+
# In stead of specifying the +options+ parameters for every API method, it's possible
|
19
|
+
# to assign default options via the +default_options+ attribute.
|
20
|
+
#
|
21
|
+
# Some of the methods in this API use +from_identifier+ and +to_identifier+.
|
22
|
+
# These identifiers can be either a UTC Time (according to the SCM's clock)
|
23
|
+
# or a String or Integer representing a label/revision
|
24
|
+
# (according to the SCM's native label/revision scheme).
|
25
|
+
#
|
26
|
+
# If +from_identifier+ or +to_identifier+ are +nil+ they should respectively default to
|
27
|
+
# Time.epoch or Time.infinite.
|
28
|
+
#
|
29
|
+
class Base
|
30
|
+
include RevisionPoller
|
31
|
+
|
32
|
+
attr_writer :default_options
|
33
|
+
attr_writer :store_revisions_command
|
34
|
+
|
35
|
+
def default_options
|
36
|
+
@default_options ||= {}
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns true if the underlying SCM tool is available on this system.
|
40
|
+
def available?
|
41
|
+
raise NotImplementedError
|
42
|
+
end
|
43
|
+
|
44
|
+
# Transforms +raw_identifier+ into the native rype used for revisions.
|
45
|
+
def to_identifier(raw_identifier)
|
46
|
+
raw_identifier.to_s
|
47
|
+
end
|
48
|
+
|
49
|
+
# Sets the checkout dir (working copy). Should be set prior to most other method
|
50
|
+
# invocations (depending on the implementation).
|
51
|
+
def checkout_dir=(dir)
|
52
|
+
@checkout_dir = PathConverter.filepath_to_nativepath(dir, false)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Gets the working copy directory.
|
56
|
+
def checkout_dir
|
57
|
+
@checkout_dir
|
58
|
+
end
|
59
|
+
|
60
|
+
def to_yaml_properties #:nodoc:
|
61
|
+
props = instance_variables
|
62
|
+
props.delete("@checkout_dir")
|
63
|
+
props.delete("@default_options")
|
64
|
+
props.sort!
|
65
|
+
end
|
66
|
+
|
67
|
+
# Destroys the working copy
|
68
|
+
def destroy_working_copy(options={})
|
69
|
+
FileUtils.rm_rf(checkout_dir) unless checkout_dir.nil?
|
70
|
+
end
|
71
|
+
|
72
|
+
# Whether or not the SCM represented by this instance exists.
|
73
|
+
def central_exists?
|
74
|
+
# The default implementation assumes yes - override if it can be
|
75
|
+
# determined programmatically.
|
76
|
+
true
|
77
|
+
end
|
78
|
+
|
79
|
+
# Whether or not this SCM is transactional (atomic).
|
80
|
+
def transactional?
|
81
|
+
false
|
82
|
+
end
|
83
|
+
alias :atomic? :transactional?
|
84
|
+
|
85
|
+
# Creates a new 'central' repository. This is intended only for creation of 'central'
|
86
|
+
# repositories (not for working copies). You shouldn't have to call this method if a central repository
|
87
|
+
# already exists. This method is used primarily for testing of RSCM, but can also
|
88
|
+
# be used if you *really* want to use RSCM to create a central repository.
|
89
|
+
#
|
90
|
+
# This method should throw an exception if the repository cannot be created (for
|
91
|
+
# example if the repository is 'remote' or if it already exists).
|
92
|
+
#
|
93
|
+
def create_central(options={})
|
94
|
+
raise NotImplementedError
|
95
|
+
end
|
96
|
+
|
97
|
+
# Destroys the central repository. Shuts down any server processes and deletes the repository.
|
98
|
+
# WARNING: calling this may result in loss of data. Only call this if you really want to wipe
|
99
|
+
# it out for good!
|
100
|
+
def destroy_central
|
101
|
+
raise NotImplementedError
|
102
|
+
end
|
103
|
+
|
104
|
+
# Whether a repository can be created.
|
105
|
+
def can_create_central?
|
106
|
+
false
|
107
|
+
end
|
108
|
+
|
109
|
+
# Adds +relative_filename+ to the working copy.
|
110
|
+
def add(relative_filename, options={})
|
111
|
+
raise NotImplementedError
|
112
|
+
end
|
113
|
+
|
114
|
+
# Schedules a move of +relative_src+ to +relative_dest+
|
115
|
+
# Should not take effect in the central repository until
|
116
|
+
# +commit+ is invoked.
|
117
|
+
def move(relative_src, relative_dest, options={})
|
118
|
+
raise NotImplementedError
|
119
|
+
end
|
120
|
+
|
121
|
+
# Recursively imports files from <tt>:dir</tt> into the central scm,
|
122
|
+
# using commit message <tt>:message</tt>
|
123
|
+
def import_central(options)
|
124
|
+
raise NotImplementedError
|
125
|
+
end
|
126
|
+
|
127
|
+
# Open a file for edit - required by scms that check out files in read-only mode e.g. perforce
|
128
|
+
def edit(file, options={})
|
129
|
+
end
|
130
|
+
|
131
|
+
# Commit (check in) modified files.
|
132
|
+
def commit(message, options={})
|
133
|
+
raise NotImplementedError
|
134
|
+
end
|
135
|
+
|
136
|
+
# Checks out or updates contents from a central SCM to +checkout_dir+ - a local working copy.
|
137
|
+
# If this is a distributed SCM, this method should create a 'working copy' repository
|
138
|
+
# if one doesn't already exist. Then the contents of the central SCM should be pulled into
|
139
|
+
# the working copy.
|
140
|
+
#
|
141
|
+
# The +to_identifier+ parameter may be optionally specified to obtain files up to a
|
142
|
+
# particular time or label. +to_identifier+ should either be a Time (in UTC - according to
|
143
|
+
# the clock on the SCM machine) or a String - reprsenting a label or revision.
|
144
|
+
#
|
145
|
+
# This method will yield the relative file name of each checked out file, and also return
|
146
|
+
# them in an array. Only files, not directories, should be yielded/returned.
|
147
|
+
#
|
148
|
+
# This method should be overridden for SCMs that are able to yield checkouts as they happen.
|
149
|
+
# For some SCMs this is not possible, or at least very hard. In that case, just override
|
150
|
+
# the checkout_silent method instead of this method (should be protected).
|
151
|
+
#
|
152
|
+
def checkout(to_identifier=Time.infinity, options={}) # :yield: file
|
153
|
+
to_identifier = Time.infinity if to_identifier.nil?
|
154
|
+
|
155
|
+
before = checked_out_files
|
156
|
+
# We expect subclasses to implement this as a protected method (unless this whole method is overridden).
|
157
|
+
checkout_silent(to_identifier, options)
|
158
|
+
after = checked_out_files
|
159
|
+
|
160
|
+
(after - before).sort!
|
161
|
+
end
|
162
|
+
|
163
|
+
def checked_out_files
|
164
|
+
raise "checkout_dir not set" if @checkout_dir.nil?
|
165
|
+
|
166
|
+
files = Dir["#{@checkout_dir}/**/*"]
|
167
|
+
files.delete_if{|file| File.directory?(file)}
|
168
|
+
ignore_paths.each do |regex|
|
169
|
+
files.delete_if{|file| file =~ regex}
|
170
|
+
end
|
171
|
+
dir = File.expand_path(@checkout_dir)
|
172
|
+
files.collect{|file| File.expand_path(file)[dir.length+1..-1]}
|
173
|
+
end
|
174
|
+
|
175
|
+
# Returns a Revisions object for the interval specified by +from_identifier+ (exclusive, i.e. after)
|
176
|
+
# and optionally +:to_identifier+ (exclusive too). If +relative_path+ is specified, the result will only contain
|
177
|
+
# revisions pertaining to that path.
|
178
|
+
#
|
179
|
+
# For example, revisions(223, 229) should return revisions 224..228
|
180
|
+
def revisions(from_identifier, options={})
|
181
|
+
raise NotImplementedError
|
182
|
+
end
|
183
|
+
|
184
|
+
# Opens a readonly IO to a file at +path+
|
185
|
+
def open(path, native_revision_identifier, options={}, &block) #:yield: io
|
186
|
+
raise NotImplementedError
|
187
|
+
end
|
188
|
+
|
189
|
+
# Whether the working copy is in synch with the central
|
190
|
+
# repository's revision/time identified by +identifier+.
|
191
|
+
# If +identifier+ is nil, 'HEAD' of repository should be assumed.
|
192
|
+
#
|
193
|
+
def uptodate?(identifier)
|
194
|
+
raise NotImplementedError
|
195
|
+
end
|
196
|
+
|
197
|
+
# Whether the project is checked out from the central repository or not.
|
198
|
+
# Subclasses should override this to check for SCM-specific administrative
|
199
|
+
# files if appliccable
|
200
|
+
def checked_out?
|
201
|
+
File.exists?(@checkout_dir)
|
202
|
+
end
|
203
|
+
|
204
|
+
# Whether triggers are supported by this SCM. A trigger is a command that can be executed
|
205
|
+
# upon a completed commit to the SCM.
|
206
|
+
def supports_trigger?
|
207
|
+
# The default implementation assumes no - override if it can be
|
208
|
+
# determined programmatically.
|
209
|
+
false
|
210
|
+
end
|
211
|
+
alias :can_install_trigger? :supports_trigger?
|
212
|
+
|
213
|
+
# Descriptive name of the trigger mechanism
|
214
|
+
def trigger_mechanism
|
215
|
+
raise NotImplementedError
|
216
|
+
end
|
217
|
+
|
218
|
+
# Installs +trigger_command+ in the SCM.
|
219
|
+
# The +install_dir+ parameter should be an empty local
|
220
|
+
# directory that the SCM can use for temporary files
|
221
|
+
# if necessary (CVS needs this to check out its administrative files).
|
222
|
+
# Most implementations will ignore this parameter.
|
223
|
+
#
|
224
|
+
def install_trigger(trigger_command, install_dir)
|
225
|
+
raise NotImplementedError
|
226
|
+
end
|
227
|
+
|
228
|
+
# Uninstalls +trigger_command+ from the SCM.
|
229
|
+
#
|
230
|
+
def uninstall_trigger(trigger_command, install_dir)
|
231
|
+
raise NotImplementedError
|
232
|
+
end
|
233
|
+
|
234
|
+
# Whether the command denoted by +trigger_command+ is installed in the SCM.
|
235
|
+
#
|
236
|
+
def trigger_installed?(trigger_command, install_dir)
|
237
|
+
raise NotImplementedError
|
238
|
+
end
|
239
|
+
|
240
|
+
# The command line to run in order to check out a fresh working copy.
|
241
|
+
#
|
242
|
+
def checkout_commandline(to_identifier=Time.infinity)
|
243
|
+
raise NotImplementedError
|
244
|
+
end
|
245
|
+
|
246
|
+
# The command line to run in order to update a working copy.
|
247
|
+
#
|
248
|
+
def update_commandline(to_identifier=Time.infinity)
|
249
|
+
raise NotImplementedError
|
250
|
+
end
|
251
|
+
|
252
|
+
# Yields an IO containing the unified diff of the change.
|
253
|
+
# Also see RevisionFile#diff
|
254
|
+
def diff(path, from, to, options={}, &block)
|
255
|
+
raise NotImplementedError
|
256
|
+
end
|
257
|
+
|
258
|
+
def ==(other_scm)
|
259
|
+
return false if self.class != other_scm.class
|
260
|
+
self.instance_variables.each do |var|
|
261
|
+
return false if self.instance_eval(var) != other_scm.instance_eval(var)
|
262
|
+
end
|
263
|
+
true
|
264
|
+
end
|
265
|
+
|
266
|
+
# Whether or not to store the revision command in the Revisions instance returned by <tt>revisions</tt>
|
267
|
+
def store_revisions_command?; @store_revisions_command.nil? ? true : @store_revisions_command; end
|
268
|
+
|
269
|
+
protected
|
270
|
+
|
271
|
+
# Directory where commands must be run
|
272
|
+
def cmd_dir
|
273
|
+
nil
|
274
|
+
end
|
275
|
+
|
276
|
+
# Wrapper for CommandLine.execute that provides default values for
|
277
|
+
# dir plus any options set in default_options (typically stdout and stderr).
|
278
|
+
def execute(cmd, options={}, &proc)
|
279
|
+
options = {:dir => cmd_dir}.merge(default_options).merge(options)
|
280
|
+
begin
|
281
|
+
CommandLine.execute(cmd, options, &proc)
|
282
|
+
rescue CommandLine::OptionError => e
|
283
|
+
e.message += "\nEither specify default_options on the scm object, or pass the required options to the method"
|
284
|
+
raise e
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
end
|
289
|
+
end
|