##// END OF EJS Templates
Adds Filesystem adapter (patch #1393 by Paul R)....
Jean-Philippe Lang -
r1494:e69b4647f201
parent child
Show More
@@ -0,0 +1,43
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
@@ -0,0 +1,94
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
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
@@ -0,0 +1,42
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
@@ -0,0 +1,54
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 Setting.enabled_scm << 'Filesystem' unless Setting.enabled_scm.include?('Filesystem')
29 assert @repository = Repository::Filesystem.create(:project => @project, :url => REPOSITORY_PATH)
30 end
31
32 if File.directory?(REPOSITORY_PATH)
33 def test_fetch_changesets
34 @repository.fetch_changesets
35 @repository.reload
36
37 assert_equal 0, @repository.changesets.count
38 assert_equal 0, @repository.changes.count
39 end
40
41 def test_entries
42 assert_equal 2, @repository.entries("", 2).size
43 assert_equal 2, @repository.entries("dir", 3).size
44 end
45
46 def test_cat
47 assert_equal "TEST CAT\n", @repository.scm.cat("test")
48 end
49
50 else
51 puts "Filesystem test repository NOT FOUND. Skipping unit tests !!! See doc/RUNNING_TESTS."
52 def test_fake; assert true end
53 end
54 end
@@ -98,4 +98,8 module RepositoriesHelper
98 def bazaar_field_tags(form, repository)
98 def bazaar_field_tags(form, repository)
99 content_tag('p', form.text_field(:url, :label => 'Root directory', :size => 60, :required => true, :disabled => (repository && !repository.new_record?)))
99 content_tag('p', form.text_field(:url, :label => 'Root directory', :size => 60, :required => true, :disabled => (repository && !repository.new_record?)))
100 end
100 end
101
102 def filesystem_field_tags(form, repository)
103 content_tag('p', form.text_field(:url, :label => 'Root directory', :size => 60, :required => true, :disabled => (repository && !repository.root_url.blank?)))
104 end
101 end
105 end
@@ -24,6 +24,10 Git
24 ---
24 ---
25 gunzip < test/fixtures/repositories/git_repository.tar.gz | tar -xv -C tmp/test
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 Running Tests
32 Running Tests
29 =============
33 =============
@@ -11,7 +11,7 rescue LoadError
11 # RMagick is not available
11 # RMagick is not available
12 end
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 # Permissions
16 # Permissions
17 Redmine::AccessControl.map do |map|
17 Redmine::AccessControl.map do |map|
@@ -100,6 +100,16 module Redmine
100 (path[-1,1] == "/") ? path : "#{path}/"
100 (path[-1,1] == "/") ? path : "#{path}/"
101 end
101 end
102
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
111 end
112
103 def shell_quote(str)
113 def shell_quote(str)
104 if RUBY_PLATFORM =~ /mswin/
114 if RUBY_PLATFORM =~ /mswin/
105 '"' + str.gsub(/"/, '\\"') + '"'
115 '"' + str.gsub(/"/, '\\"') + '"'
@@ -51,6 +51,8 class RepositoryTest < Test::Unit::TestCase
51 repository = Repository::Subversion.new(:project => Project.find(3), :url => "svn://localhost")
51 repository = Repository::Subversion.new(:project => Project.find(3), :url => "svn://localhost")
52 assert !repository.save
52 assert !repository.save
53 assert_equal :activerecord_error_invalid, repository.errors.on(:type)
53 assert_equal :activerecord_error_invalid, repository.errors.on(:type)
54 # re-enable Subversion for following tests
55 Setting.delete_all
54 end
56 end
55
57
56 def test_scan_changesets_for_issue_ids
58 def test_scan_changesets_for_issue_ids
General Comments 0
You need to be logged in to leave comments. Login now