haml 3.0.25 → 3.1.0.alpha.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of haml might be problematic. Click here for more details.

Files changed (212) hide show
  1. data/.yardopts +1 -1
  2. data/CONTRIBUTING +0 -1
  3. data/EDGE_GEM_VERSION +1 -0
  4. data/MIT-LICENSE +1 -1
  5. data/README.md +10 -175
  6. data/Rakefile +56 -84
  7. data/VERSION +1 -1
  8. data/VERSION_NAME +1 -1
  9. data/init.rb +1 -1
  10. data/lib/haml.rb +14 -12
  11. data/lib/haml/engine.rb +1 -1
  12. data/lib/haml/exec.rb +19 -316
  13. data/lib/haml/helpers/action_view_extensions.rb +1 -1
  14. data/lib/haml/html.rb +69 -76
  15. data/lib/haml/precompiler.rb +34 -41
  16. data/lib/haml/railtie.rb +4 -6
  17. data/lib/haml/template/plugin.rb +6 -16
  18. data/lib/haml/util.rb +91 -107
  19. data/lib/haml/version.rb +7 -0
  20. data/test/benchmark.rb +2 -9
  21. data/test/haml/engine_test.rb +195 -92
  22. data/test/haml/html2haml/erb_tests.rb +0 -14
  23. data/test/haml/util_test.rb +32 -0
  24. data/test/test_helper.rb +0 -39
  25. metadata +96 -324
  26. data/bin/css2sass +0 -13
  27. data/bin/sass +0 -8
  28. data/bin/sass-convert +0 -7
  29. data/extra/haml-mode.el +0 -753
  30. data/extra/sass-mode.el +0 -207
  31. data/lib/haml/util/subset_map.rb +0 -101
  32. data/lib/sass.rb +0 -29
  33. data/lib/sass/callbacks.rb +0 -52
  34. data/lib/sass/css.rb +0 -294
  35. data/lib/sass/engine.rb +0 -720
  36. data/lib/sass/environment.rb +0 -143
  37. data/lib/sass/error.rb +0 -198
  38. data/lib/sass/files.rb +0 -160
  39. data/lib/sass/less.rb +0 -382
  40. data/lib/sass/plugin.rb +0 -279
  41. data/lib/sass/plugin/configuration.rb +0 -221
  42. data/lib/sass/plugin/generic.rb +0 -15
  43. data/lib/sass/plugin/merb.rb +0 -37
  44. data/lib/sass/plugin/rack.rb +0 -47
  45. data/lib/sass/plugin/rails.rb +0 -32
  46. data/lib/sass/plugin/staleness_checker.rb +0 -123
  47. data/lib/sass/repl.rb +0 -58
  48. data/lib/sass/script.rb +0 -63
  49. data/lib/sass/script/bool.rb +0 -18
  50. data/lib/sass/script/color.rb +0 -491
  51. data/lib/sass/script/css_lexer.rb +0 -29
  52. data/lib/sass/script/css_parser.rb +0 -31
  53. data/lib/sass/script/funcall.rb +0 -77
  54. data/lib/sass/script/functions.rb +0 -861
  55. data/lib/sass/script/interpolation.rb +0 -70
  56. data/lib/sass/script/lexer.rb +0 -337
  57. data/lib/sass/script/literal.rb +0 -236
  58. data/lib/sass/script/node.rb +0 -112
  59. data/lib/sass/script/number.rb +0 -423
  60. data/lib/sass/script/operation.rb +0 -95
  61. data/lib/sass/script/parser.rb +0 -401
  62. data/lib/sass/script/string.rb +0 -67
  63. data/lib/sass/script/string_interpolation.rb +0 -93
  64. data/lib/sass/script/unary_operation.rb +0 -57
  65. data/lib/sass/script/variable.rb +0 -48
  66. data/lib/sass/scss.rb +0 -17
  67. data/lib/sass/scss/css_parser.rb +0 -46
  68. data/lib/sass/scss/parser.rb +0 -855
  69. data/lib/sass/scss/rx.rb +0 -126
  70. data/lib/sass/scss/sass_parser.rb +0 -11
  71. data/lib/sass/scss/script_lexer.rb +0 -15
  72. data/lib/sass/scss/script_parser.rb +0 -25
  73. data/lib/sass/scss/static_parser.rb +0 -40
  74. data/lib/sass/selector.rb +0 -361
  75. data/lib/sass/selector/abstract_sequence.rb +0 -62
  76. data/lib/sass/selector/comma_sequence.rb +0 -82
  77. data/lib/sass/selector/sequence.rb +0 -237
  78. data/lib/sass/selector/simple.rb +0 -113
  79. data/lib/sass/selector/simple_sequence.rb +0 -136
  80. data/lib/sass/tree/charset_node.rb +0 -37
  81. data/lib/sass/tree/comment_node.rb +0 -128
  82. data/lib/sass/tree/debug_node.rb +0 -36
  83. data/lib/sass/tree/directive_node.rb +0 -75
  84. data/lib/sass/tree/extend_node.rb +0 -65
  85. data/lib/sass/tree/for_node.rb +0 -55
  86. data/lib/sass/tree/if_node.rb +0 -69
  87. data/lib/sass/tree/import_node.rb +0 -102
  88. data/lib/sass/tree/mixin_def_node.rb +0 -48
  89. data/lib/sass/tree/mixin_node.rb +0 -111
  90. data/lib/sass/tree/node.rb +0 -464
  91. data/lib/sass/tree/prop_node.rb +0 -220
  92. data/lib/sass/tree/root_node.rb +0 -163
  93. data/lib/sass/tree/rule_node.rb +0 -261
  94. data/lib/sass/tree/variable_node.rb +0 -39
  95. data/lib/sass/tree/warn_node.rb +0 -42
  96. data/lib/sass/tree/while_node.rb +0 -36
  97. data/test/haml/util/subset_map_test.rb +0 -91
  98. data/test/sass/callbacks_test.rb +0 -61
  99. data/test/sass/conversion_test.rb +0 -1218
  100. data/test/sass/css2sass_test.rb +0 -364
  101. data/test/sass/data/hsl-rgb.txt +0 -319
  102. data/test/sass/engine_test.rb +0 -2267
  103. data/test/sass/extend_test.rb +0 -1348
  104. data/test/sass/functions_test.rb +0 -556
  105. data/test/sass/less_conversion_test.rb +0 -653
  106. data/test/sass/more_results/more1.css +0 -9
  107. data/test/sass/more_results/more1_with_line_comments.css +0 -26
  108. data/test/sass/more_results/more_import.css +0 -29
  109. data/test/sass/more_templates/_more_partial.sass +0 -2
  110. data/test/sass/more_templates/more1.sass +0 -23
  111. data/test/sass/more_templates/more_import.sass +0 -11
  112. data/test/sass/plugin_test.rb +0 -433
  113. data/test/sass/results/alt.css +0 -4
  114. data/test/sass/results/basic.css +0 -9
  115. data/test/sass/results/compact.css +0 -5
  116. data/test/sass/results/complex.css +0 -86
  117. data/test/sass/results/compressed.css +0 -1
  118. data/test/sass/results/expanded.css +0 -19
  119. data/test/sass/results/import.css +0 -31
  120. data/test/sass/results/import_charset.css +0 -4
  121. data/test/sass/results/import_charset_1_8.css +0 -4
  122. data/test/sass/results/import_charset_ibm866.css +0 -4
  123. data/test/sass/results/line_numbers.css +0 -49
  124. data/test/sass/results/mixins.css +0 -95
  125. data/test/sass/results/multiline.css +0 -24
  126. data/test/sass/results/nested.css +0 -22
  127. data/test/sass/results/options.css +0 -1
  128. data/test/sass/results/parent_ref.css +0 -13
  129. data/test/sass/results/script.css +0 -16
  130. data/test/sass/results/scss_import.css +0 -31
  131. data/test/sass/results/scss_importee.css +0 -2
  132. data/test/sass/results/subdir/nested_subdir/nested_subdir.css +0 -1
  133. data/test/sass/results/subdir/subdir.css +0 -3
  134. data/test/sass/results/units.css +0 -11
  135. data/test/sass/results/warn.css +0 -0
  136. data/test/sass/results/warn_imported.css +0 -0
  137. data/test/sass/script_conversion_test.rb +0 -314
  138. data/test/sass/script_test.rb +0 -470
  139. data/test/sass/scss/css_test.rb +0 -916
  140. data/test/sass/scss/rx_test.rb +0 -156
  141. data/test/sass/scss/scss_test.rb +0 -1122
  142. data/test/sass/scss/test_helper.rb +0 -37
  143. data/test/sass/templates/_imported_charset_ibm866.sass +0 -4
  144. data/test/sass/templates/_imported_charset_utf8.sass +0 -4
  145. data/test/sass/templates/_partial.sass +0 -2
  146. data/test/sass/templates/alt.sass +0 -16
  147. data/test/sass/templates/basic.sass +0 -23
  148. data/test/sass/templates/bork1.sass +0 -2
  149. data/test/sass/templates/bork2.sass +0 -2
  150. data/test/sass/templates/bork3.sass +0 -2
  151. data/test/sass/templates/bork4.sass +0 -2
  152. data/test/sass/templates/compact.sass +0 -17
  153. data/test/sass/templates/complex.sass +0 -305
  154. data/test/sass/templates/compressed.sass +0 -15
  155. data/test/sass/templates/expanded.sass +0 -17
  156. data/test/sass/templates/import.sass +0 -12
  157. data/test/sass/templates/import_charset.sass +0 -7
  158. data/test/sass/templates/import_charset_1_8.sass +0 -4
  159. data/test/sass/templates/import_charset_ibm866.sass +0 -9
  160. data/test/sass/templates/importee.less +0 -2
  161. data/test/sass/templates/importee.sass +0 -19
  162. data/test/sass/templates/line_numbers.sass +0 -13
  163. data/test/sass/templates/mixin_bork.sass +0 -5
  164. data/test/sass/templates/mixins.sass +0 -76
  165. data/test/sass/templates/multiline.sass +0 -20
  166. data/test/sass/templates/nested.sass +0 -25
  167. data/test/sass/templates/nested_bork1.sass +0 -2
  168. data/test/sass/templates/nested_bork2.sass +0 -2
  169. data/test/sass/templates/nested_bork3.sass +0 -2
  170. data/test/sass/templates/nested_bork4.sass +0 -2
  171. data/test/sass/templates/nested_mixin_bork.sass +0 -6
  172. data/test/sass/templates/options.sass +0 -2
  173. data/test/sass/templates/parent_ref.sass +0 -25
  174. data/test/sass/templates/script.sass +0 -101
  175. data/test/sass/templates/scss_import.scss +0 -11
  176. data/test/sass/templates/scss_importee.scss +0 -1
  177. data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +0 -2
  178. data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +0 -3
  179. data/test/sass/templates/subdir/subdir.sass +0 -6
  180. data/test/sass/templates/units.sass +0 -11
  181. data/test/sass/templates/warn.sass +0 -3
  182. data/test/sass/templates/warn_imported.sass +0 -4
  183. data/vendor/fssm/LICENSE +0 -20
  184. data/vendor/fssm/README.markdown +0 -55
  185. data/vendor/fssm/Rakefile +0 -59
  186. data/vendor/fssm/VERSION.yml +0 -5
  187. data/vendor/fssm/example.rb +0 -9
  188. data/vendor/fssm/fssm.gemspec +0 -77
  189. data/vendor/fssm/lib/fssm.rb +0 -33
  190. data/vendor/fssm/lib/fssm/backends/fsevents.rb +0 -36
  191. data/vendor/fssm/lib/fssm/backends/inotify.rb +0 -26
  192. data/vendor/fssm/lib/fssm/backends/polling.rb +0 -25
  193. data/vendor/fssm/lib/fssm/backends/rubycocoa/fsevents.rb +0 -131
  194. data/vendor/fssm/lib/fssm/monitor.rb +0 -26
  195. data/vendor/fssm/lib/fssm/path.rb +0 -91
  196. data/vendor/fssm/lib/fssm/pathname.rb +0 -502
  197. data/vendor/fssm/lib/fssm/state/directory.rb +0 -57
  198. data/vendor/fssm/lib/fssm/state/file.rb +0 -24
  199. data/vendor/fssm/lib/fssm/support.rb +0 -63
  200. data/vendor/fssm/lib/fssm/tree.rb +0 -176
  201. data/vendor/fssm/profile/prof-cache.rb +0 -40
  202. data/vendor/fssm/profile/prof-fssm-pathname.html +0 -1231
  203. data/vendor/fssm/profile/prof-pathname.rb +0 -68
  204. data/vendor/fssm/profile/prof-plain-pathname.html +0 -988
  205. data/vendor/fssm/profile/prof.html +0 -2379
  206. data/vendor/fssm/spec/path_spec.rb +0 -75
  207. data/vendor/fssm/spec/root/duck/quack.txt +0 -0
  208. data/vendor/fssm/spec/root/file.css +0 -0
  209. data/vendor/fssm/spec/root/file.rb +0 -0
  210. data/vendor/fssm/spec/root/file.yml +0 -0
  211. data/vendor/fssm/spec/root/moo/cow.txt +0 -0
  212. data/vendor/fssm/spec/spec_helper.rb +0 -14
