summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/helpers/repositories_helper.rb4
-rw-r--r--app/models/repository/filesystem.rb43
-rw-r--r--doc/RUNNING_TESTS4
-rw-r--r--lib/redmine.rb2
-rw-r--r--lib/redmine/scm/adapters/abstract_adapter.rb10
-rw-r--r--lib/redmine/scm/adapters/filesystem_adapter.rb94
-rw-r--r--test/fixtures/repositories/filesystem_repository.tar.gzbin0 -> 265 bytes
-rw-r--r--test/unit/filesystem_adapter_test.rb42
-rw-r--r--test/unit/repository_filesystem_test.rb54
-rw-r--r--test/unit/repository_test.rb2
10 files changed, 254 insertions, 1 deletions
diff --git a/app/helpers/repositories_helper.rb b/app/helpers/repositories_helper.rb
index d2cc664e6..10f6e7396 100644
--- a/app/helpers/repositories_helper.rb
+++ b/app/helpers/repositories_helper.rb
@@ -98,4 +98,8 @@ module RepositoriesHelper
def bazaar_field_tags(form, repository)
content_tag('p', form.text_field(:url, :label => 'Root directory', :size => 60, :required => true, :disabled => (repository && !repository.new_record?)))
end
+
+ def filesystem_field_tags(form, repository)
+ content_tag('p', form.text_field(:url, :label => 'Root directory', :size => 60, :required => true, :disabled => (repository && !repository.root_url.blank?)))
+ end
end
diff --git a/app/models/repository/filesystem.rb b/app/models/repository/filesystem.rb
new file mode 100644
index 000000000..da096cc09
--- /dev/null
+++ b/app/models/repository/filesystem.rb
@@ -0,0 +1,43 @@
+# redMine - project management software
+# Copyright (C) 2006-2007 Jean-Philippe Lang
+#
+# 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.
+#
+# 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.
+#
+# 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/filesystem_adapter'
+
+class Repository::Filesystem < Repository
+ attr_protected :root_url
+ validates_presence_of :url
+
+ def scm_adapter
+ Redmine::Scm::Adapters::FilesystemAdapter
+ end
+
+ def self.scm_name
+ 'Filesystem'
+ end
+
+ def entries(path=nil, identifier=nil)
+ scm.entries(path, identifier)
+ end
+
+ def fetch_changesets
+ nil
+ end
+
+end
diff --git a/doc/RUNNING_TESTS b/doc/RUNNING_TESTS
index 7a5e2b992..18dfe6983 100644
--- a/doc/RUNNING_TESTS
+++ b/doc/RUNNING_TESTS
@@ -24,6 +24,10 @@ Git
---
gunzip < test/fixtures/repositories/git_repository.tar.gz | tar -xv -C tmp/test
+FileSystem
+----------
+gunzip < test/fixtures/repositories/filesystem_repository.tar.gz | tar -xv -C tmp/test
+
Running Tests
=============
diff --git a/lib/redmine.rb b/lib/redmine.rb
index 7b9832d62..84eda9f72 100644
--- a/lib/redmine.rb
+++ b/lib/redmine.rb
@@ -11,7 +11,7 @@ rescue LoadError
# RMagick is not available
end
-REDMINE_SUPPORTED_SCM = %w( Subversion Darcs Mercurial Cvs Bazaar Git )
+REDMINE_SUPPORTED_SCM = %w( Subversion Darcs Mercurial Cvs Bazaar Git Filesystem )
# Permissions
Redmine::AccessControl.map do |map|
diff --git a/lib/redmine/scm/adapters/abstract_adapter.rb b/lib/redmine/scm/adapters/abstract_adapter.rb
index 80058a2bf..bd77ce203 100644
--- a/lib/redmine/scm/adapters/abstract_adapter.rb
+++ b/lib/redmine/scm/adapters/abstract_adapter.rb
@@ -100,6 +100,16 @@ module Redmine
(path[-1,1] == "/") ? path : "#{path}/"
end
+ def without_leading_slash(path)
+ path ||= ''
+ path.gsub(%r{^/+}, '')
+ end
+
+ def without_trailling_slash(path)
+ path ||= ''
+ (path[-1,1] == "/") ? path[0..-2] : path
+ end
+
def shell_quote(str)
if RUBY_PLATFORM =~ /mswin/
'"' + str.gsub(/"/, '\\"') + '"'
diff --git a/lib/redmine/scm/adapters/filesystem_adapter.rb b/lib/redmine/scm/adapters/filesystem_adapter.rb
new file mode 100644
index 000000000..c06b7e6e3
--- /dev/null
+++ b/lib/redmine/scm/adapters/filesystem_adapter.rb
@@ -0,0 +1,94 @@
+# redMine - project management software
+# Copyright (C) 2006-2007 Jean-Philippe Lang
+#
+# 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.
+#
+# 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.
+#
+# 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'
+require 'find'
+
+module Redmine
+ module Scm
+ module Adapters
+ class FilesystemAdapter < AbstractAdapter
+
+
+ def initialize(url, root_url=nil, login=nil, password=nil)
+ @url = with_trailling_slash(url)
+ end
+
+ def format_path_ends(path, leading=true, trailling=true)
+ path = leading ? with_leading_slash(path) :
+ without_leading_slash(path)
+ trailling ? with_trailling_slash(path) :
+ without_trailling_slash(path)
+ end
+
+ def info
+ info = Info.new({:root_url => target(),
+ :lastrev => nil
+ })
+ info
+ rescue CommandFailed
+ return nil
+ end
+
+ def entries(path="", identifier=nil)
+ entries = Entries.new
+ Dir.new(target(path)).each do |e|
+ relative_path = format_path_ends((format_path_ends(path,
+ false,
+ true) + e),
+ false,false)
+ target = target(relative_path)
+ entries <<
+ Entry.new({ :name => File.basename(e),
+ # below : list unreadable files, but dont link them.
+ :path => File.readable?(target) ? relative_path : "",
+ :kind => (File.directory?(target) ? 'dir' : 'file'),
+ :size => if (File.directory?(target))
+ nil else File.size(target) end,
+ :lastrev =>
+ Revision.new({:time => (File.mtime(target)).localtime,
+ })
+ }) if File.exist?(target) and # paranoid test
+ %w{file directory}.include?(File.ftype(target)) and # avoid special types
+ not File.basename(e).match(/^\.+$/) # avoid . and ..
+ end
+ entries.sort_by_name
+ end
+
+ def cat(path, identifier=nil)
+ File.new(target(path)).read
+ end
+
+ private
+
+ # AbstractAdapter::target is implicitly made to quote paths.
+ # Here we do not shell-out, so we do not want quotes.
+ def target(path=nil)
+ #Prevent the use of ..
+ if path and !path.match(/(^|\/)\.\.(\/|$)/)
+ return "#{self.url}#{without_leading_slash(path)}"
+ end
+ return self.url
+ end
+
+ end
+ end
+ end
+end
diff --git a/test/fixtures/repositories/filesystem_repository.tar.gz b/test/fixtures/repositories/filesystem_repository.tar.gz
new file mode 100644
index 000000000..7e8a4ac56
--- /dev/null
+++ b/test/fixtures/repositories/filesystem_repository.tar.gz
Binary files differ
diff --git a/test/unit/filesystem_adapter_test.rb b/test/unit/filesystem_adapter_test.rb
new file mode 100644
index 000000000..720d1e92c
--- /dev/null
+++ b/test/unit/filesystem_adapter_test.rb
@@ -0,0 +1,42 @@
+
+require File.dirname(__FILE__) + '/../test_helper'
+
+
+class FilesystemAdapterTest < Test::Unit::TestCase
+
+ REPOSITORY_PATH = RAILS_ROOT.gsub(%r{config\/\.\.}, '') + '/tmp/test/filesystem_repository'
+
+ if File.directory?(REPOSITORY_PATH)
+ def setup
+ @adapter = Redmine::Scm::Adapters::FilesystemAdapter.new(REPOSITORY_PATH)
+ end
+
+ def test_entries
+ assert_equal 2, @adapter.entries.size
+ assert_equal ["dir", "test"], @adapter.entries.collect(&:name)
+ assert_equal ["dir", "test"], @adapter.entries(nil).collect(&:name)
+ assert_equal ["dir", "test"], @adapter.entries("/").collect(&:name)
+ ["dir", "/dir", "/dir/", "dir/"].each do |path|
+ assert_equal ["subdir", "dirfile"], @adapter.entries(path).collect(&:name)
+ end
+ # If y try to use "..", the path is ignored
+ ["/../","dir/../", "..", "../", "/..", "dir/.."].each do |path|
+ assert_equal ["dir", "test"], @adapter.entries(path).collect(&:name), ".. must be ignored in path argument"
+ end
+ end
+
+ def test_cat
+ assert_equal "TEST CAT\n", @adapter.cat("test")
+ assert_equal "TEST CAT\n", @adapter.cat("/test")
+ # Revision number is ignored
+ assert_equal "TEST CAT\n", @adapter.cat("/test", 1)
+ end
+
+ else
+ puts "Filesystem test repository NOT FOUND. Skipping unit tests !!! See doc/RUNNING_TESTS."
+ def test_fake; assert true end
+ end
+
+end
+
+
diff --git a/test/unit/repository_filesystem_test.rb b/test/unit/repository_filesystem_test.rb
new file mode 100644
index 000000000..6b643f96f
--- /dev/null
+++ b/test/unit/repository_filesystem_test.rb
@@ -0,0 +1,54 @@
+# redMine - project management software
+# Copyright (C) 2006-2007 Jean-Philippe Lang
+#
+# 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.
+#
+# 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.
+#
+# 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 File.dirname(__FILE__) + '/../test_helper'
+
+class RepositoryFilesystemTest < Test::Unit::TestCase
+ fixtures :projects
+
+ # No '..' in the repository path
+ REPOSITORY_PATH = RAILS_ROOT.gsub(%r{config\/\.\.}, '') + '/tmp/test/filesystem_repository'
+
+ def setup
+ @project = Project.find(1)
+ Setting.enabled_scm << 'Filesystem' unless Setting.enabled_scm.include?('Filesystem')
+ assert @repository = Repository::Filesystem.create(:project => @project, :url => REPOSITORY_PATH)
+ end
+
+ if File.directory?(REPOSITORY_PATH)
+ def test_fetch_changesets
+ @repository.fetch_changesets
+ @repository.reload
+
+ assert_equal 0, @repository.changesets.count
+ assert_equal 0, @repository.changes.count
+ end
+
+ def test_entries
+ assert_equal 2, @repository.entries("", 2).size
+ assert_equal 2, @repository.entries("dir", 3).size
+ end
+
+ def test_cat
+ assert_equal "TEST CAT\n", @repository.scm.cat("test")
+ end
+
+ else
+ puts "Filesystem test repository NOT FOUND. Skipping unit tests !!! See doc/RUNNING_TESTS."
+ def test_fake; assert true end
+ end
+end
diff --git a/test/unit/repository_test.rb b/test/unit/repository_test.rb
index 270b0bea1..03d836ef7 100644
--- a/test/unit/repository_test.rb
+++ b/test/unit/repository_test.rb
@@ -51,6 +51,8 @@ class RepositoryTest < Test::Unit::TestCase
repository = Repository::Subversion.new(:project => Project.find(3), :url => "svn://localhost")
assert !repository.save
assert_equal :activerecord_error_invalid, repository.errors.on(:type)
+ # re-enable Subversion for following tests
+ Setting.delete_all
end
def test_scan_changesets_for_issue_ids