Initial commit
This commit is contained in:
commit
4d3744ff43
11
.gitignore
vendored
Normal file
11
.gitignore
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
pkg/*
|
||||||
|
*.gem
|
||||||
|
.bundle
|
||||||
|
|
||||||
|
## MAC OS
|
||||||
|
.DS_Store
|
||||||
|
.Trashes
|
||||||
|
.com.apple.timemachine.supported
|
||||||
|
.fseventsd
|
||||||
|
Desktop DB
|
||||||
|
Desktop DF
|
45
Gemfile.lock
Normal file
45
Gemfile.lock
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
PATH
|
||||||
|
remote: .
|
||||||
|
specs:
|
||||||
|
guard (0.1.0.beta.1)
|
||||||
|
growl (~> 1.0.3)
|
||||||
|
libnotify (~> 0.1.3)
|
||||||
|
rb-inotify
|
||||||
|
sys-uname (~> 0.8.4)
|
||||||
|
thor (~> 0.14.2)
|
||||||
|
|
||||||
|
GEM
|
||||||
|
remote: http://rubygems.org/
|
||||||
|
specs:
|
||||||
|
diff-lcs (1.1.2)
|
||||||
|
ffi (0.6.3)
|
||||||
|
rake (>= 0.8.7)
|
||||||
|
growl (1.0.3)
|
||||||
|
libnotify (0.1.4)
|
||||||
|
ffi (>= 0.6.2)
|
||||||
|
rake (0.8.7)
|
||||||
|
rb-inotify (0.8.1)
|
||||||
|
ffi (>= 0.5.0)
|
||||||
|
rspec (2.0.0.beta.19)
|
||||||
|
rspec-core (= 2.0.0.beta.19)
|
||||||
|
rspec-expectations (= 2.0.0.beta.19)
|
||||||
|
rspec-mocks (= 2.0.0.beta.19)
|
||||||
|
rspec-core (2.0.0.beta.19)
|
||||||
|
rspec-expectations (2.0.0.beta.19)
|
||||||
|
diff-lcs (>= 1.1.2)
|
||||||
|
rspec-mocks (2.0.0.beta.19)
|
||||||
|
sys-uname (0.8.4)
|
||||||
|
thor (0.14.2)
|
||||||
|
|
||||||
|
PLATFORMS
|
||||||
|
ruby
|
||||||
|
|
||||||
|
DEPENDENCIES
|
||||||
|
bundler (~> 1.0.1)
|
||||||
|
growl (~> 1.0.3)
|
||||||
|
guard!
|
||||||
|
libnotify (~> 0.1.3)
|
||||||
|
rb-inotify
|
||||||
|
rspec (~> 2.0.0.beta.22)
|
||||||
|
sys-uname (~> 0.8.4)
|
||||||
|
thor (~> 0.14.2)
|
25
Guardfile
Normal file
25
Guardfile
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
# guard 'spork', :rspec_port => 9010 do
|
||||||
|
# watch('^config/initializers/.*')
|
||||||
|
# end
|
||||||
|
|
||||||
|
def super
|
||||||
|
`say yo`
|
||||||
|
end
|
||||||
|
|
||||||
|
guard 'rspec', :version => 2 do
|
||||||
|
watch('^spec/(.*)_spec.rb')
|
||||||
|
watch('^lib/(.*).rb') { |m| "spec/#{m[1]}_spec.rb" }
|
||||||
|
watch('^spec/spec_helper.rb') { "spec" }
|
||||||
|
# watch('^spec/spec_helper.rb') { `say hello` }
|
||||||
|
# watch('^spec/(.*)_spec\.rb')
|
||||||
|
# watch('^app/(.*)\.rb') { |m| "spec/#{m[1]}_spec.rb" }
|
||||||
|
# watch('^app/(.*)\.html.erb') { |m| "spec/#{m[1]}_spec.rb" }
|
||||||
|
# watch('^lib/(.*)\.rb') { |m| "spec/lib/#{m[1]}_spec.rb" }
|
||||||
|
# watch('^spec/spec_helper\.rb') { |m| "spec" }
|
||||||
|
# watch('^config/routes\.rb') { |m| "spec/routing" }
|
||||||
|
# watch('^spec/factories\.rb') { |m| "spec/model" }
|
||||||
|
# watch('^app/controllers/application_controller\.rb') { |m| "spec/controllers" }
|
||||||
|
end
|
||||||
|
|
||||||
|
# guard 'livereload' do
|
||||||
|
# end
|
20
LICENSE
Normal file
20
LICENSE
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
Copyright (c) 2010 Thibaud Guillaume-Gentil
|
||||||
|
|
||||||
|
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.
|
3
README.rdoc
Normal file
3
README.rdoc
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
= Guard
|
||||||
|
|
||||||
|
Documentation is coming.
|
6
Rakefile
Normal file
6
Rakefile
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
require 'bundler'
|
||||||
|
Bundler::GemHelper.install_tasks
|
||||||
|
|
||||||
|
require 'rspec/core/rake_task'
|
||||||
|
RSpec::Core::RakeTask.new(:spec)
|
||||||
|
task :default => :spec
|
6
bin/guard
Executable file
6
bin/guard
Executable file
@ -0,0 +1,6 @@
|
|||||||
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
|
require 'guard'
|
||||||
|
require 'guard/cli'
|
||||||
|
|
||||||
|
Guard::CLI.start
|
25
bin/inotify_watch
Executable file
25
bin/inotify_watch
Executable file
@ -0,0 +1,25 @@
|
|||||||
|
#!/usr/bin/env ruby
|
||||||
|
require 'rubygems'
|
||||||
|
require 'rb-inotify'
|
||||||
|
|
||||||
|
folders = Array.new
|
||||||
|
notifier = INotify::Notifier.new
|
||||||
|
|
||||||
|
notifier.watch(ARGV.first || '.', :modify, :recursive) do |event|
|
||||||
|
dir = File.expand_path(File.dirname(event.absolute_name)) + '/'
|
||||||
|
if !folders.include?(dir)
|
||||||
|
folders << dir
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
while true do
|
||||||
|
notifier.process
|
||||||
|
|
||||||
|
if !folders.empty?
|
||||||
|
$stdout.puts folders.join(' ')
|
||||||
|
$stdout.flush
|
||||||
|
folders.clear
|
||||||
|
end
|
||||||
|
|
||||||
|
sleep(0.1)
|
||||||
|
end
|
18
ext/extconf.rb
Normal file
18
ext/extconf.rb
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Workaround to make Rubygems believe it builds a native gem
|
||||||
|
require 'mkmf'
|
||||||
|
create_makefile('none')
|
||||||
|
|
||||||
|
if `uname -s`.chomp == 'Darwin'
|
||||||
|
gem_root = File.expand_path(File.join('..'))
|
||||||
|
darwin_verion = `uname -r`.to_i
|
||||||
|
sdk_verion = { 9 => '10.5', 10 => '10.6', 11 => '10.7' }[darwin_verion]
|
||||||
|
|
||||||
|
raise "Darwin #{darwin_verion} is not supported" unless sdk_verion
|
||||||
|
|
||||||
|
# Compile the actual fsevent_watch binary
|
||||||
|
system("CFLAGS='-isysroot /Developer/SDKs/MacOSX#{sdk_verion}.sdk -mmacosx-version-min=#{sdk_verion}' /usr/bin/gcc -framework CoreServices -o '#{gem_root}/bin/fsevent_watch' fsevent/fsevent_watch.c")
|
||||||
|
|
||||||
|
unless File.executable?("#{gem_root}/bin/fsevent_watch")
|
||||||
|
raise "Compilation of fsevent_watch failed (see README)"
|
||||||
|
end
|
||||||
|
end
|
44
ext/fsevent/fsevent_watch.c
Normal file
44
ext/fsevent/fsevent_watch.c
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#include <CoreServices/CoreServices.h>
|
||||||
|
|
||||||
|
void callback(ConstFSEventStreamRef streamRef,
|
||||||
|
void *clientCallBackInfo,
|
||||||
|
size_t numEvents,
|
||||||
|
void *eventPaths,
|
||||||
|
const FSEventStreamEventFlags eventFlags[],
|
||||||
|
const FSEventStreamEventId eventIds[]
|
||||||
|
) {
|
||||||
|
// Print modified dirs
|
||||||
|
int i;
|
||||||
|
char **paths = eventPaths;
|
||||||
|
for (i = 0; i < numEvents; i++) {
|
||||||
|
printf("%s", paths[i]);
|
||||||
|
printf(" ");
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main (int argc, const char * argv[]) {
|
||||||
|
// Create event stream
|
||||||
|
CFStringRef pathToWatch = CFStringCreateWithCString(kCFAllocatorDefault, argv[1], kCFStringEncodingUTF8);
|
||||||
|
CFArrayRef pathsToWatch = CFArrayCreate(NULL, (const void **)&pathToWatch, 1, NULL);
|
||||||
|
void *callbackInfo = NULL;
|
||||||
|
FSEventStreamRef stream;
|
||||||
|
CFAbsoluteTime latency = 0.1;
|
||||||
|
stream = FSEventStreamCreate(
|
||||||
|
kCFAllocatorDefault,
|
||||||
|
callback,
|
||||||
|
callbackInfo,
|
||||||
|
pathsToWatch,
|
||||||
|
kFSEventStreamEventIdSinceNow,
|
||||||
|
latency,
|
||||||
|
kFSEventStreamCreateFlagNone
|
||||||
|
);
|
||||||
|
|
||||||
|
// Add stream to run loop
|
||||||
|
FSEventStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
|
||||||
|
FSEventStreamStart(stream);
|
||||||
|
CFRunLoopRun();
|
||||||
|
|
||||||
|
return 2;
|
||||||
|
}
|
32
guard.gemspec
Normal file
32
guard.gemspec
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
# -*- encoding: utf-8 -*-
|
||||||
|
$:.push File.expand_path('../lib', __FILE__)
|
||||||
|
require 'guard/version'
|
||||||
|
|
||||||
|
Gem::Specification.new do |s|
|
||||||
|
s.name = 'guard'
|
||||||
|
s.version = Guard::VERSION
|
||||||
|
s.platform = Gem::Platform::RUBY
|
||||||
|
s.authors = ['Thibaud Guillaume-Gentil']
|
||||||
|
s.email = ['thibaud@thibaud.me']
|
||||||
|
s.homepage = 'http://rubygems.org/gems/guard'
|
||||||
|
s.summary = 'Guard keep an eye on your files event'
|
||||||
|
s.description = 'Guard is a command line tool to easly manage script launch when your files change'
|
||||||
|
|
||||||
|
s.rubyforge_project = 'guard'
|
||||||
|
|
||||||
|
s.add_development_dependency 'bundler', '~> 1.0.1'
|
||||||
|
s.add_development_dependency 'rspec', '~> 2.0.0.beta.22'
|
||||||
|
|
||||||
|
s.add_dependency 'thor', '~> 0.14.2'
|
||||||
|
s.add_dependency 'sys-uname', '~> 0.8.4'
|
||||||
|
# Mac OS X
|
||||||
|
s.add_dependency 'growl', '~> 1.0.3'
|
||||||
|
# Linux
|
||||||
|
s.add_dependency 'rb-inotify'
|
||||||
|
s.add_dependency 'libnotify', '~> 0.1.3'
|
||||||
|
|
||||||
|
s.files = Dir.glob('{bin,images,lib,ext}/**/*') + %w[LICENSE README.rdoc]
|
||||||
|
s.extensions = ['ext/extconf.rb']
|
||||||
|
s.executable = 'guard'
|
||||||
|
s.require_path = 'lib'
|
||||||
|
end
|
BIN
images/failed.png
Normal file
BIN
images/failed.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.9 KiB |
BIN
images/pending.png
Executable file
BIN
images/pending.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 3.0 KiB |
BIN
images/success.png
Normal file
BIN
images/success.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.1 KiB |
49
lib/guard.rb
Normal file
49
lib/guard.rb
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
module Guard
|
||||||
|
|
||||||
|
autoload :UI, 'guard/ui'
|
||||||
|
autoload :Dsl, 'guard/dsl'
|
||||||
|
autoload :Interactor, 'guard/interactor'
|
||||||
|
autoload :Listener, 'guard/listener'
|
||||||
|
autoload :Watcher, 'guard/watcher'
|
||||||
|
autoload :Notifier, 'guard/notifier'
|
||||||
|
|
||||||
|
class << self
|
||||||
|
attr_accessor :options, :guards, :listener
|
||||||
|
|
||||||
|
def start(options = {})
|
||||||
|
@options = options
|
||||||
|
@listener = Listener.new
|
||||||
|
@guards = []
|
||||||
|
|
||||||
|
Dsl.evaluate_guardfile
|
||||||
|
Interactor.init_signal_traps
|
||||||
|
|
||||||
|
listener.on_change do |files|
|
||||||
|
run do
|
||||||
|
guards.each do |guard|
|
||||||
|
paths = Watcher.match_files(guard, files)
|
||||||
|
guard.run_on_change(paths) unless paths.empty?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
UI.info "Guard is now watching at '#{Dir.pwd}'"
|
||||||
|
guards.each(&:start)
|
||||||
|
listener.start
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_guard(name, watchers = [], options = {})
|
||||||
|
require "guard/#{name.downcase}"
|
||||||
|
guard_class = ObjectSpace.each_object(Class).detect { |c| c.to_s.downcase.match "^guard::#{name.downcase}" }
|
||||||
|
@guards << guard_class.new(watchers, options)
|
||||||
|
end
|
||||||
|
|
||||||
|
def run
|
||||||
|
listener.stop
|
||||||
|
yield
|
||||||
|
listener.start
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
20
lib/guard/cli.rb
Normal file
20
lib/guard/cli.rb
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
require 'thor'
|
||||||
|
require 'guard/version'
|
||||||
|
|
||||||
|
module Guard
|
||||||
|
class CLI < Thor
|
||||||
|
default_task :start
|
||||||
|
|
||||||
|
desc "start", "Starts guard"
|
||||||
|
method_option :clear, :type => :boolean, :default => false, :aliases => '-c', :banner => "Auto clear shell after each change"
|
||||||
|
def start
|
||||||
|
Guard.start(options)
|
||||||
|
end
|
||||||
|
|
||||||
|
desc "version", "Prints the guard's version information"
|
||||||
|
def version
|
||||||
|
Guard::UI.info "Guard version #{Guard::VERSION}"
|
||||||
|
end
|
||||||
|
map %w(-v --version) => :version
|
||||||
|
end
|
||||||
|
end
|
24
lib/guard/dsl.rb
Normal file
24
lib/guard/dsl.rb
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
module Guard
|
||||||
|
class Dsl
|
||||||
|
|
||||||
|
def self.evaluate_guardfile
|
||||||
|
guardfile = "#{Dir.pwd}/Guardfile"
|
||||||
|
dsl = new
|
||||||
|
dsl.instance_eval(File.read(guardfile.to_s), guardfile.to_s, 1)
|
||||||
|
rescue
|
||||||
|
UI.error "Guardfile not found or invalid"
|
||||||
|
exit 1
|
||||||
|
end
|
||||||
|
|
||||||
|
def guard(name, options = {}, &definition)
|
||||||
|
@watchers = []
|
||||||
|
definition.call
|
||||||
|
Guard.add_guard(name, @watchers, options)
|
||||||
|
end
|
||||||
|
|
||||||
|
def watch(pattern, &action)
|
||||||
|
@watchers << Guard::Watcher.new(pattern, action)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
34
lib/guard/guard.rb
Normal file
34
lib/guard/guard.rb
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
module Guard
|
||||||
|
class Guard
|
||||||
|
attr_accessor :watchers, :options
|
||||||
|
|
||||||
|
def initialize(watchers = [], options = {})
|
||||||
|
@watchers, @options = watchers, options
|
||||||
|
end
|
||||||
|
|
||||||
|
# ================
|
||||||
|
# = Guard method =
|
||||||
|
# ================
|
||||||
|
|
||||||
|
def start
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def stop
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def reload
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def run_all
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def run_on_change(paths)
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
32
lib/guard/interactor.rb
Normal file
32
lib/guard/interactor.rb
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
module Guard
|
||||||
|
module Interactor
|
||||||
|
|
||||||
|
def self.init_signal_traps
|
||||||
|
# Run all (Ctrl-\)
|
||||||
|
Signal.trap('QUIT') do
|
||||||
|
::Guard.run do
|
||||||
|
::Guard.guards.each(&:run_all)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Stop (Ctrl-C)
|
||||||
|
Signal.trap('INT') do
|
||||||
|
::Guard.listener.stop
|
||||||
|
if ::Guard.guards.all?(&:stop)
|
||||||
|
UI.info "Bye bye...", :reset => true, :clear => false
|
||||||
|
abort("\n")
|
||||||
|
else
|
||||||
|
::Guard.listener.start
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Reload (Ctrl-Z)
|
||||||
|
Signal.trap('TSTP') do
|
||||||
|
::Guard.run do
|
||||||
|
::Guard.guards.each(&:reload)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
64
lib/guard/listener.rb
Normal file
64
lib/guard/listener.rb
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
require 'sys/uname'
|
||||||
|
|
||||||
|
module Guard
|
||||||
|
class Listener
|
||||||
|
attr_reader :last_event, :callback, :pipe
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
update_last_event
|
||||||
|
end
|
||||||
|
|
||||||
|
def on_change(&block)
|
||||||
|
@callback = block
|
||||||
|
end
|
||||||
|
|
||||||
|
def start
|
||||||
|
@pipe = case Sys::Uname.sysname
|
||||||
|
when 'Darwin'
|
||||||
|
IO.popen("#{bin_path}/fsevent_watch .")
|
||||||
|
when 'Linux'
|
||||||
|
IO.popen("#{bin_path}/inotify_watch .")
|
||||||
|
end
|
||||||
|
watch_change
|
||||||
|
end
|
||||||
|
|
||||||
|
def stop
|
||||||
|
Process.kill("HUP", pipe.pid) if pipe
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def watch_change
|
||||||
|
while !pipe.eof?
|
||||||
|
if line = pipe.readline
|
||||||
|
modified_dirs = line.split(" ")
|
||||||
|
files = modified_files(modified_dirs)
|
||||||
|
update_last_event
|
||||||
|
callback.call(files)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def modified_files(dirs)
|
||||||
|
files = potentially_modified_files(dirs).select { |file| recent_file?(file) }
|
||||||
|
files.map! { |file| file.gsub("#{Dir.pwd}/", '') }
|
||||||
|
end
|
||||||
|
|
||||||
|
def potentially_modified_files(dirs)
|
||||||
|
Dir.glob(dirs.map { |dir| "#{dir}*" })
|
||||||
|
end
|
||||||
|
|
||||||
|
def recent_file?(file)
|
||||||
|
File.mtime(file) >= last_event
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_last_event
|
||||||
|
@last_event = Time.now
|
||||||
|
end
|
||||||
|
|
||||||
|
def bin_path
|
||||||
|
File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'bin'))
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
45
lib/guard/notifier.rb
Normal file
45
lib/guard/notifier.rb
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
require 'sys/uname'
|
||||||
|
require 'pathname'
|
||||||
|
|
||||||
|
case Sys::Uname.sysname
|
||||||
|
when 'Darwin'
|
||||||
|
require 'growl'
|
||||||
|
when 'Linux'
|
||||||
|
require 'libnotify'
|
||||||
|
end
|
||||||
|
|
||||||
|
module Guard
|
||||||
|
module Notifier
|
||||||
|
|
||||||
|
def self.notify(message, options = {})
|
||||||
|
unless ENV["GUARD_ENV"] == "test"
|
||||||
|
image = options[:image] || :success
|
||||||
|
title = options[:title] || "Guard"
|
||||||
|
case Sys::Uname.sysname
|
||||||
|
when 'Darwin'
|
||||||
|
Growl.notify message, :title => title, :icon => image_path(image), :name => "Guard"
|
||||||
|
when 'Linux'
|
||||||
|
Libnotify.show :body => message, :summary => title, :icon_path => image_path(image)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def self.image_path(image)
|
||||||
|
images_path = Pathname.new(File.dirname(__FILE__)).join('../../images')
|
||||||
|
case image
|
||||||
|
when :failed
|
||||||
|
images_path.join("failed.png").to_s
|
||||||
|
when :pending
|
||||||
|
images_path.join("pending.png").to_s
|
||||||
|
when :success
|
||||||
|
images_path.join("success.png").to_s
|
||||||
|
else
|
||||||
|
# path given
|
||||||
|
image
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
37
lib/guard/ui.rb
Normal file
37
lib/guard/ui.rb
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
module Guard
|
||||||
|
module UI
|
||||||
|
class << self
|
||||||
|
|
||||||
|
def info(message, options = {})
|
||||||
|
unless ENV["GUARD_ENV"] == "test"
|
||||||
|
reset_line if options[:reset]
|
||||||
|
clear if options.key?(:clear) ? options[:clear] : ::Guard.options[:clear]
|
||||||
|
puts reset_color(message) if message != ''
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def error(message)
|
||||||
|
puts "ERROR: #{message}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def reset_line
|
||||||
|
print "\r\e "
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def clear
|
||||||
|
system("clear;")
|
||||||
|
end
|
||||||
|
|
||||||
|
def reset_color(text)
|
||||||
|
color(text, "\e[0m")
|
||||||
|
end
|
||||||
|
|
||||||
|
def color(text, color_code)
|
||||||
|
"#{color_code}#{text}\e[0m"
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
3
lib/guard/version.rb
Normal file
3
lib/guard/version.rb
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
module Guard
|
||||||
|
VERSION = "0.1.0.beta.1"
|
||||||
|
end
|
35
lib/guard/watcher.rb
Normal file
35
lib/guard/watcher.rb
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
module Guard
|
||||||
|
class Watcher
|
||||||
|
attr_accessor :pattern, :action
|
||||||
|
|
||||||
|
def initialize(pattern, action = nil)
|
||||||
|
@pattern, @action = pattern, action
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.match_files(guard, files)
|
||||||
|
guard.watchers.inject([]) do |paths, watcher|
|
||||||
|
files.each do |file|
|
||||||
|
if matches = file.match(watcher.pattern)
|
||||||
|
if watcher.action
|
||||||
|
begin
|
||||||
|
case watcher.action.arity
|
||||||
|
when -1
|
||||||
|
result = watcher.action.call
|
||||||
|
when 1
|
||||||
|
result = watcher.action.call(matches)
|
||||||
|
end
|
||||||
|
rescue
|
||||||
|
UI.info "Problem with watch action"
|
||||||
|
end
|
||||||
|
paths << result if result.is_a?(String) && result != ''
|
||||||
|
else
|
||||||
|
paths << matches[0]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
paths
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
25
spec/guard/listener_spec.rb
Normal file
25
spec/guard/listener_spec.rb
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Guard::Listener do
|
||||||
|
subject { described_class.new }
|
||||||
|
|
||||||
|
its(:last_event) { should < Time.now }
|
||||||
|
|
||||||
|
describe "start" do
|
||||||
|
let(:pipe_mock) { mock("pipe", :eof? => true) }
|
||||||
|
|
||||||
|
it "should use fsevent_watch on Mac OS X" do
|
||||||
|
Sys::Uname.stub(:sysname).and_return('Darwin')
|
||||||
|
IO.should_receive(:popen).with(/.*\/fsevent_watch\s\./).and_return(pipe_mock)
|
||||||
|
subject.start
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should use inotify_watch on Linux" do
|
||||||
|
Sys::Uname.stub(:sysname).and_return('Linux')
|
||||||
|
IO.should_receive(:popen).with(/.*\/inotify_watch\s\./).and_return(pipe_mock)
|
||||||
|
subject.start
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
32
spec/guard/notifier_spec.rb
Normal file
32
spec/guard/notifier_spec.rb
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Guard::Notifier do
|
||||||
|
subject { Guard::Notifier }
|
||||||
|
|
||||||
|
describe "notify" do
|
||||||
|
before(:each) { ENV["GUARD_ENV"] = 'special_test' }
|
||||||
|
|
||||||
|
it "should use Growl on Mac OS X" do
|
||||||
|
Sys::Uname.stub(:sysname).and_return('Darwin')
|
||||||
|
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
|
||||||
|
|
||||||
|
# it "should use Libnotify on Linux" do
|
||||||
|
# Sys::Uname.stub(:sysname).and_return('Linux')
|
||||||
|
# Libnotify.should_receive(:show).with(
|
||||||
|
# :body => "great",
|
||||||
|
# :summary => 'Guard',
|
||||||
|
# :icon_path => 'image/path'
|
||||||
|
# )
|
||||||
|
# subject.notify 'great', 'Guard', 'image/path'
|
||||||
|
# end
|
||||||
|
|
||||||
|
after(:each) { ENV["GUARD_ENV"] = 'test' }
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
17
spec/spec_helper.rb
Normal file
17
spec/spec_helper.rb
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
require 'rubygems'
|
||||||
|
require 'guard'
|
||||||
|
require 'rspec'
|
||||||
|
|
||||||
|
fixture_path = Pathname.new(File.expand_path('../fixtures/', __FILE__))
|
||||||
|
|
||||||
|
RSpec.configure do |config|
|
||||||
|
config.color_enabled = true
|
||||||
|
|
||||||
|
config.before(:each) do
|
||||||
|
ENV["GUARD_ENV"] = 'test'
|
||||||
|
@fixture_path = fixture_path
|
||||||
|
end
|
||||||
|
|
||||||
|
config.after(:all) do
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue
Block a user