Class RSCM::CvsLogParser
In: lib/rscm/scm/cvs_log_parser.rb
Parent: AbstractLogParser

Methods

Constants

REVISION_SEPARATOR = /^----------------------------$/ unless defined? REVISION_SEPARATOR
ENTRY_SEPARATOR = /^=============================================================================$/ unless defined? ENTRY_SEPARATOR
STATES = {"dead" => RevisionFile::DELETED, "Exp" => RevisionFile::MODIFIED} unless defined? STATES   The state field is "Exp" both for added and modified files. retards! We need some additional logic to figure out whether it is added or not. Maybe look at the revision. (1.1 means new I think. - deal with it later)

Attributes

cvsmodule  [RW] 
cvspath  [RW] 

Public Class methods

[Source]

    # File lib/rscm/scm/cvs_log_parser.rb, line 15
15:     def initialize(io)
16:       super(io)
17:     end

Public Instance methods

[Source]

     # File lib/rscm/scm/cvs_log_parser.rb, line 120
120:     def determine_previous_native_revision_identifier(revision)
121:       if revision =~ /(.*)\.(.*)/
122:         big_version_number = $1
123:         small_version_number = $2.to_i
124:         if small_version_number == 1
125:           nil
126:         else
127:           "#{big_version_number}.#{small_version_number - 1}"
128:         end
129:       else
130:         nil
131:       end
132:     end

[Source]

     # File lib/rscm/scm/cvs_log_parser.rb, line 142
142:     def extract_match(string, regexp)
143:       if string=~regexp
144:         return($1)
145:       else
146:         ""
147:       end
148:     end

[Source]

     # File lib/rscm/scm/cvs_log_parser.rb, line 134
134:     def extract_required_match(string, regexp)
135:       if(string =~ regexp)
136:         return($1)
137:       else
138:         $stderr.puts("can't parse: '#{string}'\nexpected to match regexp: #{regexp.to_s}")
139:       end
140:     end

[Source]

    # File lib/rscm/scm/cvs_log_parser.rb, line 76
76:     def make_relative_to_module(file)
77:       return file if cvspath.nil? || cvsmodule.nil? || file.nil?
78:       cvspath = convert_all_slashes_to_forward_slashes(self.cvspath)
79:       convert_all_slashes_to_forward_slashes(file).gsub(/^#{cvspath}\/#{cvsmodule}\//, "")
80:     end

[Source]

    # File lib/rscm/scm/cvs_log_parser.rb, line 32
32:     def next_log_entry
33:       read_until_matching_line(ENTRY_SEPARATOR)
34:     end

[Source]

     # File lib/rscm/scm/cvs_log_parser.rb, line 82
 82:     def parse_file(file_entry)
 83:       raise "can't parse: #{file_entry}" if file_entry =~ REVISION_SEPARATOR
 84:          
 85:       file_entry_lines = file_entry.split(/\r?\n/)
 86:       file = RevisionFile.new
 87: 
 88:       file.native_revision_identifier =  extract_match(file_entry_lines[0], /revision (.*)$/)
 89:       
 90:       file.previous_native_revision_identifier = determine_previous_native_revision_identifier(file.native_revision_identifier)
 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
 98:       file.developer = extract_match(file_entry_lines[1], /author: (.*?);/)
 99:       
100:       state = extract_match(file_entry_lines[1], /state: (.*?);/)
101:       file.status = STATES[state]
102:       
103:       message_start = 2
104:       branches = nil
105:       if(file_entry_lines[2] =~ /^branches:\s+(.*);/)
106:         message_start = 3
107:         branches = $1
108:       end
109: 
110:       file.message = file_entry_lines[message_start..-1].join("\n")
111:          
112:       # Ignore the initial revision from import - we will have two of them

113:       if(file.message == "Initial revision" && branches == "1.1.1")
114:         return nil
115:       end
116: 
117:       file
118:     end

[Source]

    # File lib/rscm/scm/cvs_log_parser.rb, line 48
48:     def parse_files(log_entry, revisions)
49:       entries = split_entries(log_entry)
50: 
51:       entries[1..entries.length].each do |entry|
52:         file = parse_file(entry)
53:         next if file.nil?
54:         file.path = parse_path(entries[0])
55: 
56:         file.status = RevisionFile::ADDED if file.native_revision_identifier =~ /1\.1$/
57: 
58:         revision = revisions.add(file)
59:         # CVS doesn't have revision for revisions, use

60:         # Fisheye-style revision

61: #        revision.native_revision_identifier =  "MAIN:#{file.developer}:#{file.time.utc.strftime('%Y%m%d%H%M%S')}" if revision

62:       end
63:       nil
64:     end

[Source]

    # File lib/rscm/scm/cvs_log_parser.rb, line 66
66:     def parse_head_revision(first_entry)
67:       head_revision = extract_match(first_entry, /^head: (.*?)$/m)
68:     end

[Source]

    # File lib/rscm/scm/cvs_log_parser.rb, line 70
70:     def parse_path(first_entry)
71:       working_file = extract_match(first_entry, /^Working file: (.*?)$/m)
72:       return convert_all_slashes_to_forward_slashes(working_file) unless working_file.nil? || working_file == ""
73:       make_relative_to_module(extract_required_match(first_entry, /^RCS file: (.*?)(,v|$)/m))
74:     end

[Source]

    # File lib/rscm/scm/cvs_log_parser.rb, line 19
19:     def parse_revisions
20:       revisions = Revisions.new
21:       while(log_entry = next_log_entry)
22:         begin
23:           parse_files(log_entry, revisions)
24:         rescue Exception => e
25:           $stderr.puts("could not parse log entry: #{log_entry}\ndue to: #{e.message}\n\t")
26:           $stderr.puts(e.backtrace.join("\n\t"))
27:         end
28:       end
29:       revisions.sort!
30:     end

[Source]

    # File lib/rscm/scm/cvs_log_parser.rb, line 36
36:     def split_entries(log_entry)
37:       entries = [""]
38:       log_entry.each_line do |line|
39:         if line=~REVISION_SEPARATOR
40:           entries << ""
41:         else
42:           entries[entries.length-1] << line
43:         end
44:       end
45:       entries
46:     end

[Validate]