comparison lib/redmine/scm/adapters/filesystem_adapter.rb @ 245:051f544170fe

* Update to SVN trunk revision 4993
author Chris Cannam
date Thu, 03 Mar 2011 11:42:28 +0000
parents 513646585e45
children cbce1fd3b1b7
comparison
equal deleted inserted replaced
244:8972b600f4fb 245:051f544170fe
21 require 'redmine/scm/adapters/abstract_adapter' 21 require 'redmine/scm/adapters/abstract_adapter'
22 require 'find' 22 require 'find'
23 23
24 module Redmine 24 module Redmine
25 module Scm 25 module Scm
26 module Adapters 26 module Adapters
27 class FilesystemAdapter < AbstractAdapter 27 class FilesystemAdapter < AbstractAdapter
28
29 28
30 def initialize(url, root_url=nil, login=nil, password=nil) 29 class << self
30 def client_available
31 true
32 end
33 end
34
35 def initialize(url, root_url=nil, login=nil, password=nil,
36 path_encoding=nil)
31 @url = with_trailling_slash(url) 37 @url = with_trailling_slash(url)
38 @path_encoding = path_encoding || 'UTF-8'
32 end 39 end
33 40
34 def format_path_ends(path, leading=true, trailling=true) 41 def format_path_ends(path, leading=true, trailling=true)
35 path = leading ? with_leading_slash(path) : 42 path = leading ? with_leading_slash(path) :
36 without_leading_slash(path) 43 without_leading_slash(path)
44 }) 51 })
45 info 52 info
46 rescue CommandFailed 53 rescue CommandFailed
47 return nil 54 return nil
48 end 55 end
49 56
50 def entries(path="", identifier=nil) 57 def entries(path="", identifier=nil)
51 entries = Entries.new 58 entries = Entries.new
52 Dir.new(target(path)).each do |e| 59 trgt_utf8 = target(path)
53 relative_path = format_path_ends((format_path_ends(path, 60 trgt = scm_iconv(@path_encoding, 'UTF-8', trgt_utf8)
54 false, 61 Dir.new(trgt).each do |e1|
55 true) + e), 62 e_utf8 = scm_iconv('UTF-8', @path_encoding, e1)
56 false,false) 63 relative_path_utf8 = format_path_ends((format_path_ends(path,false,true) + e_utf8),false,false)
57 target = target(relative_path) 64 t1_utf8 = target(relative_path_utf8)
58 entries << 65 t1 = scm_iconv(@path_encoding, 'UTF-8', t1_utf8)
59 Entry.new({ :name => File.basename(e), 66 relative_path = scm_iconv(@path_encoding, 'UTF-8', relative_path_utf8)
67 e1 = scm_iconv(@path_encoding, 'UTF-8', e_utf8)
68 if File.exist?(t1) and # paranoid test
69 %w{file directory}.include?(File.ftype(t1)) and # avoid special types
70 not File.basename(e1).match(/^\.+$/) # avoid . and ..
71 p1 = File.readable?(t1) ? relative_path : ""
72 utf_8_path = scm_iconv('UTF-8', @path_encoding, p1)
73 entries <<
74 Entry.new({ :name => scm_iconv('UTF-8', @path_encoding, File.basename(e1)),
60 # below : list unreadable files, but dont link them. 75 # below : list unreadable files, but dont link them.
61 :path => File.readable?(target) ? relative_path : "", 76 :path => utf_8_path,
62 :kind => (File.directory?(target) ? 'dir' : 'file'), 77 :kind => (File.directory?(t1) ? 'dir' : 'file'),
63 :size => (File.directory?(target) ? nil : [File.size(target)].pack('l').unpack('L').first), 78 :size => (File.directory?(t1) ? nil : [File.size(t1)].pack('l').unpack('L').first),
64 :lastrev => 79 :lastrev =>
65 Revision.new({:time => (File.mtime(target)).localtime, 80 Revision.new({:time => (File.mtime(t1)) })
66 }) 81 })
67 }) if File.exist?(target) and # paranoid test 82 end
68 %w{file directory}.include?(File.ftype(target)) and # avoid special types
69 not File.basename(e).match(/^\.+$/) # avoid . and ..
70 end 83 end
71 entries.sort_by_name 84 entries.sort_by_name
85 rescue => err
86 logger.error "scm: filesystem: error: #{err.message}"
87 raise CommandFailed.new(err.message)
72 end 88 end
73 89
74 def cat(path, identifier=nil) 90 def cat(path, identifier=nil)
75 File.new(target(path), "rb").read 91 p = scm_iconv(@path_encoding, 'UTF-8', target(path))
92 File.new(p, "rb").read
93 rescue => err
94 logger.error "scm: filesystem: error: #{err.message}"
95 raise CommandFailed.new(err.message)
76 end 96 end
77 97
78 private 98 private
79 99
80 # AbstractAdapter::target is implicitly made to quote paths. 100 # AbstractAdapter::target is implicitly made to quote paths.
81 # Here we do not shell-out, so we do not want quotes. 101 # Here we do not shell-out, so we do not want quotes.
82 def target(path=nil) 102 def target(path=nil)
83 #Prevent the use of .. 103 # Prevent the use of ..
84 if path and !path.match(/(^|\/)\.\.(\/|$)/) 104 if path and !path.match(/(^|\/)\.\.(\/|$)/)
85 return "#{self.url}#{without_leading_slash(path)}" 105 return "#{self.url}#{without_leading_slash(path)}"
86 end 106 end
87 return self.url 107 return self.url
88 end 108 end
89
90 end 109 end
91 end 110 end
92 end 111 end
93 end 112 end