diff --git a/app/models/repository/git_remote.rb b/app/models/repository/git_remote.rb index 851ea6c..7b9b0a9 100644 --- a/app/models/repository/git_remote.rb +++ b/app/models/repository/git_remote.rb @@ -1,7 +1,8 @@ require 'redmine/scm/adapters/git_adapter' require 'pathname' require 'fileutils' -require 'open3' +# require 'open3' +require_dependency 'redmine_git_remote/poor_mans_capture3' class Repository::GitRemote < Repository::Git @@ -97,7 +98,7 @@ class Repository::GitRemote < Repository::Git end if Dir.exists? clone_path - existing_repo_remote, status = Open3::capture2("git", "--git-dir", clone_path, "config", "--get", "remote.origin.url") + existing_repo_remote, status = RedmineGitRemote::PoorMansCapture3::capture2("git", "--git-dir", clone_path, "config", "--get", "remote.origin.url") return "Unable to run: git --git-dir #{clone_path} config --get remote.origin.url" unless status.success? unless two_remotes_equal(existing_repo_remote, clone_url) @@ -154,7 +155,7 @@ class Repository::GitRemote < Repository::Git # Checks if host is in ~/.ssh/known_hosts, adds it if not present def self.add_known_host(host) # if not found... - out, status = Open3::capture2("ssh-keygen", "-F", host) + out, status = RedmineGitRemote::PoorMansCapture3::capture2("ssh-keygen", "-F", host) raise "Unable to run 'ssh-keygen -F #{host}" unless status unless out.match /found/ # hack to work with 'docker exec' where HOME isn't set (or set to /) @@ -167,7 +168,7 @@ class Repository::GitRemote < Repository::Git end puts "Adding #{host} to #{ssh_known_hosts}" - out, status = Open3::capture2("ssh-keyscan", host) + out, status = RedmineGitRemote::PoorMansCapture3::capture2("ssh-keyscan", host) raise "Unable to run 'ssh-keyscan #{host}'" unless status Kernel::open(ssh_known_hosts, 'a') { |f| f.puts out} end diff --git a/lib/redmine_git_remote/poor_mans_capture3.rb b/lib/redmine_git_remote/poor_mans_capture3.rb new file mode 100644 index 0000000..2a7a28f --- /dev/null +++ b/lib/redmine_git_remote/poor_mans_capture3.rb @@ -0,0 +1,58 @@ +# Ruby 1.8.7-compatible backport of Open3::capture3 +# +# via https://gist.github.com/vasi/8ffc21bc09ac8fe38f76 +module RedmineGitRemote + module PoorMansCapture3 + + def self.capture3(*cmd) + # Force no shell expansion, by using a non-plain string. See ruby docs: + # + # `If the first argument is a two-element array, the first element is the + # command to be executed, and the second argument is used as the argv[0] + # value, which may show up in process listings.' + cmd[0] = [cmd[0], cmd[0]] + + rout, wout = IO.pipe + rerr, werr = IO.pipe + + pid = fork do + rerr.close + rout.close + STDERR.reopen(werr) + STDOUT.reopen(wout) + exec(*cmd) + end + + wout.close + werr.close + + out = rout.read + err = rerr.read + Process.wait(pid) + rout.close + rerr.close + return [out, err, $?] + end + + def self.capture2(*cmd) + out, err, stat = capture3(*cmd) + STDERR.write err + return out, stat + end + + def self.test(*cmd) + st, err, out = capture3(*cmd) + p st + p err + p out + puts + end + + def self.run_tests + test('ls', '/var') + test('ls', '/foo') + test('lfhlkhladfla') + test('ls && ls') + end + end +end