diff --git a/lib/capistrano/ext/sshkit/backend/thread_local.rb b/lib/capistrano/ext/sshkit/backend/thread_local.rb new file mode 100644 index 00000000..c8ffe16e --- /dev/null +++ b/lib/capistrano/ext/sshkit/backend/thread_local.rb @@ -0,0 +1,25 @@ +require "sshkit/backends/abstract" + +# Monkey patch older versions of SSHKit to make the currently-executing Backend +# available via a thread local value. +# +# TODO: Remove this code once capistrano.gemspec requires newer SSHKit version. + +unless SSHKit::Backend.respond_to?(:current) + module SSHKit + module Backend + def self.current + Thread.current["sshkit_backend"] + end + + class Abstract + def run + Thread.current["sshkit_backend"] = self + instance_exec(@host, &@block) + ensure + Thread.current["sshkit_backend"] = nil + end + end + end + end +end diff --git a/spec/lib/capistrano/ext/sshkit/backend/thread_local_spec.rb b/spec/lib/capistrano/ext/sshkit/backend/thread_local_spec.rb new file mode 100644 index 00000000..90d679db --- /dev/null +++ b/spec/lib/capistrano/ext/sshkit/backend/thread_local_spec.rb @@ -0,0 +1,30 @@ +require "spec_helper" +require "capistrano/ext/sshkit/backend/thread_local" + +module SSHKit + module Backend + describe "#current" do + require "sshkit/dsl" + + it "refers to the currently executing backend" do + backend = nil + current = nil + + on(:local) do + backend = self + current = SSHKit::Backend.current + end + + expect(current).to eq(backend) + end + + it "is nil outside of an on block" do + on(:local) do + # nothing + end + + expect(SSHKit::Backend.current).to be_nil + end + end + end +end