rscm 0.3.14 → 0.3.15
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +7 -0
- data/README +1 -1
- data/Rakefile +1 -1
- data/lib/rscm/abstract_log_parser.rb +4 -18
- data/lib/rscm/base.rb +26 -26
- data/lib/rscm/historic_file.rb +14 -3
- data/lib/rscm/revision.rb +2 -6
- data/lib/rscm/revision_file.rb +0 -1
- data/lib/rscm/scm/cvs.rb +26 -13
- data/lib/rscm/scm/cvs_log_parser.rb +9 -11
- data/lib/rscm/scm/subversion.rb +16 -0
- data/test/rscm/generic_scm_tests.rb +22 -5
- data/test/rscm/scm/cvs_log_parser_test.rb +4 -12
- data/test/rscm/scm/cvs_test.rb +20 -0
- metadata +2 -2
data/CHANGES
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
= RSCM Changelog
|
2
2
|
|
3
|
+
== Version 0.3.15
|
4
|
+
|
5
|
+
This release adds support for directory listings and fixes some incompatibilities with CVS 1.12.x
|
6
|
+
|
7
|
+
* Added support for directory listings.
|
8
|
+
* Added support for parsing of revisions for CVS 1.12.x, which uses a slightly different time format.
|
9
|
+
|
3
10
|
== Version 0.3.14
|
4
11
|
|
5
12
|
Improved error messages
|
data/README
CHANGED
data/Rakefile
CHANGED
@@ -7,22 +7,17 @@ module RSCM
|
|
7
7
|
# TODO: make this a module and remove the attr_reader
|
8
8
|
class AbstractLogParser
|
9
9
|
|
10
|
-
attr_reader :io
|
11
|
-
|
12
10
|
def initialize(io)
|
13
11
|
@io = io
|
14
|
-
@current_line_number = 0
|
15
|
-
@had_error = false
|
16
12
|
end
|
17
13
|
|
18
14
|
def read_until_matching_line(regexp)
|
19
|
-
return nil if io.eof?
|
15
|
+
return nil if @io.eof?
|
20
16
|
result = ""
|
21
|
-
io.each_line do |line|
|
22
|
-
@current_line_number += 1
|
17
|
+
@io.each_line do |line|
|
23
18
|
line.gsub!(/\r\n$/, "\n")
|
24
|
-
break if line=~regexp
|
25
|
-
result<<line
|
19
|
+
break if line =~ regexp
|
20
|
+
result << line
|
26
21
|
end
|
27
22
|
if result.strip == ""
|
28
23
|
read_until_matching_line(regexp)
|
@@ -35,15 +30,6 @@ module RSCM
|
|
35
30
|
file.gsub(/\\/, "/")
|
36
31
|
end
|
37
32
|
|
38
|
-
def error(msg)
|
39
|
-
@had_error=true
|
40
|
-
$stderr.puts(msg + "\ncurrent line: #{@current_line}\nstack trace:\n")
|
41
|
-
$stderr.puts(caller.backtrace.join('\n\t'))
|
42
|
-
end
|
43
|
-
|
44
|
-
def had_error?
|
45
|
-
@had_error
|
46
|
-
end
|
47
33
|
end
|
48
34
|
|
49
35
|
end
|
data/lib/rscm/base.rb
CHANGED
@@ -16,6 +16,7 @@ module RSCM
|
|
16
16
|
# * checked_out?
|
17
17
|
# * diff
|
18
18
|
# * edit
|
19
|
+
# * ls
|
19
20
|
# * move
|
20
21
|
# * revisions
|
21
22
|
# * uptodate?
|
@@ -108,13 +109,14 @@ module RSCM
|
|
108
109
|
# example if the repository is 'remote' or if it already exists).
|
109
110
|
#
|
110
111
|
def create_central
|
111
|
-
raise
|
112
|
+
raise NotImplementedError
|
112
113
|
end
|
113
114
|
|
114
115
|
# Destroys the central repository. Shuts down any server processes and deletes the repository.
|
115
116
|
# WARNING: calling this may result in loss of data. Only call this if you really want to wipe
|
116
117
|
# it out for good!
|
117
118
|
def destroy_central
|
119
|
+
raise NotImplementedError
|
118
120
|
end
|
119
121
|
|
120
122
|
# Whether a repository can be created.
|
@@ -124,12 +126,14 @@ module RSCM
|
|
124
126
|
|
125
127
|
# Adds +relative_filename+ to the working copy.
|
126
128
|
def add(relative_filename)
|
129
|
+
raise NotImplementedError
|
127
130
|
end
|
128
131
|
|
129
132
|
# Schedules a move of +relative_src+ to +relative_dest+
|
130
133
|
# Should not take effect in the central repository until
|
131
134
|
# +commit+ is invoked.
|
132
135
|
def move(relative_src, relative_dest)
|
136
|
+
raise NotImplementedError
|
133
137
|
end
|
134
138
|
|
135
139
|
# Recursively imports files from a +dir+ into the central scm
|
@@ -143,6 +147,7 @@ module RSCM
|
|
143
147
|
|
144
148
|
# Commit (check in) modified files.
|
145
149
|
def commit(message)
|
150
|
+
raise NotImplementedError
|
146
151
|
end
|
147
152
|
|
148
153
|
# Checks out or updates contents from a central SCM to +checkout_dir+ - a local working copy.
|
@@ -190,27 +195,22 @@ module RSCM
|
|
190
195
|
# revisions pertaining to that path.
|
191
196
|
#
|
192
197
|
def revisions(from_identifier, to_identifier=Time.infinity, relative_path=nil)
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
"DamageControl",
|
200
|
-
"The #{name} class doesn't\n" +
|
201
|
-
"correctly implement the revisions method. This is\n" +
|
202
|
-
"not a real revision, but a hint to the developer to go and implement it.\n\n" +
|
203
|
-
"Do It Now!",
|
204
|
-
"999",
|
205
|
-
Time.now.utc
|
206
|
-
)
|
207
|
-
)
|
208
|
-
revisions
|
198
|
+
raise NotImplementedError
|
199
|
+
end
|
200
|
+
|
201
|
+
# Returns the HistoricFile representing the root of the repo
|
202
|
+
def rootdir
|
203
|
+
file("", true)
|
209
204
|
end
|
210
205
|
|
211
206
|
# Returns a HistoricFile for +relative_path+
|
212
|
-
def file(relative_path)
|
213
|
-
HistoricFile.new(relative_path, self)
|
207
|
+
def file(relative_path, dir)
|
208
|
+
HistoricFile.new(relative_path, dir, self)
|
209
|
+
end
|
210
|
+
|
211
|
+
# Returns an Array of the children under +relative_path+
|
212
|
+
def ls(relative_path)
|
213
|
+
raise NotImplementedError
|
214
214
|
end
|
215
215
|
|
216
216
|
# Whether the working copy is in synch with the central
|
@@ -243,7 +243,7 @@ module RSCM
|
|
243
243
|
|
244
244
|
# Descriptive name of the trigger mechanism
|
245
245
|
def trigger_mechanism
|
246
|
-
|
246
|
+
raise NotImplementedError
|
247
247
|
end
|
248
248
|
|
249
249
|
# Installs +trigger_command+ in the SCM.
|
@@ -253,37 +253,37 @@ module RSCM
|
|
253
253
|
# Most implementations will ignore this parameter.
|
254
254
|
#
|
255
255
|
def install_trigger(trigger_command, install_dir)
|
256
|
-
raise
|
256
|
+
raise NotImplementedError
|
257
257
|
end
|
258
258
|
|
259
259
|
# Uninstalls +trigger_command+ from the SCM.
|
260
260
|
#
|
261
261
|
def uninstall_trigger(trigger_command, install_dir)
|
262
|
-
raise
|
262
|
+
raise NotImplementedError
|
263
263
|
end
|
264
264
|
|
265
265
|
# Whether the command denoted by +trigger_command+ is installed in the SCM.
|
266
266
|
#
|
267
267
|
def trigger_installed?(trigger_command, install_dir)
|
268
|
-
raise
|
268
|
+
raise NotImplementedError
|
269
269
|
end
|
270
270
|
|
271
271
|
# The command line to run in order to check out a fresh working copy.
|
272
272
|
#
|
273
273
|
def checkout_commandline(to_identifier=Time.infinity)
|
274
|
-
raise
|
274
|
+
raise NotImplementedError
|
275
275
|
end
|
276
276
|
|
277
277
|
# The command line to run in order to update a working copy.
|
278
278
|
#
|
279
279
|
def update_commandline(to_identifier=Time.infinity)
|
280
|
-
raise
|
280
|
+
raise NotImplementedError
|
281
281
|
end
|
282
282
|
|
283
283
|
# Returns/yields an IO containing the unified diff of the change.
|
284
284
|
# Also see RevisionFile#diff
|
285
285
|
def diff(change, &block)
|
286
|
-
|
286
|
+
raise NotImplementedError
|
287
287
|
end
|
288
288
|
|
289
289
|
def ==(other_scm)
|
data/lib/rscm/historic_file.rb
CHANGED
@@ -1,8 +1,14 @@
|
|
1
1
|
module RSCM
|
2
|
-
# Represents the full history of a single file
|
2
|
+
# Represents the full history of a single file or directory.
|
3
3
|
class HistoricFile
|
4
|
-
|
5
|
-
|
4
|
+
attr_reader :relative_path
|
5
|
+
|
6
|
+
def initialize(relative_path, directory, scm)
|
7
|
+
@relative_path, @directory, @scm = relative_path, directory, scm
|
8
|
+
end
|
9
|
+
|
10
|
+
def directory?
|
11
|
+
@directory
|
6
12
|
end
|
7
13
|
|
8
14
|
# Returns an Array of RevisionFile - from Time.epoch until Time.infinity (now)
|
@@ -18,5 +24,10 @@ module RSCM
|
|
18
24
|
revision.files[0]
|
19
25
|
end
|
20
26
|
end
|
27
|
+
|
28
|
+
def children
|
29
|
+
raise "Not a directory" unless directory?
|
30
|
+
@scm.ls(@relative_path)
|
31
|
+
end
|
21
32
|
end
|
22
33
|
end
|
data/lib/rscm/revision.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'xmlrpc/utils'
|
2
1
|
require 'rscm/time_ext'
|
3
2
|
require 'rscm/revision_file'
|
4
3
|
|
@@ -7,7 +6,6 @@ module RSCM
|
|
7
6
|
# A collection of Revision.
|
8
7
|
class Revisions
|
9
8
|
include Enumerable
|
10
|
-
include XMLRPC::Marshallable
|
11
9
|
|
12
10
|
attr_accessor :revisions
|
13
11
|
|
@@ -115,7 +113,6 @@ module RSCM
|
|
115
113
|
# same commit message, and within a "reasonably" small timespan.
|
116
114
|
class Revision
|
117
115
|
include Enumerable
|
118
|
-
include XMLRPC::Marshallable
|
119
116
|
|
120
117
|
attr_reader :files
|
121
118
|
attr_accessor :identifier
|
@@ -167,8 +164,7 @@ module RSCM
|
|
167
164
|
end
|
168
165
|
|
169
166
|
def ==(other)
|
170
|
-
|
171
|
-
@files == other.files
|
167
|
+
other.is_a?(self.class) && @files == other.files
|
172
168
|
end
|
173
169
|
|
174
170
|
def <=>(other)
|
@@ -177,7 +173,7 @@ module RSCM
|
|
177
173
|
|
178
174
|
# Whether this instance can contain a File. Used
|
179
175
|
# by non-transactional SCMs.
|
180
|
-
def can_contain?(file)
|
176
|
+
def can_contain?(file) #:nodoc:
|
181
177
|
self.developer == file.developer &&
|
182
178
|
self.message == file.message &&
|
183
179
|
(self.time - file.time).abs < 60
|
data/lib/rscm/revision_file.rb
CHANGED
data/lib/rscm/scm/cvs.rb
CHANGED
@@ -106,12 +106,36 @@ module RSCM
|
|
106
106
|
|
107
107
|
def open(revision_file, &block)
|
108
108
|
with_working_dir(@checkout_dir) do
|
109
|
-
|
110
|
-
Better.popen(
|
109
|
+
cmd = "cvs -Q update -p -r #{revision_file.native_revision_identifier} #{revision_file.path}"
|
110
|
+
Better.popen(cmd) do |io|
|
111
111
|
block.call io
|
112
112
|
end
|
113
113
|
end
|
114
114
|
end
|
115
|
+
|
116
|
+
def ls(relative_path)
|
117
|
+
prefix = relative_path == "" ? relative_path : "#{relative_path}/"
|
118
|
+
with_working_dir(@checkout_dir) do
|
119
|
+
cmd = "cvs -Q ls -l #{relative_path}"
|
120
|
+
Better.popen(cmd) do |io|
|
121
|
+
parse_ls_log(io, prefix)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def parse_ls_log(io, prefix) #:nodoc:
|
127
|
+
io.collect do |line|
|
128
|
+
line.strip!
|
129
|
+
if(
|
130
|
+
(line =~ /(d)... \d\d\d\d\-\d\d\-\d\d \d\d:\d\d:\d\d \-\d\d\d\d (.*)/) ||
|
131
|
+
(line =~ /(.)... \d\d\d\d\-\d\d\-\d\d \d\d:\d\d:\d\d \-\d\d\d\d \d[\.\d]+ (.*)/)
|
132
|
+
)
|
133
|
+
directory = $1 == "d"
|
134
|
+
name = $2.strip
|
135
|
+
HistoricFile.new("#{prefix}#{name}", directory, self)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
115
139
|
|
116
140
|
def apply_label(label)
|
117
141
|
cvs(@checkout_dir, "tag -c #{label}")
|
@@ -236,9 +260,6 @@ module RSCM
|
|
236
260
|
end
|
237
261
|
|
238
262
|
def parse_log(cmd, &proc)
|
239
|
-
logged_command_line = command_line(cmd, hidden_password)
|
240
|
-
yield logged_command_line if block_given?
|
241
|
-
|
242
263
|
execed_command_line = command_line(cmd, password)
|
243
264
|
revisions = nil
|
244
265
|
with_working_dir(@checkout_dir) do
|
@@ -274,14 +295,6 @@ module RSCM
|
|
274
295
|
"checkout #{branch_option} -d #{target_dir} #{revision_option(to_identifier)} #{mod}"
|
275
296
|
end
|
276
297
|
|
277
|
-
def hidden_password
|
278
|
-
if(password && password != "")
|
279
|
-
"********"
|
280
|
-
else
|
281
|
-
""
|
282
|
-
end
|
283
|
-
end
|
284
|
-
|
285
298
|
def period_option(from_identifier, to_identifier)
|
286
299
|
if(from_identifier.nil? && to_identifier.nil?)
|
287
300
|
""
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'rscm/revision'
|
2
2
|
require 'rscm/abstract_log_parser'
|
3
|
-
|
4
3
|
require 'ftools'
|
4
|
+
require 'time'
|
5
5
|
|
6
6
|
module RSCM
|
7
7
|
|
@@ -14,14 +14,11 @@ module RSCM
|
|
14
14
|
|
15
15
|
def initialize(io)
|
16
16
|
super(io)
|
17
|
-
@log = ""
|
18
17
|
end
|
19
18
|
|
20
19
|
def parse_revisions
|
21
20
|
revisions = Revisions.new
|
22
21
|
while(log_entry = next_log_entry)
|
23
|
-
@log<<log_entry
|
24
|
-
@log<<""
|
25
22
|
begin
|
26
23
|
parse_files(log_entry, revisions)
|
27
24
|
rescue Exception => e
|
@@ -91,7 +88,13 @@ module RSCM
|
|
91
88
|
file.native_revision_identifier = extract_match(file_entry_lines[0], /revision (.*)$/)
|
92
89
|
|
93
90
|
file.previous_native_revision_identifier = determine_previous_native_revision_identifier(file.native_revision_identifier)
|
94
|
-
|
91
|
+
|
92
|
+
time = extract_required_match(file_entry_lines[1], /date: (.*?)(;|$)/)
|
93
|
+
if(time.strip.length == 19)
|
94
|
+
# CVS 1.11.x doesn't specify timezone (but assumes UTC), so we'll add it here.
|
95
|
+
time += " +0000"
|
96
|
+
end
|
97
|
+
file.time = Time.parse(time).utc
|
95
98
|
file.developer = extract_match(file_entry_lines[1], /author: (.*?);/)
|
96
99
|
|
97
100
|
state = extract_match(file_entry_lines[1], /state: (.*?);/)
|
@@ -128,13 +131,8 @@ module RSCM
|
|
128
131
|
end
|
129
132
|
end
|
130
133
|
|
131
|
-
def parse_cvs_time(time)
|
132
|
-
# 2003/11/09 15:39:25
|
133
|
-
Time.utc(time[0..3], time[5..6], time[8..9], time[11..12], time[14..15], time[17..18])
|
134
|
-
end
|
135
|
-
|
136
134
|
def extract_required_match(string, regexp)
|
137
|
-
if
|
135
|
+
if(string =~ regexp)
|
138
136
|
return($1)
|
139
137
|
else
|
140
138
|
$stderr.puts("can't parse: '#{string}'\nexpected to match regexp: #{regexp.to_s}")
|
data/lib/rscm/scm/subversion.rb
CHANGED
@@ -104,6 +104,22 @@ module RSCM
|
|
104
104
|
end
|
105
105
|
end
|
106
106
|
|
107
|
+
def ls(relative_path)
|
108
|
+
prefix = relative_path == "" ? relative_path : "#{relative_path}/"
|
109
|
+
cmd = "svn ls #{url}/#{relative_path}"
|
110
|
+
Better.popen(cmd) do |io|
|
111
|
+
io.collect do |line|
|
112
|
+
name = line.strip
|
113
|
+
dir = false
|
114
|
+
if(name =~ /(.*)\/$/)
|
115
|
+
name = $1
|
116
|
+
dir = true
|
117
|
+
end
|
118
|
+
HistoricFile.new("#{prefix}#{name}", dir, self)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
107
123
|
def can_create_central?
|
108
124
|
local?
|
109
125
|
end
|
@@ -11,8 +11,8 @@ module RSCM
|
|
11
11
|
def teardown
|
12
12
|
if @scm
|
13
13
|
begin
|
14
|
-
@scm.destroy_working_copy
|
15
|
-
@scm.destroy_central
|
14
|
+
# @scm.destroy_working_copy
|
15
|
+
# @scm.destroy_central
|
16
16
|
rescue => e
|
17
17
|
# Fails on windows with TortoiseCVS' cvs because of resident cvslock.exe
|
18
18
|
STDERR.puts "Couldn't destroy central #{@scm.class.name}: #{e.message}"
|
@@ -40,6 +40,7 @@ module RSCM
|
|
40
40
|
# 16) Verify that OtherWorkingCopy is now uptodate
|
41
41
|
# 17) Add and commit a file in WorkingCopy
|
42
42
|
# 18) Verify that the revision (since last revision) for CheckoutHereToo contains only one file
|
43
|
+
# 19) Get directory listings
|
43
44
|
def test_basics
|
44
45
|
work_dir = RSCM.new_temp_dir("basics")
|
45
46
|
checkout_dir = "#{work_dir}/WorkingCopy"
|
@@ -140,13 +141,29 @@ module RSCM
|
|
140
141
|
|
141
142
|
# 16
|
142
143
|
assert(other_scm.uptodate?(nil))
|
144
|
+
|
145
|
+
# 17
|
143
146
|
add_or_edit_and_commit_file(scm, checkout_dir, "src/java/com/thoughtworks/damagecontrolled/Hello.txt", "Bla bla")
|
144
147
|
assert(!other_scm.uptodate?(nil))
|
145
148
|
revisions = other_scm.revisions(revisions.latest.identifier)
|
149
|
+
|
150
|
+
# 18
|
146
151
|
assert_equal(1, revisions.length)
|
147
152
|
assert_equal(1, revisions[0].length)
|
148
|
-
|
149
|
-
|
153
|
+
assert_equal("src/java/com/thoughtworks/damagecontrolled/Hello.txt", revisions[0][0].path)
|
154
|
+
|
155
|
+
# 19
|
156
|
+
root_children = scm.rootdir.children
|
157
|
+
assert_equal "build.xml", root_children[0].relative_path
|
158
|
+
assert !root_children[0].directory?
|
159
|
+
assert_equal "project.xml", root_children[1].relative_path
|
160
|
+
assert !root_children[1].directory?
|
161
|
+
assert_equal "src", root_children[2].relative_path
|
162
|
+
assert root_children[2].directory?
|
163
|
+
|
164
|
+
src_children = root_children[2].children
|
165
|
+
assert_equal "src/java", src_children[0].relative_path
|
166
|
+
assert src_children[0].directory?
|
150
167
|
end
|
151
168
|
|
152
169
|
def test_create_destroy
|
@@ -310,7 +327,7 @@ EOF
|
|
310
327
|
assert(got_diff)
|
311
328
|
|
312
329
|
# TODO: make separate test. Make helper method for the cumbersome setup!
|
313
|
-
historic_afile = scm.file("afile.txt")
|
330
|
+
historic_afile = scm.file("afile.txt", false)
|
314
331
|
revision_files = historic_afile.revision_files
|
315
332
|
assert_equal(Array, revision_files.class)
|
316
333
|
assert(revision_files.length >= 2)
|
@@ -14,10 +14,6 @@ module RSCM
|
|
14
14
|
@parser.cvsmodule = "damagecontrol"
|
15
15
|
end
|
16
16
|
|
17
|
-
def teardown
|
18
|
-
assert(!@parser.had_error?, "parser had errors") unless @parser.nil?
|
19
|
-
end
|
20
|
-
|
21
17
|
def test_read_log_entry
|
22
18
|
assert_equal(nil, CvsLogParser.new(StringIO.new("")).next_log_entry)
|
23
19
|
end
|
@@ -330,8 +326,6 @@ EOF
|
|
330
326
|
assert_equal("website/templates/logo.gif", @parser.parse_path(LOG_ENTRY_FROM_06_07_2004_19_25_2))
|
331
327
|
end
|
332
328
|
|
333
|
-
# stand in picocontainer's java folder
|
334
|
-
# cvs log -d"2003/07/25 12:38:41<=2004/07/08 12:38:41" build.xml
|
335
329
|
LOG_WITH_DELETIONS= <<EOF
|
336
330
|
RCS file: /home/projects/picocontainer/scm/java/Attic/build.xml,v
|
337
331
|
Working file: build.xml
|
@@ -348,7 +342,7 @@ total revisions: 11; selected revisions: 2
|
|
348
342
|
description:
|
349
343
|
----------------------------
|
350
344
|
revision 1.11
|
351
|
-
date: 2003/10/13 00:04:54; author: rinkrank; state: dead; lines: +0 -0
|
345
|
+
date: 2003/10/13 00:04:54 -0500; author: rinkrank; state: dead; lines: +0 -0
|
352
346
|
Obsolete
|
353
347
|
----------------------------
|
354
348
|
revision 1.10
|
@@ -363,8 +357,7 @@ EOF
|
|
363
357
|
assert_equal(2, revisions.length)
|
364
358
|
|
365
359
|
revision_delete = revisions[1]
|
366
|
-
|
367
|
-
assert_equal(Time.utc(2003,10,13,00,04,54,0), revision_delete.time)
|
360
|
+
assert_equal(Time.utc(2003,10,13,05,04,54,0), revision_delete.time)
|
368
361
|
assert_equal("Obsolete", revision_delete.message)
|
369
362
|
assert_equal("rinkrank", revision_delete.developer)
|
370
363
|
assert_equal(1, revision_delete.length)
|
@@ -374,7 +367,6 @@ EOF
|
|
374
367
|
assert(RevisionFile::DELETED, revision_delete[0].status)
|
375
368
|
|
376
369
|
revision_fix_url = revisions[0]
|
377
|
-
# assert_equal("MAIN:rinkrank:20030725163239", revision_fix_url.revision)
|
378
370
|
assert_equal(Time.utc(2003,07,25,16,32,39,0), revision_fix_url.time)
|
379
371
|
assert_equal("fixed broken url (NANO-8)", revision_fix_url.message)
|
380
372
|
assert_equal("rinkrank", revision_fix_url.developer)
|
@@ -472,8 +464,8 @@ EOF
|
|
472
464
|
# https://sitemesh.dev.java.net/source/browse/sitemesh/.cvsignore
|
473
465
|
# The default commit message probably showed up in vi, and the committer
|
474
466
|
# probably just left it there. Not sure why CVS kept it this way
|
475
|
-
# (lines starting with CVS: should be ignored in commit message
|
476
|
-
# Anyway, the parser
|
467
|
+
# (lines starting with CVS: should be ignored in commit message afaik).
|
468
|
+
# Anyway, the parser now knows how to deal with this. (AH)
|
477
469
|
LOG_WITH_WEIRD_CVS_AND_MANY_DASHES = <<EOF
|
478
470
|
? log.txt
|
479
471
|
|
data/test/rscm/scm/cvs_test.rb
CHANGED
@@ -2,6 +2,7 @@ require 'test/unit'
|
|
2
2
|
require 'rscm/path_converter'
|
3
3
|
require 'rscm'
|
4
4
|
require 'rscm/generic_scm_tests'
|
5
|
+
require 'stringio'
|
5
6
|
|
6
7
|
module RSCM
|
7
8
|
|
@@ -28,5 +29,24 @@ module RSCM
|
|
28
29
|
end
|
29
30
|
end
|
30
31
|
|
32
|
+
LS_LOG = <<-EOF
|
33
|
+
---- 2005-11-22 21:24:40 -0500 1.1 afile
|
34
|
+
---- 2005-11-22 22:04:20 -0500 1.2 build.xml
|
35
|
+
---- 2005-11-22 22:12:43 -0500 1.1 foo bar
|
36
|
+
---- 2005-11-22 21:24:37 -0500 1.1.1.1 1.1 project.xml
|
37
|
+
d--- 2005-11-22 22:12:43 -0500 1.1 src
|
38
|
+
d--- 2005-11-22 22:12:43 -0500 togo
|
39
|
+
EOF
|
40
|
+
def test_should_parse_ls_log
|
41
|
+
history_files = Cvs.new.parse_ls_log(StringIO.new(LS_LOG), "")
|
42
|
+
assert_equal("afile", history_files[0].relative_path)
|
43
|
+
assert_equal("foo bar", history_files[2].relative_path)
|
44
|
+
assert_equal("1.1 project.xml", history_files[3].relative_path)
|
45
|
+
assert(!history_files[3].directory?)
|
46
|
+
assert_equal("1.1 src", history_files[4].relative_path)
|
47
|
+
assert(history_files[4].directory?)
|
48
|
+
assert_equal("togo", history_files[5].relative_path)
|
49
|
+
assert(history_files[5].directory?)
|
50
|
+
end
|
31
51
|
end
|
32
52
|
end
|
metadata
CHANGED