| 
									
										
										
										
											2019-03-17 16:36:34 +00:00
										 |  |  | # frozen_string_literal: true | 
					
						
							| 
									
										
										
										
											2019-03-15 01:32:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-05 13:02:45 +00:00
										 |  |  | # Redmine - project management software | 
					
						
							| 
									
										
										
										
											2023-01-01 06:19:35 +00:00
										 |  |  | # Copyright (C) 2006-2023  Jean-Philippe Lang | 
					
						
							| 
									
										
										
										
											2008-06-08 15:40:24 +00:00
										 |  |  | # | 
					
						
							|  |  |  | # FileSystem adapter | 
					
						
							|  |  |  | # File written by Paul Rivier, at Demotera. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  | # modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  | # as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  | # of the License, or (at your option) any later version. | 
					
						
							| 
									
										
										
										
											2011-05-06 12:58:14 +00:00
										 |  |  | # | 
					
						
							| 
									
										
										
										
											2008-06-08 15:40:24 +00:00
										 |  |  | # This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  | # but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  | # GNU General Public License for more details. | 
					
						
							| 
									
										
										
										
											2011-05-06 12:58:14 +00:00
										 |  |  | # | 
					
						
							| 
									
										
										
										
											2008-06-08 15:40:24 +00:00
										 |  |  | # You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  | # along with this program; if not, write to the Free Software | 
					
						
							|  |  |  | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | require 'redmine/scm/adapters/abstract_adapter' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module Redmine | 
					
						
							|  |  |  |   module Scm | 
					
						
							| 
									
										
										
										
											2011-02-21 12:10:39 +00:00
										 |  |  |     module Adapters | 
					
						
							| 
									
										
										
										
											2008-06-08 15:40:24 +00:00
										 |  |  |       class FilesystemAdapter < AbstractAdapter | 
					
						
							| 
									
										
										
										
											2011-02-14 06:14:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         class << self | 
					
						
							|  |  |  |           def client_available | 
					
						
							|  |  |  |             true | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2008-06-08 15:40:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-24 05:58:59 +00:00
										 |  |  |         def initialize(url, root_url=nil, login=nil, password=nil, | 
					
						
							|  |  |  |                        path_encoding=nil) | 
					
						
							| 
									
										
										
										
											2023-03-24 09:34:40 +00:00
										 |  |  |           super(with_trailing_slash(url), nil, nil, nil, path_encoding) | 
					
						
							| 
									
										
										
										
											2008-06-08 15:40:24 +00:00
										 |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-21 02:17:34 +00:00
										 |  |  |         def path_encoding | 
					
						
							|  |  |  |           @path_encoding | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-28 07:47:41 +00:00
										 |  |  |         def format_path_ends(path, leading=true, trailing=true) | 
					
						
							| 
									
										
										
										
											2011-05-06 12:58:14 +00:00
										 |  |  |           path = leading ? with_leading_slash(path) : | 
					
						
							| 
									
										
										
										
											2008-06-08 15:40:24 +00:00
										 |  |  |             without_leading_slash(path) | 
					
						
							| 
									
										
										
										
											2022-08-28 07:47:41 +00:00
										 |  |  |           trailing ? with_trailing_slash(path) : | 
					
						
							| 
									
										
										
										
											2022-08-28 07:32:24 +00:00
										 |  |  |             without_trailing_slash(path) | 
					
						
							| 
									
										
										
										
											2008-06-08 15:40:24 +00:00
										 |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def info | 
					
						
							| 
									
										
										
										
											2020-10-26 13:34:52 +00:00
										 |  |  |           info = Info.new({:root_url => target(), :lastrev => nil}) | 
					
						
							| 
									
										
										
										
											2008-06-08 15:40:24 +00:00
										 |  |  |           info | 
					
						
							|  |  |  |         rescue CommandFailed | 
					
						
							|  |  |  |           return nil | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2011-02-21 12:10:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-04 14:11:25 +00:00
										 |  |  |         def entries(path="", identifier=nil, options={}) | 
					
						
							| 
									
										
										
										
											2008-06-08 15:40:24 +00:00
										 |  |  |           entries = Entries.new | 
					
						
							| 
									
										
										
										
											2011-02-21 12:10:39 +00:00
										 |  |  |           trgt_utf8 = target(path) | 
					
						
							|  |  |  |           trgt = scm_iconv(@path_encoding, 'UTF-8', trgt_utf8) | 
					
						
							|  |  |  |           Dir.new(trgt).each do |e1| | 
					
						
							|  |  |  |             e_utf8 = scm_iconv('UTF-8', @path_encoding, e1) | 
					
						
							| 
									
										
										
										
											2011-05-06 12:58:14 +00:00
										 |  |  |             next if e_utf8.blank? | 
					
						
							| 
									
										
										
										
											2020-07-21 13:40:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-24 14:40:34 +00:00
										 |  |  |             relative_path_utf8 = | 
					
						
							|  |  |  |               format_path_ends( | 
					
						
							|  |  |  |                 (format_path_ends(path, false, true) + e_utf8), | 
					
						
							|  |  |  |                 false, | 
					
						
							|  |  |  |                 false | 
					
						
							|  |  |  |               ) | 
					
						
							| 
									
										
										
										
											2011-02-21 12:10:39 +00:00
										 |  |  |             t1_utf8 = target(relative_path_utf8) | 
					
						
							|  |  |  |             t1 = scm_iconv(@path_encoding, 'UTF-8', t1_utf8) | 
					
						
							|  |  |  |             relative_path = scm_iconv(@path_encoding, 'UTF-8', relative_path_utf8) | 
					
						
							|  |  |  |             e1 = scm_iconv(@path_encoding, 'UTF-8', e_utf8) | 
					
						
							|  |  |  |             if File.exist?(t1) and # paranoid test | 
					
						
							|  |  |  |                   %w{file directory}.include?(File.ftype(t1)) and # avoid special types | 
					
						
							|  |  |  |                   not File.basename(e1).match(/^\.+$/) # avoid . and .. | 
					
						
							|  |  |  |               p1         = File.readable?(t1) ? relative_path : "" | 
					
						
							|  |  |  |               utf_8_path = scm_iconv('UTF-8', @path_encoding, p1) | 
					
						
							|  |  |  |               entries << | 
					
						
							| 
									
										
										
										
											2020-08-07 12:43:32 +00:00
										 |  |  |                 Entry.new( | 
					
						
							|  |  |  |                   { | 
					
						
							|  |  |  |                     :name => scm_iconv('UTF-8', @path_encoding, File.basename(e1)), | 
					
						
							|  |  |  |                     # below : list unreadable files, but dont link them. | 
					
						
							|  |  |  |                     :path => utf_8_path, | 
					
						
							|  |  |  |                     :kind => (File.directory?(t1) ? 'dir' : 'file'), | 
					
						
							|  |  |  |                     :size => (File.directory?(t1) ? nil : File.size(t1)), | 
					
						
							|  |  |  |                     :lastrev => Revision.new({:time => (File.mtime(t1))}) | 
					
						
							|  |  |  |                   } | 
					
						
							|  |  |  |                 ) | 
					
						
							| 
									
										
										
										
											2011-02-21 12:10:39 +00:00
										 |  |  |             end | 
					
						
							| 
									
										
										
										
											2008-06-08 15:40:24 +00:00
										 |  |  |           end | 
					
						
							|  |  |  |           entries.sort_by_name | 
					
						
							| 
									
										
										
										
											2011-02-21 12:10:39 +00:00
										 |  |  |         rescue  => err | 
					
						
							|  |  |  |           logger.error "scm: filesystem: error: #{err.message}" | 
					
						
							|  |  |  |           raise CommandFailed.new(err.message) | 
					
						
							| 
									
										
										
										
											2008-06-08 15:40:24 +00:00
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											2011-02-21 12:10:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-08 15:40:24 +00:00
										 |  |  |         def cat(path, identifier=nil) | 
					
						
							| 
									
										
										
										
											2011-02-21 12:10:39 +00:00
										 |  |  |           p = scm_iconv(@path_encoding, 'UTF-8', target(path)) | 
					
						
							|  |  |  |           File.new(p, "rb").read | 
					
						
							|  |  |  |         rescue  => err | 
					
						
							|  |  |  |           logger.error "scm: filesystem: error: #{err.message}" | 
					
						
							|  |  |  |           raise CommandFailed.new(err.message) | 
					
						
							| 
									
										
										
										
											2008-06-08 15:40:24 +00:00
										 |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         private | 
					
						
							| 
									
										
										
										
											2011-02-21 12:10:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-08 15:40:24 +00:00
										 |  |  |         # AbstractAdapter::target is implicitly made to quote paths. | 
					
						
							|  |  |  |         # Here we do not shell-out, so we do not want quotes. | 
					
						
							|  |  |  |         def target(path=nil) | 
					
						
							| 
									
										
										
										
											2011-02-21 12:10:39 +00:00
										 |  |  |           # Prevent the use of .. | 
					
						
							| 
									
										
										
										
											2019-03-27 02:15:24 +00:00
										 |  |  |           if path and !/(^|\/)\.\.(\/|$)/.match?(path) | 
					
						
							| 
									
										
										
										
											2008-06-08 15:40:24 +00:00
										 |  |  |             return "#{self.url}#{without_leading_slash(path)}" | 
					
						
							|  |  |  |           end | 
					
						
							| 
									
										
										
										
											2020-07-21 13:40:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-08 15:40:24 +00:00
										 |  |  |           return self.url | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end |