rscm 0.2.1.1404 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. data/README +34 -23
  2. data/Rakefile +24 -29
  3. data/bin/touch.exe +0 -0
  4. data/lib/rscm.rb +6 -3
  5. data/lib/rscm/annotations.rb +26 -7
  6. data/lib/rscm/{abstract_scm.rb → base.rb} +109 -71
  7. data/lib/rscm/better.rb +16 -0
  8. data/lib/rscm/logging.rb +11 -5
  9. data/lib/rscm/path_converter.rb +9 -16
  10. data/lib/rscm/revision.rb +201 -0
  11. data/lib/rscm/revision_file.rb +71 -0
  12. data/lib/rscm/scm/clearcase.rb +7 -7
  13. data/lib/rscm/scm/cvs.rb +69 -70
  14. data/lib/rscm/scm/cvs_log_parser.rb +29 -29
  15. data/lib/rscm/scm/darcs.rb +82 -34
  16. data/lib/rscm/scm/darcs_log_parser.rb +65 -0
  17. data/lib/rscm/scm/monotone.rb +249 -77
  18. data/lib/rscm/scm/monotone_log_parser.rb +57 -43
  19. data/lib/rscm/scm/mooky.rb +3 -3
  20. data/lib/rscm/scm/perforce.rb +196 -134
  21. data/lib/rscm/scm/star_team.rb +10 -10
  22. data/lib/rscm/scm/subversion.rb +106 -77
  23. data/lib/rscm/scm/subversion_log_parser.rb +76 -47
  24. data/lib/rscm/time_ext.rb +2 -116
  25. data/test/rscm/annotations_test.rb +15 -2
  26. data/test/rscm/{abstract_scm_test.rb → base_test.rb} +3 -3
  27. data/test/rscm/difftool_test.rb +9 -3
  28. data/test/rscm/generic_scm_tests.rb +195 -124
  29. data/test/rscm/revision_fixture.rb +20 -0
  30. data/test/rscm/revision_test.rb +129 -0
  31. data/test/rscm/{changesets.yaml → revisions.yaml} +10 -10
  32. data/test/rscm/scm/clearcase.log +608 -0
  33. data/test/rscm/scm/clearcase_test.rb +39 -0
  34. data/test/rscm/scm/cvs_log_parser_test.rb +73 -73
  35. data/test/rscm/scm/cvs_test.rb +1 -1
  36. data/test/rscm/scm/darcs_log_parser_test.rb +171 -0
  37. data/test/rscm/scm/monotone_log_parser_test.rb +49 -31
  38. data/test/rscm/scm/monotone_test.rb +3 -2
  39. data/test/rscm/scm/p4client_test.rb +33 -0
  40. data/test/rscm/scm/perforce_test.rb +25 -3
  41. data/test/rscm/scm/star_team.rb +9 -9
  42. data/test/rscm/scm/subversion_log_parser_test.rb +107 -47
  43. metadata +17 -13
  44. data/lib/multipart.rb +0 -95
  45. data/lib/rscm/RSS.txt +0 -41
  46. data/lib/rscm/changes.rb +0 -268
  47. data/lib/rscm/example.yaml +0 -21
  48. data/lib/rubyforge_file_publisher.rb +0 -176
  49. data/test/rscm/changes_fixture.rb +0 -20
  50. data/test/rscm/changes_test.rb +0 -129
@@ -1,7 +1,7 @@
1
1
  require 'fileutils'
2
2
  require 'tempfile'
3
- require 'rscm/changes'
4
- require 'rscm/abstract_scm'
3
+ require 'rscm/revision'
4
+ require 'rscm/base'
5
5
  require 'yaml'
6
6
 
7
7
  class Time
@@ -17,8 +17,8 @@ module RSCM
17
17
  # * StarTeam SDK
18
18
  # * Apache Ant (http://ant.apache.org/)
19
19
  #
20
- class StarTeam < AbstractSCM
21
- register self
20
+ class StarTeam < Base
21
+ #register self
22
22
 
23
23
  ann :description => "User name"
24
24
  attr_accessor :user_name
