Adds Filesystem adapter (patch #1393 by Paul R).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1508 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
parent
dfe62d7f51
commit
e69b4647f2
|
@ -98,4 +98,8 @@ module RepositoriesHelper
|
||||||
def bazaar_field_tags(form, repository)
|
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?)))
|
content_tag('p', form.text_field(:url, :label => 'Root directory', :size => 60, :required => true, :disabled => (repository && !repository.new_record?)))
|
||||||
end
|
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
|
end
|
||||||
|
|
|
@ -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
|
|
@ -24,6 +24,10 @@ Git
|
||||||
---
|
---
|
||||||
gunzip < test/fixtures/repositories/git_repository.tar.gz | tar -xv -C tmp/test
|
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
|
Running Tests
|
||||||
=============
|
=============
|
||||||
|
|
|
@ -11,7 +11,7 @@ rescue LoadError
|
||||||
# RMagick is not available
|
# RMagick is not available
|
||||||
end
|
end
|
||||||
|
|
||||||
REDMINE_SUPPORTED_SCM = %w( Subversion Darcs Mercurial Cvs Bazaar Git )
|
REDMINE_SUPPORTED_SCM = %w( Subversion Darcs Mercurial Cvs Bazaar Git Filesystem )
|
||||||
|
|
||||||
# Permissions
|
# Permissions
|
||||||
Redmine::AccessControl.map do |map|
|
Redmine::AccessControl.map do |map|
|
||||||
|
|
|
@ -100,6 +100,16 @@ module Redmine
|
||||||
(path[-1,1] == "/") ? path : "#{path}/"
|
(path[-1,1] == "/") ? path : "#{path}/"
|
||||||
end
|
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)
|
def shell_quote(str)
|
||||||
if RUBY_PLATFORM =~ /mswin/
|
if RUBY_PLATFORM =~ /mswin/
|
||||||
'"' + str.gsub(/"/, '\\"') + '"'
|
'"' + str.gsub(/"/, '\\"') + '"'
|
||||||
|
|
|
@ -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
|
Binary file not shown.
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
@ -51,6 +51,8 @@ class RepositoryTest < Test::Unit::TestCase
|
||||||
repository = Repository::Subversion.new(:project => Project.find(3), :url => "svn://localhost")
|
repository = Repository::Subversion.new(:project => Project.find(3), :url => "svn://localhost")
|
||||||
assert !repository.save
|
assert !repository.save
|
||||||
assert_equal :activerecord_error_invalid, repository.errors.on(:type)
|
assert_equal :activerecord_error_invalid, repository.errors.on(:type)
|
||||||
|
# re-enable Subversion for following tests
|
||||||
|
Setting.delete_all
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_scan_changesets_for_issue_ids
|
def test_scan_changesets_for_issue_ids
|
||||||
|
|
Loading…
Reference in New Issue