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
--- /dev/null
+# 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
---
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
=============
# 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|
(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(/"/, '\\"') + '"'
--- /dev/null
+# 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
--- /dev/null
+
+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
+
+
--- /dev/null
+# 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
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