@@ -49,23 +49,23 @@ module RSCM
49
49
  "StarTeam"
50
50
  end
51
51
 
52
- def changesets(checkout_dir, from_identifier=Time.epoch, to_identifier=Time.infinity, &proc)
52
+ def revisions(checkout_dir, from_identifier=Time.epoch, to_identifier=Time.infinity, &proc)
53
53
  # just assuming it is a Time for now, may support labels later.
54
54
  # the java class really wants rfc822 and not rfc2822, but this works ok anyway.
55
55
  from = from_identifier.to_rfc2822
56
56
  to = to_identifier.to_rfc2822
57
57
 
58
- changesets = java("getChangeSets(\"#{from}\";\"#{to}\")", &proc)
59
- raise "changesets must be of type #{ChangeSets.name} - was #{changesets.class.name}" unless changesets.is_a?(::RSCM::ChangeSets)
58
+ revisions = java("getRevisions(\"#{from}\";\"#{to}\")", &proc)
59
+ raise "revisions must be of type #{Revisions.name} - was #{revisions.class.name}" unless revisions.is_a?(::RSCM::Revisions)
60
60
 
61
61
  # Just a little sanity check
62
- if(changesets.latest)
63
- latetime = changesets.latest.time
62
+ if(revisions.latest)
63
+ latetime = revisions.latest.time
64
64
  if(latetime < from_identifier || to_identifier < latetime)
65
65
  raise "Latest time (#{latetime}) is not within #{from_identifier}-#{to_identifier}"
66
66
  end
67
67
  end
68
- changesets
68
+ revisions
69
69
  end
70
70
 
71
71
  def checkout(checkout_dir, to_identifier, &proc)
@@ -1,4 +1,4 @@
1
- require 'rscm/abstract_scm'
1
+ require 'rscm/base'
2
2
  require 'rscm/path_converter'
3
3
  require 'rscm/line_editor'
4
4
  require 'rscm/scm/subversion_log_parser'
@@ -10,22 +10,29 @@ module RSCM
10
10
  # You need the svn/svnadmin executable on the PATH in order for it to work.
11
11
  #
12
12
  # NOTE: On Cygwin these have to be the win32 builds of svn/svnadmin and not the Cygwin ones.
13
- class Subversion < AbstractSCM
13
+ class Subversion < Base
14
14
  register self
15
15
 
16
16
  include FileUtils
17
17
  include PathConverter
18
18
 
19
19
  ann :description => "Repository URL"
20
- # ann :tip => "If you specify a local URL (starting with file://) DamageControl can create the repository for you after you save (unless the repository already exists).<br>Using a file:// URL will also give you the option to have DamageControl install a trigger in Subversion, so that you don't have to use polling to detect changes.<br>On Windows, file URLs must look like file:///C:/jupiter/mars"
21
20
  ann :tip => "If you use ssh, specify the URL as svn+ssh://username@server/path/to/repo"
22
21
  attr_accessor :url
23
22
 
23
+ ann :description => "Username"
24
+ ann :tip => "This only applies to svn:// URLs."
25
+ attr_accessor :username
26
+
27
+ ann :description => "Password"
28
+ ann :tip => "This only applies to svn:// URLs."
29
+ attr_accessor :password
30
+
24
31
  ann :description => "Path"
25
- ann :tip => "This is the relative path from the start of the repository <br>to the end of the URL. For example, if your URL is <br>svn://your.server/path/to/repository/path/within/repository <br>then this value should be path/within/repository."
32
+ ann :tip => "You only need to specify this if you want to be able to automatically create the repository. This should be the relative path from the start of the repository <br>to the end of the URL. For example, if your URL is <br>svn://your.server/path/to/repository/path/within/repository <br>then this value should be path/within/repository."
26
33
  attr_accessor :path
27
34
 
28
- def initialize(url="", path="trunk")
35
+ def initialize(url="", path="")
29
36
  @url, @path = url, path
30
37
  end
31
38
 
@@ -33,21 +40,21 @@ module RSCM
33
40
  "Subversion"
34
41
  end
35
42
 
