Patch #1393 » filesystem-adapter.patch
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 |