sass 3.2.0.alpha.104 → 3.2.0.alpha.236

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.
Files changed (49) hide show
  1. data/REVISION +1 -1
  2. data/Rakefile +2 -2
  3. data/VERSION +1 -1
  4. data/lib/sass/engine.rb +8 -1
  5. data/lib/sass/exec.rb +2 -2
  6. data/lib/sass/plugin/compiler.rb +51 -43
  7. data/lib/sass/script/color.rb +4 -9
  8. data/lib/sass/script/funcall.rb +11 -2
  9. data/lib/sass/script/functions.rb +16 -30
  10. data/lib/sass/script/lexer.rb +7 -1
  11. data/lib/sass/script/list.rb +2 -2
  12. data/lib/sass/script/literal.rb +8 -0
  13. data/lib/sass/script/null.rb +34 -0
  14. data/lib/sass/script/operation.rb +4 -0
  15. data/lib/sass/script/parser.rb +4 -2
  16. data/lib/sass/scss/parser.rb +1 -5
  17. data/lib/sass/scss/rx.rb +1 -1
  18. data/lib/sass/tree/directive_node.rb +5 -0
  19. data/lib/sass/tree/media_node.rb +3 -0
  20. data/lib/sass/tree/prop_node.rb +7 -3
  21. data/lib/sass/tree/visitors/base.rb +1 -1
  22. data/lib/sass/tree/visitors/check_nesting.rb +21 -18
  23. data/lib/sass/tree/visitors/convert.rb +1 -0
  24. data/lib/sass/tree/visitors/perform.rb +3 -2
  25. data/lib/sass/tree/visitors/to_css.rb +1 -0
  26. data/lib/sass/util.rb +28 -0
  27. data/test/sass/conversion_test.rb +33 -0
  28. data/test/sass/engine_test.rb +118 -3
  29. data/test/sass/functions_test.rb +56 -24
  30. data/test/sass/script_test.rb +60 -4
  31. data/test/sass/scss/scss_test.rb +10 -0
  32. data/vendor/listen/CHANGELOG.md +19 -1
  33. data/vendor/listen/README.md +27 -12
  34. data/vendor/listen/lib/listen/adapter.rb +9 -1
  35. data/vendor/listen/lib/listen/adapters/linux.rb +18 -7
  36. data/vendor/listen/lib/listen/adapters/windows.rb +7 -8
  37. data/vendor/listen/lib/listen/directory_record.rb +108 -48
  38. data/vendor/listen/lib/listen/listener.rb +28 -11
  39. data/vendor/listen/lib/listen/multi_listener.rb +6 -6
  40. data/vendor/listen/lib/listen/version.rb +1 -1
  41. data/vendor/listen/spec/listen/adapters/linux_spec.rb +11 -0
  42. data/vendor/listen/spec/listen/directory_record_spec.rb +268 -41
  43. data/vendor/listen/spec/listen/listener_spec.rb +8 -4
  44. data/vendor/listen/spec/listen/multi_listener_spec.rb +9 -4
  45. data/vendor/listen/spec/support/adapter_helper.rb +178 -0
  46. data/vendor/listen/spec/support/directory_record_helper.rb +24 -4
  47. data/vendor/listen/spec/support/listeners_helper.rb +11 -0
  48. metadata +11 -11
  49. data/lib/sass/plugin/listener.rb +0 -61
@@ -76,7 +76,7 @@ class SassFunctionTest < Test::Unit::TestCase
76
76
 
77
77
  def test_hsl_checks_bounds
78
78
  assert_error_message("Saturation -114 must be between 0% and 100% for `hsl'", "hsl(10, -114, 12)");
79
- assert_error_message("Lightness 256 must be between 0% and 100% for `hsl'", "hsl(10, 10, 256%)");
79
+ assert_error_message("Lightness 256% must be between 0% and 100% for `hsl'", "hsl(10, 10, 256%)");
80
80
  end
81
81
 
82
82
  def test_hsl_checks_types