36
- def add(checkout_dir, relative_filename)
37
- svn(checkout_dir, "add #{relative_filename}")
43
+ def add(relative_filename)
44
+ svn(@checkout_dir, "add #{relative_filename}")
38
45
  end
39
46
 
40
47
  def transactional?
41
48
  true
42
49
  end
43
50
 
44
- def checkout(checkout_dir, to_identifier=nil)
45
- checkout_dir = PathConverter.filepath_to_nativepath(checkout_dir, false)
46
- mkdir_p(checkout_dir)
51
+ def checkout(to_identifier=nil)
52
+ checkout_dir = PathConverter.filepath_to_nativepath(@checkout_dir, false)
53
+ mkdir_p(@checkout_dir)
47
54
  checked_out_files = []
48
55
  path_regex = /^[A|D|U]\s+(.*)/
49
- if(checked_out?(checkout_dir))
50
- svn(checkout_dir, update_command(to_identifier)) do |line|
56
+ if(checked_out?)
57
+ svn(@checkout_dir, update_command(to_identifier)) do |line|
51
58
  if(line =~ path_regex)
52
59
  absolute_path = "#{checkout_dir}/#{$1}"
53
60
  relative_path = $1.chomp
@@ -57,14 +64,15 @@ module RSCM
57
64
  end
58
65
  end
59
66
  else
60
- svn(checkout_dir, checkout_command(checkout_dir, to_identifier)) do |line|
67
+ svn(@checkout_dir, checkout_command(to_identifier)) do |line|
61
68
  if(line =~ path_regex)
62
69
  native_absolute_path = $1
63
- native_checkout_dir = $1
64
- absolute_path = PathConverter.nativepath_to_filepath($1)
65
- native_checkout_dir = PathConverter.filepath_to_nativepath(checkout_dir, false)
70
+ absolute_path = PathConverter.nativepath_to_filepath(native_absolute_path)
66
71
  if(File.exist?(absolute_path) && !File.directory?(absolute_path))
67
- relative_path = native_absolute_path[native_checkout_dir.length+1..-1].chomp
72
+ native_checkout_dir = PathConverter.filepath_to_nativepath(@checkout_dir, false)
73
+ # relative_path = native_absolute_path[native_checkout_dir.length+1..-1].chomp
74
+ # not sure about this old code - this seems to work. keep it here till it's verified on win32
75
+ relative_path = absolute_path
68
76
  relative_path = relative_path.gsub(/\\/, "/") if WINDOWS
69
77
  checked_out_files << relative_path
70
78
  yield relative_path if block_given?
@@ -83,60 +91,43 @@ module RSCM
83
91
  "svn update #{url} #{checkout_dir}"
84
92
  end
85
93
 
86
- def uptodate?(checkout_dir, from_identifier)
87
- if(!checked_out?(checkout_dir))
94
+ def uptodate?(identifier)
95
+ if(!checked_out?)
88
96
  false
89
97
  else
90
- lr = local_revision(checkout_dir)
91
- hr = head_revision(checkout_dir)
92
- lr == hr
93
- end
94
- end
95
-
96
- def local_revision(checkout_dir)
97
- local_revision = nil
98
- svn(checkout_dir, "info") do |line|
99
- if(line =~ /Revision: ([0-9]*)/)
100
- return $1.to_i
101
- end
98
+ rev = identifier ? identifier : head_revision_identifier
99
+ local_revision_identifier == rev
102
100
  end
103
101
  end
104
102
 
105
- def head_revision(checkout_dir)
106
- cmd = "svn log #{repourl} -r HEAD"
107
- with_working_dir(checkout_dir) do
108
- safer_popen(cmd) do |stdout|
109
- parser = SubversionLogParser.new(stdout, path, checkout_dir)
110
- changesets = parser.parse_changesets
111
- changesets[0].revision.to_i
112
- end
113
- end
114
- end
115
-
116
- def commit(checkout_dir, message)
117
- svn(checkout_dir, commit_command(message))
103
+ def commit(message)
104
+ svn(@checkout_dir, commit_command(message))
118
105
  # We have to do an update to get the local revision right
119
- svn(checkout_dir, "update")
106
+ svn(@checkout_dir, "update")
120
107
  end
