Mercurial > hg > soundsoftware-site
diff lib/redmine/scm/adapters/cvs_adapter.rb @ 245:051f544170fe
* Update to SVN trunk revision 4993
author | Chris Cannam |
---|---|
date | Thu, 03 Mar 2011 11:42:28 +0000 |
parents | 0579821a129a |
children | eeebe205a056 cbce1fd3b1b7 |
line wrap: on
line diff
--- a/lib/redmine/scm/adapters/cvs_adapter.rb Thu Mar 03 11:40:10 2011 +0000 +++ b/lib/redmine/scm/adapters/cvs_adapter.rb Thu Mar 03 11:42:28 2011 +0000 @@ -24,13 +24,46 @@ # CVS executable name 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 + + def client_version + @@client_version ||= (scm_command_version || []) + end + + def client_available + client_version_above?([1, 12]) + end + + def scm_command_version + scm_version = scm_version_from_command_line.dup + if scm_version.respond_to?(:force_encoding) + scm_version.force_encoding('ASCII-8BIT') + end + if m = scm_version.match(%r{\A(.*?)((\d+\.)+\d+)}m) + m[2].scan(%r{\d+}).collect(&:to_i) + end + end + + def scm_version_from_command_line + shellout("#{sq_bin} --version") { |io| io.read }.to_s + end + end + # Guidelines for the input: # url -> the project-path, relative to the cvsroot (eg. module name) # root_url -> the good old, sometimes damned, CVSROOT # login -> unnecessary # password -> unnecessary too - def initialize(url, root_url=nil, login=nil, password=nil) + def initialize(url, root_url=nil, login=nil, password=nil, + path_encoding=nil) @url = url @login = login if login && !login.empty? @password = (password || "") if @login @@ -38,24 +71,24 @@ raise CommandFailed if root_url.blank? @root_url = root_url end - + def root_url @root_url end - + def url @url end - + def info logger.debug "<cvs> info" Info.new({:root_url => @root_url, :lastrev => nil}) end - + def get_previous_revision(revision) CvsRevisionHelper.new(revision).prevRev end - + # Returns an Entries collection # or nil if the given path doesn't exist in the repository # this method is used by the repository-browser (aka LIST) @@ -63,14 +96,14 @@ logger.debug "<cvs> entries '#{path}' with identifier '#{identifier}'" path_with_project="#{url}#{with_leading_slash(path)}" 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 << " #{shell_quote path_with_project}" shellout(cmd) do |io| io.each_line(){|line| fields=line.chop.split('/',-1) logger.debug(">>InspectLine #{fields.inspect}") - + if fields[0]!="D" entries << Entry.new({:name => fields[-5], #:path => fields[-4].include?(path)?fields[-4]:(path + "/"+ fields[-4]), @@ -96,19 +129,19 @@ end return nil if $? && $?.exitstatus != 0 entries.sort_by_name - end + end STARTLOG="----------------------------" ENDLOG ="=============================================================================" - + # Returns all revisions found between identifier_from and identifier_to # in the repository. both identifier have to be dates or nil. # these method returns nothing but yield every result in 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}" - + 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 << " #{shell_quote path_with_project}" shellout(cmd) do |io| @@ -123,7 +156,7 @@ file_state=nil branch_map=nil - io.each_line() do |line| + io.each_line() do |line| if state!="revision" && /^#{ENDLOG}/ =~ line commit_log=String.new @@ -162,9 +195,9 @@ end next elsif state=="revision" - if /^#{ENDLOG}/ =~ line || /^#{STARTLOG}/ =~ line + if /^#{ENDLOG}/ =~ line || /^#{STARTLOG}/ =~ line if revision - + revHelper=CvsRevisionHelper.new(revision) revBranch="HEAD" @@ -176,7 +209,7 @@ logger.debug("********** YIELD Revision #{revision}::#{revBranch}") - yield Revision.new({ + yield Revision.new({ :time => date, :author => author, :message=>commit_log.chomp, @@ -188,9 +221,9 @@ :kind=>'file', :action=>file_state }] - }) + }) end - + commit_log=String.new revision=nil @@ -199,7 +232,7 @@ end next end - + if /^branches: (.+)$/ =~ line #TODO: version.branch = $1 elsif /^revision (\d+(?:\.\d+)+).*$/ =~ line @@ -216,20 +249,20 @@ # version.line_minus = linechanges[2] # else # version.line_plus = 0 - # version.line_minus = 0 - # end - else + # version.line_minus = 0 + # end + else commit_log << line unless line =~ /^\*\*\* empty log message \*\*\*/ - end - end + end + end end end - end - + end + def diff(path, identifier_from, identifier_to=nil) logger.debug "<cvs> diff path:'#{path}',identifier_from #{identifier_from}, identifier_to #{identifier_to}" 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 = [] shellout(cmd) do |io| io.each_line do |line| @@ -238,28 +271,29 @@ end return nil if $? && $?.exitstatus != 0 diff - end - + end + def cat(path, identifier=nil) identifier = (identifier) ? identifier : "HEAD" logger.debug "<cvs> cat path:'#{path}',identifier #{identifier}" 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 << " -p #{shell_quote path_with_project}" cat = nil shellout(cmd) do |io| + io.binmode cat = io.read end return nil if $? && $?.exitstatus != 0 cat - end + end def annotate(path, identifier=nil) identifier = (identifier) ? identifier.to_i : "HEAD" logger.debug "<cvs> annotate path:'#{path}',identifier #{identifier}" 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 shellout(cmd) do |io| io.each_line do |line| @@ -270,9 +304,9 @@ return nil if $? && $?.exitstatus != 0 blame end - + private - + # Returns the root url without the connexion string # :pserver:anonymous@foo.bar:/path => /path # :ext:cvsservername:/path => /path @@ -345,7 +379,11 @@ private def buildRevision(rev) if rev== 0 - @base + if @branchid.nil? + @base+".0" + else + @base + end elsif @branchid.nil? @base+"."+rev.to_s else