diff --git a/plugins/pushes/ftp/errors.rb b/plugins/pushes/ftp/errors.rb new file mode 100644 index 000000000..111dd83af --- /dev/null +++ b/plugins/pushes/ftp/errors.rb @@ -0,0 +1,13 @@ +module VagrantPlugins + module FTPPush + module Errors + class Error < Vagrant::Errors::VagrantError + error_namespace("ftp_push.errors") + end + + class TooManyFiles < Error + error_key(:too_many_files) + end + end + end +end diff --git a/plugins/pushes/ftp/locales/en.yml b/plugins/pushes/ftp/locales/en.yml index 0bbbe51f1..c5ba39869 100644 --- a/plugins/pushes/ftp/locales/en.yml +++ b/plugins/pushes/ftp/locales/en.yml @@ -9,3 +9,8 @@ en: config.push.define "ftp" do |push| push.%{attribute} = "..." end + too_many_files: |- + The configured directory for Vagrant FTP push contains too many files + to successfully complete the command. This can be resolved by either + removing extraneous files from the configured directory, or updating + the `dir` configuration option to a subdirectory. diff --git a/plugins/pushes/ftp/push.rb b/plugins/pushes/ftp/push.rb index 755304ee6..318c26d73 100644 --- a/plugins/pushes/ftp/push.rb +++ b/plugins/pushes/ftp/push.rb @@ -2,6 +2,7 @@ require "net/ftp" require "pathname" require_relative "adapter" +require_relative "errors" module VagrantPlugins module FTPPush @@ -17,12 +18,17 @@ module VagrantPlugins def push # Grab files early so if there's an exception or issue, we don't have to # wait and close the (S)FTP connection as well - files = Hash[*all_files.flat_map do |file| - relative_path = relative_path_for(file, config.dir) - destination = File.join(config.destination, relative_path) - file = File.expand_path(file, env.root_path) - [file, destination] - end] + files = nil + begin + files = Hash[*all_files.flat_map do |file| + relative_path = relative_path_for(file, config.dir) + destination = File.join(config.destination, relative_path) + file = File.expand_path(file, env.root_path) + [file, destination] + end] + rescue SystemStackError + raise Errors::TooManyFiles + end ftp = "#{config.username}@#{config.host}:#{config.destination}" env.ui.info "Uploading #{env.root_path} to #{ftp}" diff --git a/test/unit/plugins/pushes/ftp/push_test.rb b/test/unit/plugins/pushes/ftp/push_test.rb index ba69e0078..83509fb7d 100644 --- a/test/unit/plugins/pushes/ftp/push_test.rb +++ b/test/unit/plugins/pushes/ftp/push_test.rb @@ -73,6 +73,11 @@ describe VagrantPlugins::FTPPush::Push do subject.push expect(server.files).to eq(%w(Gemfile data.txt)) end + + it "raises informative exception when too many files to process" do + expect(subject).to receive(:all_files).and_raise(SystemStackError) + expect{ subject.push }.to raise_error(VagrantPlugins::FTPPush::Errors::TooManyFiles) + end end describe "#connect" do