121
108
 
122
- def label(checkout_dir)
123
- local_revision(checkout_dir).to_s
109
+ def label
110
+ local_revision_identifier.to_s
124
111
  end
125
112
 
126
- def diff(checkout_dir, change, &block)
127
- with_working_dir(checkout_dir) do
128
- cmd = "svn diff -r #{change.previous_revision}:#{change.revision} \"#{url}/#{change.path}\""
129
- safer_popen(cmd) do |io|
113
+ def diff(file, &block)
114
+ with_working_dir(@checkout_dir) do
115
+ cmd = "svn diff -r #{file.previous_native_revision_identifier}:#{file.native_revision_identifier} \"#{url}/#{file.path}\""
116
+ Better.popen(cmd) do |io|
130
117
  return(yield(io))
131
118
  end
132
119
  end
133
120
  end
134
121
 
135
- def can_create?
122
+ def can_create_central?
136
123
  local?
137
124
  end
138
125
 
139
- def exists?
126
+ def destroy_central
127
+ FileUtils.rm_rf(svnrootdir)
128
+ end
129
+
130
+ def central_exists?
140
131
  if(local?)
141
132
  File.exists?("#{svnrootdir}/db")
142
133
  else
@@ -145,7 +136,7 @@ module RSCM
145
136
  # on stdout (and an error msg on std err).
146
137
  exists = false
147
138
  cmd = "svn log #{url} -r HEAD"
148
- IO.popen(cmd) do |stdout|
139
+ Better.popen(cmd) do |stdout|
149
140
  stdout.each_line do |line|
150
141
  exists = true
151
142
  end
@@ -158,7 +149,7 @@ module RSCM
158
149
  local?
159
150
  end
160
151
 
161
- def create
152
+ def create_central
162
153
  native_path = PathConverter.filepath_to_nativepath(svnrootdir, true)
163
154
  mkdir_p(PathConverter.nativepath_to_filepath(native_path))
164
155
  svnadmin(svnrootdir, "create #{native_path}")
@@ -182,27 +173,27 @@ module RSCM
182
173
  not_already_commented
183
174
  end
184
175
 
185
- def import(dir, message)
176
+ def import_central(dir, message)
186
177
  import_cmd = "import #{url} -m \"#{message}\""
187
178
  svn(dir, import_cmd)
188
179
  end
189
180
 
190
- def changesets(checkout_dir, from_identifier, to_identifier=Time.infinity)
191
- # Return empty changeset if the requested revision doesn't exist yet.
192
- return ChangeSets.new if(from_identifier.is_a?(Integer) && head_revision(checkout_dir) < from_identifier)
181
+ def revisions(from_identifier, to_identifier=Time.infinity)
182
+ # Return empty revision if the requested revision doesn't exist yet.
183
+ return Revisions.new if(from_identifier.is_a?(Integer) && head_revision_identifier <= from_identifier)
193
184
 
194
- checkout_dir = PathConverter.filepath_to_nativepath(checkout_dir, false)
195
- changesets = nil
185
+ checkout_dir = PathConverter.filepath_to_nativepath(@checkout_dir, false)
186
+ revisions = nil
196
187
  command = "svn #{changes_command(from_identifier, to_identifier)}"
197
188
  yield command if block_given?
198
189
 
199
- with_working_dir(checkout_dir) do
200
- safer_popen(command) do |stdout|
201
- parser = SubversionLogParser.new(stdout, path, checkout_dir)
202
- changesets = parser.parse_changesets
190
+ with_working_dir(@checkout_dir) do
191
+ Better.popen(command) do |stdout|
192
+ parser = SubversionLogParser.new(stdout, @url)
193
+ revisions = parser.parse_revisions
203
194
  end
204
195
  end
205
- changesets
196
+ revisions
206
197
  end
207
198
 
208
199
  # url pointing to the root of the repo
@@ -211,7 +202,7 @@ module RSCM
211
202
  url[0..last]
212
203
  end
213
204
 
214
- def checked_out?(checkout_dir)
205
+ def checked_out?
215
206
  rootentries = File.expand_path("#{checkout_dir}/.svn/entries")
