Project

General

Profile

Patch #1393 » filesystem-adapter.patch

patch to apply against current stable - Paul Rivier, 2008-06-06 11:34

View differences:

app/helpers/repositories_helper.rb Tue Jun 03 17:32:01 2008 +0200 → app/helpers/repositories_helper.rb Fri Jun 06 11:20:28 2008 +0200
95 95
  def bazaar_field_tags(form, repository)
96 96
      content_tag('p', form.text_field(:url, :label => 'Root directory', :size => 60, :required => true, :disabled => (repository && !repository.new_record?)))
97 97
  end
98

  
99
  def filesystem_field_tags(form, repository)
100
      content_tag('p', form.text_field(:url, :label => 'Root directory', :size => 60, :required => true, :disabled => (repository && !repository.root_url.blank?)))
101
  end
102

  
98 103
end
/dev/null Thu Jan 01 00:00:00 1970 +0000 → app/models/repository/filesystem.rb Fri Jun 06 11:20:28 2008 +0200
1
# redMine - project management software
2
# Copyright (C) 2006-2007  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/filesystem_adapter'
22

  
23
class Repository::Filesystem < Repository
24
  attr_protected :root_url
25
  validates_presence_of :url
26

  
27
  def scm_adapter
28
    Redmine::Scm::Adapters::FilesystemAdapter
29
  end
30
  
31
  def self.scm_name
32
    'Filesystem'
33
  end
34
  
35
  def entries(path=nil, identifier=nil)
36
    scm.entries(path, identifier)
37
  end
38

  
39
  def fetch_changesets
40
    nil
41
  end
42
  
43
end
doc/RUNNING_TESTS Tue Jun 03 17:32:01 2008 +0200 → doc/RUNNING_TESTS Fri Jun 06 11:20:28 2008 +0200
24 24
---
25 25
gunzip < test/fixtures/repositories/git_repository.tar.gz | tar -xv -C tmp/test
26 26

  
27
FileSystem
28
----------
29
gunzip < test/fixtures/repositories/filesystem_repository.tar.gz | tar -xv -C tmp/test
30

  
27 31

  
28 32
Running Tests
29 33
=============
lib/redmine.rb Tue Jun 03 17:32:01 2008 +0200 → lib/redmine.rb Fri Jun 06 11:20:28 2008 +0200
11 11
  # RMagick is not available
12 12
end
13 13

  
14
REDMINE_SUPPORTED_SCM = %w( Subversion Darcs Mercurial Cvs Bazaar Git )
14
REDMINE_SUPPORTED_SCM = %w( Subversion Darcs Mercurial Cvs Bazaar Git Filesystem )
15 15

  
16 16
# Permissions
17 17
Redmine::AccessControl.map do |map|
lib/redmine/scm/adapters/abstract_adapter.rb Tue Jun 03 17:32:01 2008 +0200 → lib/redmine/scm/adapters/abstract_adapter.rb Fri Jun 06 11:20:28 2008 +0200
98 98
        def with_trailling_slash(path)
99 99
          path ||= ''
100 100
          (path[-1,1] == "/") ? path : "#{path}/"
101
        end
102

  
103
        def without_leading_slash(path)
104
          path ||= ''
105
          path.gsub(%r{^/+}, '')
106
        end
107

  
108
        def without_trailling_slash(path)
109
          path ||= ''
110
          (path[-1,1] == "/") ? path[0..-2] : path
101 111
        end
102 112

  
103 113
        def shell_quote(str)
/dev/null Thu Jan 01 00:00:00 1970 +0000 → lib/redmine/scm/adapters/filesystem_adapter.rb Fri Jun 06 11:20:28 2008 +0200
1
# redMine - project management software
2
# Copyright (C) 2006-2007  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

  
30
        def initialize(url, root_url=nil, login=nil, password=nil)
31
          @url = with_trailling_slash(url)
32
        end
33

  
34
        def format_path_ends(path, leading=true, trailling=true)
35
          path = leading ? with_leading_slash(path) : 
36
            without_leading_slash(path)
37
          trailling ? with_trailling_slash(path) : 
38
            without_trailling_slash(path) 
39
        end
40

  
41
        def info
42
          info = Info.new({:root_url => target(),
43
                            :lastrev => nil
44
                          })
45
          info
46
        rescue CommandFailed
47
          return nil
48
        end
49
        
50
        def entries(path="", identifier=nil)
51
          entries = Entries.new
52
          Dir.new(target(path)).each do |e|
53
            relative_path = format_path_ends((format_path_ends(path,
54
                                                               false,
55
                                                               true) + e),
56
                                             false,false)
57
            target = target(relative_path)
58
            entries << 
59
              Entry.new({ :name => File.basename(e),
60
                          # below : list unreadable files, but dont link them.
61
                          :path => File.readable?(target) ? relative_path : "",
62
                          :kind => (File.directory?(target) ? 'dir' : 'file'),
63
                          :size => if (File.directory?(target))
64
                                     nil else File.size(target) end,
65
                          :lastrev => 
66
                          Revision.new({:time => (File.mtime(target)).localtime,
67
                                       })
68
                        }) if File.exist?(target) and # paranoid test
