synced_folders/rsync: don't watch excluded paths [GH-3159]

This commit is contained in:
Mitchell Hashimoto 2014-03-12 19:40:18 -07:00
parent a6eafd6a12
commit 56dd0e8531
4 changed files with 67 additions and 5 deletions

View File

@ -3,6 +3,8 @@
IMPROVEMENTS: IMPROVEMENTS:
- guests/tinycore: Will now auto-install rsync. - guests/tinycore: Will now auto-install rsync.
- synced\_folders/rsync: rsync-auto will not watch filesystem for
excluded paths. [GH-3159]
BUG FIXES: BUG FIXES:

View File

@ -31,6 +31,7 @@ module VagrantPlugins
# Build up the paths that we need to listen to. # Build up the paths that we need to listen to.
paths = {} paths = {}
ignores = []
with_target_vms(argv) do |machine| with_target_vms(argv) do |machine|
folders = synced_folders(machine)[:rsync] folders = synced_folders(machine)[:rsync]
next if !folders || folders.empty? next if !folders || folders.empty?
@ -48,6 +49,12 @@ module VagrantPlugins
machine: machine, machine: machine,
opts: folder_opts, opts: folder_opts,
} }
if folder_opts[:exclude]
Array(folder_opts[:exclude]).each do |pattern|
ignores << RsyncHelper.exclude_to_regexp(hostpath, pattern.to_s)
end
end
end end
end end
@ -62,9 +69,13 @@ module VagrantPlugins
end end
@logger.info("Listening to paths: #{paths.keys.sort.inspect}") @logger.info("Listening to paths: #{paths.keys.sort.inspect}")
@logger.info("Ignoring #{ignores.length} paths:")
ignores.each do |ignore|
@logger.info(" -- #{ignore.to_s}")
end
@logger.info("Listening via: #{Listen::Adapter.select.inspect}") @logger.info("Listening via: #{Listen::Adapter.select.inspect}")
callback = method(:callback).to_proc.curry[paths] callback = method(:callback).to_proc.curry[paths]
listener = Listen.to(*paths.keys, &callback) listener = Listen.to(*paths.keys, ignore: ignores, &callback)
listener.start listener.start
listener.thread.join listener.thread.join
@ -73,10 +84,10 @@ module VagrantPlugins
# This is the callback that is called when any changes happen # This is the callback that is called when any changes happen
def callback(paths, modified, added, removed) def callback(paths, modified, added, removed)
@logger.debug("File change callback called!") @logger.info("File change callback called!")
@logger.debug(" - Modified: #{modified.inspect}") @logger.info(" - Modified: #{modified.inspect}")
@logger.debug(" - Added: #{added.inspect}") @logger.info(" - Added: #{added.inspect}")
@logger.debug(" - Removed: #{removed.inspect}") @logger.info(" - Removed: #{removed.inspect}")
tosync = [] tosync = []
paths.each do |hostpath, folders| paths.each do |hostpath, folders|

View File

@ -6,6 +6,31 @@ module VagrantPlugins
# This is a helper that abstracts out the functionality of rsyncing # This is a helper that abstracts out the functionality of rsyncing
# folders so that it can be called from anywhere. # folders so that it can be called from anywhere.
class RsyncHelper class RsyncHelper
# This converts an rsync exclude pattern to a regular expression
# we can send to Listen.
def self.exclude_to_regexp(path, exclude)
start_anchor = false
if exclude.start_with?("/")
start_anchor = true
exclude = exclude[1..-1]
end
path = "#{path}/" if !path.end_with?("/")
regexp = "^#{Regexp.escape(path)}"
regexp += ".*" if !start_anchor
# This is REALLY ghetto, but its a start. We can improve and
# keep unit tests passing in the future.
exclude = exclude.gsub("**", "|||GLOBAL|||")
exclude = exclude.gsub("*", "|||PATH|||")
exclude = exclude.gsub("|||PATH|||", "[^/]*")
exclude = exclude.gsub("|||GLOBAL|||", ".*")
regexp += exclude
Regexp.new(regexp)
end
def self.rsync_single(machine, ssh_info, opts) def self.rsync_single(machine, ssh_info, opts)
# Folder info # Folder info
guestpath = opts[:guestpath] guestpath = opts[:guestpath]

View File

@ -28,6 +28,30 @@ describe VagrantPlugins::SyncedFolderRSync::RsyncHelper do
end end
end end
describe "#exclude_to_regexp" do
let(:path) { "/foo/bar" }
it "converts a directory match" do
expect(described_class.exclude_to_regexp(path, "foo/")).
to eq(/^#{Regexp.escape(path)}\/.*foo\//)
end
it "converts the start anchor" do
expect(described_class.exclude_to_regexp(path, "/foo")).
to eq(/^\/foo\/bar\/foo/)
end
it "converts the **" do
expect(described_class.exclude_to_regexp(path, "fo**o")).
to eq(/^#{Regexp.escape(path)}\/.*fo.*o/)
end
it "converts the *" do
expect(described_class.exclude_to_regexp(path, "fo*o")).
to eq(/^#{Regexp.escape(path)}\/.*fo[^\/]*o/)
end
end
describe "#rsync_single" do describe "#rsync_single" do
let(:result) { Vagrant::Util::Subprocess::Result.new(0, "", "") } let(:result) { Vagrant::Util::Subprocess::Result.new(0, "", "") }