216
207
  result = File.exists?(rootentries)
217
208
  result
@@ -219,6 +210,30 @@ module RSCM
219
210
 
220
211
  private
221
212
 
213
+ def local_revision_identifier
214
+ local_revision_identifier = nil
215
+ svn(@checkout_dir, "info") do |line|
216
+ if(line =~ /Revision: ([0-9]*)/)
217
+ return $1.to_i
218
+ end
219
+ end
220
+ end
221
+
222
+ def head_revision_identifier
223
+ # This command only seems to yield any changesets if the url is the root of
224
+ # the repo, which we don't know in the case where path is not specified (likely)
225
+ # We therefore don't specify it and get the latest revision from the full url instead.
226
+ # cmd = "svn log #{login_options} #{repourl} -r HEAD"
227
+ cmd = "svn log #{login_options} #{url}"
228
+ with_working_dir(@checkout_dir) do
229
+ Better.popen(cmd) do |stdout|
230
+ parser = SubversionLogParser.new(stdout, @url)
231
+ revisions = parser.parse_revisions
232
+ revisions[0].identifier.to_i
233
+ end
234
+ end
235
+ end
236
+
222
237
  def install_unix_trigger(trigger_command, damagecontrol_install_dir)
223
238
  post_commit_exists = File.exists?(post_commit_file)
224
239
  mode = post_commit_exists ? File::APPEND|File::WRONLY : File::CREAT|File::WRONLY
@@ -227,7 +242,7 @@ module RSCM
227
242
  file.puts("#!/bin/sh") unless post_commit_exists
228
243
  file.puts("#{trigger_command}\n" )
229
244
  end
230
- system("chmod g+x #{post_commit_file}")
245
+ File.chmod(0744, post_commit_file)
231
246
  rescue
232
247
  raise "Didn't have permission to write to #{post_commit_file}. " +
233
248
  "Try to manually add the following line:\n\n#{trigger_command}\n\n" +
@@ -265,7 +280,7 @@ module RSCM
265
280
  command_line = "#{executable} #{cmd}"
266
281
  dir = File.expand_path(dir)
267
282
  with_working_dir(dir) do
268
- safer_popen(command_line) do |stdout|
283
+ Better.popen(command_line) do |stdout|
269
284
  stdout.each_line do |line|
270
285
  yield line if block_given?
271
286
  end
@@ -273,36 +288,50 @@ module RSCM
273
288
  end
274
289
  end
275
290
 
276
- def checkout_command(checkout_dir, to_identifier)
291
+ def checkout_command(to_identifier)
277
292
  checkout_dir = "\"#{checkout_dir}\""
278
- "checkout #{url} #{checkout_dir} #{revision_option(nil,to_identifier)}"
293
+ "checkout #{login_options} #{url} #{checkout_dir} #{revision_option(nil,to_identifier)}"
279
294
  end
280
295
 
281
296
  def update_command(to_identifier)
282
- "update #{revision_option(nil,to_identifier)}"
297
+ "update #{login_options} #{revision_option(nil,to_identifier)}"
283
298
  end
284
299
 
285
300
  def changes_command(from_identifier, to_identifier)
286
301
  # http://svnbook.red-bean.com/svnbook-1.1/svn-book.html#svn-ch-3-sect-3.3
287
302
  # file_list = files.join('\n')
288
303
  # WEIRD cygwin bug garbles this!?!?!?!
289
- cmd = "log --verbose #{revision_option(from_identifier, to_identifier)} #{url}"
304
+ cmd = "log --verbose #{login_options} #{revision_option(from_identifier, to_identifier)} #{url}"
290
305
  cmd
291
306
  end
292
307
 
308
+ def login_options
309
+ result = ""
310
+ u = @username ? @username.strip : nil
311
+ p = @password ? @password.strip : nil
312
+ result << "--username #{u} " if u
313
+ result << "--password #{p} " if p
314
+ result
315
+ end
316
+
293
317
  def revision_option(from_identifier, to_identifier)
318
+ # The inclusive start
294
319
  from = nil
295
320
  if(from_identifier.is_a?(Time))
