From 1db04bff6209ac7654fc4a2866bca0ed812aa83e Mon Sep 17 00:00:00 2001 From: Samuel Cochran Date: Tue, 24 Oct 2017 21:39:52 +1100 Subject: [PATCH 1/4] Resolve relative paths using `within()` stack --- CHANGELOG.md | 1 + EXAMPLES.md | 15 +++++++++++++-- lib/sshkit/backends/local.rb | 2 ++ lib/sshkit/backends/netssh.rb | 2 ++ test/functional/backends/test_local.rb | 17 +++++++++++++++++ test/functional/backends/test_netssh.rb | 17 +++++++++++++++++ 6 files changed, 52 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a53c2065..0c8d2c52 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ appear at the top. ## [Unreleased][] * Your contribution here! + * [#408](https://github.com/capistrano/sshkit/pull/408): Teach upload! and download! to respect within(...) - [@sj26](https://github.com/sj26) ## [1.14.0][] (2017-06-30) diff --git a/EXAMPLES.md b/EXAMPLES.md index c4456c33..edd0d80f 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -90,6 +90,7 @@ end ``` ## Download a file from disk + ```ruby on roles(:all) do puts 'Downloading DB Backup File' @@ -106,8 +107,18 @@ on hosts do |host| end ``` -**Note:** The `upload!()` method doesn't honor the values of `within()`, `as()` -etc, this will be improved as the library matures, but we're not there yet. +Upload and download will respect the `within()` directories: + +```ruby +on hosts do |host| + within 'my/app/directory' do + upload! 'database.yml', 'config/database.yml' + end +end +``` + +**Note:** The `upload!()` method doesn't honor the values of `as()` etc, this +will be improved as the library matures, but we're not there yet. ## Upload a file from a stream diff --git a/lib/sshkit/backends/local.rb b/lib/sshkit/backends/local.rb index 46a425cd..f04a54a1 100644 --- a/lib/sshkit/backends/local.rb +++ b/lib/sshkit/backends/local.rb @@ -11,6 +11,7 @@ def initialize(_ = nil, &block) end def upload!(local, remote, options = {}) + remote = File.join(pwd_path, remote) unless remote[0] == "/" if local.is_a?(String) if options[:recursive] FileUtils.cp_r(local, remote) @@ -25,6 +26,7 @@ def upload!(local, remote, options = {}) end def download!(remote, local=nil, _options = {}) + remote = File.join(pwd_path, remote) unless remote[0] == "/" if local.nil? FileUtils.cp(remote, File.basename(remote)) else diff --git a/lib/sshkit/backends/netssh.rb b/lib/sshkit/backends/netssh.rb index 564f1262..262f60b5 100644 --- a/lib/sshkit/backends/netssh.rb +++ b/lib/sshkit/backends/netssh.rb @@ -63,6 +63,7 @@ def assign_defaults def upload!(local, remote, options = {}) summarizer = transfer_summarizer('Uploading', options) + remote = File.join(pwd_path, remote) unless remote[0] == "/" with_ssh do |ssh| ssh.scp.upload!(local, remote, options, &summarizer) end @@ -70,6 +71,7 @@ def upload!(local, remote, options = {}) def download!(remote, local=nil, options = {}) summarizer = transfer_summarizer('Downloading', options) + remote = File.join(pwd_path, remote) unless remote[0] == "/" with_ssh do |ssh| ssh.scp.download!(remote, local, options, &summarizer) end diff --git a/test/functional/backends/test_local.rb b/test/functional/backends/test_local.rb index d60f9439..b559f241 100644 --- a/test/functional/backends/test_local.rb +++ b/test/functional/backends/test_local.rb @@ -20,6 +20,23 @@ def test_upload end end + def test_upload_within + file_contents = "Some Content" + actual_file_contents = nil + Dir.mktmpdir do |dir| + Local.new do + within dir do + execute(:mkdir, "-p", "foo") + within "foo" do + upload!(StringIO.new(file_contents), "bar") + end + end + actual_file_contents = capture(:cat, File.join(dir, "foo", "bar")) + end.run + assert_equal file_contents, actual_file_contents + end + end + def test_upload_recursive Dir.mktmpdir do |dir| Dir.mkdir("#{dir}/local") diff --git a/test/functional/backends/test_netssh.rb b/test/functional/backends/test_netssh.rb index b1c4b2c6..f260f60a 100644 --- a/test/functional/backends/test_netssh.rb +++ b/test/functional/backends/test_netssh.rb @@ -103,6 +103,23 @@ def test_upload_and_then_capture_file_contents assert_equal "Some Content\nWith a newline and trailing spaces \n ", actual_file_contents end + def test_upload_within + file_name = SecureRandom.uuid + file_contents = "Some Content" + dir_name = SecureRandom.uuid + actual_file_contents = "" + Netssh.new(a_host) do |_host| + within("/tmp") do + execute :mkdir, "-p", dir_name + within(dir_name) do + upload!(StringIO.new(file_contents), file_name) + end + end + actual_file_contents = capture(:cat, "/tmp/#{dir_name}/#{file_name}", strip: false) + end.run + assert_equal file_contents, actual_file_contents + end + def test_upload_string_io file_contents = "" Netssh.new(a_host) do |_host| From e715e05d491bbd5c795e380d1d15019727cbc4a3 Mon Sep 17 00:00:00 2001 From: Samuel Cochran Date: Mon, 30 Oct 2017 11:47:18 +1100 Subject: [PATCH 2/4] Embrace String#start_with? --- lib/sshkit/backends/local.rb | 4 ++-- lib/sshkit/backends/netssh.rb | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/sshkit/backends/local.rb b/lib/sshkit/backends/local.rb index f04a54a1..0620e102 100644 --- a/lib/sshkit/backends/local.rb +++ b/lib/sshkit/backends/local.rb @@ -11,7 +11,7 @@ def initialize(_ = nil, &block) end def upload!(local, remote, options = {}) - remote = File.join(pwd_path, remote) unless remote[0] == "/" + remote = File.join(pwd_path, remote) unless remote.start_with?("/") if local.is_a?(String) if options[:recursive] FileUtils.cp_r(local, remote) @@ -26,7 +26,7 @@ def upload!(local, remote, options = {}) end def download!(remote, local=nil, _options = {}) - remote = File.join(pwd_path, remote) unless remote[0] == "/" + remote = File.join(pwd_path, remote) unless remote.start_with?("/") if local.nil? FileUtils.cp(remote, File.basename(remote)) else diff --git a/lib/sshkit/backends/netssh.rb b/lib/sshkit/backends/netssh.rb index 262f60b5..a5533d99 100644 --- a/lib/sshkit/backends/netssh.rb +++ b/lib/sshkit/backends/netssh.rb @@ -63,7 +63,7 @@ def assign_defaults def upload!(local, remote, options = {}) summarizer = transfer_summarizer('Uploading', options) - remote = File.join(pwd_path, remote) unless remote[0] == "/" + remote = File.join(pwd_path, remote) unless remote.start_with?("/") with_ssh do |ssh| ssh.scp.upload!(local, remote, options, &summarizer) end @@ -71,7 +71,7 @@ def upload!(local, remote, options = {}) def download!(remote, local=nil, options = {}) summarizer = transfer_summarizer('Downloading', options) - remote = File.join(pwd_path, remote) unless remote[0] == "/" + remote = File.join(pwd_path, remote) unless remote.start_with?("/") with_ssh do |ssh| ssh.scp.download!(remote, local, options, &summarizer) end From e105d436e02b895ae12a781b70e4936133779998 Mon Sep 17 00:00:00 2001 From: Samuel Cochran Date: Mon, 30 Oct 2017 12:03:03 +1100 Subject: [PATCH 3/4] Add a note about potential breakage --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c8d2c52..e0a566ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,14 @@ appear at the top. * Your contribution here! * [#408](https://github.com/capistrano/sshkit/pull/408): Teach upload! and download! to respect within(...) - [@sj26](https://github.com/sj26) +### Potentially breaking changes + + * `upload!` and `download!` now support relative remote paths which are + relative to the `within` working directory. They were previously documented + as only supporting absolute paths, but relative paths still worked relative + to the remote working directory. If you rely on the previous behaviour you + may need to adjust your code. + ## [1.14.0][] (2017-06-30) ### Breaking changes From 9c7f2161d98adb853780176fc9636b15524782b0 Mon Sep 17 00:00:00 2001 From: Samuel Cochran Date: Mon, 30 Oct 2017 14:21:09 +1100 Subject: [PATCH 4/4] Fix Ruby 2.0 on Travis --- Gemfile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Gemfile b/Gemfile index 1b31471d..645afae2 100644 --- a/Gemfile +++ b/Gemfile @@ -13,3 +13,8 @@ end if Gem::Requirement.new('>= 2.1.0').satisfied_by?(Gem::Version.new(RUBY_VERSION)) gem 'chandler', '>= 0.1.1' end + +# public_suffix 3+ requires ruby 2.1+ +if Gem::Requirement.new('< 2.1').satisfied_by?(Gem::Version.new(RUBY_VERSION)) + gem 'public_suffix', '< 3' +end