--- a/rakelib/scm.rb Thu Nov 24 20:22:25 2016 +0000
+++ b/rakelib/scm.rb Thu Nov 24 20:47:41 2016 +0000
@@ -6,6 +6,22 @@
module Rake::StX
end
+# Cross-platform way of finding an executable in the $PATH.
+#
+# which('ruby') #=> /usr/bin/ruby
+def which(cmd)
+ exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
+ ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
+ exts.each { |ext|
+ exe = File.join(path, "#{cmd}#{ext}")
+ return exe if File.executable?(exe) && !File.directory?(exe)
+ }
+ end
+ return nil
+end
+
+cvs_rsh_set = false
+
module Rake::Stx::SCM
# Not quite sure why following code
#
@@ -22,6 +38,60 @@
end
end
+ # Make sure CVS_RSH environment variable is properly set. Prefer MSYS2 ssh.exe
+ # over plink.exe. For details, see `hglib.rb`, method `sshconf()`
+ module_function
+ def ensure_cvs_rsh_set()
+ if @cvs_rsh_set then
+ return
+ end
+ ssh = nil
+ ssh_configured = ENV['CVS_RSH']
+ ssh_in_path = which('ssh') ? true : false
+ plink_in_path = which('plink') ? true : false
+ if Gem.win_platform? then
+ # If CVS_RSH is not set or is set to plink.exe, try to change to
+ # MSYS2 ssh.exe as it gives better performance on (fast) LANs.
+ if /^.*[pP]link(\.exe)?"?\s*(-ssh)?\s*(-2)?$/ =~ ssh_configured then
+ if ssh_in_path then
+ ssh = 'ssh'
+ else
+ if (File.exist? "c:\\msys64\\usr\\bin\\ssh.exe") then
+ ssh = "\"c:\\msys64\\usr\\bin\\ssh.exe\""
+ end
+ end
+ # Sigh, we should not tamper with SSH configuration wildly. User may have
+ # her ssh and mercurial properly configured to use `plink.exe` and `pageant`.
+ # If we just start using `ssh.exe` clone/pull might not work beause
+ # `ssh.exe` cannot talk to `pageant`. So, if we don't find OpenSSH's
+ # style of agent, don't use `ssh.exe` event if available.
+ if ssh then
+ if ENV['SSH_AUTH_SOCK'] then
+ # Good, OpenSSH agent running but still, be nice and tell the
+ # user SSH configuration has been tampered wirh.
+ info("Setting CVS_RSH=\"#{ssh}\" for faster transfers")
+ else
+ # No agent, no fun. Be nice and give user a hit
+ warn("Not using CVS_RSH=\"#{ssh}\" option because SSH agent is not running")
+ warn("For faster CVS checkout over LAN, consider using ssh-agent or ssh-pageant (if you want to use PuTTY's pageant)")
+ ssh = nil
+ end
+ end
+ end
+ else
+ if not ssh_configured then
+ ssh = "ssh"
+ end
+ end
+ if ssh then
+ ENV['CVS_RSH'] = ssh
+ end
+ cvs_rsh_set = true
+ end
+
+
+ public
+
class CheckoutException < Exception
end # class CheckoutException
@@ -120,6 +190,7 @@
end
def self._update_cvs(repository, directory, branch, root, **kwargs)
+ ensure_cvs_rsh_set()
wc = root / directory
if File.directory? wc
if not sh %W{cvs -z 9 update -A -d}, cwd: wc
@@ -169,7 +240,7 @@
end
- def self._checkout_svn(repository, directory, branch, root, **kwargs)
+ def self._checkout_svn(repository, directory, branch, root, **kwargs)
url = "#{repository.canonical}/#{directory}/#{branch}"
if not sh %W{svn --non-interactive --trust-server-cert co #{url} #{directory}}, cwd: root
raise CheckoutException.new("SVN: Cannot checkout from #{url}")
@@ -223,6 +294,7 @@
end
def self._checkout_cvs(repository, directory, branch, root, **kwargs)
+ ensure_cvs_rsh_set()
if not sh %W{cvs -z 9 -d #{repository.canonical} co #{directory}}, cwd: root
raise CheckoutException.new("CVS: Cannot checkout #{directory}from #{repository.url}")
end