Mercurial > hg > soundsoftware-site
comparison lib/redmine/scm/adapters/darcs_adapter.rb @ 245:051f544170fe
* Update to SVN trunk revision 4993
author | Chris Cannam |
---|---|
date | Thu, 03 Mar 2011 11:42:28 +0000 |
parents | 0579821a129a |
children | cbce1fd3b1b7 |
comparison
equal
deleted
inserted
replaced
244:8972b600f4fb | 245:051f544170fe |
---|---|
18 require 'redmine/scm/adapters/abstract_adapter' | 18 require 'redmine/scm/adapters/abstract_adapter' |
19 require 'rexml/document' | 19 require 'rexml/document' |
20 | 20 |
21 module Redmine | 21 module Redmine |
22 module Scm | 22 module Scm |
23 module Adapters | 23 module Adapters |
24 class DarcsAdapter < AbstractAdapter | 24 class DarcsAdapter < AbstractAdapter |
25 # Darcs executable name | 25 # Darcs executable name |
26 DARCS_BIN = Redmine::Configuration['scm_darcs_command'] || "darcs" | 26 DARCS_BIN = Redmine::Configuration['scm_darcs_command'] || "darcs" |
27 | 27 |
28 class << self | 28 class << self |
29 def client_command | |
30 @@bin ||= DARCS_BIN | |
31 end | |
32 | |
33 def sq_bin | |
34 @@sq_bin ||= shell_quote(DARCS_BIN) | |
35 end | |
36 | |
29 def client_version | 37 def client_version |
30 @@client_version ||= (darcs_binary_version || []) | 38 @@client_version ||= (darcs_binary_version || []) |
31 end | 39 end |
32 | 40 |
41 def client_available | |
42 !client_version.empty? | |
43 end | |
44 | |
33 def darcs_binary_version | 45 def darcs_binary_version |
34 darcsversion = darcs_binary_version_from_command_line | 46 darcsversion = darcs_binary_version_from_command_line.dup |
47 if darcsversion.respond_to?(:force_encoding) | |
48 darcsversion.force_encoding('ASCII-8BIT') | |
49 end | |
35 if m = darcsversion.match(%r{\A(.*?)((\d+\.)+\d+)}) | 50 if m = darcsversion.match(%r{\A(.*?)((\d+\.)+\d+)}) |
36 m[2].scan(%r{\d+}).collect(&:to_i) | 51 m[2].scan(%r{\d+}).collect(&:to_i) |
37 end | 52 end |
38 end | 53 end |
39 | 54 |
40 def darcs_binary_version_from_command_line | 55 def darcs_binary_version_from_command_line |
41 shellout("#{DARCS_BIN} --version") { |io| io.read }.to_s | 56 shellout("#{sq_bin} --version") { |io| io.read }.to_s |
42 end | 57 end |
43 end | 58 end |
44 | 59 |
45 def initialize(url, root_url=nil, login=nil, password=nil) | 60 def initialize(url, root_url=nil, login=nil, password=nil, |
61 path_encoding=nil) | |
46 @url = url | 62 @url = url |
47 @root_url = url | 63 @root_url = url |
48 end | 64 end |
49 | 65 |
50 def supports_cat? | 66 def supports_cat? |
55 # Get info about the darcs repository | 71 # Get info about the darcs repository |
56 def info | 72 def info |
57 rev = revisions(nil,nil,nil,{:limit => 1}) | 73 rev = revisions(nil,nil,nil,{:limit => 1}) |
58 rev ? Info.new({:root_url => @url, :lastrev => rev.last}) : nil | 74 rev ? Info.new({:root_url => @url, :lastrev => rev.last}) : nil |
59 end | 75 end |
60 | 76 |
61 # Returns an Entries collection | 77 # Returns an Entries collection |
62 # or nil if the given path doesn't exist in the repository | 78 # or nil if the given path doesn't exist in the repository |
63 def entries(path=nil, identifier=nil) | 79 def entries(path=nil, identifier=nil) |
64 path_prefix = (path.blank? ? '' : "#{path}/") | 80 path_prefix = (path.blank? ? '' : "#{path}/") |
65 if path.blank? | 81 if path.blank? |
66 path = ( self.class.client_version_above?([2, 2, 0]) ? @url : '.' ) | 82 path = ( self.class.client_version_above?([2, 2, 0]) ? @url : '.' ) |
67 end | 83 end |
68 entries = Entries.new | 84 entries = Entries.new |
69 cmd = "#{DARCS_BIN} annotate --repodir #{shell_quote @url} --xml-output" | 85 cmd = "#{self.class.sq_bin} annotate --repodir #{shell_quote @url} --xml-output" |
70 cmd << " --match #{shell_quote("hash #{identifier}")}" if identifier | 86 cmd << " --match #{shell_quote("hash #{identifier}")}" if identifier |
71 cmd << " #{shell_quote path}" | 87 cmd << " #{shell_quote path}" |
72 shellout(cmd) do |io| | 88 shellout(cmd) do |io| |
73 begin | 89 begin |
74 doc = REXML::Document.new(io) | 90 doc = REXML::Document.new(io) |
84 end | 100 end |
85 end | 101 end |
86 return nil if $? && $?.exitstatus != 0 | 102 return nil if $? && $?.exitstatus != 0 |
87 entries.compact.sort_by_name | 103 entries.compact.sort_by_name |
88 end | 104 end |
89 | 105 |
90 def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={}) | 106 def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={}) |
91 path = '.' if path.blank? | 107 path = '.' if path.blank? |
92 revisions = Revisions.new | 108 revisions = Revisions.new |
93 cmd = "#{DARCS_BIN} changes --repodir #{shell_quote @url} --xml-output" | 109 cmd = "#{self.class.sq_bin} changes --repodir #{shell_quote @url} --xml-output" |
94 cmd << " --from-match #{shell_quote("hash #{identifier_from}")}" if identifier_from | 110 cmd << " --from-match #{shell_quote("hash #{identifier_from}")}" if identifier_from |
95 cmd << " --last #{options[:limit].to_i}" if options[:limit] | 111 cmd << " --last #{options[:limit].to_i}" if options[:limit] |
96 shellout(cmd) do |io| | 112 shellout(cmd) do |io| |
97 begin | 113 begin |
98 doc = REXML::Document.new(io) | 114 doc = REXML::Document.new(io) |
111 end | 127 end |
112 end | 128 end |
113 return nil if $? && $?.exitstatus != 0 | 129 return nil if $? && $?.exitstatus != 0 |
114 revisions | 130 revisions |
115 end | 131 end |
116 | 132 |
117 def diff(path, identifier_from, identifier_to=nil) | 133 def diff(path, identifier_from, identifier_to=nil) |
118 path = '*' if path.blank? | 134 path = '*' if path.blank? |
119 cmd = "#{DARCS_BIN} diff --repodir #{shell_quote @url}" | 135 cmd = "#{self.class.sq_bin} diff --repodir #{shell_quote @url}" |
120 if identifier_to.nil? | 136 if identifier_to.nil? |
121 cmd << " --match #{shell_quote("hash #{identifier_from}")}" | 137 cmd << " --match #{shell_quote("hash #{identifier_from}")}" |
122 else | 138 else |
123 cmd << " --to-match #{shell_quote("hash #{identifier_from}")}" | 139 cmd << " --to-match #{shell_quote("hash #{identifier_from}")}" |
124 cmd << " --from-match #{shell_quote("hash #{identifier_to}")}" | 140 cmd << " --from-match #{shell_quote("hash #{identifier_to}")}" |
131 end | 147 end |
132 end | 148 end |
133 return nil if $? && $?.exitstatus != 0 | 149 return nil if $? && $?.exitstatus != 0 |
134 diff | 150 diff |
135 end | 151 end |
136 | 152 |
137 def cat(path, identifier=nil) | 153 def cat(path, identifier=nil) |
138 cmd = "#{DARCS_BIN} show content --repodir #{shell_quote @url}" | 154 cmd = "#{self.class.sq_bin} show content --repodir #{shell_quote @url}" |
139 cmd << " --match #{shell_quote("hash #{identifier}")}" if identifier | 155 cmd << " --match #{shell_quote("hash #{identifier}")}" if identifier |
140 cmd << " #{shell_quote path}" | 156 cmd << " #{shell_quote path}" |
141 cat = nil | 157 cat = nil |
142 shellout(cmd) do |io| | 158 shellout(cmd) do |io| |
143 io.binmode | 159 io.binmode |
146 return nil if $? && $?.exitstatus != 0 | 162 return nil if $? && $?.exitstatus != 0 |
147 cat | 163 cat |
148 end | 164 end |
149 | 165 |
150 private | 166 private |
151 | 167 |
152 # Returns an Entry from the given XML element | 168 # Returns an Entry from the given XML element |
153 # or nil if the entry was deleted | 169 # or nil if the entry was deleted |
154 def entry_from_xml(element, path_prefix) | 170 def entry_from_xml(element, path_prefix) |
155 modified_element = element.elements['modified'] | 171 modified_element = element.elements['modified'] |
156 if modified_element.elements['modified_how'].text.match(/removed/) | 172 if modified_element.elements['modified_how'].text.match(/removed/) |
157 return nil | 173 return nil |
158 end | 174 end |
159 | 175 |
160 Entry.new({:name => element.attributes['name'], | 176 Entry.new({:name => element.attributes['name'], |
161 :path => path_prefix + element.attributes['name'], | 177 :path => path_prefix + element.attributes['name'], |
162 :kind => element.name == 'file' ? 'file' : 'dir', | 178 :kind => element.name == 'file' ? 'file' : 'dir', |
163 :size => nil, | 179 :size => nil, |
164 :lastrev => Revision.new({ | 180 :lastrev => Revision.new({ |
165 :identifier => nil, | 181 :identifier => nil, |
166 :scmid => modified_element.elements['patch'].attributes['hash'] | 182 :scmid => modified_element.elements['patch'].attributes['hash'] |
167 }) | 183 }) |
168 }) | 184 }) |
169 end | 185 end |
170 | 186 |
171 def get_paths_for_patch(hash) | 187 def get_paths_for_patch(hash) |
172 paths = get_paths_for_patch_raw(hash) | 188 paths = get_paths_for_patch_raw(hash) |
173 if self.class.client_version_above?([2, 4]) | 189 if self.class.client_version_above?([2, 4]) |
194 paths.concat mod_paths | 210 paths.concat mod_paths |
195 paths.concat other_paths | 211 paths.concat other_paths |
196 end | 212 end |
197 paths | 213 paths |
198 end | 214 end |
199 | 215 |
200 # Retrieve changed paths for a single patch | 216 # Retrieve changed paths for a single patch |
201 def get_paths_for_patch_raw(hash) | 217 def get_paths_for_patch_raw(hash) |
202 cmd = "#{DARCS_BIN} annotate --repodir #{shell_quote @url} --summary --xml-output" | 218 cmd = "#{self.class.sq_bin} annotate --repodir #{shell_quote @url} --summary --xml-output" |
203 cmd << " --match #{shell_quote("hash #{hash}")} " | 219 cmd << " --match #{shell_quote("hash #{hash}")} " |
204 paths = [] | 220 paths = [] |
205 shellout(cmd) do |io| | 221 shellout(cmd) do |io| |
206 begin | 222 begin |
207 # Darcs xml output has multiple root elements in this case (tested with darcs 1.0.7) | 223 # Darcs xml output has multiple root elements in this case (tested with darcs 1.0.7) |