@@ -1,55 +0,0 @@
1
- Monitor API
2
- ===========
3
-
4
- There are three ways you can run the monitor.
5
-
6
- 1. call monitor with a path parameter, and define callbacks in a block
7
- 2. call monitor with a block to configure multiple paths and callbacks
8
- 3. create a monitor object and run each step manually
9
-
10
- Monitor with path
11
- -----------------
12
-
13
- This form watches one path, and enters the run loop automatically. The first parameter is the path to watch, and the second parameter is an optional glob pattern or array of glob patterns that a file must match in order to trigger a callback. The default glob, if ommitted, is `'**/*'`.
14
-
15
- FSSM.monitor('/some/directory/', '**/*') do
16
- update {|base, relative|}
17
- delete {|base, relative|}
18
- create {|base, relative|}
19
- end
20
-
21
- Monitor with block
22
- ------------------
23
-
24
- This form watches one or more paths, and enters the run loop automatically. The glob configuration call can be ommitted, and defaults to `'**/*'`.
25
-
26
- FSSM.monitor do
27
- path '/some/directory/' do
28
- glob '**/*.yml'
29
-
30
- update {|base, relative|}
31
- delete {|base, relative|}
32
- create {|base, relative|}
33
- end
34
-
35
- path '/some/other/directory/' do
36
- update {|base, relative|}
37
- delete {|base, relative|}
38
- create {|base, relative|}
39
- end
40
- end
41
-
42
- Monitor object
43
- --------------
44
-
45
- This form doesn't enter the run loop automatically.
46
-
47
- monitor = FSSM::Monitor.new
48
-
49
- monitor.path '/some/directory/' do
50
- update {|base, relative|}
51
- delete {|base, relative|}
52
- create {|base, relative|}
53
- end
54
-
55
- monitor.run
@@ -1,59 +0,0 @@
1
- require 'rubygems'
2
- require 'rake'
3
-
4
- begin
5
- require 'jeweler'
6
- Jeweler::Tasks.new do |gem|
7
- gem.name = "fssm"
8
- gem.summary = %Q{file system state monitor}
9
- gem.description = %Q{file system state monitor}
10
- gem.email = "ttilley@gmail.com"
11
- gem.homepage = "http://github.com/ttilley/fssm"
12
- gem.authors = ["Travis Tilley"]
13
- gem.add_development_dependency "rspec"
14
- # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
- end
16
- rescue LoadError
17
- puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
18
- end
19
-
20
- require 'spec/rake/spectask'
21
- Spec::Rake::SpecTask.new(:spec) do |spec|
22
- spec.libs << 'lib' << 'spec'
23
- spec.spec_files = FileList['spec/**/*_spec.rb']
24
- end
25
-
26
- Spec::Rake::SpecTask.new(:rcov) do |spec|
27
- spec.libs << 'lib' << 'spec'
28
- spec.pattern = 'spec/**/*_spec.rb'
29
- spec.rcov = true
30
- end
31
-
32
- task :spec => :check_dependencies
33
-
34
- begin
35
- require 'reek/rake_task'
36
- Reek::RakeTask.new do |t|
37
- t.fail_on_error = true
38
- t.verbose = false
39
- t.source_files = 'lib/**/*.rb'
40
- end
41
- rescue LoadError
42
- task :reek do
43
- abort "Reek is not available. In order to run reek, you must: sudo gem install reek"
44
- end
45
- end
46
-
47
- begin
48
- require 'roodi'
49
- require 'roodi_task'
50
- RoodiTask.new do |t|
51
- t.verbose = false
52
- end
53
- rescue LoadError
54
- task :roodi do
55
- abort "Roodi is not available. In order to run roodi, you must: sudo gem install roodi"
56
- end
57
- end
58
-
59
- task :default => :spec
@@ -1,5 +0,0 @@
1
- ---
2
- :major: 0
3
- :minor: 1
4
- :patch: 4
5
- :build:
@@ -1,9 +0,0 @@
1
- $:.unshift(File.join(File.dirname(__FILE__), 'lib'))
2
-
3
- require 'fssm'
4
-
5
- FSSM.monitor('.', '**/*') do
6
- update {|b, r| puts "Update in #{b} to #{r}"}
7
- delete {|b, r| puts "Delete in #{b} to #{r}"}
8
- create {|b, r| puts "Create in #{b} to #{r}"}
9
- end
@@ -1,77 +0,0 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
- # -*- encoding: utf-8 -*-
5
-
6
- Gem::Specification.new do |s|
7
- s.name = %q{fssm}
8
- s.version = "0.1.4"
9
-
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Travis Tilley"]
12
- s.date = %q{2010-03-10}
13
- s.description = %q{file system state monitor}
14
- s.email = %q{ttilley@gmail.com}
15
- s.extra_rdoc_files = [
16
- "LICENSE",
17
- "README.markdown"
18
- ]
19
- s.files = [
20
- ".document",
21
- ".gitignore",
22
- "LICENSE",
23
- "README.markdown",
24
- "Rakefile",
25
- "VERSION.yml",
26
- "example.rb",
27
- "fssm.gemspec",
28
- "lib/fssm.rb",
29
- "lib/fssm/backends/fsevents.rb",
30
- "lib/fssm/backends/inotify.rb",
31
- "lib/fssm/backends/polling.rb",
32
- "lib/fssm/backends/rubycocoa/fsevents.rb",
33
- "lib/fssm/monitor.rb",
34
- "lib/fssm/path.rb",
35
- "lib/fssm/pathname.rb",
36
- "lib/fssm/state/directory.rb",
37
- "lib/fssm/state/file.rb",
38
- "lib/fssm/support.rb",
39
- "lib/fssm/tree.rb",
40
- "profile/prof-cache.rb",
41
- "profile/prof-fssm-pathname.html",
42
- "profile/prof-pathname.rb",
43
- "profile/prof-plain-pathname.html",
44
- "profile/prof.html",
45
- "spec/path_spec.rb",
46
- "spec/root/duck/quack.txt",
47
- "spec/root/file.css",
48
- "spec/root/file.rb",
49
- "spec/root/file.yml",
50
- "spec/root/moo/cow.txt",
51
- "spec/spec_helper.rb"
52
- ]
53
- s.homepage = %q{http://github.com/ttilley/fssm}
54
- s.rdoc_options = ["--charset=UTF-8"]
55
- s.require_paths = ["lib"]
56
- s.rubygems_version = %q{1.3.6}
57
- s.summary = %q{file system state monitor}
58
- s.test_files = [
59
- "spec/path_spec.rb",
60
- "spec/spec_helper.rb",
61
- "spec/root/file.rb"
62
- ]
63
-
64
- if s.respond_to? :specification_version then
65
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
66
- s.specification_version = 3
67
-
68
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
69
- s.add_development_dependency(%q<rspec>, [">= 0"])
70
- else
71
- s.add_dependency(%q<rspec>, [">= 0"])
72
- end
73
- else
74
- s.add_dependency(%q<rspec>, [">= 0"])
75
- end
76
- end
77
-
@@ -1,33 +0,0 @@
1
- dir = File.dirname(__FILE__)
2
- $LOAD_PATH.unshift dir unless $LOAD_PATH.include?(dir)
3
-
4
- module FSSM
5
- FileNotFoundError = Class.new(StandardError)
6
- CallbackError = Class.new(StandardError)
7
-
8
- class << self
9
- def dbg(msg=nil)
10
- STDERR.puts(msg)
11
- end
12
-
13
- def monitor(*args, &block)
14
- monitor = FSSM::Monitor.new
15
- FSSM::Support.use_block(args.empty? ? monitor : monitor.path(*args), block)
16
-
17
- monitor.run
18
- end
19
- end
20
- end
21
-
22
- require 'thread'
23
-
24
- require 'fssm/pathname'
25
- require 'fssm/support'
26
- require 'fssm/tree'
27
- require 'fssm/path'
28
- require 'fssm/state/directory'
29
- require 'fssm/state/file'
30
- require 'fssm/monitor'
31
-
32
- require "fssm/backends/#{FSSM::Support.backend.downcase}"
33
- FSSM::Backends::Default = FSSM::Backends.const_get(FSSM::Support.backend)
@@ -1,36 +0,0 @@
1
- require File.join(File.dirname(__FILE__), 'rubycocoa/fsevents')
2
-
3
- module FSSM::Backends
4
- class FSEvents
5
- def initialize
6
- @handlers = {}
7
- @fsevents = []
8
- end
9
-
10
- def add_handler(handler, preload=true)
11
- @handlers[handler.path.to_s] = handler
12
-
13
- fsevent = Rucola::FSEvents.new(handler.path.to_s, {:latency => 0.5}) do |events|
14
- events.each do |event|
15
- handler.refresh(event.path)
16
- end
17
- end
18
-
19
- fsevent.create_stream
20
- handler.refresh(nil, true) if preload
21
- fsevent.start
22
- @fsevents << fsevent
23
- end
24
-
25
- def run
26
- begin
27
- OSX.CFRunLoopRun
28
- rescue Interrupt
29
- @fsevents.each do |fsev|
30
- fsev.stop
31
- end
32
- end
33
- end
34
-
35
- end
36
- end
@@ -1,26 +0,0 @@
1
- module FSSM::Backends
2
- class Inotify
3
- def initialize
4
- @notifier = INotify::Notifier.new
5
- end
6
-
7
- def add_handler(handler, preload=true)
8
- @notifier.watch(handler.path.to_s, :recursive, :attrib, :modify, :create,
9
- :delete, :delete_self, :moved_from, :moved_to, :move_self) do |event|
10
- path = FSSM::Pathname.for(event.absolute_name)
11
- path = path.dirname unless event.name == "" # Event on root directory
12
- handler.refresh(path)
13
- end
14
-
15
- handler.refresh(nil, true) if preload
16
- end
17
-
18
- def run
19
- begin
20
- @notifier.run
21
- rescue Interrupt
22
- end
23
- end
24
-
25
- end
26
- end
@@ -1,25 +0,0 @@
1
- module FSSM::Backends
2
- class Polling
3
- def initialize(options={})
4
- @handlers = []
5
- @latency = options[:latency] || 1.5
6
- end
7
-
8
- def add_handler(handler, preload=true)
9
- handler.refresh(nil, true) if preload
10
- @handlers << handler
11
- end
12
-
13
- def run
14
- begin
15
- loop do
16
- start = Time.now.to_f
17
- @handlers.each {|handler| handler.refresh}
18
- nap_time = @latency - (Time.now.to_f - start)
19
- sleep nap_time if nap_time > 0
20
- end
21
- rescue Interrupt
22
- end
23
- end
24
- end
25
- end
@@ -1,131 +0,0 @@
1
- OSX.require_framework '/System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework'
2
-
3
- module Rucola
4
- class FSEvents
5
- class FSEvent
6
- attr_reader :fsevents_object
7
- attr_reader :id
8
- attr_reader :path
9
-
10
- def initialize(fsevents_object, id, path)
11
- @fsevents_object, @id, @path = fsevents_object, id, path
12
- end
13
-
14
- # Returns an array of the files/dirs in the path that the event occurred in.
15
- # The files are sorted by the modification time, the first entry is the last modified file.
16
- def files
17
- Dir.glob("#{File.expand_path(path)}/*").sort_by {|f| File.mtime(f) }.reverse
18
- end
19
-
20
- # Returns the last modified file in the path that the event occurred in.
21
- def last_modified_file
22
- files.first
23
- end
24
- end
25
-
26
- class StreamError < StandardError;
27
- end
28
-
29
- attr_reader :paths
30
- attr_reader :stream
31
-
32
- attr_accessor :allocator
33
- attr_accessor :context
34
- attr_accessor :since
35
- attr_accessor :latency
36
- attr_accessor :flags
37
-
38
- # Initializes a new FSEvents `watchdog` object and starts watching the directories you specify for events. The
39
- # block is used as a handler for events, which are passed as the block's argument. This method is the easiest
40
- # way to start watching some directories if you don't care about the details of setting up the event stream.
41
- #
42
- # Rucola::FSEvents.start_watching('/tmp') do |events|
43
- # events.each { |event| log.debug("#{event.files.inspect} were changed.") }
44
- # end
45
- #
46
- # Rucola::FSEvents.start_watching('/var/log/system.log', '/var/log/secure.log', :since => last_id, :latency => 5) do
47
- # Growl.notify("Something was added to your log files!")
48
- # end
49
- #
50
- # Note that the method also returns the FSEvents object. This enables you to control the event stream if you want to.
51
- #
52
- # fsevents = Rucola::FSEvents.start_watching('/Volumes') do |events|
53
- # events.each { |event| Growl.notify("Volume changes: #{event.files.to_sentence}") }
54
- # end
55
- # fsevents.stop
56
- def self.start_watching(*params, &block)
57
- fsevents = new(*params, &block)
58
- fsevents.create_stream
59
- fsevents.start
60
- fsevents
61
- end
62
-
63
- # Creates a new FSEvents `watchdog` object. You can specify a list of paths to watch and options to control the
64
- # behaviour of the watchdog. The block you pass serves as a callback when an event is generated on one of the
65
- # specified paths.
66
- #
67
- # fsevents = FSEvents.new('/etc/passwd') { Mailer.send_mail("Someone touched the password file!") }
68
- # fsevents.create_stream
69
- # fsevents.start
70
- #
71
- # fsevents = FSEvents.new('/home/upload', :since => UploadWatcher.last_event_id) do |events|
72
- # events.each do |event|
73
- # UploadWatcher.last_event_id = event.id
74
- # event.files.each do |file|
75
- # UploadWatcher.logfile.append("#{file} was changed")
76
- # end
77
- # end
78
- # end
79
- #
80
- # *:since: The service will report events that have happened after the supplied event ID. Never use 0 because that
81
- # will cause every fsevent since the "beginning of time" to be reported. Use OSX::KFSEventStreamEventIdSinceNow
82
- # if you want to receive events that have happened after this call. (Default: OSX::KFSEventStreamEventIdSinceNow).
83
- # You can find the ID's passed with :since in the events passed to your block.
84
- # *:latency: Number of seconds to wait until an FSEvent is reported, this allows the service to bundle events. (Default: 0.0)
85
- #
86
- # Please refer to the Cocoa documentation for the rest of the options.
87
- def initialize(*params, &block)
88
- raise ArgumentError, 'No callback block was specified.' unless block_given?
89
-
90
- options = params.last.kind_of?(Hash) ? params.pop : {}
91
- @paths = params.flatten
92
-
93
- paths.each { |path| raise ArgumentError, "The specified path (#{path}) does not exist." unless File.exist?(path) }
94
-
95
- @allocator = options[:allocator] || OSX::KCFAllocatorDefault
96
- @context = options[:context] || nil
97
- @since = options[:since] || OSX::KFSEventStreamEventIdSinceNow
98
- @latency = options[:latency] || 0.0
99
- @flags = options[:flags] || 0
100
- @stream = options[:stream] || nil
101
-
102
- @user_callback = block
103
- @callback = Proc.new do |stream, client_callback_info, number_of_events, paths_pointer, event_flags, event_ids|
104
- paths_pointer.regard_as('*')
105
- events = []
106
- number_of_events.times {|i| events << Rucola::FSEvents::FSEvent.new(self, event_ids[i], paths_pointer[i]) }
107
- @user_callback.call(events)
108
- end
109
- end
110
-
111
- # Create the stream.
112
- # Raises a Rucola::FSEvents::StreamError if the stream could not be created.
113
- def create_stream
114
- @stream = OSX.FSEventStreamCreate(@allocator, @callback, @context, @paths, @since, @latency, @flags)
115
- raise(StreamError, 'Unable to create FSEvents stream.') unless @stream
116
- OSX.FSEventStreamScheduleWithRunLoop(@stream, OSX.CFRunLoopGetCurrent, OSX::KCFRunLoopDefaultMode)
117
- end
118
-
119
- # Start the stream.
120
- # Raises a Rucola::FSEvents::StreamError if the stream could not be started.
121
- def start
122
- raise(StreamError, 'Unable to start FSEvents stream.') unless OSX.FSEventStreamStart(@stream)
123
- end
124
-
125
- # Stop the stream.
126
- # You can resume it by calling `start` again.
127
- def stop
128
- OSX.FSEventStreamStop(@stream)
129
- end
130
- end
131
- end