guard 0.1.1 → 0.2.0.beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.rdoc CHANGED
@@ -4,17 +4,17 @@ Guard is a command line tool to easly handle events on files modifications.
4
4
 
5
5
  == Features
6
6
 
7
- - FSEvent support on Mac OS X (without RubyCocoa!)
8
- - Inotify support on Linux (beta)
9
- - Super fast change detection
7
+ - FSEvent support on Mac OS X 10.5+ (without RubyCocoa!, please install {rb-fsevent, >= 0.3.2}[https://rubygems.org/gems/rb-fsevent])
8
+ - Inotify support on Linux (beta, please install {rb-inotify, >= 0.5.1}[https://rubygems.org/gems/rb-inotify])
9
+ - Polling for others (help us to support more systems)
10
+ - Super fast change detection (when polling not used)
10
11
  - Automatic files modifications detection (even new files are detected)
11
12
  - Growl notification (please install {growlnotify}[http://growl.info/documentation/growlnotify.php])
12
13
  - Libnotify notification
14
+ - Tested on Ruby 1.8.7 & 1.9.2.
13
15
 
14
16
  == Install
15
17
 
16
- Only Mac OS X (10.5+) & Linux are supported. Tested on Ruby 1.8.7 & 1.9.2.
17
-
18
18
  Install the gem:
19
19
 
20
20
  gem install guard
@@ -35,9 +35,13 @@ Just launch Guard inside your ruby/rails project with:
35
35
 
36
36
  guard
37
37
 
38
+ Shell can be cleared after each change with:
39
+
40
+ guard -c
41
+
38
42
  Options list is available with:
39
43
 
40
- guard help
44
+ guard help [TASK]
41
45
 
42
46
  Signal handlers are used to interact with Guard:
43
47
 
@@ -48,11 +52,11 @@ Signal handlers are used to interact with Guard:
48
52
  == Available Guards
49
53
 
50
54
  - {guard-rspec}[http://github.com/guard/guard-rspec]
55
+ - {guard-livereload}[http://github.com/guard/guard-livereload]
51
56
 
52
57
  guard ideas:
53
58
 
54
59
  - guard-spork
55
- - guard-livereload
56
60
  - guard-cucumber
57
61
  - guard-test
58
62
  - guard-sass
@@ -65,7 +69,7 @@ Add it to your Gemfile (inside test group):
65
69
 
66
70
  gem '<guard-name>'
67
71
 
68
- Add guard definition to your Guardfile with:
72
+ Add guard definition to your Guardfile by running this command:
69
73
 
70
74
  guard init <guard-name>
71
75
 
data/lib/guard.rb CHANGED
@@ -14,7 +14,7 @@ module Guard
14
14
 
15
15
  def start(options = {})
16
16
  @options = options
17
- @listener = Listener.new
17
+ @listener = Listener.init
18
18
  @guards = []
19
19
 
20
20
  Dsl.evaluate_guardfile
@@ -59,7 +59,7 @@ module Guard
59
59
 
60
60
  def run
61
61
  listener.stop
62
- UI.clear if options[:clear]
62
+ UI. clear if options[:clear]
63
63
  yield
64
64
  listener.start
65
65
  end
@@ -1,51 +1,39 @@
1
- require 'sys/uname'
1
+ require 'rbconfig'
2
2
 
3
3
  module Guard
4
+
5
+ autoload :Darwin, 'guard/listeners/darwin'
6
+ autoload :Linux, 'guard/listeners/linux'
7
+ autoload :Polling, 'guard/listeners/polling'
8
+
4
9
  class Listener
5
- attr_reader :last_event, :callback, :pipe
6
-
7
- def initialize
8
- update_last_event
9
- end
10
-
11
- def on_change(&block)
12
- @callback = block
13
- end
14
-
15
- def start
16
- @pipe = case Sys::Uname.sysname
17
- when 'Darwin'
18
- IO.popen("#{bin_path}/fsevent_watch .")
19
- when 'Linux'
20
- IO.popen("#{bin_path}/inotify_watch .")
10
+ attr_reader :last_event
11
+
12
+ def self.init
13
+ if mac? && Darwin.usable?
14
+ Darwin.new
15
+ elsif linux? && Linux.usable?
16
+ Linux.new
17
+ else
18
+ UI.info "Using polling (Please help us to support your system better than that.)"
19
+ Polling.new
21
20
  end
22
- watch_change
23
21
  end
24
22
 
25
- def stop
26
- Process.kill("HUP", pipe.pid) if pipe
23
+ def initialize
24
+ update_last_event
27
25
  end
28
26
 
29
27
  private
30
28
 
31
- def watch_change
32
- while !pipe.eof?
33
- if line = pipe.readline
34
- modified_dirs = line.split(" ")
35
- files = modified_files(modified_dirs)
36
- update_last_event
37
- callback.call(files)
38
- end
39
- end
40
- end
41
-
42
- def modified_files(dirs)
43
- files = potentially_modified_files(dirs).select { |file| recent_file?(file) }
29
+ def modified_files(dirs, options = {})
30
+ files = potentially_modified_files(dirs, options).select { |path| File.file?(path) && recent_file?(path) }
44
31
  files.map! { |file| file.gsub("#{Dir.pwd}/", '') }
45
32
  end
46
33
 
47
- def potentially_modified_files(dirs)
48
- Dir.glob(dirs.map { |dir| "#{dir}*" })
34
+ def potentially_modified_files(dirs, options = {})
35
+ match = options[:all] ? "**/*" : "*"
36
+ Dir.glob(dirs.map { |dir| "#{dir}#{match}" })
49
37
  end
50
38
 
51
39
  def recent_file?(file)
@@ -58,8 +46,12 @@ module Guard
58
46
  @last_event = Time.now
59
47
  end
60
48
 
61
- def bin_path
62
- File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'bin'))
49
+ def self.mac?
50
+ Config::CONFIG['target_os'] =~ /darwin/i
51
+ end
52
+
53
+ def self.linux?
54
+ Config::CONFIG['target_os'] =~ /linux/i
63
55
  end
64
56
 
65
57
  end
@@ -0,0 +1,40 @@
1
+ module Guard
2
+ class Darwin < Listener
3
+ attr_reader :fsevent
4
+
5
+ def initialize
6
+ super
7
+ @fsevent = FSEvent.new
8
+ end
9
+
10
+ def on_change(&callback)
11
+ @fsevent.watch Dir.pwd do |modified_dirs|
12
+ files = modified_files(modified_dirs)
13
+ update_last_event
14
+ callback.call(files)
15
+ end
16
+ end
17
+
18
+ def start
19
+ @fsevent.run
20
+ end
21
+
22
+ def stop
23
+ @fsevent.stop
24
+ end
25
+
26
+ def self.usable?
27
+ require 'rb-fsevent'
28
+ if !defined?(FSEvent::VERSION) || Gem::Version.new(FSEvent::VERSION) < Gem::Version.new('0.3.2')
29
+ UI.info "Please update rb-fsevent (>= 0.3.2)"
30
+ false
31
+ else
32
+ true
33
+ end
34
+ rescue LoadError
35
+ UI.info "Please install rb-fsevent gem for Mac OSX FSEvents support"
36
+ false
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,58 @@
1
+ module Guard
2
+ class Linux < Listener
3
+ attr_reader :inotify, :files, :latency, :callback
4
+
5
+ def initialize
6
+ @inotify = INotify::Notifier.new
7
+ @files = []
8
+ @latency = 0.5
9
+ end
10
+
11
+ def on_change(&callback)
12
+ @callback = callback
13
+ inotify.watch(Dir.pwd, :recursive, :attrib, :modify, :create) do |event|
14
+ unless event.name == "" # Event on root directory
15
+ @files << event.absolute_name
16
+ end
17
+ end
18
+ end
19
+
20
+ def start
21
+ @stop = false
22
+ watch_change
23
+ end
24
+
25
+ def stop
26
+ @stop = true
27
+ inotify.stop
28
+ end
29
+
30
+ def self.usable?
31
+ require 'rb-inotify'
32
+ if !defined?(INotify::VERSION) || Gem::Version.new(INotify::VERSION) < Gem::Version.new('0.5.1')
33
+ UI.info "Please update rb-inotify (>= 0.5.1)"
34
+ false
35
+ else
36
+ true
37
+ end
38
+ rescue LoadError
39
+ UI.info "Please install rb-inotify gem for Linux inotify support"
40
+ false
41
+ end
42
+
43
+ private
44
+
45
+ def watch_change
46
+ while !@stop
47
+ inotify.process
48
+ unless files.empty?
49
+ files.map! { |file| file.gsub("#{Dir.pwd}/", '') }
50
+ callback.call(files)
51
+ files.clear
52
+ end
53
+ sleep latency
54
+ end
55
+ end
56
+
57
+ end
58
+ end
@@ -0,0 +1,37 @@
1
+ module Guard
2
+ class Polling < Listener
3
+ attr_reader :callback, :latency
4
+
5
+ def initialize
6
+ super
7
+ @latency = 1.5
8
+ end
9
+
10
+ def on_change(&callback)
11
+ @callback = callback
12
+ end
13
+
14
+ def start
15
+ @stop = false
16
+ watch_change
17
+ end
18
+
19
+ def stop
20
+ @stop = true
21
+ end
22
+
23
+ private
24
+
25
+ def watch_change
26
+ while !@stop
27
+ start = Time.now.to_f
28
+ files = modified_files([Dir.pwd + '/'], :all => true)
29
+ update_last_event
30
+ callback.call(files) unless files.empty?
31
+ nap_time = latency - (Time.now.to_f - start)
32
+ sleep(nap_time) if nap_time > 0
33
+ end
34
+ end
35
+
36
+ end
37
+ end
@@ -1,10 +1,10 @@
1
- require 'sys/uname'
1
+ require 'rbconfig'
2
2
  require 'pathname'
3
3
 
4
- case Sys::Uname.sysname
5
- when 'Darwin'
4
+ case Config::CONFIG['target_os']
5
+ when /darwin/i
6
6
  require 'growl'
7
- when 'Linux'
7
+ when /linux/i
8
8
  require 'libnotify'
9
9
  end
10
10
 
@@ -15,10 +15,10 @@ module Guard
15
15
  unless ENV["GUARD_ENV"] == "test"
16
16
  image = options[:image] || :success
17
17
  title = options[:title] || "Guard"
18
- case Sys::Uname.sysname
19
- when 'Darwin'
18
+ case Config::CONFIG['target_os']
19
+ when /darwin/i
20
20
  Growl.notify message, :title => title, :icon => image_path(image), :name => "Guard"
21
- when 'Linux'
21
+ when /linux/i
22
22
  Libnotify.show :body => message, :summary => title, :icon_path => image_path(image)
23
23
  end
24
24
  end
data/lib/guard/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Guard
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.0.beta.1"
3
3
  end
metadata CHANGED
@@ -1,13 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: guard
3
3
  version: !ruby/object:Gem::Version
4
- hash: 25
5
- prerelease: false
4
+ hash: 62196353
5
+ prerelease: true
6
6
  segments:
7
7
  - 0
8
+ - 2
9
+ - 0
10
+ - beta
8
11
  - 1
9
- - 1
10
- version: 0.1.1
12
+ version: 0.2.0.beta.1
11
13
  platform: ruby
12
14
  authors:
13
15
  - Thibaud Guillaume-Gentil
@@ -15,7 +17,7 @@ autorequire:
15
17
  bindir: bin
16
18
  cert_chain: []
17
19
 
18
- date: 2010-10-10 00:00:00 +02:00
20
+ date: 2010-10-17 00:00:00 +02:00
19
21
  default_executable:
20
22
  dependencies:
21
23
  - !ruby/object:Gem::Dependency
@@ -26,13 +28,12 @@ dependencies:
26
28
  requirements:
27
29
  - - ~>
28
30
  - !ruby/object:Gem::Version
29
- hash: 7712058
31
+ hash: 15
30
32
  segments:
31
33
  - 2
32
34
  - 0
33
35
  - 0
34
- - rc
35
- version: 2.0.0.rc
36
+ version: 2.0.0
36
37
  type: :development
37
38
  version_requirements: *id001
38
39
  - !ruby/object:Gem::Dependency
@@ -43,12 +44,12 @@ dependencies:
43
44
  requirements:
44
45
  - - ~>
45
46
  - !ruby/object:Gem::Version
46
- hash: 27
47
+ hash: 29
47
48
  segments:
48
49
  - 0
49
50
  - 1
50
- - 0
51
- version: 0.1.0
51
+ - 3
52
+ version: 0.1.3
52
53
  type: :development
53
54
  version_requirements: *id002
54
55
  - !ruby/object:Gem::Dependency
@@ -83,26 +84,10 @@ dependencies:
83
84
  version: 0.14.3
84
85
  type: :runtime
85
86
  version_requirements: *id004
86
- - !ruby/object:Gem::Dependency
87
- name: sys-uname
88
- prerelease: false
89
- requirement: &id005 !ruby/object:Gem::Requirement
90
- none: false
91
- requirements:
92
- - - ~>
93
- - !ruby/object:Gem::Version
94
- hash: 55
95
- segments:
96
- - 0
97
- - 8
98
- - 4
99
- version: 0.8.4
100
- type: :runtime
101
- version_requirements: *id005
102
87
  - !ruby/object:Gem::Dependency
103
88
  name: growl
104
89
  prerelease: false
105
- requirement: &id006 !ruby/object:Gem::Requirement
90
+ requirement: &id005 !ruby/object:Gem::Requirement
106
91
  none: false
107
92
  requirements:
108
93
  - - ~>
@@ -114,27 +99,11 @@ dependencies:
114
99
  - 3
115
100
  version: 1.0.3
116
101
  type: :runtime
117
- version_requirements: *id006
118
- - !ruby/object:Gem::Dependency
119
- name: rb-inotify
120
- prerelease: false
121
- requirement: &id007 !ruby/object:Gem::Requirement
122
- none: false
123
- requirements:
124
- - - ~>
125
- - !ruby/object:Gem::Version
126
- hash: 61
127
- segments:
128
- - 0
129
- - 8
130
- - 1
131
- version: 0.8.1
132
- type: :runtime
133
- version_requirements: *id007
102
+ version_requirements: *id005
134
103
  - !ruby/object:Gem::Dependency
135
104
  name: libnotify
136
105
  prerelease: false
137
- requirement: &id008 !ruby/object:Gem::Requirement
106
+ requirement: &id006 !ruby/object:Gem::Requirement
138
107
  none: false
139
108
  requirements:
140
109
  - - ~>
@@ -146,19 +115,18 @@ dependencies:
146
115
  - 3
147
116
  version: 0.1.3
148
117
  type: :runtime
149
- version_requirements: *id008
118
+ version_requirements: *id006
150
119
  description: Guard is a command line tool to easily handle events on files modifications.
151
120
  email:
152
121
  - thibaud@thibaud.me
153
122
  executables:
154
123
  - guard
155
- extensions:
156
- - ext/extconf.rb
124
+ extensions: []
125
+
157
126
  extra_rdoc_files: []
158
127
 
159
128
  files:
160
129
  - bin/guard
161
- - bin/inotify_watch
162
130
  - images/failed.png
163
131
  - images/pending.png
164
132
  - images/success.png
@@ -167,14 +135,15 @@ files:
167
135
  - lib/guard/guard.rb
168
136
  - lib/guard/interactor.rb
169
137
  - lib/guard/listener.rb
138
+ - lib/guard/listeners/darwin.rb
139
+ - lib/guard/listeners/linux.rb
140
+ - lib/guard/listeners/polling.rb
170
141
  - lib/guard/notifier.rb
171
142
  - lib/guard/templates/Guardfile
172
143
  - lib/guard/ui.rb
173
144
  - lib/guard/version.rb
174
145
  - lib/guard/watcher.rb
175
146
  - lib/guard.rb
176
- - ext/extconf.rb
177
- - ext/fsevent/fsevent_watch.c
178
147
  - LICENSE
179
148
  - README.rdoc
180
149
  has_rdoc: true
data/bin/inotify_watch DELETED
@@ -1,25 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require 'rubygems'
3
- require 'rb-inotify'
4
-
5
- folders = Array.new
6
- notifier = INotify::Notifier.new
7
-
8
- notifier.watch(ARGV.first || '.', :modify, :recursive) do |event|
9
- dir = File.expand_path(File.dirname(event.absolute_name)) + '/'
10
- if !folders.include?(dir)
11
- folders << dir
12
- end
13
- end
14
-
15
- while true do
16
- notifier.process
17
-
18
- if !folders.empty?
19
- $stdout.puts folders.join(' ')
20
- $stdout.flush
21
- folders.clear
22
- end
23
-
24
- sleep(0.1)
25
- end
data/ext/extconf.rb DELETED
@@ -1,18 +0,0 @@
1
- # Workaround to make Rubygems believe it builds a native gem
2
- require 'mkmf'
3
- create_makefile('none')
4
-
5
- if `uname -s`.chomp == 'Darwin'
6
- gem_root = File.expand_path(File.join('..'))
7
- darwin_verion = `uname -r`.to_i
8
- sdk_verion = { 9 => '10.5', 10 => '10.6', 11 => '10.7' }[darwin_verion]
9
-
10
- raise "Darwin #{darwin_verion} is not supported" unless sdk_verion
11
-
12
- # Compile the actual fsevent_watch binary
13
- 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")
14
-
15
- unless File.executable?("#{gem_root}/bin/fsevent_watch")
16
- raise "Compilation of fsevent_watch failed (see README)"
17
- end
18
- end
@@ -1,44 +0,0 @@
1
- #include <CoreServices/CoreServices.h>
2
-
3
- void callback(ConstFSEventStreamRef streamRef,
4
- void *clientCallBackInfo,
5
- size_t numEvents,
6
- void *eventPaths,
7
- const FSEventStreamEventFlags eventFlags[],
8
- const FSEventStreamEventId eventIds[]
9
- ) {
10
- // Print modified dirs
11
- int i;
12
- char **paths = eventPaths;
13
- for (i = 0; i < numEvents; i++) {
14
- printf("%s", paths[i]);
15
- printf(" ");
16
- }
17
- printf("\n");
18
- fflush(stdout);
19
- }
20
-
21
- int main (int argc, const char * argv[]) {
22
- // Create event stream
23
- CFStringRef pathToWatch = CFStringCreateWithCString(kCFAllocatorDefault, argv[1], kCFStringEncodingUTF8);
24
- CFArrayRef pathsToWatch = CFArrayCreate(NULL, (const void **)&pathToWatch, 1, NULL);
25
- void *callbackInfo = NULL;
26
- FSEventStreamRef stream;
27
- CFAbsoluteTime latency = 0.1;
28
- stream = FSEventStreamCreate(
29
- kCFAllocatorDefault,
30
- callback,
31
- callbackInfo,
32
- pathsToWatch,
33
- kFSEventStreamEventIdSinceNow,
34
- latency,
35
- kFSEventStreamCreateFlagNone
36
- );
37
-
38
- // Add stream to run loop
39
- FSEventStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
40
- FSEventStreamStart(stream);
41
- CFRunLoopRun();
42
-
43
- return 2;
44
- }