##// END OF EJS Templates
Added svn command output to error log when SubversionAdapter#entries parsing fails....
Jean-Philippe Lang -
r769:c2220cffcfbf
parent child
Show More
@@ -1,175 +1,178
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require 'redmine/scm/adapters/abstract_adapter'
19 19 require 'rexml/document'
20 20
21 21 module Redmine
22 22 module Scm
23 23 module Adapters
24 24 class SubversionAdapter < AbstractAdapter
25 25
26 26 # SVN executable name
27 27 SVN_BIN = "svn"
28 28
29 29 # Get info about the svn repository
30 30 def info
31 31 cmd = "#{SVN_BIN} info --xml #{target('')}"
32 32 cmd << " --username #{@login} --password #{@password}" if @login
33 33 info = nil
34 34 shellout(cmd) do |io|
35 35 begin
36 36 doc = REXML::Document.new(io)
37 37 #root_url = doc.elements["info/entry/repository/root"].text
38 38 info = Info.new({:root_url => doc.elements["info/entry/repository/root"].text,
39 39 :lastrev => Revision.new({
40 40 :identifier => doc.elements["info/entry/commit"].attributes['revision'],
41 41 :time => Time.parse(doc.elements["info/entry/commit/date"].text).localtime,
42 42 :author => (doc.elements["info/entry/commit/author"] ? doc.elements["info/entry/commit/author"].text : "")
43 43 })
44 44 })
45 45 rescue
46 46 end
47 47 end
48 48 return nil if $? && $?.exitstatus != 0
49 49 info
50 50 rescue Errno::ENOENT => e
51 51 return nil
52 52 end
53 53
54 54 # Returns the entry identified by path and revision identifier
55 55 # or nil if entry doesn't exist in the repository
56 56 def entry(path=nil, identifier=nil)
57 57 e = entries(path, identifier)
58 58 e ? e.first : nil
59 59 end
60 60
61 61 # Returns an Entries collection
62 62 # or nil if the given path doesn't exist in the repository
63 63 def entries(path=nil, identifier=nil)
64 64 path ||= ''
65 65 identifier = 'HEAD' unless identifier and identifier > 0
66 66 entries = Entries.new
67 67 cmd = "#{SVN_BIN} list --xml #{target(path)}@#{identifier}"
68 68 cmd << " --username #{@login} --password #{@password}" if @login
69 cmd << " 2>&1"
69 70 shellout(cmd) do |io|
71 output = io.read
70 72 begin
71 doc = REXML::Document.new(io)
73 doc = REXML::Document.new(output)
72 74 doc.elements.each("lists/list/entry") do |entry|
73 75 entries << Entry.new({:name => entry.elements['name'].text,
74 76 :path => ((path.empty? ? "" : "#{path}/") + entry.elements['name'].text),
75 77 :kind => entry.attributes['kind'],
76 78 :size => (entry.elements['size'] and entry.elements['size'].text).to_i,
77 79 :lastrev => Revision.new({
78 80 :identifier => entry.elements['commit'].attributes['revision'],
79 81 :time => Time.parse(entry.elements['commit'].elements['date'].text).localtime,
80 82 :author => (entry.elements['commit'].elements['author'] ? entry.elements['commit'].elements['author'].text : "")
81 83 })
82 84 })
83 85 end
84 86 rescue Exception => e
85 logger.info("Error parsing svn output: #{e.message}")
87 logger.error("Error parsing svn output: #{e.message}")
88 logger.error("Output was:\n #{output}")
86 89 end
87 90 end
88 91 return nil if $? && $?.exitstatus != 0
89 92 logger.debug("Found #{entries.size} entries in the repository for #{target(path)}") if logger && logger.debug?
90 93 entries.sort_by_name
91 94 rescue Errno::ENOENT => e
92 95 raise CommandFailed
93 96 end
94 97
95 98 def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={})
96 99 path ||= ''
97 100 identifier_from = 'HEAD' unless identifier_from and identifier_from.to_i > 0
98 101 identifier_to = 1 unless identifier_to and identifier_to.to_i > 0
99 102 revisions = Revisions.new
100 103 cmd = "#{SVN_BIN} log --xml -r #{identifier_from}:#{identifier_to}"
101 104 cmd << " --username #{@login} --password #{@password}" if @login
102 105 cmd << " --verbose " if options[:with_paths]
103 106 cmd << target(path)
104 107 shellout(cmd) do |io|
105 108 begin
106 109 doc = REXML::Document.new(io)
107 110 doc.elements.each("log/logentry") do |logentry|
108 111 paths = []
109 112 logentry.elements.each("paths/path") do |path|
110 113 paths << {:action => path.attributes['action'],
111 114 :path => path.text,
112 115 :from_path => path.attributes['copyfrom-path'],
113 116 :from_revision => path.attributes['copyfrom-rev']
114 117 }
115 118 end
116 119 paths.sort! { |x,y| x[:path] <=> y[:path] }
117 120
118 121 revisions << Revision.new({:identifier => logentry.attributes['revision'],
119 122 :author => (logentry.elements['author'] ? logentry.elements['author'].text : ""),
120 123 :time => Time.parse(logentry.elements['date'].text).localtime,
121 124 :message => logentry.elements['msg'].text,
122 125 :paths => paths
123 126 })
124 127 end
125 128 rescue
126 129 end
127 130 end
128 131 return nil if $? && $?.exitstatus != 0
129 132 revisions
130 133 rescue Errno::ENOENT => e
131 134 raise CommandFailed
132 135 end
133 136
134 137 def diff(path, identifier_from, identifier_to=nil, type="inline")
135 138 path ||= ''
136 139 if identifier_to and identifier_to.to_i > 0
137 140 identifier_to = identifier_to.to_i
138 141 else
139 142 identifier_to = identifier_from.to_i - 1
140 143 end
141 144 cmd = "#{SVN_BIN} diff -r "
142 145 cmd << "#{identifier_to}:"
143 146 cmd << "#{identifier_from}"
144 147 cmd << "#{target(path)}@#{identifier_from}"
145 148 cmd << " --username #{@login} --password #{@password}" if @login
146 149 diff = []
147 150 shellout(cmd) do |io|
148 151 io.each_line do |line|
149 152 diff << line
150 153 end
151 154 end
152 155 return nil if $? && $?.exitstatus != 0
153 156 DiffTableList.new diff, type
154 157 rescue Errno::ENOENT => e
155 158 raise CommandFailed
156 159 end
157 160
158 161 def cat(path, identifier=nil)
159 162 identifier = (identifier and identifier.to_i > 0) ? identifier.to_i : "HEAD"
160 163 cmd = "#{SVN_BIN} cat #{target(path)}@#{identifier}"
161 164 cmd << " --username #{@login} --password #{@password}" if @login
162 165 cat = nil
163 166 shellout(cmd) do |io|
164 167 io.binmode
165 168 cat = io.read
166 169 end
167 170 return nil if $? && $?.exitstatus != 0
168 171 cat
169 172 rescue Errno::ENOENT => e
170 173 raise CommandFailed
171 174 end
172 175 end
173 176 end
174 177 end
175 178 end
General Comments 0
You need to be logged in to leave comments. Login now