diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..36b2ab4 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,4 @@ +rvm: + - 1.8.7 + - 1.9.2 + - ree diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown new file mode 100644 index 0000000..aca5c94 --- /dev/null +++ b/CHANGELOG.markdown @@ -0,0 +1,90 @@ +### Bugs fixes: + +- Issue [#41](https://github.com/guard/guard/issues/41): Removed useless Bundler requirement. ([@thibaudgg](https://github.com/thibaudgg)) + +### New features: + +- Changed CHANGELOG from RDOC to Markdown and cleaned it! Let's celebrate! ([@rymai](https://github.com/rymai)) +- Changed README from RDOC to Markdown! Let's celebrate! ([@thibaudgg](https://github.com/thibaudgg)) +- Issue [#48](https://github.com/guard/guard/issues/48): Adding support for inline Guard classes rather than requiring a gem. ([@jrsacks](https://github.com/jrsacks)) + + +## 0.3.3 - April 18, 2011 + +### Bugs fixes: + +- Fixed `new_modified_files` rerun conditions on `Guard.run_on_change_for_all_guards`. ([@thibaudgg](https://github.com/thibaudgg)) + + +## 0.3.2 - April 17, 2011 + +### Bugs fixes: + +- Pull request [#43](https://github.com/guard/guard/issues/43): Fixed `guard init` command. ([@brainopia](https://github.com/brainopia)) + + +## 0.3.1 - April 14, 2011 + +### Bugs fixes: + +- Return unique filenames from Linux listener. (Marian Schubert) +- `Guard.get_guard_class` return wrong class when loaded nested class. ([@koshigoe](https://github.com/koshigoe)) +- Issue [#35](https://github.com/guard/guard/issues/35): Fixed open-gem/gem_open dependency problem by using `gem which` to locate guards gem path. (reported by [@thierryhenrio](https://github.com/thierryhenrio), fixed by [@thibaudgg](https://github.com/thibaudgg)) +- Issue [#38](https://github.com/guard/guard/issues/38) & Pull request [#39](https://github.com/guard/guard/issues/39): Fixed an invalid ANSI escape code in `Guard::UI.reset_line`. ([@gix](https://github.com/gix)) + +### New features: + +- Issue [#28](https://github.com/guard/guard/issues/28): New `-n` command line option to disable notifications (Growl / Libnotify). ([@thibaudgg](https://github.com/thibaudgg)) + + +## 0.3.0 - January 19, 2011 + +### Bugs fixes: + +- Avoid launching run_on_change guards method when no files matched. --clear guard argument is now usable. ([@thibaudgg](https://github.com/thibaudgg)) + +### New features: + +- The whole directory is now watched during `run_on_change` to detect new files modifications. ([@thibaudgg](https://github.com/thibaudgg)) +- Pull request [#26](https://github.com/guard/guard/issues/26): New DSL method: `group` allows you to group several guards. ([@netzpirat](https://github.com/netzpirat)) +- Pull request [#26](https://github.com/guard/guard/issues/26): New CLI option: `--group group_name` to specify certain groups of guards to start. ([@netzpirat](https://github.com/netzpirat)) +- `watch` patterns are now more strict: strings are matched with `String#==`, `Regexp` are matched with `Regexp#match`. ([@rymai](https://github.com/rymai)) +- A deprecation warning is displayed if your `Guardfile` contains `String` that look like `Regexp` (bad!). ([@rymai](https://github.com/rymai)) +- It's now possible to return an `Enumerable` in the `watch` optional blocks in the `Guardfile`. ([@rymai](https://github.com/rymai)) + +### New specs: + +- Guard::Watcher. ([@rymai](https://github.com/rymai)) +- Pull request [#13](https://github.com/guard/guard/issues/13): Guard::Dsl. ([@oliamb](https://github.com/oliamb)) + + +## 0.2.2 - October 25, 2010 + +### Bugs fixes: + +- Issue [#5](https://github.com/guard/guard/issues/5): avoid creating new copy of `fsevent_watch` every time a file is changed. (reported by [@stouset](https://github.com/stouset), fixed by [@thibaudgg](https://github.com/thibaudgg)) + + +## 0.2.1 - October 24, 2010 + +### Bugs fixes: + +- Pull request [#7](https://github.com/guard/guard/issues/7): Fixes for Linux support. ([@yannlugrin](https://github.com/yannlugrin))) +- Pull request [#6](https://github.com/guard/guard/issues/6): Locate guard now chomp newline in result path. ([@yannlugrin](https://github.com/yannlugrin))) + + +## 0.2.0 - October 21, 2010 + +### Bugs fixes: + +- Issue [#3](https://github.com/guard/guard/issues/3): `guard init ` no more need `Gemfile` but `open_gem` is required now. (reported by [@wereHamster](https://github.com/wereHamster), fixed by [@thibaudgg](https://github.com/thibaudgg)) +- Issue [#2](https://github.com/guard/guard/issues/2): 1.8.6 compatibility. (reported by [@veged](https://github.com/veged), fixed by [@thibaudgg](https://github.com/thibaudgg)) +- Removes Growl & Libnotify dependencies. ([@thibaudgg](https://github.com/thibaudgg)) + + +## 0.2.0.beta.1 - October 17, 2010 + +### New features: + +- Improved listeners support (`rb-fsevent` & `rb-inotify`). ([@thibaudgg](https://github.com/thibaudgg)) +- Added polling listening fallback. ([@thibaudgg](https://github.com/thibaudgg)) \ No newline at end of file diff --git a/CHANGELOG.rdoc b/CHANGELOG.rdoc deleted file mode 100644 index e22ec01..0000000 --- a/CHANGELOG.rdoc +++ /dev/null @@ -1,77 +0,0 @@ -== 0.3.3 (Avril 18, 2011) - -Bugs fixes: -- Fixed new_modified_files rerun conditions on Guard.run_on_change_for_all_guards - -== 0.3.2 (Avril 17, 2011) - -Bugs fixes: -- Fixed "guard init" command (@brainopia) - -== 0.3.1 (Avril 14, 2011) - -Features: -- Added a command line option (-n false) to disable notifications (growl/libnotify) - -Bugs fixes: -- Return unique filenames from Linux listener (Marian Schubert) -- Guard.get_guard_class return wrong class when loaded nested class. (@koshigoe) -- Fixed open-gem/gem_open dependency problem by using `gem which` to locate guards gem path -- Fixed an invalid ANSI escape code in UI.reset_line (@gix) - -== 0.3.0 (Jan 19, 2011) - -== Jan 19, 2011 [by thibaudgg] - -Features: -- The whole directory are now watched after that run_on_change was launched on all guards to detect new files modifications. - -== Dec 17, 2010 [by netzpirat] - -Features: -- New DSL method: `group` allows you to group several guards. -- New CLI option: `--group group_name` to specify certain groups of guards to start. - -== Dec 16, 2010 [by rymai] - -Features: -- 'watch' patterns are now more strict: Strings are matched with '==', Regexp are matched with Regexp#match. -- A deprecation warning is displayed if your Guardfile contains String that look like Regexp (bad!). - -== Nov 26, 2010 [by rymai] - -Features: -- It's now possible to return an enumerable in the 'watch' optional blocks in the Guardfile. - -Specs: -- Guard::Watcher - -Bugs fixes: -- Avoid launching run_on_change guards method when no files matched. --clear guard argument is now usable. - -== 0.2.2 (Oct 25, 2010) - -Bugs fixes: - -- Avoid creating new copy of fsevent_watch every time a file is changed. (issue #5) - -== 0.2.1 (Oct 24, 2010) - -Bugs fixes: - -- Fixes for Linux support - -== 0.2.0 (Oct 21, 2010) - -Bugs fixes: - -- Fixes for 1.8.6 compatibility (issue #2) -- guard init no more need Gemfile presence but open_gem is required now (issue #3) -- Removes growl & libnotify dependencies - -== 0.2.0.beta.1 (Oct 17, 2010) - -Features: - -- Improved listeners support (rb-fsevent & rb-inotify) -- Added polling listening fallback \ No newline at end of file diff --git a/Gemfile b/Gemfile index 8b676d9..00c598c 100644 --- a/Gemfile +++ b/Gemfile @@ -5,12 +5,12 @@ gemspec require 'rbconfig' if Config::CONFIG['target_os'] =~ /darwin/i - gem 'rb-fsevent', '>= 0.3.9' - gem 'growl', '~> 1.0.3' + gem 'rb-fsevent', '>= 0.3.9', :require => false + gem 'growl', '~> 1.0.3', :require => false end if Config::CONFIG['target_os'] =~ /linux/i - gem 'rb-inotify', '>= 0.5.1' - gem 'libnotify', '~> 0.1.3' + gem 'rb-inotify', '>= 0.5.1', :require => false + gem 'libnotify', '~> 0.1.3', :require => false end if Config::CONFIG['target_os'] =~ /mswin|mingw/i gem 'win32console' diff --git a/Guardfile b/Guardfile index c7303d5..d5c6bd9 100644 --- a/Guardfile +++ b/Guardfile @@ -1,4 +1,4 @@ -guard('rspec', :cli => '-f doc', :version => 2) do +guard('rspec', :version => 2) do watch(%r{^spec/(.*)_spec\.rb}) watch(%r{^lib/(.*)\.rb}) { |m| "spec/#{m[1]}_spec.rb" } watch('spec/spec_helper.rb') { "spec" } diff --git a/README.markdown b/README.markdown new file mode 100644 index 0000000..1a8d72a --- /dev/null +++ b/README.markdown @@ -0,0 +1,273 @@ +Guard +===== + +![travis-ci](http://travis-ci.org/guard/guard.png) + +Guard is a command line tool that easily handle events on files modifications. + +Features +-------- + +* [FSEvent](http://en.wikipedia.org/wiki/FSEvents) support on Mac OS X 10.5+ (without RubyCocoa!, [rb-fsevent gem, >= 0.3.5](https://rubygems.org/gems/rb-fsevent) required). +* [Inotify](http://en.wikipedia.org/wiki/Inotify) support on Linux ([rb-inotify gem, >= 0.5.1](https://rubygems.org/gems/rb-inotify) required). +* Polling on the other operating systems (help us to support more OS). +* Automatic & Super fast (when polling is not used) files modifications detection (even new files are detected). +* Growl notifications ([growlnotify](http://growl.info/documentation/growlnotify.php) & [growl gem](https://rubygems.org/gems/growl) required). +* Libnotify notifications ([libnotify gem](https://rubygems.org/gems/libnotify) required). +* Tested on Ruby 1.8.7, 1.9.2 && ree. + +Install +------- + +Install the gem: + + $ gem install guard + +Add it to your Gemfile (inside the test group): + +``` ruby +gem 'guard' +``` + +Generate an empty Guardfile with: + + $ guard init + +Add the guards you need to your Guardfile (see the existing guards below). + +### On Mac OS X + +Install the rb-fsevent gem for [FSEvent](http://en.wikipedia.org/wiki/FSEvents) support: + + $ gem install rb-fsevent + +Install the Growl gem if you want notification support: + + $ gem install growl + +And add it to you Gemfile: + +``` ruby +gem 'growl' +``` + +### On Linux + +Install the rb-inotify gem for [inotify](http://en.wikipedia.org/wiki/Inotify) support: + + $ gem install rb-inotify + +Install the Libnotify gem if you want notification support: + + $ gem install libnotify + +And add it to you Gemfile: + +``` ruby +gem 'libnotify' +``` + +Usage +----- + +Just launch Guard inside your Ruby / Rails project with: + + $ guard [start] + +or if you use Bundler, to run the Guard executable specific to your bundle: + + $ bundle exec guard + +Command line options +-------------------- + +Shell can be cleared after each change with: + + $ guard --clear + $ guard -c # shortcut + +Notifications (growl/libnotify) can be disabled with: + + $ guard --notify false + $ guard -n false # shortcut + +Notifications can also be disabled by setting a `GUARD_NOTIFY` environment variable to `false` + +The guards to start can be specified by group (see the Guardfile DSL below) specifying the --group (or -g) option: + + $ guard --group group_name another_group_name + $ guard -g group_name another_group_name # shortcut + +Options list is available with: + + $ guard help [TASK] + +Signal handlers +--------------- + +Signal handlers are used to interact with Guard: + +* Ctrl-C - Calls each guard's stop method, in the same order they are declared in the Guardfile, and then quits Guard itself. +* Ctrl-\\ - Calls each guard's run_all method, in the same order they are declared in the Guardfile. +* Ctrl-Z - Calls each guard's reload method, in the same order they are declared in the Guardfile. + +Available Guards +---------------- + +[Available Guards list](https://github.com/guard/guard/wiki/List-of-available-Guards) (on the wiki now) + +### Add a guard to your Guardfile + +Add it to your Gemfile (inside the test group): + +``` ruby +gem '' +``` + +Insert default guard's definition to your Guardfile by running this command: + + $ guard init + +You are good to go! + +Guardfile DSL +------------- + +The Guardfile DSL consists of just three simple methods: guard, watch & group. + +Required: +* The guard method allows you to add a guard with an optional hash of options. +* The watch method allows you to define which files are supervised by this guard. An optional block can be added to overwrite the paths sent to the run_on_change guard method or to launch any arbitrary command. + +Optional: +* The group method allows you to group several guards together. Groups to be run can be specified with the Guard DSL option --group (or -g). This comes in handy especially when you have a huge Guardfile and want to focus your development on a certain part. + +Example: + +``` ruby +group 'backend' do + guard 'bundler' do + watch('Gemfile') + end + + guard 'rspec', :cli => '--color --format doc' do + # Regexp watch patterns are matched with Regexp#match + watch(%r{^spec/.+_spec\.rb}) + watch(%r{^lib/(.+)\.rb}) { |m| "spec/lib/#{m[1]}_spec.rb" } + watch(%r{^spec/models/.+\.rb}) { ["spec/models", "spec/acceptance"] } + watch(%r{^spec/.+\.rb}) { `say hello` } + + # String watch patterns are matched with simple '==' + watch('spec/spec_helper.rb') { "spec" } + end +end + +group 'frontend' do + guard 'coffeescript', :output => 'public/javascripts/compiled' do + watch(%r{^app/coffeescripts/.+\.coffee}) + end + + guard 'livereload' do + watch(%r{^app/.+\.(erb|haml)}) + end +end +``` + +Create a new guard +------------------ + +Creating a new guard is very easy, just create a new gem (bundle gem if you use Bundler) with this basic structure: + + lib/ + guard/ + guard-name/ + templates/ + Guardfile (needed for guard init ) + guard-name.rb + +Guard::GuardName (in lib/guard/guard-name.rb) must inherit from Guard::Guard and should overwrite at least one of the five basic Guard::Guard instance methods. Example: + +``` ruby +require 'guard' +require 'guard/guard' + +module Guard + class GuardName < Guard + + def initialize(watchers=[], options={}) + super + # init stuff here, thx! + end + + # ================= + # = Guard methods = + # ================= + + # If one of those methods raise an exception, the Guard::GuardName instance + # will be removed from the active guards. + + # Called once when Guard starts + # Please override initialize method to init stuff + def start + true + end + + # Called on Ctrl-C signal (when Guard quits) + def stop + true + end + + # Called on Ctrl-Z signal + # This method should be mainly used for "reload" (really!) actions like reloading passenger/spork/bundler/... + def reload + true + end + + # Called on Ctrl-/ signal + # This method should be principally used for long action like running all specs/tests/... + def run_all + true + end + + # Called on file(s) modifications + def run_on_change(paths) + true + end + + end +end +``` + +Please take a look at the existing guards' source code (see the list above) for more concrete example. + +Alternatively, a new guard can be added inline to a Guardfile with this basic structure: + +``` ruby +require 'guard/guard' + +module ::Guard + class Example < ::Guard::Guard + def run_all + true + end + + def run_on_change(paths) + true + end + end +end +``` + +Development +----------- + +* Source hosted at [GitHub](https://github.com/guard/guard). +* Report Issues/Questions/Feature requests on [GitHub Issues](https://github.com/guard/guard/issues). + +Pull requests are very welcome! Make sure your patches are well tested. Please create a topic branch for every separate change +you make. + +Author +------ + +[Thibaud Guillaume-Gentil](https://github.com/thibaudgg) diff --git a/README.rdoc b/README.rdoc deleted file mode 100644 index 8eeb123..0000000 --- a/README.rdoc +++ /dev/null @@ -1,235 +0,0 @@ -= Guard - -Guard is a command line tool that easily handle events on files modifications. - -== Features - -- {FSEvent}[http://en.wikipedia.org/wiki/FSEvents] support on Mac OS X 10.5+ (without RubyCocoa!, {rb-fsevent gem, >= 0.3.5}[https://rubygems.org/gems/rb-fsevent] required). -- {Inotify}[http://en.wikipedia.org/wiki/Inotify] support on Linux ({rb-inotify gem, >= 0.5.1}[https://rubygems.org/gems/rb-inotify] required). -- {Directory Change Notification}[http://msdn.microsoft.com/en-us/library/aa365261(VS.85).aspx] suuport on Windows ({rb-fchange, >= 0.0.2}[https://github.com/stereobooster/rb-fchange] required) -- Polling on the other operating systems (help us to support more OS). -- Automatic & Super fast (when polling is not used) files modifications detection (even new files are detected). -- Growl notifications ({growlnotify}[http://growl.info/documentation/growlnotify.php] & {growl gem}[https://rubygems.org/gems/growl] required). -- Libnotify notifications ({libnotify gem}[https://rubygems.org/gems/libnotify] required). -- Tested on Ruby 1.8.7 & 1.9.2. - -== Install - -Install the gem: - - $ gem install guard - -Add it to your Gemfile (inside the test group): - - gem 'guard' - -Generate an empty Guardfile with: - - $ guard init - -Add the guards you need to your Guardfile (see the existing guards below). - -=== On Mac OS X - -Install the rb-fsevent gem for {FSEvent}[http://en.wikipedia.org/wiki/FSEvents] support: - - $ gem install rb-fsevent - -Install the Growl gem if you want notification support: - - $ gem install growl - -And add it to you Gemfile: - - gem 'growl' - -=== On Linux - -Install the rb-inotify gem for {inotify}[http://en.wikipedia.org/wiki/Inotify] support: - - $ gem install rb-inotify - -Install the Libnotify gem if you want notification support: - - $ gem install libnotify - -And add it to you Gemfile: - - gem 'libnotify' - -=== On Windows - -Install the rb-fchange gem for {Directory Change Notification}[http://msdn.microsoft.com/en-us/library/aa365261(VS.85).aspx] support: - - $ gem install rb-fchange - -== Usage - -Just launch Guard inside your Ruby / Rails project with: - - $ guard [start] - -or if you use Bundler, to run the Guard executable specific to your bundle: - - $ bundle exec guard - -== Command line options - -Shell can be cleared after each change with: - - $ guard --clear - $ guard -c # shortcut - -Notifications (growl/libnotify) can be disabled with: - - $ guard --notify false - $ guard -n false # shortcut - -The guards to start can be specified by group (see the Guardfile DSL below) specifying the --group (or -g) option: - - $ guard --group group_name another_group_name - $ guard -g group_name another_group_name # shortcut - -Options list is available with: - - $ guard help [TASK] - -== Signal handlers - -Signal handlers are used to interact with Guard: - -- Ctrl-C - Calls each guard's stop method, in the same order they are declared in the Guardfile, and then quits Guard itself. -- Ctrl-\\ - Calls each guard's run_all method, in the same order they are declared in the Guardfile. -- Ctrl-Z - Calls each guard's reload method, in the same order they are declared in the Guardfile. - -== Available Guards - -{Available Guards list}[https://github.com/guard/guard/wiki/List-of-available-Guards] (on the wiki now) - -=== Add a guard to your Guardfile - -Add it to your Gemfile (inside the test group): - - gem '' - -Insert default guard's definition to your Guardfile by running this command: - - $ guard init - -You are good to go! - -== Guardfile DSL - -The Guardfile DSL consists of just three simple methods: guard, watch & group. - -Required: -- The guard method allows you to add a guard with an optional hash of options. -- The watch method allows you to define which files are supervised by this guard. An optional block can be added to overwrite the paths sent to the run_on_change guard method or to launch any arbitrary command. - -Optional: -- The group method allows you to group several guards together. Groups to be run can be specified with the Guard DSL option --group (or -g). This comes in handy especially when you have a huge Guardfile and want to focus your development on a certain part. - -Example: - - group 'backend' do - guard 'bundler' do - watch('Gemfile') - end - - guard 'rspec', :cli => '--color --format doc' do - # Regexp watch patterns are matched with Regexp#match - watch(%r{^spec/.+_spec\.rb}) - watch(%r{^lib/(.+)\.rb}) { |m| "spec/lib/#{m[1]}_spec.rb" } - watch(%r{^spec/models/.+\.rb}) { ["spec/models", "spec/acceptance"] } - watch(%r{^spec/.+\.rb}) { `say hello` } - - # String watch patterns are matched with simple '==' - watch('spec/spec_helper.rb') { "spec" } - end - end - - group 'frontend' do - guard 'coffeescript', :output => 'public/javascripts/compiled' do - watch(%r{^app/coffeescripts/.+\.coffee}) - end - - guard 'livereload' do - watch(%r{^app/.+\.(erb|haml)}) - end - end - -== Create a new guard - -Creating a new guard is very easy, just create a new gem (bundle gem if you use Bundler) with this basic structure: - - lib/ - guard/ - guard-name/ - templates/ - Guardfile (needed for guard init ) - guard-name.rb - -Guard::GuardName (in lib/guard/guard-name.rb) must inherit from Guard::Guard and should overwrite at least one of the five basic Guard::Guard instance methods. Example: - - require 'guard' - require 'guard/guard' - - module Guard - class GuardName < Guard - - def initialize(watchers=[], options={}) - super - # init stuff here, thx! - end - - # ================= - # = Guard methods = - # ================= - - # If one of those methods raise an exception, the Guard::GuardName instance - # will be removed from the active guards. - - # Called once when Guard starts - # Please override initialize method to init stuff - def start - true - end - - # Called on Ctrl-C signal (when Guard quits) - def stop - true - end - - # Called on Ctrl-Z signal - # This method should be mainly used for "reload" (really!) actions like reloading passenger/spork/bundler/... - def reload - true - end - - # Called on Ctrl-/ signal - # This method should be principally used for long action like running all specs/tests/... - def run_all - true - end - - # Called on file(s) modifications - def run_on_change(paths) - true - end - - end - end - -Please take a look at the existing guards' source code (see the list above) for more concrete example. - -== Development - -- Source hosted at {GitHub}[https://github.com/guard/guard]. -- Report Issues/Questions/Feature requests on {GitHub Issues}[https://github.com/guard/guard/issues]. - -Pull requests are very welcome! Make sure your patches are well tested. Please create a topic branch for every separate change -you make. - -== Authors - -{Thibaud Guillaume-Gentil}[https://github.com/thibaudgg] \ No newline at end of file diff --git a/Rakefile b/Rakefile index 4541498..289b504 100644 --- a/Rakefile +++ b/Rakefile @@ -8,7 +8,7 @@ task :default => :spec namespace(:spec) do desc "Run all specs on multiple ruby versions (requires rvm)" task(:portability) do - %w[1.8.6 1.8.7 1.9.2].each do |version| + %w[1.8.7 1.9.2 ree].each do |version| system <<-BASH bash -c 'source ~/.rvm/scripts/rvm; rvm #{version}; diff --git a/guard.gemspec b/guard.gemspec index 045de79..b24b9bb 100644 --- a/guard.gemspec +++ b/guard.gemspec @@ -21,7 +21,7 @@ Gem::Specification.new do |s| s.add_dependency 'thor', '~> 0.14.6' - s.files = Dir.glob('{bin,images,lib}/**/*') + %w[LICENSE README.rdoc] + s.files = Dir.glob('{bin,images,lib}/**/*') + %w[LICENSE README.markdown] s.executable = 'guard' s.require_path = 'lib' end \ No newline at end of file diff --git a/lib/guard.rb b/lib/guard.rb index df2109b..12c35a9 100644 --- a/lib/guard.rb +++ b/lib/guard.rb @@ -1,5 +1,3 @@ -require 'bundler' - module Guard autoload :UI, 'guard/ui' @@ -18,7 +16,8 @@ module Guard @listener = Listener.select_and_init @guards = [] - Notifier.turn_off unless options[:notify] + options[:notify] = false if ENV["GUARD_NOTIFY"] == 'false' + options[:notify] ? Notifier.turn_on : Notifier.turn_off self end @@ -90,12 +89,16 @@ module Guard end def try_to_load_gem(name) - Kernel.require "guard/#{name.downcase}" + require "guard/#{name.downcase}" rescue LoadError end def locate_guard(name) - Gem.source_index.find_name("guard-#{name}").last.full_gem_path + if Gem::Version.create(Gem::VERSION) >= Gem::Version.create('1.8.0') + Gem::Specification.find_by_name("guard-#{name}").full_gem_path + else + Gem.source_index.find_name("guard-#{name}").last.full_gem_path + end rescue UI.error "Could not find 'guard-#{name}' gem path." end diff --git a/lib/guard/interactor.rb b/lib/guard/interactor.rb index 32dab08..cea6eb7 100644 --- a/lib/guard/interactor.rb +++ b/lib/guard/interactor.rb @@ -1,13 +1,31 @@ module Guard module Interactor + extend self - def self.init_signal_traps + def run_all + ::Guard.run do + ::Guard.guards.each { |guard| ::Guard.supervised_task(guard, :run_all) } + end + end + + def stop + UI.info "Bye bye...\n", :reset => true + ::Guard.listener.stop + ::Guard.guards.each { |guard| ::Guard.supervised_task(guard, :stop) } + abort + end + + def reload + ::Guard.run do + ::Guard.guards.each { |guard| ::Guard.supervised_task(guard, :reload) } + end + end + + def self.init_signal_traps # Run all (Ctrl-\) if Signal.list.has_key?('QUIT') Signal.trap('QUIT') do - ::Guard.run do - ::Guard.guards.each { |guard| ::Guard.supervised_task(guard, :run_all) } - end + run_all end else UI.info "Your system doesn't support QUIT signal, so Ctrl-\\ (Run all) won't work" @@ -16,10 +34,7 @@ module Guard # Stop (Ctrl-C) if Signal.list.has_key?('INT') Signal.trap('INT') do - UI.info "Bye bye...", :reset => true - ::Guard.listener.stop - ::Guard.guards.each { |guard| ::Guard.supervised_task(guard, :stop) } - abort("\n") + stop end else UI.info "Your system doesn't support INT signal, so Ctrl-C (stop) won't work" @@ -28,14 +43,12 @@ module Guard # Reload (Ctrl-Z) if Signal.list.has_key?('TSTP') Signal.trap('TSTP') do - ::Guard.run do - ::Guard.guards.each { |guard| ::Guard.supervised_task(guard, :reload) } - end + reload end else UI.info "Your system doesn't support TSTP signal, so Ctrl-Z (Reload) won't work" end - end + end end -end \ No newline at end of file +end diff --git a/lib/guard/listeners/linux.rb b/lib/guard/listeners/linux.rb index 6436d59..2d53b62 100644 --- a/lib/guard/listeners/linux.rb +++ b/lib/guard/listeners/linux.rb @@ -51,7 +51,7 @@ module Guard def watch_change @watch_change = true - while !@stop + until @stop if Config::CONFIG['build'] =~ /java/ || IO.select([inotify.to_io], [], [], latency) break if @stop diff --git a/lib/guard/listeners/polling.rb b/lib/guard/listeners/polling.rb index e0dd5ca..bf5a17b 100644 --- a/lib/guard/listeners/polling.rb +++ b/lib/guard/listeners/polling.rb @@ -23,7 +23,7 @@ module Guard private def watch_change - while !@stop + until @stop start = Time.now.to_f files = modified_files([Dir.pwd + '/'], :all => true) update_last_event diff --git a/lib/guard/notifier.rb b/lib/guard/notifier.rb index d250a22..27e92df 100644 --- a/lib/guard/notifier.rb +++ b/lib/guard/notifier.rb @@ -8,23 +8,33 @@ module Guard @disable = true end + def self.turn_on + @disable = false + case Config::CONFIG['target_os'] + when /darwin/i + require_growl + when /linux/i + require_libnotify + end + end + def self.notify(message, options = {}) - unless @disable || ENV["GUARD_ENV"] == "test" + unless @disable image = options[:image] || :success title = options[:title] || "Guard" case Config::CONFIG['target_os'] when /darwin/i - if growl_installed? - Growl.notify message, :title => title, :icon => image_path(image), :name => "Guard" - end + Growl.notify message, :title => title, :icon => image_path(image), :name => "Guard" when /linux/i - if libnotify_installed? - Libnotify.show :body => message, :summary => title, :icon_path => image_path(image) - end + Libnotify.show :body => message, :summary => title, :icon_path => image_path(image) end end end + def self.disabled? + @disable + end + private def self.image_path(image) @@ -42,24 +52,18 @@ module Guard end end - def self.growl_installed? - @installed ||= begin - require 'growl' - true - rescue LoadError - UI.info "Please install growl gem for Mac OS X notification support and add it to your Gemfile" - false - end + def self.require_growl + require 'growl' + rescue LoadError + @disable = true + UI.info "Please install growl gem for Mac OS X notification support and add it to your Gemfile" end - def self.libnotify_installed? - @installed ||= begin - require 'libnotify' - true - rescue LoadError - UI.info "Please install libnotify gem for Linux notification support and add it to your Gemfile" - false - end + def self.require_libnotify + require 'libnotify' + rescue LoadError + @disable = true + UI.info "Please install libnotify gem for Linux notification support and add it to your Gemfile" end end diff --git a/lib/guard/ui.rb b/lib/guard/ui.rb index 587d6de..fffb40d 100644 --- a/lib/guard/ui.rb +++ b/lib/guard/ui.rb @@ -2,29 +2,6 @@ module Guard module UI class << self - @color_enabled = true - @color_tested = false - @new_line = "\r" - - def color_enabled? - if !@color_tested - @color_tested = true - if Config::CONFIG['target_os'] =~ /mswin|mingw/i - @new_line = "\r\n" - unless ENV['ANSICON'] - begin - require 'rubygems' unless ENV['NO_RUBYGEMS'] - require 'Win32/Console/ANSI' - rescue LoadError - @color_enabled = false - info "You must 'gem install win32console' to use color on Windows" - end - end - end - end - return @color_enabled - end - def info(message, options = {}) unless ENV["GUARD_ENV"] == "test" reset_line if options[:reset] @@ -47,10 +24,10 @@ module Guard end def reset_line - if color_enabled? - print @new_line + "\e[0m" + if color_enabled? + print "\r\e[0m" else - print @new_line + print "\r\n" end end @@ -72,6 +49,22 @@ module Guard end end + def color_enabled? + @color_enabled ||= if Config::CONFIG['target_os'] =~ /mswin|mingw/i + unless ENV['ANSICON'] + begin + require 'rubygems' unless ENV['NO_RUBYGEMS'] + require 'Win32/Console/ANSI' + rescue LoadError + info "You must 'gem install win32console' to use color on Windows" + false + end + end + else + true + end + end + end end end diff --git a/lib/guard/version.rb b/lib/guard/version.rb index 71fc9ba..1db0eec 100644 --- a/lib/guard/version.rb +++ b/lib/guard/version.rb @@ -1,3 +1,3 @@ module Guard - VERSION = "0.3.3" -end \ No newline at end of file + VERSION = "0.3.4" +end diff --git a/spec/guard/interactor_spec.rb b/spec/guard/interactor_spec.rb new file mode 100644 index 0000000..9621831 --- /dev/null +++ b/spec/guard/interactor_spec.rb @@ -0,0 +1,27 @@ +require 'spec_helper' + +describe Guard::Interactor do + subject { Guard::Interactor } + let(:guard) { mock "guard" } + + before :each do + Guard.stub!(:guards).and_return([guard]) + Guard.stub!(:options).and_return({}) + Guard.stub!(:listener).and_return(mock(:start => nil, :stop => nil)) + end + + it ".run_all should send :run_all to all guards" do + guard.should_receive(:run_all) + subject.run_all + end + + it ".stop should send :stop to all guards" do + guard.should_receive(:stop) + lambda { subject.stop }.should raise_error(SystemExit) + end + + it ".reload should send :reload to all guards" do + guard.should_receive(:reload) + subject.reload + end +end diff --git a/spec/guard/listeners/darwin_spec.rb b/spec/guard/listeners/darwin_spec.rb index 7a562f1..6168f49 100644 --- a/spec/guard/listeners/darwin_spec.rb +++ b/spec/guard/listeners/darwin_spec.rb @@ -10,7 +10,7 @@ describe Guard::Darwin do end end - if mac? + if mac? && Guard::Darwin.usable? it "is usable on 10.6" do subject.should be_usable end diff --git a/spec/guard/listeners/linux_spec.rb b/spec/guard/listeners/linux_spec.rb index ba5d86f..bbdffba 100644 --- a/spec/guard/listeners/linux_spec.rb +++ b/spec/guard/listeners/linux_spec.rb @@ -11,7 +11,7 @@ describe Guard::Linux do end end - if linux? + if linux? && Guard::Linux.usable? it "is usable on linux" do subject.should be_usable end diff --git a/spec/guard/notifier_spec.rb b/spec/guard/notifier_spec.rb index b12781b..e09622c 100644 --- a/spec/guard/notifier_spec.rb +++ b/spec/guard/notifier_spec.rb @@ -4,56 +4,55 @@ describe Guard::Notifier do subject { Guard::Notifier } describe ".notify" do - before(:each) do - @saved_guard_env = ENV["GUARD_ENV"] - ENV["GUARD_ENV"] = 'dont_mute_notify' - end + before(:each) { subject.turn_on } if mac? - require 'growl' - it "uses Growl on Mac OS X" do - Growl.should_receive(:notify).with("great", - :title => "Guard", - :icon => Pathname.new(File.dirname(__FILE__)).join('../../images/success.png').to_s, - :name => "Guard" - ) - subject.notify 'great', :title => 'Guard' + if growl_installed? + it "uses Growl on Mac OS X" do + Growl.should_receive(:notify).with("great", + :title => "Guard", + :icon => Pathname.new(File.dirname(__FILE__)).join('../../images/success.png').to_s, + :name => "Guard" + ) + subject.notify 'great', :title => 'Guard' + end + else + it { should be_disabled } end end if linux? - require 'libnotify' - it "uses Libnotify on Linux" do - Libnotify.should_receive(:show).with( - :body => "great", - :summary => 'Guard', - :icon_path => Pathname.new(File.dirname(__FILE__)).join('../../images/success.png').to_s - ) + if libnotify_installed? + it "uses Libnotify on Linux" do + Libnotify.should_receive(:show).with( + :body => "great", + :summary => 'Guard', + :icon_path => Pathname.new(File.dirname(__FILE__)).join('../../images/success.png').to_s + ) + subject.notify 'great', :title => 'Guard' + end + else + it { should be_disabled } + end + end + end + + describe ".turn_off" do + if mac? && growl_installed? + it "does nothing" do + Growl.should_not_receive(:notify) subject.notify 'great', :title => 'Guard' end end - describe ".turn_off" do - before(:each) { subject.turn_off } - - if mac? - require 'growl' - it "does nothing" do - Growl.should_not_receive(:notify) - subject.notify 'great', :title => 'Guard' - end - end - - if linux? - require 'libnotify' - it "does nothing" do - Libnotify.should_not_receive(:show) - subject.notify 'great', :title => 'Guard' - end + if linux? && libnotify_installed? + it "does nothing" do + Libnotify.should_not_receive(:show) + subject.notify 'great', :title => 'Guard' end end - after(:each) { ENV["GUARD_ENV"] = @saved_guard_env } + it { should be_disabled } end end diff --git a/spec/guard_spec.rb b/spec/guard_spec.rb index 0162c06..bf3faa8 100644 --- a/spec/guard_spec.rb +++ b/spec/guard_spec.rb @@ -23,10 +23,22 @@ describe Guard do ::Guard.listener.should be_kind_of(Guard::Listener) end + it "should turn on by default" do + ::Guard::Notifier.should_receive(:turn_on) + ::Guard.setup(:notify => true) + end + it "should turn off notifier if notify option is false" do ::Guard::Notifier.should_receive(:turn_off) ::Guard.setup(:notify => false) end + + it "should turn off notifier if env[GUARD_NOTIFY] is false" do + ::Guard::Notifier.should_receive(:turn_off) + ENV["GUARD_NOTIFY"] = 'false' + ::Guard.setup(:notify => true) + ENV["GUARD_NOTIFY"] = nil + end end describe ".get_guard_class" do @@ -37,8 +49,8 @@ describe Guard do context 'loaded some nested classes' do it "should find and return loaded class" do - Kernel.should_receive(:require) { |file_name| - file_name.should == 'guard/classname' + Guard.should_receive(:try_to_load_gem) { |className| + className.should == 'classname' class Guard::Classname end } @@ -111,7 +123,13 @@ describe Guard do describe ".locate_guard" do it "returns the path of the guard gem" do - Guard.locate_guard('rspec').should == Gem.source_index.find_name("guard-rspec").last.full_gem_path + if Gem::Version.create(Gem::VERSION) >= Gem::Version.create('1.8.0') + gem_location = Gem::Specification.find_by_name("guard-rspec").full_gem_path + else + gem_location = Gem.source_index.find_name("guard-rspec").last.full_gem_path + end + + Guard.locate_guard('rspec').should == gem_location end end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 1520849..f69ed16 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -15,6 +15,7 @@ RSpec.configure do |config| config.run_all_when_everything_filtered = true config.before(:each) do + Guard::Notifier.turn_off @fixture_path = Pathname.new(File.expand_path('../fixtures/', __FILE__)) end diff --git a/spec/support/gems_helper.rb b/spec/support/gems_helper.rb new file mode 100644 index 0000000..2ccf7fe --- /dev/null +++ b/spec/support/gems_helper.rb @@ -0,0 +1,13 @@ +def growl_installed? + require 'growl' + true +rescue LoadError + false +end + +def libnotify_installed? + require 'libnotify' + true +rescue LoadError + false +end \ No newline at end of file