61 |
61 |
# this method is used by the repository-browser (aka LIST)
|
62 |
62 |
def entries(path=nil, identifier=nil)
|
63 |
63 |
logger.debug "<cvs> entries '#{path}' with identifier '#{identifier}'"
|
64 |
|
path_with_project="#{url}#{with_leading_slash(path)}"
|
|
64 |
# build regular expression used to parse revision info
|
|
65 |
re_loginfo = "revision ([0-9.]+)\s*\n"
|
|
66 |
re_loginfo << "date: ([^;]+); author: ([^;]+)[^\n]*?\n"
|
|
67 |
re_loginfo << "(branches: [0-9.]+;[^\n]*?\n)?"
|
|
68 |
re_loginfo << "(.*?)\r?\n(#{STARTLOG}|#{ENDLOG})"
|
|
69 |
re_loginfo = Regexp.new(re_loginfo, Regexp:: MULTILINE)
|
|
70 |
# read directory listing
|
|
71 |
path_with_project = "#{url}#{with_leading_slash(path)}"
|
|
72 |
path_with_project = with_trailling_slash(path_with_project)
|
65 |
73 |
entries = Entries.new
|
66 |
|
cmd = "#{CVS_BIN} -d #{root_url} rls -e"
|
67 |
|
cmd << " -D \"#{time_to_cvstime(identifier)}\"" if identifier
|
|
74 |
cmd = "#{CVS_BIN} -d #{root_url} -q -n rlog -R"
|
|
75 |
cmd << " -d \"#{time_to_cvstime(identifier)}\"" if identifier
|
68 |
76 |
cmd << " #{shell_quote path_with_project}"
|
|
77 |
dir_path_len = "#{root_url_path}/#{path_with_project}".length
|
|
78 |
dirs = {}
|
69 |
79 |
shellout(cmd) do |io|
|
70 |
80 |
io.each_line(){|line|
|
71 |
|
fields=line.chop.split('/',-1)
|
72 |
|
logger.debug(">>InspectLine #{fields.inspect}")
|
73 |
|
|
74 |
|
if fields[0]!="D"
|
75 |
|
entries << Entry.new({:name => fields[-5],
|
76 |
|
#:path => fields[-4].include?(path)?fields[-4]:(path + "/"+ fields[-4]),
|
77 |
|
:path => "#{path}/#{fields[-5]}",
|
78 |
|
:kind => 'file',
|
79 |
|
:size => nil,
|
80 |
|
:lastrev => Revision.new({
|
81 |
|
:revision => fields[-4],
|
82 |
|
:name => fields[-4],
|
83 |
|
:time => Time.parse(fields[-3]),
|
84 |
|
:author => ''
|
|
81 |
logger.debug(">>InspectLine #{line}")
|
|
82 |
line.chomp!.slice!(0, dir_path_len)
|
|
83 |
slash_pos = line.index('/')
|
|
84 |
if slash_pos
|
|
85 |
# directory
|
|
86 |
line.slice!(slash_pos, line.length)
|
|
87 |
if not dirs.has_key?(line)
|
|
88 |
entries << Entry.new({:name => line,
|
|
89 |
:path => "#{path}/#{line}",
|
|
90 |
:kind => 'dir',
|
|
91 |
:size => nil,
|
|
92 |
:lastrev => nil
|
85 |
93 |
})
|
86 |
|
})
|
|
94 |
dirs[line] = 1
|
|
95 |
end
|
87 |
96 |
else
|
88 |
|
entries << Entry.new({:name => fields[1],
|
89 |
|
:path => "#{path}/#{fields[1]}",
|
90 |
|
:kind => 'dir',
|
|
97 |
# file
|
|
98 |
line.sub!(/,.*/, '')
|
|
99 |
file_path = "#{path_with_project}#{line}"
|
|
100 |
# try to read revision info
|
|
101 |
rev = nil
|
|
102 |
cmd = "#{CVS_BIN} -d #{root_url} -q -n rlog -b"
|
|
103 |
cmd << " -d \"#{time_to_cvstime(identifier)}\"" if identifier
|
|
104 |
cmd << " #{shell_quote file_path}"
|
|
105 |
shellout(cmd) do |log|
|
|
106 |
# We need only the first revision. Take sufficiently large
|
|
107 |
# chunk from the beginnig of the output.
|
|
108 |
match = re_loginfo.match(log.read(16384))
|
|
109 |
if match
|
|
110 |
rev = Revision.new({
|
|
111 |
:revision => match[1],
|
|
112 |
:name => match[1],
|
|
113 |
:time => Time.parse(match[2]),
|
|
114 |
:author => match[3]
|
|
115 |
})
|
|
116 |
end
|
|
117 |
end
|
|
118 |
entries << Entry.new({:name => line,
|
|
119 |
:path => "#{path}/#{line}",
|
|
120 |
:kind => 'file',
|
91 |
121 |
:size => nil,
|
92 |
|
:lastrev => nil
|
|
122 |
:lastrev => rev
|
93 |
123 |
})
|
94 |
124 |
end
|
95 |
125 |
}
|