sass 3.3.0.alpha.93 → 3.3.0.alpha.101
Sign up to get free protection for your applications and to get access to all the features.
- data/REVISION +1 -1
- data/VERSION +1 -1
- data/VERSION_DATE +1 -1
- data/bin/sass +2 -1
- data/bin/sass-convert +2 -1
- data/bin/scss +2 -1
- data/lib/sass/cache_stores/chain.rb +1 -1
- data/lib/sass/cache_stores/filesystem.rb +0 -1
- data/lib/sass/engine.rb +7 -1
- data/lib/sass/exec.rb +1 -0
- data/lib/sass/importers/filesystem.rb +1 -1
- data/lib/sass/media.rb +1 -4
- data/lib/sass/plugin/compiler.rb +1 -1
- data/lib/sass/script/funcall.rb +43 -8
- data/lib/sass/script/functions.rb +8 -16
- data/lib/sass/script/lexer.rb +0 -2
- data/lib/sass/script/parser.rb +26 -25
- data/lib/sass/scss/parser.rb +13 -1
- data/lib/sass/selector/simple_sequence.rb +1 -1
- data/lib/sass/tree/comment_node.rb +2 -2
- data/lib/sass/tree/visitors/cssize.rb +10 -1
- data/lib/sass/tree/visitors/perform.rb +4 -2
- data/lib/sass/util.rb +54 -1
- data/lib/sass/util/multibyte_string_scanner.rb +29 -8
- data/test/sass/engine_test.rb +20 -4
- data/test/sass/extend_test.rb +15 -0
- data/test/sass/functions_test.rb +20 -1
- data/test/sass/script_test.rb +5 -1
- data/vendor/listen/CHANGELOG.md +76 -2
- data/vendor/listen/CONTRIBUTING.md +38 -0
- data/vendor/listen/Gemfile +8 -1
- data/vendor/listen/Guardfile +1 -1
- data/vendor/listen/LICENSE +1 -1
- data/vendor/listen/README.md +8 -5
- data/vendor/listen/lib/listen.rb +7 -5
- data/vendor/listen/lib/listen/adapter.rb +76 -29
- data/vendor/listen/lib/listen/adapters/bsd.rb +112 -0
- data/vendor/listen/lib/listen/adapters/darwin.rb +11 -10
- data/vendor/listen/lib/listen/adapters/linux.rb +33 -30
- data/vendor/listen/lib/listen/adapters/polling.rb +2 -1
- data/vendor/listen/lib/listen/adapters/windows.rb +27 -21
- data/vendor/listen/lib/listen/dependency_manager.rb +126 -0
- data/vendor/listen/lib/listen/directory_record.rb +63 -10
- data/vendor/listen/lib/listen/listener.rb +22 -0
- data/vendor/listen/lib/listen/multi_listener.rb +22 -0
- data/vendor/listen/lib/listen/version.rb +1 -1
- data/vendor/listen/listen.gemspec +0 -4
- data/vendor/listen/spec/listen/adapter_spec.rb +45 -4
- data/vendor/listen/spec/listen/adapters/bsd_spec.rb +36 -0
- data/vendor/listen/spec/listen/adapters/darwin_spec.rb +6 -0
- data/vendor/listen/spec/listen/adapters/linux_spec.rb +6 -0
- data/vendor/listen/spec/listen/adapters/windows_spec.rb +7 -1
- data/vendor/listen/spec/listen/dependency_manager_spec.rb +107 -0
- data/vendor/listen/spec/listen/directory_record_spec.rb +91 -4
- data/vendor/listen/spec/listen/listener_spec.rb +14 -0
- data/vendor/listen/spec/listen/multi_listener_spec.rb +19 -1
- data/vendor/listen/spec/spec_helper.rb +6 -3
- data/vendor/listen/spec/support/adapter_helper.rb +125 -212
- data/vendor/listen/spec/support/listeners_helper.rb +13 -1
- data/vendor/listen/spec/support/platform_helper.rb +4 -0
- metadata +11 -6
@@ -3,23 +3,44 @@ require 'strscan'
|
|
3
3
|
if Sass::Util.ruby1_8?
|
4
4
|
Sass::Util::MultibyteStringScanner = StringScanner
|
5
5
|
else
|
6
|
+
if Sass::Util.rbx?
|
7
|
+
# Rubinius's StringScanner class implements some of its methods in terms of
|
8
|
+
# others, which causes us to double-count bytes in some cases if we do
|
9
|
+
# straightforward inheritance. To work around this, we use a delegate class.
|
10
|
+
require 'delegate'
|
11
|
+
class Sass::Util::MultibyteStringScanner < DelegateClass(StringScanner)
|
12
|
+
def initialize(str)
|
13
|
+
super(StringScanner.new(str))
|
14
|
+
@mb_pos = 0
|
15
|
+
@mb_matched_size = nil
|
16
|
+
@mb_last_pos = nil
|
17
|
+
end
|
18
|
+
|
19
|
+
def is_a?(klass)
|
20
|
+
__getobj__.is_a?(klass) || super
|
21
|
+
end
|
22
|
+
end
|
23
|
+
else
|
24
|
+
class Sass::Util::MultibyteStringScanner < StringScanner
|
25
|
+
def initialize(str)
|
26
|
+
super
|
27
|
+
@mb_pos = 0
|
28
|
+
@mb_matched_size = nil
|
29
|
+
@mb_last_pos = nil
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
6
34
|
# A wrapper of the native StringScanner class that works correctly with
|
7
35
|
# multibyte character encodings. The native class deals only in bytes, not
|
8
36
|
# characters, for methods like [#pos] and [#matched_size]. This class deals
|
9
37
|
# only in characters, instead.
|
10
|
-
class Sass::Util::MultibyteStringScanner
|
38
|
+
class Sass::Util::MultibyteStringScanner
|
11
39
|
def self.new(str)
|
12
40
|
return StringScanner.new(str) if str.ascii_only?
|
13
41
|
super
|
14
42
|
end
|
15
43
|
|
16
|
-
def initialize(str)
|
17
|
-
super
|
18
|
-
@mb_pos = 0
|
19
|
-
@mb_matched_size = nil
|
20
|
-
@mb_last_pos = nil
|
21
|
-
end
|
22
|
-
|
23
44
|
alias_method :byte_pos, :pos
|
24
45
|
alias_method :byte_matched_size, :matched_size
|
25
46
|
|
data/test/sass/engine_test.rb
CHANGED
@@ -143,13 +143,13 @@ MSG
|
|
143
143
|
'+foo(1 + 1: 2)' => 'Invalid CSS after "(1 + 1": expected comma, was ": 2)"',
|
144
144
|
'+foo($var: )' => 'Invalid CSS after "($var: ": expected mixin argument, was ")"',
|
145
145
|
'+foo($var: a, $var: b)' => 'Keyword argument "$var" passed more than once',
|
146
|
-
'+foo($var-var: a, $var_var: b)' => 'Keyword argument "$
|
147
|
-
'+foo($var_var: a, $var-var: b)' => 'Keyword argument "$
|
146
|
+
'+foo($var-var: a, $var_var: b)' => 'Keyword argument "$var_var" passed more than once',
|
147
|
+
'+foo($var_var: a, $var-var: b)' => 'Keyword argument "$var-var" passed more than once',
|
148
148
|
"a\n b: foo(1 + 1: 2)" => 'Invalid CSS after "foo(1 + 1": expected comma, was ": 2)"',
|
149
149
|
"a\n b: foo($var: )" => 'Invalid CSS after "foo($var: ": expected function argument, was ")"',
|
150
150
|
"a\n b: foo($var: a, $var: b)" => 'Keyword argument "$var" passed more than once',
|
151
|
-
"a\n b: foo($var-var: a, $var_var: b)" => 'Keyword argument "$
|
152
|
-
"a\n b: foo($var_var: a, $var-var: b)" => 'Keyword argument "$
|
151
|
+
"a\n b: foo($var-var: a, $var_var: b)" => 'Keyword argument "$var_var" passed more than once',
|
152
|
+
"a\n b: foo($var_var: a, $var-var: b)" => 'Keyword argument "$var-var" passed more than once',
|
153
153
|
"@if foo\n @extend .bar" => ["Extend directives may only be used within rules.", 2],
|
154
154
|
"$var: true\n@while $var\n @extend .bar\n $var: false" => ["Extend directives may only be used within rules.", 3],
|
155
155
|
"@for $i from 0 to 1\n @extend .bar" => ["Extend directives may only be used within rules.", 2],
|
@@ -2416,6 +2416,22 @@ SASS
|
|
2416
2416
|
|
2417
2417
|
# Regression tests
|
2418
2418
|
|
2419
|
+
def test_supports_bubbles
|
2420
|
+
assert_equal <<CSS, render(<<SASS)
|
2421
|
+
parent {
|
2422
|
+
background: orange; }
|
2423
|
+
@supports (perspective: 10px) or (-moz-perspective: 10px) {
|
2424
|
+
parent child {
|
2425
|
+
background: blue; } }
|
2426
|
+
CSS
|
2427
|
+
parent
|
2428
|
+
background: orange
|
2429
|
+
@supports (perspective: 10px) or (-moz-perspective: 10px)
|
2430
|
+
child
|
2431
|
+
background: blue
|
2432
|
+
SASS
|
2433
|
+
end
|
2434
|
+
|
2419
2435
|
def test_line_numbers_with_dos_line_endings
|
2420
2436
|
assert_equal <<CSS, render(<<SASS, :line_comments => true)
|
2421
2437
|
/* line 5, test_line_numbers_with_dos_line_endings_inline.sass */
|
data/test/sass/extend_test.rb
CHANGED
@@ -1130,6 +1130,21 @@ SCSS
|
|
1130
1130
|
|
1131
1131
|
# Regression Tests
|
1132
1132
|
|
1133
|
+
def test_extend_in_double_nested_media_query
|
1134
|
+
assert_equal <<CSS, render(<<SCSS)
|
1135
|
+
@media all and (orientation: landscape) {
|
1136
|
+
.bar {
|
1137
|
+
color: blue; } }
|
1138
|
+
CSS
|
1139
|
+
@media all {
|
1140
|
+
@media (orientation: landscape) {
|
1141
|
+
%foo {color: blue}
|
1142
|
+
.bar {@extend %foo}
|
1143
|
+
}
|
1144
|
+
}
|
1145
|
+
SCSS
|
1146
|
+
end
|
1147
|
+
|
1133
1148
|
def test_partially_failed_extend
|
1134
1149
|
assert_no_warning {assert_equal(<<CSS, render(<<SCSS))}
|
1135
1150
|
.rc, test {
|
data/test/sass/functions_test.rb
CHANGED
@@ -1103,14 +1103,17 @@ MSG
|
|
1103
1103
|
def test_zip
|
1104
1104
|
assert_equal("1 3 5, 2 4 6", evaluate("zip(1 2, 3 4, 5 6)"))
|
1105
1105
|
assert_equal("1 4 7, 2 5 8", evaluate("zip(1 2 3, 4 5 6, 7 8)"))
|
1106
|
+
assert_equal("1 2 3", evaluate("zip(1, 2, 3)"))
|
1106
1107
|
end
|
1107
1108
|
|
1108
1109
|
def test_index
|
1109
1110
|
assert_equal("1", evaluate("index(1px solid blue, 1px)"))
|
1110
1111
|
assert_equal("2", evaluate("index(1px solid blue, solid)"))
|
1111
1112
|
assert_equal("3", evaluate("index(1px solid blue, #00f)"))
|
1113
|
+
assert_equal("1", evaluate("index(1px, 1px)"))
|
1112
1114
|
assert_equal("false", evaluate("index(1px solid blue, 1em)"))
|
1113
1115
|
assert_equal("false", evaluate("index(1px solid blue, notfound)"))
|
1116
|
+
assert_equal("false", evaluate("index(1px, #00f)"))
|
1114
1117
|
end
|
1115
1118
|
|
1116
1119
|
def test_if
|
@@ -1179,21 +1182,37 @@ MSG
|
|
1179
1182
|
end
|
1180
1183
|
|
1181
1184
|
def test_assert_unit
|
1182
|
-
ctx = Sass::Script::Functions::EvaluationContext.new({})
|
1185
|
+
ctx = Sass::Script::Functions::EvaluationContext.new(Sass::Environment.new(nil, {}))
|
1183
1186
|
ctx.assert_unit Sass::Script::Number.new(10, ["px"], []), "px"
|
1184
1187
|
ctx.assert_unit Sass::Script::Number.new(10, [], []), nil
|
1188
|
+
|
1185
1189
|
begin
|
1186
1190
|
ctx.assert_unit Sass::Script::Number.new(10, [], []), "px"
|
1187
1191
|
fail
|
1188
1192
|
rescue ArgumentError => e
|
1189
1193
|
assert_equal "Expected 10 to have a unit of px", e.message
|
1190
1194
|
end
|
1195
|
+
|
1191
1196
|
begin
|
1192
1197
|
ctx.assert_unit Sass::Script::Number.new(10, ["px"], []), nil
|
1193
1198
|
fail
|
1194
1199
|
rescue ArgumentError => e
|
1195
1200
|
assert_equal "Expected 10px to be unitless", e.message
|
1196
1201
|
end
|
1202
|
+
|
1203
|
+
begin
|
1204
|
+
ctx.assert_unit Sass::Script::Number.new(10, [], []), "px", "arg"
|
1205
|
+
fail
|
1206
|
+
rescue ArgumentError => e
|
1207
|
+
assert_equal "Expected $arg to have a unit of px but got 10", e.message
|
1208
|
+
end
|
1209
|
+
|
1210
|
+
begin
|
1211
|
+
ctx.assert_unit Sass::Script::Number.new(10, ["px"], []), nil, "arg"
|
1212
|
+
fail
|
1213
|
+
rescue ArgumentError => e
|
1214
|
+
assert_equal "Expected $arg to be unitless but got 10px", e.message
|
1215
|
+
end
|
1197
1216
|
end
|
1198
1217
|
|
1199
1218
|
## Regression Tests
|
data/test/sass/script_test.rb
CHANGED
@@ -493,7 +493,9 @@ SASS
|
|
493
493
|
# argument errors caused by programming errors in a function and
|
494
494
|
# argument errors explicitly thrown within that function.
|
495
495
|
return if RUBY_PLATFORM =~ /java/
|
496
|
-
|
496
|
+
|
497
|
+
# Don't validate the message; it's different on Rubinius.
|
498
|
+
assert_raise(ArgumentError) {resolve("arg-error()")}
|
497
499
|
end
|
498
500
|
|
499
501
|
def test_shallow_argument_error_unwrapped
|
@@ -544,6 +546,8 @@ SASS
|
|
544
546
|
assert Sass::Script::Number.new(10, "px").is_unit?("px")
|
545
547
|
assert Sass::Script::Number.new(10).is_unit?(nil)
|
546
548
|
assert !Sass::Script::Number.new(10, "px", "em").is_unit?("px")
|
549
|
+
assert !Sass::Script::Number.new(10, [], "em").is_unit?("em")
|
550
|
+
assert !Sass::Script::Number.new(10, ["px", "em"]).is_unit?("px")
|
547
551
|
end
|
548
552
|
|
549
553
|
private
|
data/vendor/listen/CHANGELOG.md
CHANGED
@@ -1,3 +1,62 @@
|
|
1
|
+
## 0.7.2 - January 11, 2013
|
2
|
+
|
3
|
+
### Bug fix
|
4
|
+
|
5
|
+
- [#76] Exception on filename which is not in UTF-8. (fixed by [@piotr-sokolowski][])
|
6
|
+
|
7
|
+
## 0.7.1 - January 6, 2013
|
8
|
+
|
9
|
+
### Bug fix
|
10
|
+
|
11
|
+
- [#75] Default high precision off if the mtime call fails. (fixed by [@zanker][])
|
12
|
+
|
13
|
+
## 0.7.0 - December 29, 2012
|
14
|
+
|
15
|
+
### Bug fixes
|
16
|
+
|
17
|
+
- [#73] Rescue Errno::EOPNOTSUPP on sha1_checksum generation. (fixed by [@thibaudgg][])
|
18
|
+
|
19
|
+
### New feature
|
20
|
+
|
21
|
+
- Add support for *BSD with rb-kqueue. ([@mat813][])
|
22
|
+
|
23
|
+
## 0.6.0 - November 21, 2012
|
24
|
+
|
25
|
+
### New feature
|
26
|
+
|
27
|
+
- Add bang versions for filter and ignore listener methods. ([@tarsolya][])
|
28
|
+
|
29
|
+
## 0.5.3 - October 3, 2012
|
30
|
+
|
31
|
+
### Bug fixes
|
32
|
+
|
33
|
+
- [#65] Fix ruby warning in adapter.rb. (fixed by [@vongruenigen][])
|
34
|
+
- [#64] ENXIO raised when hashing UNIX domain socket file. (fixed by [@sunaku][])
|
35
|
+
|
36
|
+
## 0.5.2 - Septemper 23, 2012
|
37
|
+
|
38
|
+
### Bug fix
|
39
|
+
|
40
|
+
- [#62] Fix double change callback with polling adapter. (fixed by [@thibaudgg][])
|
41
|
+
|
42
|
+
## 0.5.1 - Septemper 18, 2012
|
43
|
+
|
44
|
+
### Bug fix
|
45
|
+
|
46
|
+
- [#61] Fix a synchronisation bug that caused constant fallback to polling. (fixed by [@Maher4Ever][])
|
47
|
+
|
48
|
+
## 0.5.0 - Septemper 1, 2012
|
49
|
+
|
50
|
+
### New features
|
51
|
+
|
52
|
+
- Add a dependency manager to handle platform-specific gems. So there is no need anymore to install
|
53
|
+
extra gems which will never be used on the user system. ([@Maher4Ever][])
|
54
|
+
- Add a manual reporting mode to the adapters. ([@Maher4Ever][])
|
55
|
+
|
56
|
+
### Improvements
|
57
|
+
|
58
|
+
- [#28] Enhance the speed of detecting changes on Windows by using the [WDM][] library. ([@Maher4Ever][])
|
59
|
+
|
1
60
|
## 0.4.7 - June 27, 2012
|
2
61
|
|
3
62
|
### Bug fixes
|
@@ -128,8 +187,16 @@
|
|
128
187
|
[#21]: https://github.com/guard/listen/issues/21
|
129
188
|
[#24]: https://github.com/guard/listen/issues/24
|
130
189
|
[#27]: https://github.com/guard/listen/issues/27
|
190
|
+
[#28]: https://github.com/guard/listen/issues/28
|
131
191
|
[#32]: https://github.com/guard/listen/issues/32
|
132
|
-
[#
|
192
|
+
[#41]: https://github.com/guard/listen/issues/41
|
193
|
+
[#61]: https://github.com/guard/listen/issues/61
|
194
|
+
[#62]: https://github.com/guard/listen/issues/62
|
195
|
+
[#64]: https://github.com/guard/listen/issues/64
|
196
|
+
[#65]: https://github.com/guard/listen/issues/65
|
197
|
+
[#73]: https://github.com/guard/listen/issues/73
|
198
|
+
[#75]: https://github.com/guard/listen/issues/75
|
199
|
+
[#76]: https://github.com/guard/listen/issues/76
|
133
200
|
[@Maher4Ever]: https://github.com/Maher4Ever
|
134
201
|
[@dkubb]: https://github.com/dkubb
|
135
202
|
[@ebroder]: https://github.com/ebroder
|
@@ -138,10 +205,17 @@
|
|
138
205
|
[@daemonza]: https://github.com/daemonza
|
139
206
|
[@fny]: https://github.com/fny
|
140
207
|
[@markiz]: https://github.com/markiz
|
208
|
+
[@mat813]: https://github.com/mat813
|
141
209
|
[@napcs]: https://github.com/napcs
|
142
210
|
[@netzpirat]: https://github.com/netzpirat
|
143
211
|
[@nex3]: https://github.com/nex3
|
212
|
+
[@piotr-sokolowski]: https://github.com/piotr-sokolowski
|
144
213
|
[@rymai]: https://github.com/rymai
|
145
214
|
[@scottdavis]: https://github.com/scottdavis
|
215
|
+
[@sunaku]: https://github.com/sunaku
|
146
216
|
[@textgoeshere]: https://github.com/textgoeshere
|
147
|
-
[@thibaudgg]: https://github.com/thibaudgg
|
217
|
+
[@thibaudgg]: https://github.com/thibaudgg
|
218
|
+
[@tarsolya]: https://github.com/tarsolya
|
219
|
+
[@vongruenigen]: https://github.com/vongruenigen
|
220
|
+
[@zanker]: https://github.com/zanker
|
221
|
+
[WDM]: https://github.com/Maher4Ever/wdm
|
@@ -0,0 +1,38 @@
|
|
1
|
+
Contribute to Listen
|
2
|
+
===================
|
3
|
+
|
4
|
+
File an issue
|
5
|
+
-------------
|
6
|
+
|
7
|
+
You can report bugs and feature requests to [GitHub Issues](https://github.com/guard/listen/issues).
|
8
|
+
|
9
|
+
**Please don't ask question in the issue tracker**, instead ask them in our
|
10
|
+
[Google group](http://groups.google.com/group/guard-dev) or on `#guard` (irc.freenode.net).
|
11
|
+
|
12
|
+
Try to figure out where the issue belongs to: Is it an issue with Listen itself or with Guard?
|
13
|
+
|
14
|
+
When you file a bug, please try to follow these simple rules if applicable:
|
15
|
+
|
16
|
+
* Make sure you run Listen with `bundle exec` first.
|
17
|
+
* Add your `Guardfile` (if used) and `Gemfile` to the issue.
|
18
|
+
* Make sure that the issue is reproducible with your description.
|
19
|
+
|
20
|
+
**It's most likely that your bug gets resolved faster if you provide as much information as possible!**
|
21
|
+
|
22
|
+
Development
|
23
|
+
-----------
|
24
|
+
|
25
|
+
* Documentation hosted at [RubyDoc](http://rubydoc.info/github/guard/listen/master/frames).
|
26
|
+
* Source hosted at [GitHub](https://github.com/guard/listen).
|
27
|
+
|
28
|
+
Pull requests are very welcome! Please try to follow these simple rules if applicable:
|
29
|
+
|
30
|
+
* Please create a topic branch for every separate change you make.
|
31
|
+
* Make sure your patches are well tested. All specs run with `rake spec` must pass.
|
32
|
+
* Update the [Yard](http://yardoc.org/) documentation.
|
33
|
+
* Update the [README](https://github.com/guard/listen/blob/master/README.md).
|
34
|
+
* Update the [CHANGELOG](https://github.com/guard/listen/blob/master/CHANGELOG.md) for noteworthy changes.
|
35
|
+
* Please **do not change** the version number.
|
36
|
+
|
37
|
+
For questions please join us in our [Google group](http://groups.google.com/group/guard-dev) or on
|
38
|
+
`#guard` (irc.freenode.net).
|
data/vendor/listen/Gemfile
CHANGED
@@ -1,9 +1,16 @@
|
|
1
|
+
require 'rbconfig'
|
2
|
+
|
1
3
|
source :rubygems
|
2
4
|
|
3
5
|
gemspec
|
4
6
|
|
5
7
|
gem 'rake'
|
6
8
|
|
9
|
+
gem 'rb-kqueue', '~> 0.2' if RbConfig::CONFIG['target_os'] =~ /freebsd/i
|
10
|
+
gem 'rb-fsevent', '~> 0.9.1' if RbConfig::CONFIG['target_os'] =~ /darwin(1.+)?$/i
|
11
|
+
gem 'rb-inotify', '~> 0.8.8', :github => 'mbj/rb-inotify' if RbConfig::CONFIG['target_os'] =~ /linux/i
|
12
|
+
gem 'wdm', '~> 0.0.3' if RbConfig::CONFIG['target_os'] =~ /mswin|mingw/i
|
13
|
+
|
7
14
|
group :development do
|
8
15
|
platform :ruby do
|
9
16
|
gem 'coolline'
|
@@ -20,4 +27,4 @@ end
|
|
20
27
|
|
21
28
|
group :test do
|
22
29
|
gem 'rspec'
|
23
|
-
end
|
30
|
+
end
|
data/vendor/listen/Guardfile
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
guard :rspec, :all_on_start => false, :all_after_pass => false
|
1
|
+
guard :rspec, :all_on_start => false, :all_after_pass => false do
|
2
2
|
watch(%r{^spec/.+_spec\.rb$})
|
3
3
|
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
4
4
|
watch('spec/support/adapter_helper.rb') { "spec/listen/adapters" }
|
data/vendor/listen/LICENSE
CHANGED
data/vendor/listen/README.md
CHANGED
@@ -6,10 +6,10 @@ The Listen gem listens to file modifications and notifies you about the changes.
|
|
6
6
|
|
7
7
|
* Works everywhere!
|
8
8
|
* Supports watching multiple directories from a single listener.
|
9
|
-
* OS-specific adapters for Mac OS X 10.6+, Linux and Windows.
|
9
|
+
* OS-specific adapters for Mac OS X 10.6+, Linux, *BSD and Windows.
|
10
10
|
* Automatic fallback to polling if OS-specific adapter doesn't work.
|
11
|
-
* Detects
|
12
|
-
* Checksum
|
11
|
+
* Detects file modification, addition and removal.
|
12
|
+
* Checksum comparison for modifications made under the same second.
|
13
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
|
|
@@ -215,6 +215,8 @@ with a directory-separator, otherwise they won't work as expected.
|
|
215
215
|
As an example: to ignore the `build` directory in a C-project, use `%r{build/}`
|
216
216
|
and not `%r{/build/}`.
|
217
217
|
|
218
|
+
Use `#filter!` and `#ignore!` methods to overwrites default patterns.
|
219
|
+
|
218
220
|
### Non-blocking listening to changes
|
219
221
|
|
220
222
|
Starting a listener blocks the current thread by default. That means any code after the
|
@@ -240,7 +242,7 @@ block execution. See the "Block API" section for an example.
|
|
240
242
|
## Listen adapters
|
241
243
|
|
242
244
|
The Listen gem has a set of adapters to notify it when there are changes.
|
243
|
-
There are 3 OS-specific adapters to support Mac, Linux and Windows. These adapters are fast
|
245
|
+
There are 3 OS-specific adapters to support Mac, Linux, *BSD and Windows. These adapters are fast
|
244
246
|
as they use some system-calls to implement the notifying function.
|
245
247
|
|
246
248
|
There is also a polling adapter which is a cross-platform adapter and it will
|
@@ -251,7 +253,6 @@ want to force the use of the polling adapter, either use the `:force_polling` op
|
|
251
253
|
while initializing the listener or call the `force_polling` method on your listener
|
252
254
|
before starting it.
|
253
255
|
|
254
|
-
<a name="fallback"/>
|
255
256
|
## Polling fallback
|
256
257
|
|
257
258
|
When a OS-specific adapter doesn't work the Listen gem automatically falls back to the polling adapter.
|
@@ -286,6 +287,7 @@ For questions please join us in our [Google group](http://groups.google.com/grou
|
|
286
287
|
* [Michael Kessler (netzpirat)][] for having written the [initial specs](https://github.com/guard/listen/commit/1e457b13b1bb8a25d2240428ce5ed488bafbed1f).
|
287
288
|
* [Travis Tilley (ttilley)][] for this awesome work on [fssm][] & [rb-fsevent][].
|
288
289
|
* [Nathan Weizenbaum (nex3)][] for [rb-inotify][], a thorough inotify wrapper.
|
290
|
+
* [Mathieu Arnold (mat813)][] for [rb-kqueue][], a simple kqueue wrapper.
|
289
291
|
* [stereobooster][] for [rb-fchange][], windows support wouldn't exist without him.
|
290
292
|
* [Yehuda Katz (wycats)][] for [vigilo][], that has been a great source of inspiration.
|
291
293
|
|
@@ -304,6 +306,7 @@ For questions please join us in our [Google group](http://groups.google.com/grou
|
|
304
306
|
[Travis Tilley (ttilley)]: https://github.com/ttilley
|
305
307
|
[fssm]: https://github.com/ttilley/fssm
|
306
308
|
[rb-fsevent]: https://github.com/thibaudgg/rb-fsevent
|
309
|
+
[Mathieu Arnold (mat813)]: https://github.com/mat813
|
307
310
|
[Nathan Weizenbaum (nex3)]: https://github.com/nex3
|
308
311
|
[rb-inotify]: https://github.com/nex3/rb-inotify
|
309
312
|
[stereobooster]: https://github.com/stereobooster
|
data/vendor/listen/lib/listen.rb
CHANGED
@@ -1,14 +1,16 @@
|
|
1
1
|
module Listen
|
2
2
|
|
3
|
-
autoload :Turnstile,
|
4
|
-
autoload :Listener,
|
5
|
-
autoload :MultiListener,
|
6
|
-
autoload :DirectoryRecord,
|
7
|
-
autoload :
|
3
|
+
autoload :Turnstile, 'listen/turnstile'
|
4
|
+
autoload :Listener, 'listen/listener'
|
5
|
+
autoload :MultiListener, 'listen/multi_listener'
|
6
|
+
autoload :DirectoryRecord, 'listen/directory_record'
|
7
|
+
autoload :DependencyManager, 'listen/dependency_manager'
|
8
|
+
autoload :Adapter, 'listen/adapter'
|
8
9
|
|
9
10
|
module Adapters
|
10
11
|
autoload :Darwin, 'listen/adapters/darwin'
|
11
12
|
autoload :Linux, 'listen/adapters/linux'
|
13
|
+
autoload :BSD, 'listen/adapters/bsd'
|
12
14
|
autoload :Windows, 'listen/adapters/windows'
|
13
15
|
autoload :Polling, 'listen/adapters/polling'
|
14
16
|
end
|
@@ -10,8 +10,15 @@ module Listen
|
|
10
10
|
# The default delay between checking for changes.
|
11
11
|
DEFAULT_LATENCY = 0.25
|
12
12
|
|
13
|
+
# The default warning message when there is a missing dependency.
|
14
|
+
MISSING_DEPENDENCY_MESSAGE = <<-EOS.gsub(/^\s*/, '')
|
15
|
+
For a better performance, it's recommended that you satisfy the missing dependency.
|
16
|
+
EOS
|
17
|
+
|
13
18
|
# The default warning message when falling back to polling adapter.
|
14
|
-
POLLING_FALLBACK_MESSAGE =
|
19
|
+
POLLING_FALLBACK_MESSAGE = <<-EOS.gsub(/^\s*/, '')
|
20
|
+
Listen will be polling changes. Learn more at https://github.com/guard/listen#polling-fallback.
|
21
|
+
EOS
|
15
22
|
|
16
23
|
# Selects the appropriate adapter implementation for the
|
17
24
|
# current OS and initializes it.
|
@@ -31,18 +38,28 @@ module Listen
|
|
31
38
|
def self.select_and_initialize(directories, options = {}, &callback)
|
32
39
|
return Adapters::Polling.new(directories, options, &callback) if options.delete(:force_polling)
|
33
40
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
Adapters::
|
38
|
-
|
39
|
-
Adapters::
|
40
|
-
|
41
|
-
|
42
|
-
|
41
|
+
warning = ''
|
42
|
+
|
43
|
+
begin
|
44
|
+
if Adapters::Darwin.usable_and_works?(directories, options)
|
45
|
+
return Adapters::Darwin.new(directories, options, &callback)
|
46
|
+
elsif Adapters::Linux.usable_and_works?(directories, options)
|
47
|
+
return Adapters::Linux.new(directories, options, &callback)
|
48
|
+
elsif Adapters::BSD.usable_and_works?(directories, options)
|
49
|
+
return Adapters::BSD.new(directories, options, &callback)
|
50
|
+
elsif Adapters::Windows.usable_and_works?(directories, options)
|
51
|
+
return Adapters::Windows.new(directories, options, &callback)
|
43
52
|
end
|
44
|
-
|
53
|
+
rescue DependencyManager::Error => e
|
54
|
+
warning += e.message + "\n" + MISSING_DEPENDENCY_MESSAGE
|
55
|
+
end
|
56
|
+
|
57
|
+
unless options[:polling_fallback_message] == false
|
58
|
+
warning += options[:polling_fallback_message] || POLLING_FALLBACK_MESSAGE
|
59
|
+
Kernel.warn "[Listen warning]:\n" + warning.gsub(/^(.*)/, ' \1')
|
45
60
|
end
|
61
|
+
|
62
|
+
Adapters::Polling.new(directories, options, &callback)
|
46
63
|
end
|
47
64
|
|
48
65
|
# Initializes the adapter.
|
@@ -50,6 +67,7 @@ module Listen
|
|
50
67
|
# @param [String, Array<String>] directories the directories to watch
|
51
68
|
# @param [Hash] options the adapter options
|
52
69
|
# @option options [Float] latency the delay between checking for changes in seconds
|
70
|
+
# @option options [Boolean] report_changes whether or not to automatically report changes (run the callback)
|
53
71
|
#
|
54
72
|
# @yield [changed_dirs, options] callback Callback called when a change happens
|
55
73
|
# @yieldparam [Array<String>] changed_dirs the changed directories
|
@@ -60,12 +78,13 @@ module Listen
|
|
60
78
|
def initialize(directories, options = {}, &callback)
|
61
79
|
@directories = Array(directories)
|
62
80
|
@callback = callback
|
63
|
-
@latency ||= DEFAULT_LATENCY
|
64
|
-
@latency = options[:latency] if options[:latency]
|
65
81
|
@paused = false
|
66
82
|
@mutex = Mutex.new
|
67
83
|
@changed_dirs = Set.new
|
68
84
|
@turnstile = Turnstile.new
|
85
|
+
@latency ||= DEFAULT_LATENCY
|
86
|
+
@latency = options[:latency] if options[:latency]
|
87
|
+
@report_changes = options[:report_changes].nil? ? true : options[:report_changes]
|
69
88
|
end
|
70
89
|
|
71
90
|
# Starts the adapter.
|
@@ -92,12 +111,37 @@ module Listen
|
|
92
111
|
end
|
93
112
|
|
94
113
|
# Blocks the main thread until the poll thread
|
95
|
-
#
|
114
|
+
# runs the callback.
|
96
115
|
#
|
97
116
|
def wait_for_callback
|
98
117
|
@turnstile.wait unless @paused
|
99
118
|
end
|
100
119
|
|
120
|
+
# Blocks the main thread until N changes are
|
121
|
+
# detected.
|
122
|
+
#
|
123
|
+
def wait_for_changes(goal = 0)
|
124
|
+
changes = 0
|
125
|
+
|
126
|
+
loop do
|
127
|
+
@mutex.synchronize { changes = @changed_dirs.size }
|
128
|
+
|
129
|
+
return if @paused || @stop
|
130
|
+
return if changes >= goal
|
131
|
+
|
132
|
+
sleep(@latency)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
# Checks if the adapter is usable on the current OS.
|
137
|
+
#
|
138
|
+
# @return [Boolean] whether usable or not
|
139
|
+
#
|
140
|
+
def self.usable?
|
141
|
+
load_depenencies
|
142
|
+
dependencies_loaded?
|
143
|
+
end
|
144
|
+
|
101
145
|
# Checks if the adapter is usable and works on the current OS.
|
102
146
|
#
|
103
147
|
# @param [String, Array<String>] directories the directories to watch
|
@@ -124,7 +168,7 @@ module Listen
|
|
124
168
|
def self.works?(directory, options = {})
|
125
169
|
work = false
|
126
170
|
test_file = "#{directory}/.listen_test"
|
127
|
-
callback = lambda {
|
171
|
+
callback = lambda { |*| work = true }
|
128
172
|
adapter = self.new(directory, options, &callback)
|
129
173
|
adapter.start(false)
|
130
174
|
|
@@ -140,27 +184,30 @@ module Listen
|
|
140
184
|
adapter.stop if adapter && adapter.started?
|
141
185
|
end
|
142
186
|
|
187
|
+
# Runs the callback and passes it the changes if there are any.
|
188
|
+
#
|
189
|
+
def report_changes
|
190
|
+
changed_dirs = nil
|
191
|
+
|
192
|
+
@mutex.synchronize do
|
193
|
+
return if @changed_dirs.empty?
|
194
|
+
changed_dirs = @changed_dirs.to_a
|
195
|
+
@changed_dirs.clear
|
196
|
+
end
|
197
|
+
|
198
|
+
@callback.call(changed_dirs, {})
|
199
|
+
@turnstile.signal
|
200
|
+
end
|
201
|
+
|
143
202
|
private
|
144
203
|
|
145
204
|
# Polls changed directories and reports them back
|
146
205
|
# when there are changes.
|
147
206
|
#
|
148
|
-
|
149
|
-
#
|
150
|
-
def poll_changed_dirs(recursive = false)
|
207
|
+
def poll_changed_dirs
|
151
208
|
until @stop
|
152
209
|
sleep(@latency)
|
153
|
-
|
154
|
-
|
155
|
-
changed_dirs = []
|
156
|
-
|
157
|
-
@mutex.synchronize do
|
158
|
-
changed_dirs = @changed_dirs.to_a
|
159
|
-
@changed_dirs.clear
|
160
|
-
end
|
161
|
-
|
162
|
-
@callback.call(changed_dirs, recursive ? {:recursive => recursive} : {})
|
163
|
-
@turnstile.signal
|
210
|
+
report_changes
|
164
211
|
end
|
165
212
|
end
|
166
213
|
end
|