Index: cvs_adapter.rb =================================================================== --- cvs_adapter.rb (revision 2904) +++ cvs_adapter.rb (working copy) @@ -61,35 +61,65 @@ # this method is used by the repository-browser (aka LIST) def entries(path=nil, identifier=nil) logger.debug " entries '#{path}' with identifier '#{identifier}'" - path_with_project="#{url}#{with_leading_slash(path)}" + # build regular expression used to parse revision info + re_loginfo = "revision ([0-9.]+)\s*\n" + re_loginfo << "date: ([^;]+); author: ([^;]+)[^\n]*?\n" + re_loginfo << "(branches: [0-9.]+;[^\n]*?\n)?" + re_loginfo << "(.*?)\r?\n(#{STARTLOG}|#{ENDLOG})" + re_loginfo = Regexp.new(re_loginfo, Regexp:: MULTILINE) + # read directory listing + path_with_project = "#{url}#{with_leading_slash(path)}" + path_with_project = with_trailling_slash(path_with_project) entries = Entries.new - cmd = "#{CVS_BIN} -d #{root_url} rls -e" - cmd << " -D \"#{time_to_cvstime(identifier)}\"" if identifier + cmd = "#{CVS_BIN} -d #{root_url} -q -n rlog -R" + cmd << " -d \"#{time_to_cvstime(identifier)}\"" if identifier cmd << " #{shell_quote path_with_project}" + dir_path_len = "#{root_url_path}/#{path_with_project}".length + dirs = {} shellout(cmd) do |io| io.each_line(){|line| - fields=line.chop.split('/',-1) - logger.debug(">>InspectLine #{fields.inspect}") - - if fields[0]!="D" - entries << Entry.new({:name => fields[-5], - #:path => fields[-4].include?(path)?fields[-4]:(path + "/"+ fields[-4]), - :path => "#{path}/#{fields[-5]}", - :kind => 'file', - :size => nil, - :lastrev => Revision.new({ - :revision => fields[-4], - :name => fields[-4], - :time => Time.parse(fields[-3]), - :author => '' + logger.debug(">>InspectLine #{line}") + line.chomp!.slice!(0, dir_path_len) + slash_pos = line.index('/') + if slash_pos + # directory + line.slice!(slash_pos, line.length) + if not dirs.has_key?(line) + entries << Entry.new({:name => line, + :path => "#{path}/#{line}", + :kind => 'dir', + :size => nil, + :lastrev => nil }) - }) + dirs[line] = 1 + end else - entries << Entry.new({:name => fields[1], - :path => "#{path}/#{fields[1]}", - :kind => 'dir', + # file + line.sub!(/,.*/, '') + file_path = "#{path_with_project}#{line}" + # try to read revision info + rev = nil + cmd = "#{CVS_BIN} -d #{root_url} -q -n rlog -b" + cmd << " -d \"#{time_to_cvstime(identifier)}\"" if identifier + cmd << " #{shell_quote file_path}" + shellout(cmd) do |log| + # We need only the first revision. Take sufficiently large + # chunk from the beginnig of the output. + match = re_loginfo.match(log.read(16384)) + if match + rev = Revision.new({ + :revision => match[1], + :name => match[1], + :time => Time.parse(match[2]), + :author => match[3] + }) + end + end + entries << Entry.new({:name => line, + :path => "#{path}/#{line}", + :kind => 'file', :size => nil, - :lastrev => nil + :lastrev => rev }) end }