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 115
115:     def determine_previous_native_revision_identifier(revision)
116:       if revision =~ /(.*)\.(.*)/
117:         big_version_number = $1
118:         small_version_number = $2.to_i
119:         if small_version_number == 1
120:           nil
121:         else
122:           "#{big_version_number}.#{small_version_number - 1}"
123:         end
124:       else
125:         nil
126:       end
127:     end

[Source]

     # File lib/rscm/scm/cvs_log_parser.rb, line 137
137:     def extract_match(string, regexp)
138:       if string=~regexp
139:         return($1)
140:       else
141:         ""
142:       end
143:     end

[Source]

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

[Source]

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

[Source]

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

[Source]

     # File lib/rscm/scm/cvs_log_parser.rb, line 78
 78:     def parse_file(file_entry)
 79:       raise "can't parse: #{file_entry}" if file_entry =~ REVISION_SEPARATOR
 80:          
 81:       file_entry_lines = file_entry.split(/\r?\n/)
 82: 
 83:       file = RevisionFile.new
 84:       file.native_revision_identifier =  extract_match(file_entry_lines[0], /revision (.*)$/)
 85:       file.previous_native_revision_identifier = determine_previous_native_revision_identifier(file.native_revision_identifier)
 86: 
 87:       time = extract_required_match(file_entry_lines[1], /date: (.*?)(;|$)/)
 88:       if(time.strip.length == 19)
 89:         # CVS 1.11.x doesn't specify timezone (but assumes UTC), so we'll add it here.

 90:         time += " +0000"
 91:       end
 92:       file.time = Time.parse(time).utc
 93:       file.developer = extract_match(file_entry_lines[1], /author: (.*?);/)
 94:       
 95:       state = extract_match(file_entry_lines[1], /state: (.*?);/)
 96:       file.status = STATES[state]
 97:       
 98:       message_start = 2
 99:       branches = nil
100:       if(file_entry_lines[2] =~ /^branches:\s+(.*);/)
101:         message_start = 3
102:         branches = $1
103:       end
104: 
105:       file.message = file_entry_lines[message_start..-1].join("\n")
106:          
107:       # Ignore the initial revision from import - we will have two of them

108:       if(file.message == "Initial revision" && branches == "1.1.1")
109:         return nil
110:       end
111: 
112:       file
113:     end

[Source]

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

[Source]

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

[Source]

    # File lib/rscm/scm/cvs_log_parser.rb, line 66
66:     def parse_path(first_entry)
67:       working_file = extract_match(first_entry, /^Working file: (.*?)$/m)
68:       return convert_all_slashes_to_forward_slashes(working_file) unless working_file.nil? || working_file == ""
69:       make_relative_to_module(extract_required_match(first_entry, /^RCS file: (.*?)(,v|$)/m))
70:     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:       revisions
31:     end

[Source]

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

[Validate]