296
- from = svndate(from_identifier)
297
- else
298
- from = from_identifier
321
+ from = svndate(from_identifier + 1)
322
+ elsif(from_identifier.is_a?(Numeric))
323
+ from = from_identifier + 1
324
+ elsif(!from_identifier.nil?)
325
+ raise "from_identifier must be Numeric, Time or nil. Was: #{from_identifier} (#{from_identifier.class.name})"
299
326
  end
300
327
 
301
328
  to = nil
302
329
  if(to_identifier.is_a?(Time))
303
330
  to = svndate(to_identifier)
304
- else
331
+ elsif(to_identifier.is_a?(Numeric))
305
332
  to = to_identifier
333
+ elsif(!from_identifier.nil?)
334
+ raise "to_identifier must be Numeric, Time or nil. Was: #{to_identifier} (#{to_identifier.class.name})"
306
335
  end
307
336
 
308
337
  revision_option = nil
@@ -1,108 +1,137 @@
1
1
  require 'rscm/parser'
2
- require 'rscm/changes'
2
+ require 'rscm/revision'
3
3
 
4
4
  module RSCM
5
5
 
6
6
  class SubversionLogParser
7
- def initialize(io, path, checkout_dir)
7
+ def initialize(io, url)
8
8
  @io = io
9
- @changeset_parser = SubversionLogEntryParser.new(path, checkout_dir)
9
+ @revision_parser = SubversionLogEntryParser.new(url)
10
10
  end
11
11
 
12
- def parse_changesets(&line_proc)
12
+ def parse_revisions(&line_proc)
13
13
  # skip over the first ------
14
- @changeset_parser.parse(@io, true, &line_proc)
15
- changesets = ChangeSets.new
14
+ @revision_parser.parse(@io, true, &line_proc)
15
+ revisions = Revisions.new
16
16
  while(!@io.eof?)
17
- changeset = @changeset_parser.parse(@io, &line_proc)
18
- if(changeset)
19
- changesets.add(changeset)
17
+ revision = @revision_parser.parse(@io, &line_proc)
18
+ if(revision)
19
+ revisions.add(revision)
20
20
  end
21
21
  end
22
- changesets
22
+ revisions
23
23
  end
24
24
  end
25
25
 
26
26
  class SubversionLogEntryParser < Parser
27
27
 
28
- def initialize(path, checkout_dir)
28
+ def initialize(url)
29
29
  super(/^------------------------------------------------------------------------/)
30
- @path = path ? path : ""
31
- @checkout_dir = checkout_dir
30
+ @url = url
32
31
  end
33
32
 
34
33
  def parse(io, skip_line_parsing=false, &line_proc)
35
34
  # We have to trim off the last newline - it's not meant to be part of the message
36
- changeset = super
37
- changeset.message = changeset.message[0..-2] if changeset
38
- changeset
35
+ revision = super
36
+ revision.message = revision.message[0..-2] if revision
37
+ revision
39
38
  end
40
39
 
40
+ def relative_path(url, repo_path)
41
+ url_tokens = url.split('/')
42
+ repo_path_tokens = repo_path.split('/')
43
+
44
+ max_similar = repo_path_tokens.length
45
+ while(max_similar > 0)
46
+ url = url_tokens[-max_similar..-1]
47
+ path = repo_path_tokens[0..max_similar-1]
48
+ if(url == path)
49
+ break
50
+ end
51
+ max_similar -= 1
52
+ end
53
+ max_similar == 0 ? nil : repo_path_tokens[max_similar..-1].join("/")
54
+ end
55
+
41
56
  protected
42
57
 
43
58
  def parse_line(line)
44
- if(@changeset.nil?)
59
+ if(@revision.nil?)
45
60
  parse_header(line)
46
61
  elsif(line.strip == "")
47
62
  @parse_state = :parse_message
48
63
  elsif(line =~ /Changed paths/)