69
              %w{file directory}.include?(File.ftype(target)) and # avoid special types
70
              not File.basename(e).match(/^\.+$/) # avoid . and ..             
71
          end
72
          entries.sort_by_name
73
        end
74
        
75
        def cat(path, identifier=nil)
76
          File.new(target(path)).read
77
        end
78

  
79
        private
80
        
81
        # AbstractAdapter::target is implicitly made to quote paths.
82
        # Here we do not shell-out, so we do not want quotes.
83
        def target(path=nil)
84
          #Prevent the use of ..
85
          if path and !path.match(/(^|\/)\.\.(\/|$)/)
86
            return "#{self.url}#{without_leading_slash(path)}"
87
          end
88
          return self.url
89
        end
90
        
91
      end
92
    end
93
  end
94
end
/dev/null Thu Jan 01 00:00:00 1970 +0000 → test/unit/filesystem_adapter_test.rb Fri Jun 06 11:20:28 2008 +0200
1

  
2
require File.dirname(__FILE__) + '/../test_helper'
3

  
4

  
5
class FilesystemAdapterTest < Test::Unit::TestCase
6
  
7
  REPOSITORY_PATH = RAILS_ROOT.gsub(%r{config\/\.\.}, '') + '/tmp/test/filesystem_repository'  
8
  
9
  if File.directory?(REPOSITORY_PATH)    
10
    def setup
11
      @adapter = Redmine::Scm::Adapters::FilesystemAdapter.new(REPOSITORY_PATH)
12
    end
13
    
14
    def test_entries
15
      assert_equal 2, @adapter.entries.size
16
      assert_equal ["dir", "test"], @adapter.entries.collect(&:name)
17
      assert_equal ["dir", "test"], @adapter.entries(nil).collect(&:name)
18
      assert_equal ["dir", "test"], @adapter.entries("/").collect(&:name)
19
      ["dir", "/dir", "/dir/", "dir/"].each do |path|
20
        assert_equal ["subdir", "dirfile"], @adapter.entries(path).collect(&:name)
21
      end
22
      # If y try to use "..", the path is ignored
23
      ["/../","dir/../", "..", "../", "/..", "dir/.."].each do |path|
24
        assert_equal ["dir", "test"], @adapter.entries(path).collect(&:name), ".. must be ignored in path argument"
25
      end
26
    end
27
    
28
    def test_cat
29
      assert_equal "TEST CAT\n", @adapter.cat("test")
30
      assert_equal "TEST CAT\n", @adapter.cat("/test")
31
      # Revision number is ignored
32
      assert_equal "TEST CAT\n", @adapter.cat("/test", 1)
33
    end
34
    
35
  else
36
    puts "Filesystem test repository NOT FOUND. Skipping unit tests !!! See doc/RUNNING_TESTS."
37
    def test_fake; assert true end
38
  end
39
  
40
end
41

  
42

  
/dev/null Thu Jan 01 00:00:00 1970 +0000 → test/unit/repository_filesystem_test.rb Fri Jun 06 11:20:28 2008 +0200
1
# redMine - project management software
2
# Copyright (C) 2006-2007  Jean-Philippe Lang
3
#
4
# This program is free software; you can redistribute it and/or
5
# modify it under the terms of the GNU General Public License
6
# as published by the Free Software Foundation; either version 2
7
# of the License, or (at your option) any later version.
8
# 
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
# 
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17

  
18
require File.dirname(__FILE__) + '/../test_helper'
19

  
20
class RepositoryFilesystemTest < Test::Unit::TestCase
21
  fixtures :projects
22
  
23
  # No '..' in the repository path
24
  REPOSITORY_PATH = RAILS_ROOT.gsub(%r{config\/\.\.}, '') + '/tmp/test/filesystem_repository'
25
  
26
  def setup
27
    @project = Project.find(1)
28
    assert @repository = Repository::Filesystem.create(:project => @project, :url => REPOSITORY_PATH)
29
  end
30
  
31
  if File.directory?(REPOSITORY_PATH)  
32
    def test_fetch_changesets
33
      @repository.fetch_changesets
34
      @repository.reload
35
      
36
      assert_equal 0, @repository.changesets.count
37
      assert_equal 0, @repository.changes.count
38
    end
39
        
40
    def test_entries
41
      assert_equal 2, @repository.entries("", 2).size
42
      assert_equal 2, @repository.entries("dir", 3).size
43
    end
44

  
45
    def test_cat
46
      assert_equal "TEST CAT\n", @repository.scm.cat("test")
47
    end
48

  
49
  else
50
    puts "Filesystem test repository NOT FOUND. Skipping unit tests !!! See doc/RUNNING_TESTS."
51
    def test_fake; assert true end
52
  end
53
end
(1-1/2)