diff lib/redmine/scm/adapters/.svn/text-base/cvs_adapter.rb.svn-base @ 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/.svn/text-base/cvs_adapter.rb.svn-base	Thu Mar 03 11:40:10 2011 +0000
+++ b/lib/redmine/scm/adapters/.svn/text-base/cvs_adapter.rb.svn-base	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