49
- @parse_state = :parse_changes
50
- elsif(@parse_state == :parse_changes)
51
- change = parse_change(line)
52
- if change
53
- # This unless won't work for new directories or if changesets are computed before checkout (which it usually is!)
54
- fullpath = "#{@checkout_dir}/#{change.path}"
55
- @changeset << change unless File.directory?(fullpath)
64
+ @parse_state = :parse_files
65
+ elsif(@parse_state == :parse_files)
66
+ file = parse_file(line)
67
+ if(file)
68
+ previously_added_file = @revision[-1]
69
+ if(previously_added_file)
70
+ # remove previous revision_file it if it's a dir
71
+ previous_tokens = previously_added_file.path.split("/")
72
+ current_tokens = file.path.split("/")
73
+ current_tokens.pop
74
+ if(previous_tokens == current_tokens)
75
+ @revision.pop
76
+ end
77
+ end
78
+ @revision << file
56
79
  end
57
80
  elsif(@parse_state == :parse_message)
58
- @changeset.message << line.chomp << "\n"
81
+ @revision.message << line.chomp << "\n"
59
82
  end
60
83
  end
61
84
 
62
85
  def next_result
63
- result = @changeset
64
- @changeset = nil
86
+ result = @revision
87
+ @revision = nil
65
88
  result
66
89
  end
67
90
 
68
91
  private
69
92
 
70
- STATES = {"M" => Change::MODIFIED, "A" => Change::ADDED, "D" => Change::DELETED} unless defined? STATES
93
+ STATES = {"M" => RevisionFile::MODIFIED, "A" => RevisionFile::ADDED, "D" => RevisionFile::DELETED} unless defined? STATES
71
94
 
72
95
  def parse_header(line)
73
- @changeset = ChangeSet.new
74
- @changeset.message = ""
96
+ @revision = Revision.new
97
+ @revision.message = ""
75
98
  revision, developer, time, the_rest = line.split("|")
76
- @changeset.revision = revision.strip[1..-1].to_i unless revision.nil?
77
- @changeset.developer = developer.strip unless developer.nil?
78
- @changeset.time = parse_time(time.strip) unless time.nil?
99
+ @revision.identifier = revision.strip[1..-1].to_i unless revision.nil?
100
+ @revision.developer = developer.strip unless developer.nil?
101
+ @revision.time = parse_time(time.strip) unless time.nil?
79
102
  end
80
103
 
81
- def parse_change(line)
82
- change = Change.new
104
+ def parse_file(line)
105
+ file = RevisionFile.new
83
106
  path_from_root = nil
84
107
  if(line =~ /^ [M|A|D|R] ([^\s]+) \(from (.*)\)/)
85
108
  path_from_root = $1
86
- change.status = Change::MOVED
109
+ file.status = RevisionFile::MOVED
87
110
  elsif(line =~ /^ ([M|A|D|R]) (.+)$/)
88
111
  status = $1
89
112
  path_from_root = $2
90
- change.status = STATES[status]
113
+ file.status = STATES[status]
91
114
  else
92
- raise "could not parse change line: '#{line}'"
115
+ raise "could not parse file line: '#{line}'"
93
116
  end
94
117
 
95
118
  path_from_root.gsub!(/\\/, "/")
96
- return nil unless path_from_root =~ /^\/#{@path}/
97
- if(@path.length+1 == path_from_root.length)
98
- change.path = path_from_root[@path.length+1..-1]
99
- else
100
- change.path = path_from_root[@path.length+2..-1]
101
- end
102
- change.revision = @changeset.revision
119
+ path_from_root = path_from_root[1..-1]
120
+ rp = relative_path(@url, path_from_root)
121
+ return if rp.nil?
122
+ file.path = rp
123
+
124
+
125
+ # if(@path.length+1 == path_from_root.length)
126
+ # file.path = path_from_root[@path.length+1..-1]
127
+ # else
128
+ # file.path = path_from_root[@path.length+2..-1]
129
+ # end
130
+
131
+ file.native_revision_identifier = @revision.identifier
103
132
  # http://jira.codehaus.org/browse/DC-204
104
- change.previous_revision = change.revision.to_i - 1;
105
- change
133
+ file.previous_native_revision_identifier = file.native_revision_identifier.to_i - 1;
134
+ file
106
135
  end
107
136
 
108
137
  def parse_time(svn_time)