From 60add619ac1dab6518baa7952e3292dcb65625e4 Mon Sep 17 00:00:00 2001 From: elijah Date: Mon, 18 Mar 2013 00:55:08 -0700 Subject: added gem rsync_command --- vendor/rsync_command/lib/rsync_command.rb | 96 +++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 vendor/rsync_command/lib/rsync_command.rb (limited to 'vendor/rsync_command/lib/rsync_command.rb') diff --git a/vendor/rsync_command/lib/rsync_command.rb b/vendor/rsync_command/lib/rsync_command.rb new file mode 100644 index 0000000..39e5945 --- /dev/null +++ b/vendor/rsync_command/lib/rsync_command.rb @@ -0,0 +1,96 @@ +require "rsync_command/version" +require "rsync_command/ssh_options" +require "rsync_command/thread_pool" + +require 'monitor' + +class RsyncCommand + attr_accessor :failures, :logger + + def initialize(options={}) + @options = options.dup + @logger = @options.delete(:logger) + @flags = @options.delete(:flags) + @failures = [] + @failures.extend(MonitorMixin) + end + + # + # takes an Enumerable and iterates each item in the list in parallel. + # + def asynchronously(array, &block) + pool = ThreadPool.new + array.each do |item| + pool.schedule(item, &block) + end + pool.shutdown + end + + # + # runs rsync, recording failures + # + def exec(src, dest, options={}) + @failures.synchronize do + @failures.clear + end + rsync_cmd = command(src, dest, options) + if options[:chdir] + rsync_cmd = "cd '#{options[:chdir]}'; #{rsync_cmd}" + end + @logger.debug rsync_cmd if @logger + ok = system(rsync_cmd) + unless ok + @failures.synchronize do + @failures << {:source => src, :dest => dest, :options => options.dup} + end + end + end + + # + # returns true if last exec returned a failure + # + def failed? + @failures && @failures.any? + end + + # + # build rsync command + # + def command(src, dest, options={}) + src = remote_address(src) + dest = remote_address(dest) + options = @options.merge(options) + flags = [] + flags << @flags if @flags + flags << options[:flags] if options.has_key?(:flags) + flags << '--delete' if options[:delete] + flags << includes(options[:includes]) if options.has_key?(:includes) + flags << excludes(options[:excludes]) if options.has_key?(:excludes) + flags << SshOptions.new(options[:ssh]).to_flags if options.has_key?(:ssh) + "rsync #{flags.compact.join(' ')} #{src} #{dest}" + end + + private + + # + # Creates an rsync location if the +address+ is a hash with keys :user, :host, and :path + # (each component is optional). If +address+ is a string, we just pass it through. + # + def remote_address(address) + if address.is_a? String + address # assume it is already formatted. + elsif address.is_a? Hash + [[address[:user], address[:host]].compact.join('@'), address[:path]].compact.join(':') + end + end + + def excludes(patterns) + [patterns].flatten.compact.map { |p| "--exclude='#{p}'" } + end + + def includes(patterns) + [patterns].flatten.compact.map { |p| "--include='#{p}'" } + end + +end + -- cgit v1.2.3