@@ -94,7 +94,7 @@ class SassFunctionTest < Test::Unit::TestCase
94
94
 
95
95
  def test_hsla_checks_bounds
96
96
  assert_error_message("Saturation -114 must be between 0% and 100% for `hsla'", "hsla(10, -114, 12, 1)");
97
- assert_error_message("Lightness 256 must be between 0% and 100% for `hsla'", "hsla(10, 10, 256%, 0)");
97
+ assert_error_message("Lightness 256% must be between 0% and 100% for `hsla'", "hsla(10, 10, 256%, 0)");
98
98
  assert_error_message("Alpha channel -0.1 must be between 0 and 1 for `hsla'", "hsla(10, 10, 10, -0.1)");
99
99
  assert_error_message("Alpha channel 1.1 must be between 0 and 1 for `hsla'", "hsla(10, 10, 10, 1.1)");
100
100
  end
@@ -189,24 +189,24 @@ class SassFunctionTest < Test::Unit::TestCase
189
189
  end
190
190
 
191
191
  def test_rgb_tests_bounds
192
- assert_error_message("Color value 256 must be between 0 and 255 inclusive for `rgb'",
192
+ assert_error_message("Color value 256 must be between 0 and 255 for `rgb'",
193
193
  "rgb(256, 1, 1)")
194
- assert_error_message("Color value 256 must be between 0 and 255 inclusive for `rgb'",
194
+ assert_error_message("Color value 256 must be between 0 and 255 for `rgb'",
195
195
  "rgb(1, 256, 1)")
196
- assert_error_message("Color value 256 must be between 0 and 255 inclusive for `rgb'",
196
+ assert_error_message("Color value 256 must be between 0 and 255 for `rgb'",
197
197
  "rgb(1, 1, 256)")
198
- assert_error_message("Color value 256 must be between 0 and 255 inclusive for `rgb'",
198
+ assert_error_message("Color value 256 must be between 0 and 255 for `rgb'",
199
199
  "rgb(1, 256, 257)")
200
- assert_error_message("Color value -1 must be between 0 and 255 inclusive for `rgb'",
200
+ assert_error_message("Color value -1 must be between 0 and 255 for `rgb'",
201
201
  "rgb(-1, 1, 1)")
202
202
  end
203
203
 
204
204
  def test_rgb_test_percent_bounds
205
- assert_error_message("Color value 100.1% must be between 0% and 100% inclusive for `rgb'",
205
+ assert_error_message("Color value 100.1% must be between 0% and 100% for `rgb'",
206
206
  "rgb(100.1%, 0, 0)")
207
- assert_error_message("Color value -0.1% must be between 0% and 100% inclusive for `rgb'",
207
+ assert_error_message("Color value -0.1% must be between 0% and 100% for `rgb'",
208
208
  "rgb(0, -0.1%, 0)")
209
- assert_error_message("Color value 101% must be between 0% and 100% inclusive for `rgb'",
209
+ assert_error_message("Color value 101% must be between 0% and 100% for `rgb'",
210
210
  "rgb(0, 0, 101%)")
211
211
  end
212
212
 
@@ -224,19 +224,19 @@ class SassFunctionTest < Test::Unit::TestCase
224
224
  end
225
225
 
226
226
  def test_rgb_tests_bounds
227
- assert_error_message("Color value 256 must be between 0 and 255 inclusive for `rgba'",
227
+ assert_error_message("Color value 256 must be between 0 and 255 for `rgba'",
228
228
  "rgba(256, 1, 1, 0.3)")
229
- assert_error_message("Color value 256 must be between 0 and 255 inclusive for `rgba'",
229
+ assert_error_message("Color value 256 must be between 0 and 255 for `rgba'",
230
230
  "rgba(1, 256, 1, 0.3)")
231
- assert_error_message("Color value 256 must be between 0 and 255 inclusive for `rgba'",
231
+ assert_error_message("Color value 256 must be between 0 and 255 for `rgba'",
232
232
  "rgba(1, 1, 256, 0.3)")
233
- assert_error_message("Color value 256 must be between 0 and 255 inclusive for `rgba'",
233
+ assert_error_message("Color value 256 must be between 0 and 255 for `rgba'",
234
234
  "rgba(1, 256, 257, 0.3)")
235
- assert_error_message("Color value -1 must be between 0 and 255 inclusive for `rgba'",
235
+ assert_error_message("Color value -1 must be between 0 and 255 for `rgba'",
236
236
  "rgba(-1, 1, 1, 0.3)")
237
- assert_error_message("Alpha channel -0.2 must be between 0 and 1 inclusive for `rgba'",
237
+ assert_error_message("Alpha channel -0.2 must be between 0 and 1 for `rgba'",
238
238
  "rgba(1, 1, 1, -0.2)")
239
- assert_error_message("Alpha channel 1.2 must be between 0 and 1 inclusive for `rgba'",
239
+ assert_error_message("Alpha channel 1.2 must be between 0 and 1 for `rgba'",
240
240
  "rgba(1, 1, 1, 1.2)")
241
241
  end
242
242
 
@@ -733,15 +733,15 @@ class SassFunctionTest < Test::Unit::TestCase
733
733
 
734
734
  def test_change_color_argument_errors
735
735
  # Range
736
- assert_error_message("Saturation must be between 0 and 100 for `change-color'",
736
+ assert_error_message("Saturation 101% must be between 0% and 100% for `change-color'",
737
737
  "change-color(blue, $saturation: 101%)")
738
- assert_error_message("Lightness must be between 0 and 100 for `change-color'",
738
+ assert_error_message("Lightness 101% must be between 0% and 100% for `change-color'",
739
739
  "change-color(blue, $lightness: 101%)")
740
- assert_error_message("Red value must be between 0 and 255 for `change-color'",
740
+ assert_error_message("Red value -1 must be between 0 and 255 for `change-color'",
741
741
  "change-color(blue, $red: -1)")
742
- assert_error_message("Green value must be between 0 and 255 for `change-color'",
742
+ assert_error_message("Green value 256 must be between 0 and 255 for `change-color'",
743
743
  "change-color(blue, $green: 256)")
744
- assert_error_message("Blue value must be between 0 and 255 for `change-color'",
744
+ assert_error_message("Blue value 500 must be between 0 and 255 for `change-color'",
745
745
  "change-color(blue, $blue: 500)")
746
746
 
747
747
  # Unknown argument
@@ -871,6 +871,7 @@ MSG
871
871
  assert_equal("bool", evaluate("type-of(true)"))
872
872
  assert_equal("color", evaluate("type-of(#fff)"))
873
873
  assert_equal("color", evaluate("type-of($value: #fff)"))
874
+ assert_equal("null", evaluate("type-of(null)"))
874
875
  end
875
876
 
876
877
  def test_unit
@@ -1011,6 +1012,7 @@ MSG
1011
1012
  def test_if
1012
1013
  assert_equal("1px", evaluate("if(true, 1px, 2px)"))
1013
1014
  assert_equal("2px", evaluate("if(false, 1px, 2px)"))
1015
+ assert_equal("2px", evaluate("if(null, 1px, 2px)"))
1014
1016
  end
1015
1017
 
1016
1018
  def test_keyword_args_rgb
@@ -1023,23 +1025,47 @@ MSG
1023
1025
  end
1024
1026
 
1025
1027
  def test_keyword_args_rgba_with_extra_args
1026
- assert_equal(%Q{rgba(255, 255, 255, 0.5)}, evaluate("rgba($red: 255, $green: 255, $blue: 255, $alpha: 0.5, $extra: error)"))
1028
+ evaluate("rgba($red: 255, $green: 255, $blue: 255, $alpha: 0.5, $extra: error)")
1029
+ flunk("Expected exception")
1027
1030
  rescue Sass::SyntaxError => e
1028
- assert_equal("Function rgba doesn't take an argument named $extra", e.message)
1031
+ assert_equal("Function rgba doesn't have an argument named $extra", e.message)
1029
1032
  end
1030
1033
 
1031
1034
  def test_keyword_args_must_have_signature
1032
1035
  evaluate("no-kw-args($fake: value)")
1036
+ flunk("Expected exception")
1033
1037
  rescue Sass::SyntaxError => e
1034
1038
  assert_equal("Function no_kw_args doesn't support keyword arguments", e.message)
1035
1039
  end
1036
1040
 
1037
1041
  def test_keyword_args_with_missing_argument
1038
1042
  evaluate("rgb($red: 255, $green: 255)")
1043
+ flunk("Expected exception")
1039
1044
  rescue Sass::SyntaxError => e
1040
1045
  assert_equal("Function rgb requires an argument named $blue", e.message)
1041
1046
  end
1042
1047
 
1048
+ def test_keyword_args_with_extra_argument
1049
+ evaluate("rgb($red: 255, $green: 255, $blue: 255, $purple: 255)")
1050
+ flunk("Expected exception")
1051
+ rescue Sass::SyntaxError => e
1052
+ assert_equal("Function rgb doesn't have an argument named $purple", e.message)
1053
+ end
1054
+
1055
+ def test_keyword_args_with_positional_and_keyword_argument
1056
+ evaluate("rgb(255, 255, 255, $red: 255)")
1057
+ flunk("Expected exception")
1058
+ rescue Sass::SyntaxError => e
1059
+ assert_equal("Function rgb was passed argument $red both by position and by name", e.message)
1060
+ end
1061
+
1062
+ def test_keyword_args_with_keyword_before_positional_argument
1063
+ evaluate("rgb($red: 255, 255, 255)")
1064
+ flunk("Expected exception")
1065
+ rescue Sass::SyntaxError => e
1066
+ assert_equal("Positional arguments must come before keyword arguments", e.message)
1067
+ end
1068
+
1043
1069
  def test_only_var_args
1044
1070
  assert_equal "only-var-args(2px, 3px, 4px)", evaluate("only-var-args(1px, 2px, 3px)")
1045
1071
  end
@@ -1048,6 +1074,12 @@ MSG
1048
1074
  assert_equal "only-kw-args(a, b, c)", evaluate("only-kw-args($a: 1, $b: 2, $c: 3)")
1049
1075
  end
1050
1076
 
1077
+ ## Regression Tests
1078
+
1079
+ def test_saturation_bounds
1080
+ assert_equal "#fbfdff", evaluate("hsl(hue(#fbfdff), saturation(#fbfdff), lightness(#fbfdff))")
1081
+ end
1082
+
1051
1083
  private
1052
1084
 
1053
1085
  def evaluate(value)
@@ -21,13 +21,13 @@ class SassScriptTest < Test::Unit::TestCase
21
21
  include Sass::Script
22
22
 
23
23
  def test_color_checks_input
24
- assert_raise_message(ArgumentError, "Blue value must be between 0 and 255") {Color.new([1, 2, -1])}
25
- assert_raise_message(ArgumentError, "Red value must be between 0 and 255") {Color.new([256, 2, 3])}
24
+ assert_raise_message(ArgumentError, "Blue value -1 must be between 0 and 255") {Color.new([1, 2, -1])}
25
+ assert_raise_message(ArgumentError, "Red value 256 must be between 0 and 255") {Color.new([256, 2, 3])}
26
26
  end
27
27
 
28
28
  def test_color_checks_rgba_input
29
- assert_raise_message(ArgumentError, "Alpha channel must be between 0 and 1") {Color.new([1, 2, 3, 1.1])}
30
- assert_raise_message(ArgumentError, "Alpha channel must be between 0 and 1") {Color.new([1, 2, 3, -0.1])}
29
+ assert_raise_message(ArgumentError, "Alpha channel 1.1 must be between 0 and 1") {Color.new([1, 2, 3, 1.1])}
30
+ assert_raise_message(ArgumentError, "Alpha channel -0.1 must be between 0 and 1") {Color.new([1, 2, 3, -0.1])}
31
31
  end
32
32
 
33
33
  def test_string_escapes
@@ -263,6 +263,10 @@ SASS
263
263
  assert_equal "false", resolve("false")
264
264
  end
265
265
 
266
+ def test_null
267
+ assert_equal "", resolve("null")
268
+ end
269
+
266
270
  def test_boolean_ops
267
271
  assert_equal "true", resolve("true and true")
268
272
  assert_equal "true", resolve("false or true")
@@ -281,6 +285,18 @@ SASS
281
285
  assert_equal "false", resolve("false and 1")
282
286
  assert_equal "2", resolve("2 or 3")
283
287
  assert_equal "3", resolve("2 and 3")
288
+
289
+ assert_equal "true", resolve("null or true")
290
+ assert_equal "true", resolve("true or null")
291
+ assert_equal "", resolve("null or null")
292
+ assert_equal "", resolve("null and true")
293
+ assert_equal "", resolve("true and null")
294
+ assert_equal "", resolve("null and null")
295
+
296
+ assert_equal "true", resolve("not null")
297
+
298
+ assert_equal "1", resolve("null or 1")
299
+ assert_equal "", resolve("null and 1")
284
300
  end
285
301
 
286
302
  def test_arithmetic_ops
@@ -326,6 +342,37 @@ SASS
326
342
  assert_equal "false", resolve("3 <= 2")
327
343
  end
328
344
 
345
+ def test_null_ops
346
+ assert_raise_message(Sass::SyntaxError,
347
+ 'Invalid null operation: "null plus 1".') {eval("null + 1")}
348
+ assert_raise_message(Sass::SyntaxError,
349
+ 'Invalid null operation: "null minus 1".') {eval("null - 1")}
350
+ assert_raise_message(Sass::SyntaxError,
351
+ 'Invalid null operation: "null times 1".') {eval("null * 1")}
352
+ assert_raise_message(Sass::SyntaxError,
353
+ 'Invalid null operation: "null div 1".') {eval("null / 1")}
354
+ assert_raise_message(Sass::SyntaxError,
355
+ 'Invalid null operation: "null mod 1".') {eval("null % 1")}
356
+ assert_raise_message(Sass::SyntaxError,
357
+ 'Invalid null operation: "1 plus null".') {eval("1 + null")}
358
+ assert_raise_message(Sass::SyntaxError,
359
+ 'Invalid null operation: "1 minus null".') {eval("1 - null")}
360
+ assert_raise_message(Sass::SyntaxError,
361
+ 'Invalid null operation: "1 times null".') {eval("1 * null")}
362
+ assert_raise_message(Sass::SyntaxError,
363
+ 'Invalid null operation: "1 div null".') {eval("1 / null")}
364
+ assert_raise_message(Sass::SyntaxError,
365
+ 'Invalid null operation: "1 mod null".') {eval("1 % null")}
366
+ assert_raise_message(Sass::SyntaxError,
367
+ 'Invalid null operation: "1 gt null".') {eval("1 > null")}
368
+ assert_raise_message(Sass::SyntaxError,
369
+ 'Invalid null operation: "null lt 1".') {eval("null < 1")}
370
+ assert_raise_message(Sass::SyntaxError,
371
+ 'Invalid null operation: "null plus null".') {eval("null + null")}
372
+ assert_raise_message(Sass::SyntaxError,
373
+ 'Invalid null operation: ""foo" plus null".') {eval("foo + null")}
374
+ end
375
+
329
376
  def test_equals
330
377
  assert_equal("true", resolve('"foo" == $foo', {},
331
378
  env("foo" => Sass::Script::String.new("foo"))))
@@ -424,6 +471,15 @@ SASS
424
471
  assert_raise_message(Sass::SyntaxError, "() isn't a valid CSS value.") {resolve("nth(append((), ()), 1)")}
425
472
  end
426
473
 
474
+ def test_list_with_nulls
475
+ assert_equal "1, 2, 3", resolve("1, 2, null, 3")
476
+ assert_equal "1 2 3", resolve("1 2 null 3")
477
+ assert_equal "1, 2, 3", resolve("1, 2, 3, null")
478
+ assert_equal "1 2 3", resolve("1 2 3 null")
479
+ assert_equal "1, 2, 3", resolve("null, 1, 2, 3")
480
+ assert_equal "1 2 3", resolve("null 1 2 3")
481
+ end
482
+
427
483
  def test_deep_argument_error_not_unwrapped
428
484
  assert_raise_message(ArgumentError, 'wrong number of arguments (0 for 1)') {resolve("arg-error()")}
429
485
  end
@@ -850,6 +850,16 @@ $zzz: zzz;
850
850
  SCSS
851
851
  end
852
852
 
853
+ def test_selector_interpolation_at_attr_end
854
+ assert_equal <<CSS, render(<<SCSS)
855
+ [foo=zzz] {
856
+ a: b; }
857
+ CSS
858
+ $zzz: zzz;
859
+ [foo=\#{$zzz}] { a: b; }
860
+ SCSS
861
+ end
862
+
853
863
  def test_selector_interpolation_at_dashes
854
864
  assert_equal <<CSS, render(<<SCSS)
855
865
  div {
@@ -1,8 +1,23 @@
1
+ ## 0.4.2 - May 1, 2012
2
+
3
+ ### Bug fixes
4
+
5
+ - [#21](https://github.com/guard/listen/issues/21): Issues when listening to changes in relative paths. (reported by [@akerbos][], fixed by [@Maher4Ever][])
6
+ - [#27](https://github.com/guard/listen/issues/27): Wrong reports for files modifications. (reported by [@cobychapple][], fixed by [@Maher4Ever][])
7
+ - Fix segmentation fault when profiling on Windows. ([@Maher4Ever][])
8
+ - Fix redundant watchers on Windows. ([@Maher4Ever][])
9
+
10
+ ### Improvements
11
+
12
+ - [#17](https://github.com/guard/listen/issues/17): Use regexp-patterns with the `ignore` method instead of supplying paths. (reported by [@fny][], added by [@Maher4Ever][])
13
+ - Speed improvement when listening to changes in directories with ignored paths. ([@Maher4Ever][])
14
+ - Added `.rbx` and `.svn` to ignored directories. ([@Maher4Ever][])
15
+
1
16
  ## 0.4.1 - April 15, 2012
2
17
 
3
18
  ### Bug fixes
4
19
 
5
- - [#18](https://github.com/guard/listen/issues/18): Listener crashes when removing directories with nested paths (reported by [@daemonza][], fixed by [@Maher4Ever][])
20
+ - [#18]((https://github.com/guard/listen/issues/18): Listener crashes when removing directories with nested paths. (reported by [@daemonza][], fixed by [@Maher4Ever][])
6
21
 
7
22
  ## 0.4.0 - April 9, 2012
8
23
 
@@ -70,3 +85,6 @@
70
85
  [@thibaudgg]: https://github.com/thibaudgg
71
86
  [@Maher4Ever]: https://github.com/Maher4Ever
72
87
  [@daemonza]: https://github.com/daemonza
88
+ [@akerbos]: https://github.com/akerbos
89
+ [@fny]: https://github.com/fny
90
+ [@cobychapple]: https://github.com/cobychapple
@@ -10,7 +10,7 @@ The Listen gem listens to file modifications and notifies you about the changes.
10
10
  * Automatic fallback to polling if OS-specific adapter doesn't work.
11
11
  * Detects files modification, addidation and removal.
12
12
  * Checksum comparaison for modifications made under the same second.
13
- * Allows ignoring paths and supplying filters for better results.
13
+ * Allows supplying regexp-patterns to ignore and filter paths for better results.
14
14
  * Tested on all Ruby environments via [travis-ci](http://travis-ci.org/guard/listen).
15
15
 
16
16
  ## Install
@@ -26,18 +26,18 @@ There are **two ways** to use Listen:
26
26
  1. Call `Listen.to` with either a single directory or multiple directories, then define the `change` callback in a block.
27
27
  2. Create a `listener` object and use it in an (ARel style) chainable way.
28
28
 
29
- Feel free to give your feeback via [Listen issues](https://github.com/guard/listener/issues)
29
+ Feel free to give your feeback via [Listen issues](https://github.com/guard/listen/issues)
30
30
 
31
31
  ### Block API
32
32
 
33
33
  ``` ruby
34
34
  # Listen to a single directory.
35
- Listen.to('dir/path/to/listen', filter: /.*\.rb/, ignore: '/ignored/path') do |modified, added, removed|
35
+ Listen.to('dir/path/to/listen', filter: /\.rb$/, ignore: %r{ignored/path/}) do |modified, added, removed|
36
36
  # ...
37
37
  end
38
38
 
39
39
  # Listen to multiple directories.
40
- Listen.to('dir/to/awesome_app', 'dir/to/other_app', filter: /.*\.rb/, latency: 0.1) do |modified, added, removed|
40
+ Listen.to('dir/to/awesome_app', 'dir/to/other_app', filter: /\.rb$/, latency: 0.1) do |modified, added, removed|
41
41
  # ...
42
42
  end
43
43
  ```
@@ -46,8 +46,8 @@ end
46
46
 
47
47
  ``` ruby
48
48
  listener = Listen.to('dir/path/to/listen')
49
- listener = listener.ignore('/ignored/path')
50
- listener = listener.filter(/.*\.rb/)
49
+ listener = listener.ignore(%r{^ignored/path/})
50
+ listener = listener.filter(/\.rb$/)
51
51
  listener = listener.latency(0.5)
52
52
  listener = listener.force_polling(true)
53
53
  listener = listener.polling_fallback_message(false)
@@ -59,8 +59,8 @@ listener.start # blocks execution!
59
59
 
60
60
  ``` ruby
61
61
  Listen.to('dir/path/to/listen')
62
- .ignore('/ignored/path')
63
- .filter(/.*\.rb/)
62
+ .ignore(%r{^ignored/path/})
63
+ .filter(/\.rb$/)
64
64
  .latency(0.5)
65
65
  .force_polling(true)
66
66
  .polling_fallback_message('custom message')
@@ -99,7 +99,7 @@ For an easier access, the `Listen.to` method can also be used to create a multi-
99
99
 
100
100
  ``` ruby
101
101
  listener = Listen.to('app/css', 'app/js')
102
- .ignore('vendor') # both js/vendor and css/vendor will be ignored
102
+ .ignore(%r{^vendor/}) # both js/vendor and css/vendor will be ignored
103
103
  .change(&assets_callback)
104
104
 
105
105
  listener.start # blocks execution!
@@ -184,15 +184,18 @@ end
184
184
  These options can be set through `Listen.to` params or via methods (see the "Object" API)
185
185
 
186
186
  ```ruby
187
- :filter => /.*\.rb/, /.*\.coffee/ # Filter files to listen to via a regexps list.
187
+ :filter => /\.rb$/, /\.coffee$/ # Filter files to listen to via a regexps list.
188
188
  # default: none
189
189
 
190
- :ignore => 'path1', 'path2' # Ignore a list of paths (root directory or sub-dir)
191
- # default: '.bundle', '.git', '.DS_Store', 'log', 'tmp', 'vendor'
190
+ :ignore => %r{app/CMake/}, /\.pid$/ # Ignore a list of paths (root directory or sub-dir)
191
+ # default: See DEFAULT_IGNORED_DIRECTORIES and DEFAULT_IGNORED_EXTENSIONS in Listen::DirectoryRecord
192
192
 
193
193
  :latency => 0.5 # Set the delay (**in seconds**) between checking for changes
194
194
  # default: 0.1 sec (1.0 sec for polling)
195
195
 
196
+ :relative_paths => true # Enable the use of relative paths in the callback.
197
+ # default: false
198
+
196
199
  :force_polling => true # Force the use of the polling adapter
197
200
  # default: none
198
201
 
@@ -200,6 +203,18 @@ These options can be set through `Listen.to` params or via methods (see the "Obj
200
203
  # default: "WARNING: Listen fallen back to polling, learn more at https://github.com/guard/listen#fallback."
201
204
  ```
202
205
 
206
+ ### The patterns for filtering and ignoring paths
207
+
208
+ Just like the unix convention of beginning absolute paths with the
209
+ directory-separator (forward slash `/` in unix) and with no prefix for relative paths,
210
+ Listen doesn't prefix relative paths (to the watched directory) with a directory-separator.
211
+
212
+ Therefore make sure _NOT_ to prefix your regexp-patterns for filtering or ignoring paths
213
+ with a directory-separator, otherwise they won't work as expected.
214
+
215
+ As an example: to ignore the `build` directory in a C-project, use `%r{build/}`
216
+ and not `%r{/build/}`.
217
+
203
218
  ### Non-blocking listening to changes
204
219
 
205
220
  Starting a listener blocks the current thread by default. That means any code after the
@@ -83,6 +83,14 @@ module Listen
83
83
  @turnstile.signal # ensure no thread is blocked
84
84
  end
85
85
 
86
+ # Returns whether the adapter is statred or not
87
+ #
88
+ # @return [Boolean] whether the adapter is started or not
89
+ #
90
+ def started?
91
+ @stop.nil? ? false : !@stop
92
+ end
93
+
86
94
  # Blocks the main thread until the poll thread
87
95
  # calls the callback.
88
96
  #
@@ -129,7 +137,7 @@ module Listen
129
137
  ensure
130
138
  Thread.kill(t) if t
131
139
  FileUtils.rm(test_file) if File.exists?(test_file)
132
- adapter.stop
140
+ adapter.stop if adapter && adapter.started?
133
141
  end
134
142
 
135
143
  private
@@ -1,22 +1,33 @@
1
1
  module Listen
2
2
  module Adapters
3
3
 
4
- # Watched INotify EVENTS
5
- #
6
- # @see http://www.tin.org/bin/man.cgi?section=7&topic=inotify
7
- # @see https://github.com/nex3/rb-inotify/blob/master/lib/rb-inotify/notifier.rb#L99-L177
8
- #
9
- EVENTS = %w[recursive attrib close modify move create delete delete_self move_self]
10
-
11
4
  # Listener implementation for Linux `inotify`.
12
5
  #
13
6
  class Linux < Adapter
14
7
 
8
+ # Watched inotify events
9
+ #
10
+ # @see http://www.tin.org/bin/man.cgi?section=7&topic=inotify
11
+ # @see https://github.com/nex3/rb-inotify/blob/master/lib/rb-inotify/notifier.rb#L99-L177
12
+ #
13
+ EVENTS = %w[recursive attrib close modify move create delete delete_self move_self]
14
+
15
+ # The message to show when the limit of inotify watchers is not enough
16
+ #
17
+ INOTIFY_LIMIT_MESSAGE = <<-EOS.gsub(/^\s*/, '')
18
+ Listen error: unable to monitor directories for changes.
19
+
20
+ Please head to https://github.com/guard/listen/wiki/Increasing-the-amount-of-inotify-watchers
21
+ for information on how to solve this issue.
22
+ EOS
23
+
15
24
  # Initializes the Adapter. See {Listen::Adapter#initialize} for more info.
16
25
  #
17
26
  def initialize(directories, options = {}, &callback)
18
27
  super
19
28
  @worker = init_worker
29
+ rescue Errno::ENOSPC
30
+ abort(INOTIFY_LIMIT_MESSAGE)
20
31
  end
21
32
 
22
33
  # Starts the adapter.