From 965cddbcc193ea0d07c4b18f334ab29732873dac Mon Sep 17 00:00:00 2001 From: Kris Selden Date: Mon, 12 Sep 2011 14:57:10 -0700 Subject: [PATCH] initial --- LICENSE | 21 ++++++++++++ README.md | 56 +++++++++++++++++++++++++++++++ guard-rsync.gemspec | 19 +++++++++++ lib/guard/rsync.rb | 80 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 176 insertions(+) create mode 100644 LICENSE create mode 100644 README.md create mode 100644 guard-rsync.gemspec create mode 100644 lib/guard/rsync.rb diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..a99580e --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +Copyright (c) 2011 Kristofor Selden + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/README.md b/README.md new file mode 100644 index 0000000..7e6c926 --- /dev/null +++ b/README.md @@ -0,0 +1,56 @@ +Guard::Rsync +=========== + +Rsync guard allows to automatically sync directories when source file +changes. + +Focus of this guard task is to sync directories while excluding +autogenerated files and their sources. + +Install +------- + +Please be sure to have [Guard](https://github.com/guard/guard) installed before continue. + +Install the gem: + + $ gem install guard-rsync + +Add it to your Gemfile (inside development group): + +``` ruby +gem 'guard-rsync' +``` + +Usage +----- + +Please read [Guard usage doc](https://github.com/guard/guard#readme) + +Guardfile +--------- + +The following example pairs the coffeescript guard with a rsync guard. + +``` ruby +group(:build_my_app) do + guard('rsync', { + :input => 'apps_src/my_app', + :output => 'apps', + :excludes => { + /(.+)\.coffee$/ => (lambda {|m| "#{m[1]}.js"}) + }, + :run_group_on_start => true + }) do + watch(%r{^apps_src/my_app/(.+\.(?!coffee)(.*)|[^.]+)$}) + end + + guard 'coffeescript', :input => 'apps_src/my_app', :output => 'apps/my_app' +end +``` + +Author +------ + +[Kristofor Selden](https://github.com/kselden) + diff --git a/guard-rsync.gemspec b/guard-rsync.gemspec new file mode 100644 index 0000000..ba637f2 --- /dev/null +++ b/guard-rsync.gemspec @@ -0,0 +1,19 @@ +Gem::Specification.new do |s| + s.name = 'guard-rsync' + s.version = '0.1.0' + s.platform = Gem::Platform::RUBY + s.authors = ['Kris Selden'] + s.email = ['kris.selden@gmail.com'] + s.homepage = 'http://github.com/kselden/guard-rsync' + s.summary = 'Guard gem for syncing directories' + s.description = 'Guard::Rsync automatically syncs directories.' + + s.required_rubygems_version = '>= 1.3.6' + s.rubyforge_project = 'guard-rsync' + + s.add_dependency 'guard', '>= 0.4' + s.add_development_dependency 'bundler', '~> 1.0' + + s.files = Dir.glob('{lib}/**/*') + %w[LICENSE README.md] + s.require_path = 'lib' +end diff --git a/lib/guard/rsync.rb b/lib/guard/rsync.rb new file mode 100644 index 0000000..e111fb2 --- /dev/null +++ b/lib/guard/rsync.rb @@ -0,0 +1,80 @@ +require 'guard' +require 'guard/guard' +require 'guard/watcher' +require 'tempfile' + +module Guard + + # The CoffeeScript guard that gets notifications about the following + # Guard events: `start`, `stop`, `reload`, `run_all` and `run_on_change`. + # + class Rsync < Guard + # Initialize Guard::Sync. + # + # @param [Array] watchers the watchers in the Guard block + # @param [Hash] options the options for the Guard + # @option options [String] :input the input directory + # @option options [String] :output the output directory + # @option options [Hash] :excludes the map of excludes patterns in the + # input directory to exclude files in the output directory. + def initialize(watchers = [], options = { }) + @input = options[:input] + @output = options[:output] + @excludes = options[:excludes] + @run_group_on_start = options[:run_group_on_start] + super + end + + # Call once when guard starts + def start + run_all + if @run_group_on_start + ::Guard.guards.each do |guard| + guard.run_all if self != guard && group == guard.group + end + end + end + + # Gets called when rsync should be run. + # + # @return [Boolean] rsync was successful + def run_all + run_on_change([]) + end + + # Gets called when watched paths and files have changes. + # + # @param [Array] paths the changed paths and files + # @return [Boolean] rsync was successful + def run_on_change(paths) + input_excludes = [] + output_excludes = [] + Dir.chdir(@input) do + Dir.glob('**/*').each do |file| + @excludes.each do |pattern, transform| + matches = file.match(pattern) + if matches + input_excludes << file + output_excludes << transform.call(matches) if transform + end + end + end + end + exclude_file = Tempfile.new('exclude') + begin + exclude_file.puts(input_excludes) + exclude_file.puts(output_excludes) + exclude_file.puts(::Guard.listener.ignore_paths) + exclude_file.flush + UI.info `rsync -av --delete --exclude-from "#{exclude_file.path}" "#{@input}" "#{@output}"` + success = $?.success? + return success + ensure + exclude_file.close + exclude_file.unlink + end + end + + end +end +