File: lib/redmine/scm/adapters/filesystem_adapter.rb

Overview
Module Structure
Class Hierarchy
Code

Overview

Module Structure

  module: <Toplevel Module>
  module: Redmine#24
  module: Scm#25
  module: Adapters#26
  class: FilesystemAdapter#27
inherits from
  AbstractAdapter ( Redmine::Scm::Adapters )
has properties
class method: client_available #30
method: initialize / 5 #35
method: path_encoding #41
method: format_path_ends / 3 #45
method: info #52
method: entries / 3 #61
method: cat / 2 #96
method: target / 1 #108

Class Hierarchy

Code

   1  # RedMine - project management software
   2  # Copyright (C) 2006-2011  Jean-Philippe Lang
   3  #
   4  # FileSystem adapter
   5  # File written by Paul Rivier, at Demotera.
   6  #
   7  # This program is free software; you can redistribute it and/or
   8  # modify it under the terms of the GNU General Public License
   9  # as published by the Free Software Foundation; either version 2
  10  # of the License, or (at your option) any later version.
  11  #
  12  # This program is distributed in the hope that it will be useful,
  13  # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15  # GNU General Public License for more details.
  16  #
  17  # You should have received a copy of the GNU General Public License
  18  # along with this program; if not, write to the Free Software
  19  # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  20 
  21  require 'redmine/scm/adapters/abstract_adapter'
  22  require 'find'
  23 
  24  module Redmine
  25    module Scm
  26      module Adapters
  27        class FilesystemAdapter < AbstractAdapter
  28 
  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)
  37            @url = with_trailling_slash(url)
  38            @path_encoding = path_encoding.blank? ? 'UTF-8' : path_encoding
  39          end
  40 
  41          def path_encoding
  42            @path_encoding
  43          end
  44 
  45          def format_path_ends(path, leading=true, trailling=true)
  46            path = leading ? with_leading_slash(path) :
  47              without_leading_slash(path)
  48            trailling ? with_trailling_slash(path) :
  49              without_trailling_slash(path)
  50          end
  51 
  52          def info
  53            info = Info.new({:root_url => target(),
  54                              :lastrev => nil
  55                            })
  56            info
  57          rescue CommandFailed
  58            return nil
  59          end
  60 
  61          def entries(path="", identifier=nil, options={})
  62            entries = Entries.new
  63            trgt_utf8 = target(path)
  64            trgt = scm_iconv(@path_encoding, 'UTF-8', trgt_utf8)
  65            Dir.new(trgt).each do |e1|
  66              e_utf8 = scm_iconv('UTF-8', @path_encoding, e1)
  67              next if e_utf8.blank?
  68              relative_path_utf8 = format_path_ends(
  69                  (format_path_ends(path,false,true) + e_utf8),false,false)
  70              t1_utf8 = target(relative_path_utf8)
  71              t1 = scm_iconv(@path_encoding, 'UTF-8', t1_utf8)
  72              relative_path = scm_iconv(@path_encoding, 'UTF-8', relative_path_utf8)
  73              e1 = scm_iconv(@path_encoding, 'UTF-8', e_utf8)
  74              if File.exist?(t1) and # paranoid test
  75                    %w{file directory}.include?(File.ftype(t1)) and # avoid special types
  76                    not File.basename(e1).match(/^\.+$/) # avoid . and ..
  77                p1         = File.readable?(t1) ? relative_path : ""
  78                utf_8_path = scm_iconv('UTF-8', @path_encoding, p1)
  79                entries <<
  80                  Entry.new({ :name => scm_iconv('UTF-8', @path_encoding, File.basename(e1)),
  81                            # below : list unreadable files, but dont link them.
  82                            :path => utf_8_path,
  83                            :kind => (File.directory?(t1) ? 'dir' : 'file'),
  84                            :size => (File.directory?(t1) ? nil : [File.size(t1)].pack('l').unpack('L').first),
  85                            :lastrev =>
  86                                Revision.new({:time => (File.mtime(t1)) })
  87                          })
  88              end
  89            end
  90            entries.sort_by_name
  91          rescue  => err
  92            logger.error "scm: filesystem: error: #{err.message}"
  93            raise CommandFailed.new(err.message)
  94          end
  95 
  96          def cat(path, identifier=nil)
  97            p = scm_iconv(@path_encoding, 'UTF-8', target(path))
  98            File.new(p, "rb").read
  99          rescue  => err
 100            logger.error "scm: filesystem: error: #{err.message}"
 101            raise CommandFailed.new(err.message)
 102          end
 103 
 104          private
 105 
 106          # AbstractAdapter::target is implicitly made to quote paths.
 107          # Here we do not shell-out, so we do not want quotes.
 108          def target(path=nil)
 109            # Prevent the use of ..
 110            if path and !path.match(/(^|\/)\.\.(\/|$)/)
 111              return "#{self.url}#{without_leading_slash(path)}"
 112            end
 113            return self.url
 114          end
 115        end
 116      end
 117    end
 118  end