Merge branch 'ticket/master/225-upstream-scm'
This commit is contained in:
commit
86faa88e55
|
@ -1,3 +1,5 @@
|
||||||
|
/.project
|
||||||
|
/.loadpath
|
||||||
/config/additional_environment.rb
|
/config/additional_environment.rb
|
||||||
/config/configuration.yml
|
/config/configuration.yml
|
||||||
/config/database.yml
|
/config/database.yml
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
syntax: glob
|
syntax: glob
|
||||||
|
|
||||||
|
.project
|
||||||
|
.loadpath
|
||||||
config/additional_environment.rb
|
config/additional_environment.rb
|
||||||
config/configuration.yml
|
config/configuration.yml
|
||||||
config/database.yml
|
config/database.yml
|
||||||
|
|
|
@ -67,13 +67,13 @@ class RepositoriesController < ApplicationController
|
||||||
redirect_to :action => 'committers', :id => @project
|
redirect_to :action => 'committers', :id => @project
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
@repository.destroy
|
@repository.destroy
|
||||||
redirect_to :controller => 'projects', :action => 'settings', :id => @project, :tab => 'repository'
|
redirect_to :controller => 'projects', :action => 'settings', :id => @project, :tab => 'repository'
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@repository.fetch_changesets if Setting.autofetch_changesets? && @path.empty?
|
@repository.fetch_changesets if Setting.autofetch_changesets? && @path.empty?
|
||||||
|
|
||||||
@entries = @repository.entries(@path, @rev)
|
@entries = @repository.entries(@path, @rev)
|
||||||
|
@ -88,7 +88,7 @@ class RepositoriesController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
alias_method :browse, :show
|
alias_method :browse, :show
|
||||||
|
|
||||||
def changes
|
def changes
|
||||||
@entry = @repository.entry(@path, @rev)
|
@entry = @repository.entry(@path, @rev)
|
||||||
(show_error_not_found; return) unless @entry
|
(show_error_not_found; return) unless @entry
|
||||||
|
@ -96,23 +96,23 @@ class RepositoriesController < ApplicationController
|
||||||
@properties = @repository.properties(@path, @rev)
|
@properties = @repository.properties(@path, @rev)
|
||||||
@changeset = @repository.find_changeset_by_name(@rev)
|
@changeset = @repository.find_changeset_by_name(@rev)
|
||||||
end
|
end
|
||||||
|
|
||||||
def revisions
|
def revisions
|
||||||
@changeset_count = @repository.changesets.count
|
@changeset_count = @repository.changesets.count
|
||||||
@changeset_pages = Paginator.new self, @changeset_count,
|
@changeset_pages = Paginator.new self, @changeset_count,
|
||||||
per_page_option,
|
per_page_option,
|
||||||
params['page']
|
params['page']
|
||||||
@changesets = @repository.changesets.find(:all,
|
@changesets = @repository.changesets.find(:all,
|
||||||
:limit => @changeset_pages.items_per_page,
|
:limit => @changeset_pages.items_per_page,
|
||||||
:offset => @changeset_pages.current.offset,
|
:offset => @changeset_pages.current.offset,
|
||||||
:include => [:user, :repository])
|
:include => [:user, :repository])
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html { render :layout => false if request.xhr? }
|
format.html { render :layout => false if request.xhr? }
|
||||||
format.atom { render_feed(@changesets, :title => "#{@project.name}: #{l(:label_revision_plural)}") }
|
format.atom { render_feed(@changesets, :title => "#{@project.name}: #{l(:label_revision_plural)}") }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def entry
|
def entry
|
||||||
@entry = @repository.entry(@path, @rev)
|
@entry = @repository.entry(@path, @rev)
|
||||||
(show_error_not_found; return) unless @entry
|
(show_error_not_found; return) unless @entry
|
||||||
|
@ -122,9 +122,10 @@ class RepositoriesController < ApplicationController
|
||||||
|
|
||||||
@content = @repository.cat(@path, @rev)
|
@content = @repository.cat(@path, @rev)
|
||||||
(show_error_not_found; return) unless @content
|
(show_error_not_found; return) unless @content
|
||||||
if 'raw' == params[:format] || @content.is_binary_data? || (@entry.size && @entry.size > Setting.file_max_size_displayed.to_i.kilobyte)
|
if 'raw' == params[:format] || @content.is_binary_data? ||
|
||||||
|
(@entry.size && @entry.size > Setting.file_max_size_displayed.to_i.kilobyte)
|
||||||
# Force the download
|
# Force the download
|
||||||
send_data @content, :filename => @path.split('/').last
|
send_data @content, :filename => filename_for_content_disposition(@path.split('/').last)
|
||||||
else
|
else
|
||||||
# Prevent empty lines when displaying a file with Windows style eol
|
# Prevent empty lines when displaying a file with Windows style eol
|
||||||
@content.gsub!("\r\n", "\n")
|
@content.gsub!("\r\n", "\n")
|
||||||
|
@ -135,7 +136,7 @@ class RepositoriesController < ApplicationController
|
||||||
def annotate
|
def annotate
|
||||||
@entry = @repository.entry(@path, @rev)
|
@entry = @repository.entry(@path, @rev)
|
||||||
(show_error_not_found; return) unless @entry
|
(show_error_not_found; return) unless @entry
|
||||||
|
|
||||||
@annotate = @repository.scm.annotate(@path, @rev)
|
@annotate = @repository.scm.annotate(@path, @rev)
|
||||||
(render_error l(:error_scm_annotate); return) if @annotate.nil? || @annotate.empty?
|
(render_error l(:error_scm_annotate); return) if @annotate.nil? || @annotate.empty?
|
||||||
@changeset = @repository.find_changeset_by_name(@rev)
|
@changeset = @repository.find_changeset_by_name(@rev)
|
||||||
|
@ -153,7 +154,7 @@ class RepositoriesController < ApplicationController
|
||||||
rescue ChangesetNotFound
|
rescue ChangesetNotFound
|
||||||
show_error_not_found
|
show_error_not_found
|
||||||
end
|
end
|
||||||
|
|
||||||
def diff
|
def diff
|
||||||
if params[:format] == 'diff'
|
if params[:format] == 'diff'
|
||||||
@diff = @repository.diff(@path, @rev, @rev_to)
|
@diff = @repository.diff(@path, @rev, @rev_to)
|
||||||
|
@ -185,11 +186,11 @@ class RepositoriesController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def stats
|
def stats
|
||||||
end
|
end
|
||||||
|
|
||||||
def graph
|
def graph
|
||||||
data = nil
|
data = nil
|
||||||
case params[:graph]
|
case params[:graph]
|
||||||
when "commits_per_month"
|
when "commits_per_month"
|
||||||
data = graph_commits_per_month(@repository)
|
data = graph_commits_per_month(@repository)
|
||||||
|
|
|
@ -25,6 +25,10 @@ module Redmine
|
||||||
|
|
||||||
class AbstractAdapter #:nodoc:
|
class AbstractAdapter #:nodoc:
|
||||||
class << self
|
class << self
|
||||||
|
def client_command
|
||||||
|
""
|
||||||
|
end
|
||||||
|
|
||||||
# Returns the version of the scm client
|
# Returns the version of the scm client
|
||||||
# Eg: [1, 5, 0] or [] if unknown
|
# Eg: [1, 5, 0] or [] if unknown
|
||||||
def client_version
|
def client_version
|
||||||
|
@ -45,8 +49,20 @@ module Redmine
|
||||||
def client_version_above?(v, options={})
|
def client_version_above?(v, options={})
|
||||||
((client_version <=> v) >= 0) || (client_version.empty? && options[:unknown])
|
((client_version <=> v) >= 0) || (client_version.empty? && options[:unknown])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def client_available
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def shell_quote(str)
|
||||||
|
if Redmine::Platform.mswin?
|
||||||
|
'"' + str.gsub(/"/, '\\"') + '"'
|
||||||
|
else
|
||||||
|
"'" + str.gsub(/'/, "'\"'\"'") + "'"
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def initialize(url, root_url=nil, login=nil, password=nil)
|
def initialize(url, root_url=nil, login=nil, password=nil)
|
||||||
@url = url
|
@url = url
|
||||||
@login = login if login && !login.empty?
|
@login = login if login && !login.empty?
|
||||||
|
@ -138,7 +154,7 @@ module Redmine
|
||||||
path ||= ''
|
path ||= ''
|
||||||
(path[-1,1] == "/") ? path : "#{path}/"
|
(path[-1,1] == "/") ? path : "#{path}/"
|
||||||
end
|
end
|
||||||
|
|
||||||
def without_leading_slash(path)
|
def without_leading_slash(path)
|
||||||
path ||= ''
|
path ||= ''
|
||||||
path.gsub(%r{^/+}, '')
|
path.gsub(%r{^/+}, '')
|
||||||
|
@ -148,13 +164,9 @@ module Redmine
|
||||||
path ||= ''
|
path ||= ''
|
||||||
(path[-1,1] == "/") ? path[0..-2] : path
|
(path[-1,1] == "/") ? path[0..-2] : path
|
||||||
end
|
end
|
||||||
|
|
||||||
def shell_quote(str)
|
def shell_quote(str)
|
||||||
if Redmine::Platform.mswin?
|
self.class.shell_quote(str)
|
||||||
'"' + str.gsub(/"/, '\\"') + '"'
|
|
||||||
else
|
|
||||||
"'" + str.gsub(/'/, "'\"'\"'") + "'"
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -168,11 +180,11 @@ module Redmine
|
||||||
base = path.match(/^\//) ? root_url : url
|
base = path.match(/^\//) ? root_url : url
|
||||||
shell_quote("#{base}/#{path}".gsub(/[?<>\*]/, ''))
|
shell_quote("#{base}/#{path}".gsub(/[?<>\*]/, ''))
|
||||||
end
|
end
|
||||||
|
|
||||||
def logger
|
def logger
|
||||||
self.class.logger
|
self.class.logger
|
||||||
end
|
end
|
||||||
|
|
||||||
def shellout(cmd, &block)
|
def shellout(cmd, &block)
|
||||||
self.class.shellout(cmd, &block)
|
self.class.shellout(cmd, &block)
|
||||||
end
|
end
|
||||||
|
|
|
@ -19,15 +19,25 @@ require 'redmine/scm/adapters/abstract_adapter'
|
||||||
|
|
||||||
module Redmine
|
module Redmine
|
||||||
module Scm
|
module Scm
|
||||||
module Adapters
|
module Adapters
|
||||||
class BazaarAdapter < AbstractAdapter
|
class BazaarAdapter < AbstractAdapter
|
||||||
|
|
||||||
# Bazaar executable name
|
# Bazaar executable name
|
||||||
BZR_BIN = Redmine::Configuration['scm_bazaar_command'] || "bzr"
|
BZR_BIN = Redmine::Configuration['scm_bazaar_command'] || "bzr"
|
||||||
|
|
||||||
|
class << self
|
||||||
|
def client_command
|
||||||
|
@@bin ||= BZR_BIN
|
||||||
|
end
|
||||||
|
|
||||||
|
def sq_bin
|
||||||
|
@@sq_bin ||= shell_quote(BZR_BIN)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# Get info about the repository
|
# Get info about the repository
|
||||||
def info
|
def info
|
||||||
cmd = "#{BZR_BIN} revno #{target('')}"
|
cmd = "#{self.class.sq_bin} revno #{target('')}"
|
||||||
info = nil
|
info = nil
|
||||||
shellout(cmd) do |io|
|
shellout(cmd) do |io|
|
||||||
if io.read =~ %r{^(\d+)\r?$}
|
if io.read =~ %r{^(\d+)\r?$}
|
||||||
|
@ -43,13 +53,13 @@ module Redmine
|
||||||
rescue CommandFailed
|
rescue CommandFailed
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns an Entries collection
|
# Returns an Entries collection
|
||||||
# or nil if the given path doesn't exist in the repository
|
# or nil if the given path doesn't exist in the repository
|
||||||
def entries(path=nil, identifier=nil)
|
def entries(path=nil, identifier=nil)
|
||||||
path ||= ''
|
path ||= ''
|
||||||
entries = Entries.new
|
entries = Entries.new
|
||||||
cmd = "#{BZR_BIN} ls -v --show-ids"
|
cmd = "#{self.class.sq_bin} ls -v --show-ids"
|
||||||
identifier = -1 unless identifier && identifier.to_i > 0
|
identifier = -1 unless identifier && identifier.to_i > 0
|
||||||
cmd << " -r#{identifier.to_i}"
|
cmd << " -r#{identifier.to_i}"
|
||||||
cmd << " #{target(path)}"
|
cmd << " #{target(path)}"
|
||||||
|
@ -71,13 +81,13 @@ module Redmine
|
||||||
logger.debug("Found #{entries.size} entries in the repository for #{target(path)}") if logger && logger.debug?
|
logger.debug("Found #{entries.size} entries in the repository for #{target(path)}") if logger && logger.debug?
|
||||||
entries.sort_by_name
|
entries.sort_by_name
|
||||||
end
|
end
|
||||||
|
|
||||||
def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={})
|
def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={})
|
||||||
path ||= ''
|
path ||= ''
|
||||||
identifier_from = (identifier_from and identifier_from.to_i > 0) ? identifier_from.to_i : 'last:1'
|
identifier_from = (identifier_from and identifier_from.to_i > 0) ? identifier_from.to_i : 'last:1'
|
||||||
identifier_to = (identifier_to and identifier_to.to_i > 0) ? identifier_to.to_i : 1
|
identifier_to = (identifier_to and identifier_to.to_i > 0) ? identifier_to.to_i : 1
|
||||||
revisions = Revisions.new
|
revisions = Revisions.new
|
||||||
cmd = "#{BZR_BIN} log -v --show-ids -r#{identifier_to}..#{identifier_from} #{target(path)}"
|
cmd = "#{self.class.sq_bin} log -v --show-ids -r#{identifier_to}..#{identifier_from} #{target(path)}"
|
||||||
shellout(cmd) do |io|
|
shellout(cmd) do |io|
|
||||||
revision = nil
|
revision = nil
|
||||||
parsing = nil
|
parsing = nil
|
||||||
|
@ -132,7 +142,7 @@ module Redmine
|
||||||
return nil if $? && $?.exitstatus != 0
|
return nil if $? && $?.exitstatus != 0
|
||||||
revisions
|
revisions
|
||||||
end
|
end
|
||||||
|
|
||||||
def diff(path, identifier_from, identifier_to=nil)
|
def diff(path, identifier_from, identifier_to=nil)
|
||||||
path ||= ''
|
path ||= ''
|
||||||
if identifier_to
|
if identifier_to
|
||||||
|
@ -143,7 +153,7 @@ module Redmine
|
||||||
if identifier_from
|
if identifier_from
|
||||||
identifier_from = identifier_from.to_i
|
identifier_from = identifier_from.to_i
|
||||||
end
|
end
|
||||||
cmd = "#{BZR_BIN} diff -r#{identifier_to}..#{identifier_from} #{target(path)}"
|
cmd = "#{self.class.sq_bin} diff -r#{identifier_to}..#{identifier_from} #{target(path)}"
|
||||||
diff = []
|
diff = []
|
||||||
shellout(cmd) do |io|
|
shellout(cmd) do |io|
|
||||||
io.each_line do |line|
|
io.each_line do |line|
|
||||||
|
@ -153,9 +163,9 @@ module Redmine
|
||||||
#return nil if $? && $?.exitstatus != 0
|
#return nil if $? && $?.exitstatus != 0
|
||||||
diff
|
diff
|
||||||
end
|
end
|
||||||
|
|
||||||
def cat(path, identifier=nil)
|
def cat(path, identifier=nil)
|
||||||
cmd = "#{BZR_BIN} cat"
|
cmd = "#{self.class.sq_bin} cat"
|
||||||
cmd << " -r#{identifier.to_i}" if identifier && identifier.to_i > 0
|
cmd << " -r#{identifier.to_i}" if identifier && identifier.to_i > 0
|
||||||
cmd << " #{target(path)}"
|
cmd << " #{target(path)}"
|
||||||
cat = nil
|
cat = nil
|
||||||
|
@ -166,9 +176,9 @@ module Redmine
|
||||||
return nil if $? && $?.exitstatus != 0
|
return nil if $? && $?.exitstatus != 0
|
||||||
cat
|
cat
|
||||||
end
|
end
|
||||||
|
|
||||||
def annotate(path, identifier=nil)
|
def annotate(path, identifier=nil)
|
||||||
cmd = "#{BZR_BIN} annotate --all"
|
cmd = "#{self.class.sq_bin} annotate --all"
|
||||||
cmd << " -r#{identifier.to_i}" if identifier && identifier.to_i > 0
|
cmd << " -r#{identifier.to_i}" if identifier && identifier.to_i > 0
|
||||||
cmd << " #{target(path)}"
|
cmd << " #{target(path)}"
|
||||||
blame = Annotate.new
|
blame = Annotate.new
|
||||||
|
|
|
@ -24,7 +24,17 @@ module Redmine
|
||||||
|
|
||||||
# CVS executable name
|
# CVS executable name
|
||||||
CVS_BIN = Redmine::Configuration['scm_cvs_command'] || "cvs"
|
CVS_BIN = Redmine::Configuration['scm_cvs_command'] || "cvs"
|
||||||
|
|
||||||
|
class << self
|
||||||
|
def client_command
|
||||||
|
@@bin ||= CVS_BIN
|
||||||
|
end
|
||||||
|
|
||||||
|
def sq_bin
|
||||||
|
@@sq_bin ||= shell_quote(CVS_BIN)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# Guidelines for the input:
|
# Guidelines for the input:
|
||||||
# url -> the project-path, relative to the cvsroot (eg. module name)
|
# url -> the project-path, relative to the cvsroot (eg. module name)
|
||||||
# root_url -> the good old, sometimes damned, CVSROOT
|
# root_url -> the good old, sometimes damned, CVSROOT
|
||||||
|
@ -38,24 +48,24 @@ module Redmine
|
||||||
raise CommandFailed if root_url.blank?
|
raise CommandFailed if root_url.blank?
|
||||||
@root_url = root_url
|
@root_url = root_url
|
||||||
end
|
end
|
||||||
|
|
||||||
def root_url
|
def root_url
|
||||||
@root_url
|
@root_url
|
||||||
end
|
end
|
||||||
|
|
||||||
def url
|
def url
|
||||||
@url
|
@url
|
||||||
end
|
end
|
||||||
|
|
||||||
def info
|
def info
|
||||||
logger.debug "<cvs> info"
|
logger.debug "<cvs> info"
|
||||||
Info.new({:root_url => @root_url, :lastrev => nil})
|
Info.new({:root_url => @root_url, :lastrev => nil})
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_previous_revision(revision)
|
def get_previous_revision(revision)
|
||||||
CvsRevisionHelper.new(revision).prevRev
|
CvsRevisionHelper.new(revision).prevRev
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns an Entries collection
|
# Returns an Entries collection
|
||||||
# or nil if the given path doesn't exist in the repository
|
# or nil if the given path doesn't exist in the repository
|
||||||
# this method is used by the repository-browser (aka LIST)
|
# this method is used by the repository-browser (aka LIST)
|
||||||
|
@ -63,14 +73,14 @@ module Redmine
|
||||||
logger.debug "<cvs> entries '#{path}' with identifier '#{identifier}'"
|
logger.debug "<cvs> entries '#{path}' with identifier '#{identifier}'"
|
||||||
path_with_project="#{url}#{with_leading_slash(path)}"
|
path_with_project="#{url}#{with_leading_slash(path)}"
|
||||||
entries = Entries.new
|
entries = Entries.new
|
||||||
cmd = "#{CVS_BIN} -d #{shell_quote root_url} rls -e"
|
cmd = "#{self.class.sq_bin} -d #{shell_quote root_url} rls -e"
|
||||||
cmd << " -D \"#{time_to_cvstime(identifier)}\"" if identifier
|
cmd << " -D \"#{time_to_cvstime(identifier)}\"" if identifier
|
||||||
cmd << " #{shell_quote path_with_project}"
|
cmd << " #{shell_quote path_with_project}"
|
||||||
shellout(cmd) do |io|
|
shellout(cmd) do |io|
|
||||||
io.each_line(){|line|
|
io.each_line(){|line|
|
||||||
fields=line.chop.split('/',-1)
|
fields=line.chop.split('/',-1)
|
||||||
logger.debug(">>InspectLine #{fields.inspect}")
|
logger.debug(">>InspectLine #{fields.inspect}")
|
||||||
|
|
||||||
if fields[0]!="D"
|
if fields[0]!="D"
|
||||||
entries << Entry.new({:name => fields[-5],
|
entries << Entry.new({:name => fields[-5],
|
||||||
#:path => fields[-4].include?(path)?fields[-4]:(path + "/"+ fields[-4]),
|
#:path => fields[-4].include?(path)?fields[-4]:(path + "/"+ fields[-4]),
|
||||||
|
@ -96,19 +106,19 @@ module Redmine
|
||||||
end
|
end
|
||||||
return nil if $? && $?.exitstatus != 0
|
return nil if $? && $?.exitstatus != 0
|
||||||
entries.sort_by_name
|
entries.sort_by_name
|
||||||
end
|
end
|
||||||
|
|
||||||
STARTLOG="----------------------------"
|
STARTLOG="----------------------------"
|
||||||
ENDLOG ="============================================================================="
|
ENDLOG ="============================================================================="
|
||||||
|
|
||||||
# Returns all revisions found between identifier_from and identifier_to
|
# Returns all revisions found between identifier_from and identifier_to
|
||||||
# in the repository. both identifier have to be dates or nil.
|
# in the repository. both identifier have to be dates or nil.
|
||||||
# these method returns nothing but yield every result in block
|
# these method returns nothing but yield every result in block
|
||||||
def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={}, &block)
|
def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={}, &block)
|
||||||
logger.debug "<cvs> revisions path:'#{path}',identifier_from #{identifier_from}, identifier_to #{identifier_to}"
|
logger.debug "<cvs> revisions path:'#{path}',identifier_from #{identifier_from}, identifier_to #{identifier_to}"
|
||||||
|
|
||||||
path_with_project="#{url}#{with_leading_slash(path)}"
|
path_with_project="#{url}#{with_leading_slash(path)}"
|
||||||
cmd = "#{CVS_BIN} -d #{shell_quote root_url} rlog"
|
cmd = "#{self.class.sq_bin} -d #{shell_quote root_url} rlog"
|
||||||
cmd << " -d\">#{time_to_cvstime_rlog(identifier_from)}\"" if identifier_from
|
cmd << " -d\">#{time_to_cvstime_rlog(identifier_from)}\"" if identifier_from
|
||||||
cmd << " #{shell_quote path_with_project}"
|
cmd << " #{shell_quote path_with_project}"
|
||||||
shellout(cmd) do |io|
|
shellout(cmd) do |io|
|
||||||
|
@ -123,7 +133,7 @@ module Redmine
|
||||||
file_state=nil
|
file_state=nil
|
||||||
branch_map=nil
|
branch_map=nil
|
||||||
|
|
||||||
io.each_line() do |line|
|
io.each_line() do |line|
|
||||||
|
|
||||||
if state!="revision" && /^#{ENDLOG}/ =~ line
|
if state!="revision" && /^#{ENDLOG}/ =~ line
|
||||||
commit_log=String.new
|
commit_log=String.new
|
||||||
|
@ -162,9 +172,9 @@ module Redmine
|
||||||
end
|
end
|
||||||
next
|
next
|
||||||
elsif state=="revision"
|
elsif state=="revision"
|
||||||
if /^#{ENDLOG}/ =~ line || /^#{STARTLOG}/ =~ line
|
if /^#{ENDLOG}/ =~ line || /^#{STARTLOG}/ =~ line
|
||||||
if revision
|
if revision
|
||||||
|
|
||||||
revHelper=CvsRevisionHelper.new(revision)
|
revHelper=CvsRevisionHelper.new(revision)
|
||||||
revBranch="HEAD"
|
revBranch="HEAD"
|
||||||
|
|
||||||
|
@ -176,7 +186,7 @@ module Redmine
|
||||||
|
|
||||||
logger.debug("********** YIELD Revision #{revision}::#{revBranch}")
|
logger.debug("********** YIELD Revision #{revision}::#{revBranch}")
|
||||||
|
|
||||||
yield Revision.new({
|
yield Revision.new({
|
||||||
:time => date,
|
:time => date,
|
||||||
:author => author,
|
:author => author,
|
||||||
:message=>commit_log.chomp,
|
:message=>commit_log.chomp,
|
||||||
|
@ -188,9 +198,9 @@ module Redmine
|
||||||
:kind=>'file',
|
:kind=>'file',
|
||||||
:action=>file_state
|
:action=>file_state
|
||||||
}]
|
}]
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
commit_log=String.new
|
commit_log=String.new
|
||||||
revision=nil
|
revision=nil
|
||||||
|
|
||||||
|
@ -199,7 +209,7 @@ module Redmine
|
||||||
end
|
end
|
||||||
next
|
next
|
||||||
end
|
end
|
||||||
|
|
||||||
if /^branches: (.+)$/ =~ line
|
if /^branches: (.+)$/ =~ line
|
||||||
#TODO: version.branch = $1
|
#TODO: version.branch = $1
|
||||||
elsif /^revision (\d+(?:\.\d+)+).*$/ =~ line
|
elsif /^revision (\d+(?:\.\d+)+).*$/ =~ line
|
||||||
|
@ -216,20 +226,20 @@ module Redmine
|
||||||
# version.line_minus = linechanges[2]
|
# version.line_minus = linechanges[2]
|
||||||
# else
|
# else
|
||||||
# version.line_plus = 0
|
# version.line_plus = 0
|
||||||
# version.line_minus = 0
|
# version.line_minus = 0
|
||||||
# end
|
# end
|
||||||
else
|
else
|
||||||
commit_log << line unless line =~ /^\*\*\* empty log message \*\*\*/
|
commit_log << line unless line =~ /^\*\*\* empty log message \*\*\*/
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def diff(path, identifier_from, identifier_to=nil)
|
def diff(path, identifier_from, identifier_to=nil)
|
||||||
logger.debug "<cvs> diff path:'#{path}',identifier_from #{identifier_from}, identifier_to #{identifier_to}"
|
logger.debug "<cvs> diff path:'#{path}',identifier_from #{identifier_from}, identifier_to #{identifier_to}"
|
||||||
path_with_project="#{url}#{with_leading_slash(path)}"
|
path_with_project="#{url}#{with_leading_slash(path)}"
|
||||||
cmd = "#{CVS_BIN} -d #{shell_quote root_url} rdiff -u -r#{identifier_to} -r#{identifier_from} #{shell_quote path_with_project}"
|
cmd = "#{self.class.sq_bin} -d #{shell_quote root_url} rdiff -u -r#{identifier_to} -r#{identifier_from} #{shell_quote path_with_project}"
|
||||||
diff = []
|
diff = []
|
||||||
shellout(cmd) do |io|
|
shellout(cmd) do |io|
|
||||||
io.each_line do |line|
|
io.each_line do |line|
|
||||||
|
@ -238,28 +248,29 @@ module Redmine
|
||||||
end
|
end
|
||||||
return nil if $? && $?.exitstatus != 0
|
return nil if $? && $?.exitstatus != 0
|
||||||
diff
|
diff
|
||||||
end
|
end
|
||||||
|
|
||||||
def cat(path, identifier=nil)
|
def cat(path, identifier=nil)
|
||||||
identifier = (identifier) ? identifier : "HEAD"
|
identifier = (identifier) ? identifier : "HEAD"
|
||||||
logger.debug "<cvs> cat path:'#{path}',identifier #{identifier}"
|
logger.debug "<cvs> cat path:'#{path}',identifier #{identifier}"
|
||||||
path_with_project="#{url}#{with_leading_slash(path)}"
|
path_with_project="#{url}#{with_leading_slash(path)}"
|
||||||
cmd = "#{CVS_BIN} -d #{shell_quote root_url} co"
|
cmd = "#{self.class.sq_bin} -d #{shell_quote root_url} co"
|
||||||
cmd << " -D \"#{time_to_cvstime(identifier)}\"" if identifier
|
cmd << " -D \"#{time_to_cvstime(identifier)}\"" if identifier
|
||||||
cmd << " -p #{shell_quote path_with_project}"
|
cmd << " -p #{shell_quote path_with_project}"
|
||||||
cat = nil
|
cat = nil
|
||||||
shellout(cmd) do |io|
|
shellout(cmd) do |io|
|
||||||
|
io.binmode
|
||||||
cat = io.read
|
cat = io.read
|
||||||
end
|
end
|
||||||
return nil if $? && $?.exitstatus != 0
|
return nil if $? && $?.exitstatus != 0
|
||||||
cat
|
cat
|
||||||
end
|
end
|
||||||
|
|
||||||
def annotate(path, identifier=nil)
|
def annotate(path, identifier=nil)
|
||||||
identifier = (identifier) ? identifier.to_i : "HEAD"
|
identifier = (identifier) ? identifier.to_i : "HEAD"
|
||||||
logger.debug "<cvs> annotate path:'#{path}',identifier #{identifier}"
|
logger.debug "<cvs> annotate path:'#{path}',identifier #{identifier}"
|
||||||
path_with_project="#{url}#{with_leading_slash(path)}"
|
path_with_project="#{url}#{with_leading_slash(path)}"
|
||||||
cmd = "#{CVS_BIN} -d #{shell_quote root_url} rannotate -r#{identifier} #{shell_quote path_with_project}"
|
cmd = "#{self.class.sq_bin} -d #{shell_quote root_url} rannotate -r#{identifier} #{shell_quote path_with_project}"
|
||||||
blame = Annotate.new
|
blame = Annotate.new
|
||||||
shellout(cmd) do |io|
|
shellout(cmd) do |io|
|
||||||
io.each_line do |line|
|
io.each_line do |line|
|
||||||
|
@ -270,9 +281,9 @@ module Redmine
|
||||||
return nil if $? && $?.exitstatus != 0
|
return nil if $? && $?.exitstatus != 0
|
||||||
blame
|
blame
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# Returns the root url without the connexion string
|
# Returns the root url without the connexion string
|
||||||
# :pserver:anonymous@foo.bar:/path => /path
|
# :pserver:anonymous@foo.bar:/path => /path
|
||||||
# :ext:cvsservername:/path => /path
|
# :ext:cvsservername:/path => /path
|
||||||
|
|
|
@ -20,16 +20,24 @@ require 'rexml/document'
|
||||||
|
|
||||||
module Redmine
|
module Redmine
|
||||||
module Scm
|
module Scm
|
||||||
module Adapters
|
module Adapters
|
||||||
class DarcsAdapter < AbstractAdapter
|
class DarcsAdapter < AbstractAdapter
|
||||||
# Darcs executable name
|
# Darcs executable name
|
||||||
DARCS_BIN = Redmine::Configuration['scm_darcs_command'] || "darcs"
|
DARCS_BIN = Redmine::Configuration['scm_darcs_command'] || "darcs"
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
|
def client_command
|
||||||
|
@@bin ||= DARCS_BIN
|
||||||
|
end
|
||||||
|
|
||||||
|
def sq_bin
|
||||||
|
@@sq_bin ||= shell_quote(DARCS_BIN)
|
||||||
|
end
|
||||||
|
|
||||||
def client_version
|
def client_version
|
||||||
@@client_version ||= (darcs_binary_version || [])
|
@@client_version ||= (darcs_binary_version || [])
|
||||||
end
|
end
|
||||||
|
|
||||||
def darcs_binary_version
|
def darcs_binary_version
|
||||||
darcsversion = darcs_binary_version_from_command_line
|
darcsversion = darcs_binary_version_from_command_line
|
||||||
if m = darcsversion.match(%r{\A(.*?)((\d+\.)+\d+)})
|
if m = darcsversion.match(%r{\A(.*?)((\d+\.)+\d+)})
|
||||||
|
@ -38,7 +46,7 @@ module Redmine
|
||||||
end
|
end
|
||||||
|
|
||||||
def darcs_binary_version_from_command_line
|
def darcs_binary_version_from_command_line
|
||||||
shellout("#{DARCS_BIN} --version") { |io| io.read }.to_s
|
shellout("#{sq_bin} --version") { |io| io.read }.to_s
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -57,7 +65,7 @@ module Redmine
|
||||||
rev = revisions(nil,nil,nil,{:limit => 1})
|
rev = revisions(nil,nil,nil,{:limit => 1})
|
||||||
rev ? Info.new({:root_url => @url, :lastrev => rev.last}) : nil
|
rev ? Info.new({:root_url => @url, :lastrev => rev.last}) : nil
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns an Entries collection
|
# Returns an Entries collection
|
||||||
# or nil if the given path doesn't exist in the repository
|
# or nil if the given path doesn't exist in the repository
|
||||||
def entries(path=nil, identifier=nil)
|
def entries(path=nil, identifier=nil)
|
||||||
|
@ -66,7 +74,7 @@ module Redmine
|
||||||
path = ( self.class.client_version_above?([2, 2, 0]) ? @url : '.' )
|
path = ( self.class.client_version_above?([2, 2, 0]) ? @url : '.' )
|
||||||
end
|
end
|
||||||
entries = Entries.new
|
entries = Entries.new
|
||||||
cmd = "#{DARCS_BIN} annotate --repodir #{shell_quote @url} --xml-output"
|
cmd = "#{self.class.sq_bin} annotate --repodir #{shell_quote @url} --xml-output"
|
||||||
cmd << " --match #{shell_quote("hash #{identifier}")}" if identifier
|
cmd << " --match #{shell_quote("hash #{identifier}")}" if identifier
|
||||||
cmd << " #{shell_quote path}"
|
cmd << " #{shell_quote path}"
|
||||||
shellout(cmd) do |io|
|
shellout(cmd) do |io|
|
||||||
|
@ -86,11 +94,11 @@ module Redmine
|
||||||
return nil if $? && $?.exitstatus != 0
|
return nil if $? && $?.exitstatus != 0
|
||||||
entries.compact.sort_by_name
|
entries.compact.sort_by_name
|
||||||
end
|
end
|
||||||
|
|
||||||
def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={})
|
def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={})
|
||||||
path = '.' if path.blank?
|
path = '.' if path.blank?
|
||||||
revisions = Revisions.new
|
revisions = Revisions.new
|
||||||
cmd = "#{DARCS_BIN} changes --repodir #{shell_quote @url} --xml-output"
|
cmd = "#{self.class.sq_bin} changes --repodir #{shell_quote @url} --xml-output"
|
||||||
cmd << " --from-match #{shell_quote("hash #{identifier_from}")}" if identifier_from
|
cmd << " --from-match #{shell_quote("hash #{identifier_from}")}" if identifier_from
|
||||||
cmd << " --last #{options[:limit].to_i}" if options[:limit]
|
cmd << " --last #{options[:limit].to_i}" if options[:limit]
|
||||||
shellout(cmd) do |io|
|
shellout(cmd) do |io|
|
||||||
|
@ -113,10 +121,10 @@ module Redmine
|
||||||
return nil if $? && $?.exitstatus != 0
|
return nil if $? && $?.exitstatus != 0
|
||||||
revisions
|
revisions
|
||||||
end
|
end
|
||||||
|
|
||||||
def diff(path, identifier_from, identifier_to=nil)
|
def diff(path, identifier_from, identifier_to=nil)
|
||||||
path = '*' if path.blank?
|
path = '*' if path.blank?
|
||||||
cmd = "#{DARCS_BIN} diff --repodir #{shell_quote @url}"
|
cmd = "#{self.class.sq_bin} diff --repodir #{shell_quote @url}"
|
||||||
if identifier_to.nil?
|
if identifier_to.nil?
|
||||||
cmd << " --match #{shell_quote("hash #{identifier_from}")}"
|
cmd << " --match #{shell_quote("hash #{identifier_from}")}"
|
||||||
else
|
else
|
||||||
|
@ -133,9 +141,9 @@ module Redmine
|
||||||
return nil if $? && $?.exitstatus != 0
|
return nil if $? && $?.exitstatus != 0
|
||||||
diff
|
diff
|
||||||
end
|
end
|
||||||
|
|
||||||
def cat(path, identifier=nil)
|
def cat(path, identifier=nil)
|
||||||
cmd = "#{DARCS_BIN} show content --repodir #{shell_quote @url}"
|
cmd = "#{self.class.sq_bin} show content --repodir #{shell_quote @url}"
|
||||||
cmd << " --match #{shell_quote("hash #{identifier}")}" if identifier
|
cmd << " --match #{shell_quote("hash #{identifier}")}" if identifier
|
||||||
cmd << " #{shell_quote path}"
|
cmd << " #{shell_quote path}"
|
||||||
cat = nil
|
cat = nil
|
||||||
|
@ -148,7 +156,7 @@ module Redmine
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# Returns an Entry from the given XML element
|
# Returns an Entry from the given XML element
|
||||||
# or nil if the entry was deleted
|
# or nil if the entry was deleted
|
||||||
def entry_from_xml(element, path_prefix)
|
def entry_from_xml(element, path_prefix)
|
||||||
|
@ -196,10 +204,10 @@ module Redmine
|
||||||
end
|
end
|
||||||
paths
|
paths
|
||||||
end
|
end
|
||||||
|
|
||||||
# Retrieve changed paths for a single patch
|
# Retrieve changed paths for a single patch
|
||||||
def get_paths_for_patch_raw(hash)
|
def get_paths_for_patch_raw(hash)
|
||||||
cmd = "#{DARCS_BIN} annotate --repodir #{shell_quote @url} --summary --xml-output"
|
cmd = "#{self.class.sq_bin} annotate --repodir #{shell_quote @url} --summary --xml-output"
|
||||||
cmd << " --match #{shell_quote("hash #{hash}")} "
|
cmd << " --match #{shell_quote("hash #{hash}")} "
|
||||||
paths = []
|
paths = []
|
||||||
shellout(cmd) do |io|
|
shellout(cmd) do |io|
|
||||||
|
|
|
@ -25,7 +25,12 @@ module Redmine
|
||||||
module Scm
|
module Scm
|
||||||
module Adapters
|
module Adapters
|
||||||
class FilesystemAdapter < AbstractAdapter
|
class FilesystemAdapter < AbstractAdapter
|
||||||
|
|
||||||
|
class << self
|
||||||
|
def client_available
|
||||||
|
true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def initialize(url, root_url=nil, login=nil, password=nil)
|
def initialize(url, root_url=nil, login=nil, password=nil)
|
||||||
@url = with_trailling_slash(url)
|
@url = with_trailling_slash(url)
|
||||||
|
|
|
@ -19,11 +19,25 @@ require 'redmine/scm/adapters/abstract_adapter'
|
||||||
|
|
||||||
module Redmine
|
module Redmine
|
||||||
module Scm
|
module Scm
|
||||||
module Adapters
|
module Adapters
|
||||||
class GitAdapter < AbstractAdapter
|
class GitAdapter < AbstractAdapter
|
||||||
# Git executable name
|
# Git executable name
|
||||||
GIT_BIN = Redmine::Configuration['scm_git_command'] || "git"
|
GIT_BIN = Redmine::Configuration['scm_git_command'] || "git"
|
||||||
|
|
||||||
|
class << self
|
||||||
|
def client_command
|
||||||
|
@@bin ||= GIT_BIN
|
||||||
|
end
|
||||||
|
|
||||||
|
def sq_bin
|
||||||
|
@@sq_bin ||= shell_quote(GIT_BIN)
|
||||||
|
end
|
||||||
|
|
||||||
|
def client_available
|
||||||
|
!client_version.empty?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def info
|
def info
|
||||||
begin
|
begin
|
||||||
Info.new(:root_url => url, :lastrev => lastrev('',nil))
|
Info.new(:root_url => url, :lastrev => lastrev('',nil))
|
||||||
|
@ -35,7 +49,7 @@ module Redmine
|
||||||
def branches
|
def branches
|
||||||
return @branches if @branches
|
return @branches if @branches
|
||||||
@branches = []
|
@branches = []
|
||||||
cmd = "#{GIT_BIN} --git-dir #{target('')} branch --no-color"
|
cmd = "#{self.class.sq_bin} --git-dir #{target('')} branch --no-color"
|
||||||
shellout(cmd) do |io|
|
shellout(cmd) do |io|
|
||||||
io.each_line do |line|
|
io.each_line do |line|
|
||||||
@branches << line.match('\s*\*?\s*(.*)$')[1]
|
@branches << line.match('\s*\*?\s*(.*)$')[1]
|
||||||
|
@ -46,7 +60,7 @@ module Redmine
|
||||||
|
|
||||||
def tags
|
def tags
|
||||||
return @tags if @tags
|
return @tags if @tags
|
||||||
cmd = "#{GIT_BIN} --git-dir #{target('')} tag"
|
cmd = "#{self.class.sq_bin} --git-dir #{target('')} tag"
|
||||||
shellout(cmd) do |io|
|
shellout(cmd) do |io|
|
||||||
@tags = io.readlines.sort!.map{|t| t.strip}
|
@tags = io.readlines.sort!.map{|t| t.strip}
|
||||||
end
|
end
|
||||||
|
@ -59,7 +73,7 @@ module Redmine
|
||||||
def entries(path=nil, identifier=nil)
|
def entries(path=nil, identifier=nil)
|
||||||
path ||= ''
|
path ||= ''
|
||||||
entries = Entries.new
|
entries = Entries.new
|
||||||
cmd = "#{GIT_BIN} --git-dir #{target('')} ls-tree -l "
|
cmd = "#{self.class.sq_bin} --git-dir #{target('')} ls-tree -l "
|
||||||
cmd << shell_quote("HEAD:" + path) if identifier.nil?
|
cmd << shell_quote("HEAD:" + path) if identifier.nil?
|
||||||
cmd << shell_quote(identifier + ":" + path) if identifier
|
cmd << shell_quote(identifier + ":" + path) if identifier
|
||||||
shellout(cmd) do |io|
|
shellout(cmd) do |io|
|
||||||
|
@ -86,7 +100,7 @@ module Redmine
|
||||||
|
|
||||||
def lastrev(path,rev)
|
def lastrev(path,rev)
|
||||||
return nil if path.nil?
|
return nil if path.nil?
|
||||||
cmd = "#{GIT_BIN} --git-dir #{target('')} log --no-color --date=iso --pretty=fuller --no-merges -n 1 "
|
cmd = "#{self.class.sq_bin} --git-dir #{target('')} log --no-color --date=iso --pretty=fuller --no-merges -n 1 "
|
||||||
cmd << " #{shell_quote rev} " if rev
|
cmd << " #{shell_quote rev} " if rev
|
||||||
cmd << "-- #{shell_quote path} " unless path.empty?
|
cmd << "-- #{shell_quote path} " unless path.empty?
|
||||||
lines = []
|
lines = []
|
||||||
|
@ -114,7 +128,7 @@ module Redmine
|
||||||
def revisions(path, identifier_from, identifier_to, options={})
|
def revisions(path, identifier_from, identifier_to, options={})
|
||||||
revisions = Revisions.new
|
revisions = Revisions.new
|
||||||
|
|
||||||
cmd = "#{GIT_BIN} --git-dir #{target('')} log --no-color --raw --date=iso --pretty=fuller "
|
cmd = "#{self.class.sq_bin} --git-dir #{target('')} log --no-color --raw --date=iso --pretty=fuller "
|
||||||
cmd << " --reverse " if options[:reverse]
|
cmd << " --reverse " if options[:reverse]
|
||||||
cmd << " --all " if options[:all]
|
cmd << " --all " if options[:all]
|
||||||
cmd << " -n #{options[:limit].to_i} " if options[:limit]
|
cmd << " -n #{options[:limit].to_i} " if options[:limit]
|
||||||
|
@ -209,9 +223,9 @@ module Redmine
|
||||||
path ||= ''
|
path ||= ''
|
||||||
|
|
||||||
if identifier_to
|
if identifier_to
|
||||||
cmd = "#{GIT_BIN} --git-dir #{target('')} diff --no-color #{shell_quote identifier_to} #{shell_quote identifier_from}"
|
cmd = "#{self.class.sq_bin} --git-dir #{target('')} diff --no-color #{shell_quote identifier_to} #{shell_quote identifier_from}"
|
||||||
else
|
else
|
||||||
cmd = "#{GIT_BIN} --git-dir #{target('')} show --no-color #{shell_quote identifier_from}"
|
cmd = "#{self.class.sq_bin} --git-dir #{target('')} show --no-color #{shell_quote identifier_from}"
|
||||||
end
|
end
|
||||||
|
|
||||||
cmd << " -- #{shell_quote path}" unless path.empty?
|
cmd << " -- #{shell_quote path}" unless path.empty?
|
||||||
|
@ -227,7 +241,7 @@ module Redmine
|
||||||
|
|
||||||
def annotate(path, identifier=nil)
|
def annotate(path, identifier=nil)
|
||||||
identifier = 'HEAD' if identifier.blank?
|
identifier = 'HEAD' if identifier.blank?
|
||||||
cmd = "#{GIT_BIN} --git-dir #{target('')} blame -p #{shell_quote identifier} -- #{shell_quote path}"
|
cmd = "#{self.class.sq_bin} --git-dir #{target('')} blame -p #{shell_quote identifier} -- #{shell_quote path}"
|
||||||
blame = Annotate.new
|
blame = Annotate.new
|
||||||
content = nil
|
content = nil
|
||||||
shellout(cmd) { |io| io.binmode; content = io.read }
|
shellout(cmd) { |io| io.binmode; content = io.read }
|
||||||
|
@ -255,7 +269,7 @@ module Redmine
|
||||||
if identifier.nil?
|
if identifier.nil?
|
||||||
identifier = 'HEAD'
|
identifier = 'HEAD'
|
||||||
end
|
end
|
||||||
cmd = "#{GIT_BIN} --git-dir #{target('')} show --no-color #{shell_quote(identifier + ':' + path)}"
|
cmd = "#{self.class.sq_bin} --git-dir #{target('')} show --no-color #{shell_quote(identifier + ':' + path)}"
|
||||||
cat = nil
|
cat = nil
|
||||||
shellout(cmd) do |io|
|
shellout(cmd) do |io|
|
||||||
io.binmode
|
io.binmode
|
||||||
|
|
|
@ -20,7 +20,7 @@ require 'cgi'
|
||||||
|
|
||||||
module Redmine
|
module Redmine
|
||||||
module Scm
|
module Scm
|
||||||
module Adapters
|
module Adapters
|
||||||
class MercurialAdapter < AbstractAdapter
|
class MercurialAdapter < AbstractAdapter
|
||||||
|
|
||||||
# Mercurial executable name
|
# Mercurial executable name
|
||||||
|
@ -30,11 +30,23 @@ module Redmine
|
||||||
TEMPLATE_EXTENSION = "tmpl"
|
TEMPLATE_EXTENSION = "tmpl"
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
|
def client_command
|
||||||
|
@@bin ||= HG_BIN
|
||||||
|
end
|
||||||
|
|
||||||
|
def sq_bin
|
||||||
|
@@sq_bin ||= shell_quote(HG_BIN)
|
||||||
|
end
|
||||||
|
|
||||||
def client_version
|
def client_version
|
||||||
@@client_version ||= (hgversion || [])
|
@@client_version ||= (hgversion || [])
|
||||||
end
|
end
|
||||||
|
|
||||||
def hgversion
|
def client_available
|
||||||
|
!client_version.empty?
|
||||||
|
end
|
||||||
|
|
||||||
|
def hgversion
|
||||||
# The hg version is expressed either as a
|
# The hg version is expressed either as a
|
||||||
# release number (eg 0.9.5 or 1.0) or as a revision
|
# release number (eg 0.9.5 or 1.0) or as a revision
|
||||||
# id composed of 12 hexa characters.
|
# id composed of 12 hexa characters.
|
||||||
|
@ -45,7 +57,7 @@ module Redmine
|
||||||
end
|
end
|
||||||
|
|
||||||
def hgversion_from_command_line
|
def hgversion_from_command_line
|
||||||
shellout("#{HG_BIN} --version") { |io| io.read }.to_s
|
shellout("#{sq_bin} --version") { |io| io.read }.to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
def template_path
|
def template_path
|
||||||
|
@ -63,7 +75,7 @@ module Redmine
|
||||||
end
|
end
|
||||||
|
|
||||||
def info
|
def info
|
||||||
cmd = "#{HG_BIN} -R #{target('')} root"
|
cmd = "#{self.class.sq_bin} -R #{target('')} root"
|
||||||
root_url = nil
|
root_url = nil
|
||||||
shellout(cmd) do |io|
|
shellout(cmd) do |io|
|
||||||
root_url = io.read
|
root_url = io.read
|
||||||
|
@ -80,7 +92,7 @@ module Redmine
|
||||||
def entries(path=nil, identifier=nil)
|
def entries(path=nil, identifier=nil)
|
||||||
path ||= ''
|
path ||= ''
|
||||||
entries = Entries.new
|
entries = Entries.new
|
||||||
cmd = "#{HG_BIN} -R #{target('')} --cwd #{target('')} locate"
|
cmd = "#{self.class.sq_bin} -R #{target('')} --cwd #{target('')} locate"
|
||||||
cmd << " -r #{hgrev(identifier)}"
|
cmd << " -r #{hgrev(identifier)}"
|
||||||
cmd << " " + shell_quote("path:#{path}") unless path.empty?
|
cmd << " " + shell_quote("path:#{path}") unless path.empty?
|
||||||
shellout(cmd) do |io|
|
shellout(cmd) do |io|
|
||||||
|
@ -106,7 +118,7 @@ module Redmine
|
||||||
# makes Mercurial produce a xml output.
|
# makes Mercurial produce a xml output.
|
||||||
def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={})
|
def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={})
|
||||||
revisions = Revisions.new
|
revisions = Revisions.new
|
||||||
cmd = "#{HG_BIN} --debug --encoding utf8 -R #{target('')} log -C --style #{shell_quote self.class.template_path}"
|
cmd = "#{self.class.sq_bin} --debug --encoding utf8 -R #{target('')} log -C --style #{shell_quote self.class.template_path}"
|
||||||
if identifier_from && identifier_to
|
if identifier_from && identifier_to
|
||||||
cmd << " -r #{hgrev(identifier_from)}:#{hgrev(identifier_to)}"
|
cmd << " -r #{hgrev(identifier_from)}:#{hgrev(identifier_to)}"
|
||||||
elsif identifier_from
|
elsif identifier_from
|
||||||
|
@ -164,7 +176,7 @@ module Redmine
|
||||||
return []
|
return []
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
cmd = "#{HG_BIN} -R #{target('')} --config diff.git=false diff --nodates #{diff_args}"
|
cmd = "#{self.class.sq_bin} -R #{target('')} --config diff.git=false diff --nodates #{diff_args}"
|
||||||
cmd << " -I #{target(path)}" unless path.empty?
|
cmd << " -I #{target(path)}" unless path.empty?
|
||||||
shellout(cmd) do |io|
|
shellout(cmd) do |io|
|
||||||
io.each_line do |line|
|
io.each_line do |line|
|
||||||
|
@ -176,7 +188,7 @@ module Redmine
|
||||||
end
|
end
|
||||||
|
|
||||||
def cat(path, identifier=nil)
|
def cat(path, identifier=nil)
|
||||||
cmd = "#{HG_BIN} -R #{target('')} cat"
|
cmd = "#{self.class.sq_bin} -R #{target('')} cat"
|
||||||
cmd << " -r #{hgrev(identifier)}"
|
cmd << " -r #{hgrev(identifier)}"
|
||||||
cmd << " #{target(path)}"
|
cmd << " #{target(path)}"
|
||||||
cat = nil
|
cat = nil
|
||||||
|
@ -190,7 +202,7 @@ module Redmine
|
||||||
|
|
||||||
def annotate(path, identifier=nil)
|
def annotate(path, identifier=nil)
|
||||||
path ||= ''
|
path ||= ''
|
||||||
cmd = "#{HG_BIN} -R #{target('')}"
|
cmd = "#{self.class.sq_bin} -R #{target('')}"
|
||||||
cmd << " annotate -ncu"
|
cmd << " annotate -ncu"
|
||||||
cmd << " -r #{hgrev(identifier)}"
|
cmd << " -r #{hgrev(identifier)}"
|
||||||
cmd << " #{target(path)}"
|
cmd << " #{target(path)}"
|
||||||
|
|
|
@ -20,19 +20,27 @@ require 'uri'
|
||||||
|
|
||||||
module Redmine
|
module Redmine
|
||||||
module Scm
|
module Scm
|
||||||
module Adapters
|
module Adapters
|
||||||
class SubversionAdapter < AbstractAdapter
|
class SubversionAdapter < AbstractAdapter
|
||||||
|
|
||||||
# SVN executable name
|
# SVN executable name
|
||||||
SVN_BIN = Redmine::Configuration['scm_subversion_command'] || "svn"
|
SVN_BIN = Redmine::Configuration['scm_subversion_command'] || "svn"
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
|
def client_command
|
||||||
|
@@bin ||= SVN_BIN
|
||||||
|
end
|
||||||
|
|
||||||
|
def sq_bin
|
||||||
|
@@sq_bin ||= shell_quote(SVN_BIN)
|
||||||
|
end
|
||||||
|
|
||||||
def client_version
|
def client_version
|
||||||
@@client_version ||= (svn_binary_version || [])
|
@@client_version ||= (svn_binary_version || [])
|
||||||
end
|
end
|
||||||
|
|
||||||
def svn_binary_version
|
def svn_binary_version
|
||||||
cmd = "#{SVN_BIN} --version"
|
cmd = "#{sq_bin} --version"
|
||||||
version = nil
|
version = nil
|
||||||
shellout(cmd) do |io|
|
shellout(cmd) do |io|
|
||||||
# Read svn version in first returned line
|
# Read svn version in first returned line
|
||||||
|
@ -44,10 +52,10 @@ module Redmine
|
||||||
version
|
version
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Get info about the svn repository
|
# Get info about the svn repository
|
||||||
def info
|
def info
|
||||||
cmd = "#{SVN_BIN} info --xml #{target}"
|
cmd = "#{self.class.sq_bin} info --xml #{target}"
|
||||||
cmd << credentials_string
|
cmd << credentials_string
|
||||||
info = nil
|
info = nil
|
||||||
shellout(cmd) do |io|
|
shellout(cmd) do |io|
|
||||||
|
@ -70,14 +78,14 @@ module Redmine
|
||||||
rescue CommandFailed
|
rescue CommandFailed
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns an Entries collection
|
# Returns an Entries collection
|
||||||
# or nil if the given path doesn't exist in the repository
|
# or nil if the given path doesn't exist in the repository
|
||||||
def entries(path=nil, identifier=nil)
|
def entries(path=nil, identifier=nil)
|
||||||
path ||= ''
|
path ||= ''
|
||||||
identifier = (identifier and identifier.to_i > 0) ? identifier.to_i : "HEAD"
|
identifier = (identifier and identifier.to_i > 0) ? identifier.to_i : "HEAD"
|
||||||
entries = Entries.new
|
entries = Entries.new
|
||||||
cmd = "#{SVN_BIN} list --xml #{target(path)}@#{identifier}"
|
cmd = "#{self.class.sq_bin} list --xml #{target(path)}@#{identifier}"
|
||||||
cmd << credentials_string
|
cmd << credentials_string
|
||||||
shellout(cmd) do |io|
|
shellout(cmd) do |io|
|
||||||
output = io.read
|
output = io.read
|
||||||
|
@ -110,13 +118,13 @@ module Redmine
|
||||||
logger.debug("Found #{entries.size} entries in the repository for #{target(path)}") if logger && logger.debug?
|
logger.debug("Found #{entries.size} entries in the repository for #{target(path)}") if logger && logger.debug?
|
||||||
entries.sort_by_name
|
entries.sort_by_name
|
||||||
end
|
end
|
||||||
|
|
||||||
def properties(path, identifier=nil)
|
def properties(path, identifier=nil)
|
||||||
# proplist xml output supported in svn 1.5.0 and higher
|
# proplist xml output supported in svn 1.5.0 and higher
|
||||||
return nil unless self.class.client_version_above?([1, 5, 0])
|
return nil unless self.class.client_version_above?([1, 5, 0])
|
||||||
|
|
||||||
identifier = (identifier and identifier.to_i > 0) ? identifier.to_i : "HEAD"
|
identifier = (identifier and identifier.to_i > 0) ? identifier.to_i : "HEAD"
|
||||||
cmd = "#{SVN_BIN} proplist --verbose --xml #{target(path)}@#{identifier}"
|
cmd = "#{self.class.sq_bin} proplist --verbose --xml #{target(path)}@#{identifier}"
|
||||||
cmd << credentials_string
|
cmd << credentials_string
|
||||||
properties = {}
|
properties = {}
|
||||||
shellout(cmd) do |io|
|
shellout(cmd) do |io|
|
||||||
|
@ -132,13 +140,13 @@ module Redmine
|
||||||
return nil if $? && $?.exitstatus != 0
|
return nil if $? && $?.exitstatus != 0
|
||||||
properties
|
properties
|
||||||
end
|
end
|
||||||
|
|
||||||
def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={})
|
def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={})
|
||||||
path ||= ''
|
path ||= ''
|
||||||
identifier_from = (identifier_from && identifier_from.to_i > 0) ? identifier_from.to_i : "HEAD"
|
identifier_from = (identifier_from && identifier_from.to_i > 0) ? identifier_from.to_i : "HEAD"
|
||||||
identifier_to = (identifier_to && identifier_to.to_i > 0) ? identifier_to.to_i : 1
|
identifier_to = (identifier_to && identifier_to.to_i > 0) ? identifier_to.to_i : 1
|
||||||
revisions = Revisions.new
|
revisions = Revisions.new
|
||||||
cmd = "#{SVN_BIN} log --xml -r #{identifier_from}:#{identifier_to}"
|
cmd = "#{self.class.sq_bin} log --xml -r #{identifier_from}:#{identifier_to}"
|
||||||
cmd << credentials_string
|
cmd << credentials_string
|
||||||
cmd << " --verbose " if options[:with_paths]
|
cmd << " --verbose " if options[:with_paths]
|
||||||
cmd << " --limit #{options[:limit].to_i}" if options[:limit]
|
cmd << " --limit #{options[:limit].to_i}" if options[:limit]
|
||||||
|
@ -171,13 +179,13 @@ module Redmine
|
||||||
return nil if $? && $?.exitstatus != 0
|
return nil if $? && $?.exitstatus != 0
|
||||||
revisions
|
revisions
|
||||||
end
|
end
|
||||||
|
|
||||||
def diff(path, identifier_from, identifier_to=nil, type="inline")
|
def diff(path, identifier_from, identifier_to=nil, type="inline")
|
||||||
path ||= ''
|
path ||= ''
|
||||||
identifier_from = (identifier_from and identifier_from.to_i > 0) ? identifier_from.to_i : ''
|
identifier_from = (identifier_from and identifier_from.to_i > 0) ? identifier_from.to_i : ''
|
||||||
identifier_to = (identifier_to and identifier_to.to_i > 0) ? identifier_to.to_i : (identifier_from.to_i - 1)
|
identifier_to = (identifier_to and identifier_to.to_i > 0) ? identifier_to.to_i : (identifier_from.to_i - 1)
|
||||||
|
|
||||||
cmd = "#{SVN_BIN} diff -r "
|
cmd = "#{self.class.sq_bin} diff -r "
|
||||||
cmd << "#{identifier_to}:"
|
cmd << "#{identifier_to}:"
|
||||||
cmd << "#{identifier_from}"
|
cmd << "#{identifier_from}"
|
||||||
cmd << " #{target(path)}@#{identifier_from}"
|
cmd << " #{target(path)}@#{identifier_from}"
|
||||||
|
@ -191,10 +199,10 @@ module Redmine
|
||||||
return nil if $? && $?.exitstatus != 0
|
return nil if $? && $?.exitstatus != 0
|
||||||
diff
|
diff
|
||||||
end
|
end
|
||||||
|
|
||||||
def cat(path, identifier=nil)
|
def cat(path, identifier=nil)
|
||||||
identifier = (identifier and identifier.to_i > 0) ? identifier.to_i : "HEAD"
|
identifier = (identifier and identifier.to_i > 0) ? identifier.to_i : "HEAD"
|
||||||
cmd = "#{SVN_BIN} cat #{target(path)}@#{identifier}"
|
cmd = "#{self.class.sq_bin} cat #{target(path)}@#{identifier}"
|
||||||
cmd << credentials_string
|
cmd << credentials_string
|
||||||
cat = nil
|
cat = nil
|
||||||
shellout(cmd) do |io|
|
shellout(cmd) do |io|
|
||||||
|
@ -204,10 +212,10 @@ module Redmine
|
||||||
return nil if $? && $?.exitstatus != 0
|
return nil if $? && $?.exitstatus != 0
|
||||||
cat
|
cat
|
||||||
end
|
end
|
||||||
|
|
||||||
def annotate(path, identifier=nil)
|
def annotate(path, identifier=nil)
|
||||||
identifier = (identifier and identifier.to_i > 0) ? identifier.to_i : "HEAD"
|
identifier = (identifier and identifier.to_i > 0) ? identifier.to_i : "HEAD"
|
||||||
cmd = "#{SVN_BIN} blame #{target(path)}@#{identifier}"
|
cmd = "#{self.class.sq_bin} blame #{target(path)}@#{identifier}"
|
||||||
cmd << credentials_string
|
cmd << credentials_string
|
||||||
blame = Annotate.new
|
blame = Annotate.new
|
||||||
shellout(cmd) do |io|
|
shellout(cmd) do |io|
|
||||||
|
|
|
@ -51,7 +51,8 @@ namespace :test do
|
||||||
(supported_scms - [:subversion, :mercurial]).each do |scm|
|
(supported_scms - [:subversion, :mercurial]).each do |scm|
|
||||||
desc "Creates a test #{scm} repository"
|
desc "Creates a test #{scm} repository"
|
||||||
task scm => :create_dir do
|
task scm => :create_dir do
|
||||||
system "gunzip < test/fixtures/repositories/#{scm}_repository.tar.gz | tar -xv -C tmp/test"
|
# system "gunzip < test/fixtures/repositories/#{scm}_repository.tar.gz | tar -xv -C tmp/test"
|
||||||
|
system "tar -xvz -C tmp/test -f test/fixtures/repositories/#{scm}_repository.tar.gz"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
require File.expand_path('../../../../../../test_helper', __FILE__)
|
||||||
|
begin
|
||||||
|
require 'mocha'
|
||||||
|
|
||||||
|
class BazaarAdapterTest < ActiveSupport::TestCase
|
||||||
|
|
||||||
|
REPOSITORY_PATH = RAILS_ROOT.gsub(%r{config\/\.\.}, '') + '/tmp/test/bazaar_repository'
|
||||||
|
|
||||||
|
if File.directory?(REPOSITORY_PATH)
|
||||||
|
def setup
|
||||||
|
@adapter = Redmine::Scm::Adapters::BazaarAdapter.new(MODULE_NAME, REPOSITORY_PATH)
|
||||||
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
puts "Bazaar test repository NOT FOUND. Skipping unit tests !!!"
|
||||||
|
def test_fake; assert true end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
rescue LoadError
|
||||||
|
class BazaarMochaFake < ActiveSupport::TestCase
|
||||||
|
def test_fake; assert(false, "Requires mocha to run those tests") end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
@ -5,6 +5,7 @@ begin
|
||||||
class CvsAdapterTest < ActiveSupport::TestCase
|
class CvsAdapterTest < ActiveSupport::TestCase
|
||||||
|
|
||||||
REPOSITORY_PATH = RAILS_ROOT.gsub(%r{config\/\.\.}, '') + '/tmp/test/cvs_repository'
|
REPOSITORY_PATH = RAILS_ROOT.gsub(%r{config\/\.\.}, '') + '/tmp/test/cvs_repository'
|
||||||
|
REPOSITORY_PATH.gsub!(/\//, "\\") if Redmine::Platform.mswin?
|
||||||
MODULE_NAME = 'test'
|
MODULE_NAME = 'test'
|
||||||
|
|
||||||
if File.directory?(REPOSITORY_PATH)
|
if File.directory?(REPOSITORY_PATH)
|
||||||
|
|
|
@ -1,71 +1,92 @@
|
||||||
# encoding: utf-8
|
# encoding: utf-8
|
||||||
|
|
||||||
|
# This file includes UTF-8 "Felix Schäfer".
|
||||||
|
# We need to consider Ruby 1.9 compatibility.
|
||||||
|
|
||||||
require File.expand_path('../../../../../../test_helper', __FILE__)
|
require File.expand_path('../../../../../../test_helper', __FILE__)
|
||||||
|
begin
|
||||||
|
require 'mocha'
|
||||||
|
|
||||||
class GitAdapterTest < ActiveSupport::TestCase
|
class GitAdapterTest < ActiveSupport::TestCase
|
||||||
REPOSITORY_PATH = RAILS_ROOT.gsub(%r{config\/\.\.}, '') + '/tmp/test/git_repository'
|
REPOSITORY_PATH = RAILS_ROOT.gsub(%r{config\/\.\.}, '') + '/tmp/test/git_repository'
|
||||||
|
|
||||||
if File.directory?(REPOSITORY_PATH)
|
if File.directory?(REPOSITORY_PATH)
|
||||||
def setup
|
def setup
|
||||||
@adapter = Redmine::Scm::Adapters::GitAdapter.new(REPOSITORY_PATH)
|
@adapter = Redmine::Scm::Adapters::GitAdapter.new(REPOSITORY_PATH)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_branches
|
def test_branches
|
||||||
assert_equal @adapter.branches, ['master', 'test_branch']
|
assert_equal @adapter.branches, ['master', 'test_branch']
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_getting_all_revisions
|
def test_getting_all_revisions
|
||||||
assert_equal 15, @adapter.revisions('',nil,nil,:all => true).length
|
assert_equal 15, @adapter.revisions('',nil,nil,:all => true).length
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_getting_certain_revisions
|
||||||
|
assert_equal 1, @adapter.revisions('','899a15d^','899a15d').length
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_getting_revisions_with_spaces_in_filename
|
||||||
|
assert_equal 1, @adapter.revisions("filemane with spaces.txt",
|
||||||
|
nil, nil, :all => true).length
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_getting_revisions_with_leading_and_trailing_spaces_in_filename
|
||||||
|
assert_equal " filename with a leading space.txt ",
|
||||||
|
@adapter.revisions(" filename with a leading space.txt ",
|
||||||
|
nil, nil, :all => true)[0].paths[0][:path]
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_getting_entries_with_leading_and_trailing_spaces_in_filename
|
||||||
|
assert_equal " filename with a leading space.txt ",
|
||||||
|
@adapter.entries('',
|
||||||
|
'83ca5fd546063a3c7dc2e568ba3355661a9e2b2c')[3].name
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_annotate
|
||||||
|
annotate = @adapter.annotate('sources/watchers_controller.rb')
|
||||||
|
assert_kind_of Redmine::Scm::Adapters::Annotate, annotate
|
||||||
|
assert_equal 41, annotate.lines.size
|
||||||
|
assert_equal "# This program is free software; you can redistribute it and/or", annotate.lines[4].strip
|
||||||
|
assert_equal "7234cb2750b63f47bff735edc50a1c0a433c2518",
|
||||||
|
annotate.revisions[4].identifier
|
||||||
|
assert_equal "jsmith", annotate.revisions[4].author
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_annotate_moved_file
|
||||||
|
annotate = @adapter.annotate('renamed_test.txt')
|
||||||
|
assert_kind_of Redmine::Scm::Adapters::Annotate, annotate
|
||||||
|
assert_equal 2, annotate.lines.size
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_last_rev
|
||||||
|
last_rev = @adapter.lastrev("README",
|
||||||
|
"4f26664364207fa8b1af9f8722647ab2d4ac5d43")
|
||||||
|
assert_equal "4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8", last_rev.scmid
|
||||||
|
assert_equal "4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8", last_rev.identifier
|
||||||
|
assert_equal "Adam Soltys <asoltys@gmail.com>", last_rev.author
|
||||||
|
assert_equal "2009-06-24 05:27:38".to_time, last_rev.time
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_last_rev_with_spaces_in_filename
|
||||||
|
last_rev = @adapter.lastrev("filemane with spaces.txt",
|
||||||
|
"ed5bb786bbda2dee66a2d50faf51429dbc043a7b")
|
||||||
|
assert_equal "ed5bb786bbda2dee66a2d50faf51429dbc043a7b", last_rev.scmid
|
||||||
|
assert_equal "ed5bb786bbda2dee66a2d50faf51429dbc043a7b", last_rev.identifier
|
||||||
|
assert_equal "Felix Schäfer <felix@fachschaften.org>",
|
||||||
|
last_rev.author
|
||||||
|
assert_equal "2010-09-18 19:59:46".to_time, last_rev.time
|
||||||
|
end
|
||||||
|
else
|
||||||
|
puts "Git test repository NOT FOUND. Skipping unit tests !!!"
|
||||||
|
def test_fake; assert true end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
def test_getting_certain_revisions
|
|
||||||
assert_equal 1, @adapter.revisions('','899a15d^','899a15d').length
|
rescue LoadError
|
||||||
end
|
class GitMochaFake < ActiveSupport::TestCase
|
||||||
|
def test_fake; assert(false, "Requires mocha to run those tests") end
|
||||||
def test_getting_revisions_with_spaces_in_filename
|
|
||||||
assert_equal 1, @adapter.revisions("filemane with spaces.txt", nil, nil, :all => true).length
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_getting_revisions_with_leading_and_trailing_spaces_in_filename
|
|
||||||
assert_equal " filename with a leading space.txt ", @adapter.revisions(" filename with a leading space.txt ", nil, nil, :all => true)[0].paths[0][:path]
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_getting_entries_with_leading_and_trailing_spaces_in_filename
|
|
||||||
assert_equal " filename with a leading space.txt ", @adapter.entries('', '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c')[3].name
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_annotate
|
|
||||||
annotate = @adapter.annotate('sources/watchers_controller.rb')
|
|
||||||
assert_kind_of Redmine::Scm::Adapters::Annotate, annotate
|
|
||||||
assert_equal 41, annotate.lines.size
|
|
||||||
assert_equal "# This program is free software; you can redistribute it and/or", annotate.lines[4].strip
|
|
||||||
assert_equal "7234cb2750b63f47bff735edc50a1c0a433c2518", annotate.revisions[4].identifier
|
|
||||||
assert_equal "jsmith", annotate.revisions[4].author
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_annotate_moved_file
|
|
||||||
annotate = @adapter.annotate('renamed_test.txt')
|
|
||||||
assert_kind_of Redmine::Scm::Adapters::Annotate, annotate
|
|
||||||
assert_equal 2, annotate.lines.size
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_last_rev
|
|
||||||
last_rev = @adapter.lastrev("README", "4f26664364207fa8b1af9f8722647ab2d4ac5d43")
|
|
||||||
assert_equal "4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8", last_rev.scmid
|
|
||||||
assert_equal "4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8", last_rev.identifier
|
|
||||||
assert_equal "Adam Soltys <asoltys@gmail.com>", last_rev.author
|
|
||||||
assert_equal "2009-06-24 05:27:38".to_time, last_rev.time
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_last_rev_with_spaces_in_filename
|
|
||||||
last_rev = @adapter.lastrev("filemane with spaces.txt", "ed5bb786bbda2dee66a2d50faf51429dbc043a7b")
|
|
||||||
assert_equal "ed5bb786bbda2dee66a2d50faf51429dbc043a7b", last_rev.scmid
|
|
||||||
assert_equal "ed5bb786bbda2dee66a2d50faf51429dbc043a7b", last_rev.identifier
|
|
||||||
assert_equal "Felix Schäfer <felix@fachschaften.org>", last_rev.author
|
|
||||||
assert_equal "2010-09-18 19:59:46".to_time, last_rev.time
|
|
||||||
end
|
|
||||||
else
|
|
||||||
puts "Git test repository NOT FOUND. Skipping unit tests !!!"
|
|
||||||
def test_fake; assert true end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -17,15 +17,27 @@
|
||||||
|
|
||||||
require File.expand_path('../../../../../../test_helper', __FILE__)
|
require File.expand_path('../../../../../../test_helper', __FILE__)
|
||||||
|
|
||||||
class SubversionAdapterTest < ActiveSupport::TestCase
|
begin
|
||||||
|
require 'mocha'
|
||||||
|
|
||||||
|
class SubversionAdapterTest < ActiveSupport::TestCase
|
||||||
|
|
||||||
if repository_configured?('subversion')
|
if repository_configured?('subversion')
|
||||||
def test_client_version
|
def setup
|
||||||
v = Redmine::Scm::Adapters::SubversionAdapter.client_version
|
end
|
||||||
assert v.is_a?(Array)
|
|
||||||
|
def test_client_version
|
||||||
|
v = Redmine::Scm::Adapters::SubversionAdapter.client_version
|
||||||
|
assert v.is_a?(Array)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
puts "Subversion test repository NOT FOUND. Skipping unit tests !!!"
|
||||||
|
def test_fake; assert true end
|
||||||
end
|
end
|
||||||
else
|
end
|
||||||
puts "Subversion test repository NOT FOUND. Skipping unit tests !!!"
|
|
||||||
def test_fake; assert true end
|
rescue LoadError
|
||||||
|
class SubversionMochaFake < ActiveSupport::TestCase
|
||||||
|
def test_fake; assert(false, "Requires mocha to run those tests") end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue