haml 3.1.8 → 3.2.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.
- data/CONTRIBUTING +1 -1
- data/README.md +2 -2
- data/REVISION +1 -1
- data/Rakefile +16 -41
- data/VERSION +1 -1
- data/VERSION_NAME +1 -1
- data/lib/haml/buffer.rb +1 -5
- data/lib/haml/compiler.rb +7 -8
- data/lib/haml/exec.rb +1 -1
- data/lib/haml/helpers.rb +3 -5
- data/lib/haml/helpers/action_view_mods.rb +5 -21
- data/lib/haml/parser.rb +1 -1
- data/lib/haml/template.rb +1 -3
- data/lib/haml/util.rb +1 -1
- data/test/haml/engine_test.rb +12 -51
- data/test/haml/helper_test.rb +8 -25
- data/test/haml/html2haml_test.rb +1 -1
- data/test/haml/results/whitespace_handling.xhtml +50 -46
- data/test/haml/template_test.rb +2 -28
- data/test/haml/templates/partial_layout.haml +1 -4
- data/test/linked_rails.rb +4 -4
- data/vendor/sass/VERSION +1 -1
- data/vendor/sass/doc-src/SASS_CHANGELOG.md +2 -115
- data/vendor/sass/doc-src/SASS_REFERENCE.md +4 -12
- data/vendor/sass/lib/sass.rb +0 -1
- data/vendor/sass/lib/sass/cache_stores/base.rb +1 -3
- data/vendor/sass/lib/sass/cache_stores/filesystem.rb +0 -2
- data/vendor/sass/lib/sass/css.rb +1 -2
- data/vendor/sass/lib/sass/engine.rb +23 -39
- data/vendor/sass/lib/sass/environment.rb +0 -11
- data/vendor/sass/lib/sass/exec.rb +1 -14
- data/vendor/sass/lib/sass/importers/base.rb +1 -2
- data/vendor/sass/lib/sass/importers/filesystem.rb +13 -18
- data/vendor/sass/lib/sass/less.rb +2 -2
- data/vendor/sass/lib/sass/plugin.rb +8 -4
- data/vendor/sass/lib/sass/plugin/compiler.rb +17 -42
- data/vendor/sass/lib/sass/plugin/configuration.rb +2 -0
- data/vendor/sass/lib/sass/railtie.rb +1 -1
- data/vendor/sass/lib/sass/script/funcall.rb +1 -14
- data/vendor/sass/lib/sass/script/functions.rb +1 -44
- data/vendor/sass/lib/sass/script/interpolation.rb +0 -9
- data/vendor/sass/lib/sass/script/lexer.rb +1 -6
- data/vendor/sass/lib/sass/script/list.rb +0 -7
- data/vendor/sass/lib/sass/script/literal.rb +0 -5
- data/vendor/sass/lib/sass/script/node.rb +0 -8
- data/vendor/sass/lib/sass/script/number.rb +5 -28
- data/vendor/sass/lib/sass/script/operation.rb +0 -8
- data/vendor/sass/lib/sass/script/parser.rb +5 -12
- data/vendor/sass/lib/sass/script/string_interpolation.rb +0 -9
- data/vendor/sass/lib/sass/script/unary_operation.rb +0 -7
- data/vendor/sass/lib/sass/script/variable.rb +0 -5
- data/vendor/sass/lib/sass/scss/parser.rb +38 -78
- data/vendor/sass/lib/sass/scss/rx.rb +1 -2
- data/vendor/sass/lib/sass/scss/static_parser.rb +2 -2
- data/vendor/sass/lib/sass/shared.rb +1 -1
- data/vendor/sass/lib/sass/tree/comment_node.rb +11 -24
- data/vendor/sass/lib/sass/tree/debug_node.rb +1 -1
- data/vendor/sass/lib/sass/tree/each_node.rb +1 -1
- data/vendor/sass/lib/sass/tree/extend_node.rb +1 -1
- data/vendor/sass/lib/sass/tree/for_node.rb +2 -2
- data/vendor/sass/lib/sass/tree/function_node.rb +1 -1
- data/vendor/sass/lib/sass/tree/if_node.rb +14 -1
- data/vendor/sass/lib/sass/tree/mixin_def_node.rb +1 -1
- data/vendor/sass/lib/sass/tree/mixin_node.rb +2 -2
- data/vendor/sass/lib/sass/tree/node.rb +5 -2
- data/vendor/sass/lib/sass/tree/prop_node.rb +9 -2
- data/vendor/sass/lib/sass/tree/return_node.rb +1 -1
- data/vendor/sass/lib/sass/tree/rule_node.rb +2 -9
- data/vendor/sass/lib/sass/tree/variable_node.rb +1 -1
- data/vendor/sass/lib/sass/tree/visitors/check_nesting.rb +18 -17
- data/vendor/sass/lib/sass/tree/visitors/convert.rb +5 -10
- data/vendor/sass/lib/sass/tree/visitors/perform.rb +19 -50
- data/vendor/sass/lib/sass/tree/visitors/to_css.rb +15 -9
- data/vendor/sass/lib/sass/tree/warn_node.rb +1 -1
- data/vendor/sass/lib/sass/tree/while_node.rb +1 -1
- data/vendor/sass/lib/sass/util.rb +6 -58
- data/vendor/sass/sass.gemspec +1 -2
- data/vendor/sass/test/sass/cache_test.rb +0 -15
- data/vendor/sass/test/sass/conversion_test.rb +6 -2
- data/vendor/sass/test/sass/css2sass_test.rb +0 -9
- data/vendor/sass/test/sass/engine_test.rb +26 -124
- data/vendor/sass/test/sass/functions_test.rb +0 -13
- data/vendor/sass/test/sass/importer_test.rb +0 -110
- data/vendor/sass/test/sass/plugin_test.rb +13 -16
- data/vendor/sass/test/sass/script_conversion_test.rb +0 -2
- data/vendor/sass/test/sass/script_test.rb +0 -18
- data/vendor/sass/test/sass/scss/css_test.rb +1 -7
- data/vendor/sass/test/sass/scss/scss_test.rb +13 -37
- data/vendor/sass/test/sass/test_helper.rb +1 -1
- data/vendor/sass/test/sass/util_test.rb +0 -12
- data/vendor/sass/vendor/fssm/LICENSE +1 -1
- data/vendor/sass/vendor/fssm/README.markdown +27 -55
- data/vendor/sass/vendor/fssm/Rakefile +54 -6
- data/vendor/sass/vendor/fssm/VERSION.yml +5 -0
- data/vendor/sass/vendor/fssm/example.rb +3 -6
- data/vendor/sass/vendor/fssm/fssm.gemspec +70 -17
- data/vendor/sass/vendor/fssm/lib/fssm.rb +3 -7
- data/vendor/sass/vendor/fssm/lib/fssm/backends/fsevents.rb +1 -1
- data/vendor/sass/vendor/fssm/lib/fssm/backends/inotify.rb +2 -2
- data/vendor/sass/vendor/fssm/lib/fssm/backends/polling.rb +2 -2
- data/vendor/sass/vendor/fssm/lib/fssm/backends/rubycocoa/fsevents.rb +10 -10
- data/vendor/sass/vendor/fssm/lib/fssm/monitor.rb +9 -19
- data/vendor/sass/vendor/fssm/lib/fssm/path.rb +21 -24
- data/vendor/sass/vendor/fssm/lib/fssm/pathname.rb +479 -13
- data/vendor/sass/vendor/fssm/lib/fssm/state/directory.rb +11 -29
- data/vendor/sass/vendor/fssm/lib/fssm/state/file.rb +1 -1
- data/vendor/sass/vendor/fssm/lib/fssm/support.rb +12 -41
- data/vendor/sass/vendor/fssm/lib/fssm/tree.rb +6 -6
- data/vendor/sass/vendor/fssm/profile/prof-cache.rb +3 -3
- data/vendor/sass/vendor/fssm/profile/prof-pathname.rb +7 -7
- data/vendor/sass/vendor/fssm/spec/path_spec.rb +15 -36
- data/vendor/sass/vendor/fssm/spec/spec_helper.rb +6 -6
- metadata +78 -125
- data/lib/haml/helpers/rails_323_textarea_fix.rb +0 -41
- data/test/gemfiles/Gemfile.rails-2.0.x +0 -8
- data/test/gemfiles/Gemfile.rails-2.0.x.lock +0 -38
- data/test/gemfiles/Gemfile.rails-2.1.x +0 -8
- data/test/gemfiles/Gemfile.rails-2.1.x.lock +0 -38
- data/test/gemfiles/Gemfile.rails-2.2.x +0 -8
- data/test/gemfiles/Gemfile.rails-2.2.x.lock +0 -38
- data/test/gemfiles/Gemfile.rails-2.3.x +0 -8
- data/test/gemfiles/Gemfile.rails-2.3.x.lock +0 -40
- data/test/gemfiles/Gemfile.rails-3.0.x +0 -8
- data/test/gemfiles/Gemfile.rails-3.0.x.lock +0 -85
- data/test/gemfiles/Gemfile.rails-3.1.x +0 -8
- data/test/gemfiles/Gemfile.rails-3.1.x.lock +0 -97
- data/test/gemfiles/Gemfile.rails-3.2.x +0 -8
- data/test/gemfiles/Gemfile.rails-3.2.x.lock +0 -95
- data/test/gemfiles/Gemfile.rails-xss-2.3.x +0 -9
- data/test/gemfiles/Gemfile.rails-xss-2.3.x.lock +0 -42
- data/vendor/sass/lib/sass/logger.rb +0 -15
- data/vendor/sass/lib/sass/logger/base.rb +0 -32
- data/vendor/sass/lib/sass/logger/log_level.rb +0 -49
- data/vendor/sass/lib/sass/tree/visitors/deep_copy.rb +0 -87
- data/vendor/sass/lib/sass/tree/visitors/set_options.rb +0 -97
- data/vendor/sass/test/Gemfile +0 -4
- data/vendor/sass/test/Gemfile.lock +0 -19
- data/vendor/sass/test/sass/fixtures/test_staleness_check_across_importers.css +0 -1
- data/vendor/sass/test/sass/fixtures/test_staleness_check_across_importers.scss +0 -1
- data/vendor/sass/test/sass/logger_test.rb +0 -58
- data/vendor/sass/test/sass/templates/bork5.sass +0 -3
- data/vendor/sass/test/sass/templates/nested_bork5.sass +0 -2
- data/vendor/sass/vendor/fssm/Gemfile +0 -3
- data/vendor/sass/vendor/fssm/lib/fssm/backends/rbfsevent.rb +0 -42
- data/vendor/sass/vendor/fssm/lib/fssm/version.rb +0 -3
- data/vendor/sass/vendor/fssm/profile/prof-pathname-rubinius.rb +0 -35
- data/vendor/sass/vendor/fssm/spec/count_down_latch.rb +0 -151
- data/vendor/sass/vendor/fssm/spec/monitor_spec.rb +0 -202
@@ -1,11 +1,59 @@
|
|
1
1
|
require 'rubygems'
|
2
|
-
require '
|
3
|
-
Bundler::GemHelper.install_tasks
|
2
|
+
require 'rake'
|
4
3
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
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
|
9
57
|
end
|
10
58
|
|
11
59
|
task :default => :spec
|
@@ -1,12 +1,9 @@
|
|
1
1
|
$:.unshift(File.join(File.dirname(__FILE__), 'lib'))
|
2
2
|
|
3
|
-
# for rb-inotify/rb-fsevent
|
4
|
-
require 'rubygems'
|
5
|
-
|
6
3
|
require 'fssm'
|
7
4
|
|
8
5
|
FSSM.monitor('.', '**/*') do
|
9
|
-
update {
|
10
|
-
delete {
|
11
|
-
create {
|
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}"}
|
12
9
|
end
|
@@ -1,24 +1,77 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
1
4
|
# -*- encoding: utf-8 -*-
|
2
|
-
$:.push File.expand_path("../lib", __FILE__)
|
3
|
-
require "fssm/version"
|
4
5
|
|
5
6
|
Gem::Specification.new do |s|
|
6
|
-
s.name
|
7
|
-
s.version
|
8
|
-
s.platform = Gem::Platform::RUBY
|
9
|
-
s.authors = ["Travis Tilley", "Nathan Weizenbaum", "Chris Eppstein",
|
10
|
-
"Jonathan Castello", "Tuomas Kareinen"]
|
11
|
-
s.email = ["ttilley@gmail.com"]
|
12
|
-
s.homepage = "https://github.com/ttilley/fssm"
|
13
|
-
s.summary = %q{File System State Monitor}
|
14
|
-
s.description = %q{The File System State Monitor keeps track of the state of any number of paths and will fire events when said state changes (create/update/delete). FSSM supports using FSEvents on MacOS, Inotify on GNU/Linux, and polling anywhere else.}
|
7
|
+
s.name = %q{fssm}
|
8
|
+
s.version = "0.1.4"
|
15
9
|
|
16
|
-
s.
|
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
|
+
]
|
17
63
|
|
18
|
-
s.
|
19
|
-
|
20
|
-
|
21
|
-
s.require_paths = ["lib"]
|
64
|
+
if s.respond_to? :specification_version then
|
65
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
66
|
+
s.specification_version = 3
|
22
67
|
|
23
|
-
|
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
|
24
76
|
end
|
77
|
+
|
@@ -1,20 +1,17 @@
|
|
1
1
|
dir = File.dirname(__FILE__)
|
2
2
|
$LOAD_PATH.unshift dir unless $LOAD_PATH.include?(dir)
|
3
3
|
|
4
|
-
#noinspection ALL
|
5
4
|
module FSSM
|
6
5
|
FileNotFoundError = Class.new(StandardError)
|
7
|
-
|
8
|
-
CallbackError = Class.new(StandardError)
|
6
|
+
CallbackError = Class.new(StandardError)
|
9
7
|
|
10
8
|
class << self
|
11
9
|
def dbg(msg=nil)
|
12
|
-
STDERR.puts(
|
10
|
+
STDERR.puts(msg)
|
13
11
|
end
|
14
12
|
|
15
13
|
def monitor(*args, &block)
|
16
|
-
|
17
|
-
monitor = FSSM::Monitor.new(options)
|
14
|
+
monitor = FSSM::Monitor.new
|
18
15
|
FSSM::Support.use_block(args.empty? ? monitor : monitor.path(*args), block)
|
19
16
|
|
20
17
|
monitor.run
|
@@ -24,7 +21,6 @@ end
|
|
24
21
|
|
25
22
|
require 'thread'
|
26
23
|
|
27
|
-
require 'fssm/version'
|
28
24
|
require 'fssm/pathname'
|
29
25
|
require 'fssm/support'
|
30
26
|
require 'fssm/tree'
|
@@ -10,7 +10,7 @@ module FSSM::Backends
|
|
10
10
|
def add_handler(handler, preload=true)
|
11
11
|
@handlers[handler.path.to_s] = handler
|
12
12
|
|
13
|
-
fsevent
|
13
|
+
fsevent = Rucola::FSEvents.new(handler.path.to_s, {:latency => 0.5}) do |events|
|
14
14
|
events.each do |event|
|
15
15
|
handler.refresh(event.path)
|
16
16
|
end
|
@@ -5,8 +5,8 @@ module FSSM::Backends
|
|
5
5
|
end
|
6
6
|
|
7
7
|
def add_handler(handler, preload=true)
|
8
|
-
@notifier.watch(handler.path.to_s, :recursive, :attrib, :
|
9
|
-
|
8
|
+
@notifier.watch(handler.path.to_s, :recursive, :attrib, :modify, :create,
|
9
|
+
:delete, :delete_self, :moved_from, :moved_to, :move_self) do |event|
|
10
10
|
path = FSSM::Pathname.for(event.absolute_name)
|
11
11
|
path = path.dirname unless event.name == "" # Event on root directory
|
12
12
|
handler.refresh(path)
|
@@ -2,7 +2,7 @@ module FSSM::Backends
|
|
2
2
|
class Polling
|
3
3
|
def initialize(options={})
|
4
4
|
@handlers = []
|
5
|
-
@latency
|
5
|
+
@latency = options[:latency] || 1.5
|
6
6
|
end
|
7
7
|
|
8
8
|
def add_handler(handler, preload=true)
|
@@ -14,7 +14,7 @@ module FSSM::Backends
|
|
14
14
|
begin
|
15
15
|
loop do
|
16
16
|
start = Time.now.to_f
|
17
|
-
@handlers.each {
|
17
|
+
@handlers.each {|handler| handler.refresh}
|
18
18
|
nap_time = @latency - (Time.now.to_f - start)
|
19
19
|
sleep nap_time if nap_time > 0
|
20
20
|
end
|
@@ -14,7 +14,7 @@ module Rucola
|
|
14
14
|
# Returns an array of the files/dirs in the path that the event occurred in.
|
15
15
|
# The files are sorted by the modification time, the first entry is the last modified file.
|
16
16
|
def files
|
17
|
-
Dir.glob("#{File.expand_path(path)}/*").sort_by {
|
17
|
+
Dir.glob("#{File.expand_path(path)}/*").sort_by {|f| File.mtime(f) }.reverse
|
18
18
|
end
|
19
19
|
|
20
20
|
# Returns the last modified file in the path that the event occurred in.
|
@@ -88,22 +88,22 @@ module Rucola
|
|
88
88
|
raise ArgumentError, 'No callback block was specified.' unless block_given?
|
89
89
|
|
90
90
|
options = params.last.kind_of?(Hash) ? params.pop : {}
|
91
|
-
@paths
|
91
|
+
@paths = params.flatten
|
92
92
|
|
93
93
|
paths.each { |path| raise ArgumentError, "The specified path (#{path}) does not exist." unless File.exist?(path) }
|
94
94
|
|
95
|
-
@allocator
|
96
|
-
@context
|
97
|
-
@since
|
98
|
-
@latency
|
99
|
-
@flags
|
100
|
-
@stream
|
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
101
|
|
102
102
|
@user_callback = block
|
103
|
-
@callback
|
103
|
+
@callback = Proc.new do |stream, client_callback_info, number_of_events, paths_pointer, event_flags, event_ids|
|
104
104
|
paths_pointer.regard_as('*')
|
105
105
|
events = []
|
106
|
-
number_of_events.times {
|
106
|
+
number_of_events.times {|i| events << Rucola::FSEvents::FSEvent.new(self, event_ids[i], paths_pointer[i]) }
|
107
107
|
@user_callback.call(events)
|
108
108
|
end
|
109
109
|
end
|
@@ -4,33 +4,23 @@ class FSSM::Monitor
|
|
4
4
|
@backend = FSSM::Backends::Default.new
|
5
5
|
end
|
6
6
|
|
7
|
-
def path(
|
8
|
-
path =
|
9
|
-
|
7
|
+
def path(*args, &block)
|
8
|
+
path = FSSM::Path.new(*args)
|
9
|
+
FSSM::Support.use_block(path, block)
|
10
|
+
|
11
|
+
@backend.add_handler(FSSM::State::Directory.new(path))
|
10
12
|
path
|
11
|
-
rescue FSSM::FileNotRealError => e
|
12
|
-
FSSM.dbg("#{e}")
|
13
|
-
nil
|
14
13
|
end
|
15
14
|
|
16
|
-
def file(
|
17
|
-
path =
|
15
|
+
def file(*args, &block)
|
16
|
+
path = FSSM::Path.new(*args)
|
17
|
+
FSSM::Support.use_block(path, block)
|
18
|
+
|
18
19
|
@backend.add_handler(FSSM::State::File.new(path))
|
19
20
|
path
|
20
|
-
rescue FSSM::FileNotRealError => e
|
21
|
-
FSSM.dbg("#{e}")
|
22
|
-
nil
|
23
21
|
end
|
24
22
|
|
25
23
|
def run
|
26
24
|
@backend.run
|
27
25
|
end
|
28
|
-
|
29
|
-
private
|
30
|
-
|
31
|
-
def create_path(path, glob, &block)
|
32
|
-
path = FSSM::Path.new(path, glob, @options)
|
33
|
-
FSSM::Support.use_block(path, block)
|
34
|
-
path
|
35
|
-
end
|
36
26
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
class FSSM::Path
|
2
|
-
def initialize(path=nil, glob=nil,
|
3
|
-
@options = options
|
2
|
+
def initialize(path=nil, glob=nil, &block)
|
4
3
|
set_path(path || '.')
|
5
4
|
set_glob(glob || '**/*')
|
6
5
|
init_callbacks
|
@@ -27,32 +26,32 @@ class FSSM::Path
|
|
27
26
|
set_glob(value)
|
28
27
|
end
|
29
28
|
|
30
|
-
def create(
|
31
|
-
callback_action(:create, (block_given? ? block :
|
29
|
+
def create(callback_or_path=nil, &block)
|
30
|
+
callback_action(:create, (block_given? ? block : callback_or_path))
|
32
31
|
end
|
33
32
|
|
34
|
-
def update(
|
35
|
-
callback_action(:update, (block_given? ? block :
|
33
|
+
def update(callback_or_path=nil, &block)
|
34
|
+
callback_action(:update, (block_given? ? block : callback_or_path))
|
36
35
|
end
|
37
36
|
|
38
|
-
def delete(
|
39
|
-
callback_action(:delete, (block_given? ? block :
|
37
|
+
def delete(callback_or_path=nil, &block)
|
38
|
+
callback_action(:delete, (block_given? ? block : callback_or_path))
|
40
39
|
end
|
41
40
|
|
42
41
|
private
|
43
42
|
|
44
43
|
def init_callbacks
|
45
|
-
do_nothing = lambda {
|
44
|
+
do_nothing = lambda {|base, relative|}
|
46
45
|
@callbacks = Hash.new(do_nothing)
|
47
46
|
end
|
48
47
|
|
49
|
-
def callback_action(type,
|
50
|
-
if
|
51
|
-
set_callback(type,
|
52
|
-
elsif
|
48
|
+
def callback_action(type, arg=nil)
|
49
|
+
if arg.is_a?(Proc)
|
50
|
+
set_callback(type, arg)
|
51
|
+
elsif arg.nil?
|
53
52
|
get_callback(type)
|
54
53
|
else
|
55
|
-
run_callback(type,
|
54
|
+
run_callback(type, arg)
|
56
55
|
end
|
57
56
|
end
|
58
57
|
|
@@ -65,27 +64,25 @@ class FSSM::Path
|
|
65
64
|
@callbacks[type]
|
66
65
|
end
|
67
66
|
|
68
|
-
def run_callback(type,
|
69
|
-
|
70
|
-
callback_args << args[1] if @options[:directories]
|
67
|
+
def run_callback(type, arg)
|
68
|
+
base, relative = split_path(arg)
|
71
69
|
|
72
70
|
begin
|
73
|
-
@callbacks[type].call(
|
71
|
+
@callbacks[type].call(base, relative)
|
74
72
|
rescue Exception => e
|
75
|
-
raise FSSM::CallbackError, "#{type} - #{
|
73
|
+
raise FSSM::CallbackError, "#{type} - #{base.join(relative)}: #{e.message}", e.backtrace
|
76
74
|
end
|
77
75
|
end
|
78
76
|
|
79
77
|
def split_path(path)
|
80
78
|
path = FSSM::Pathname.for(path)
|
81
|
-
[@path
|
79
|
+
[@path, (path.relative? ? path : path.relative_path_from(@path))]
|
82
80
|
end
|
83
81
|
|
84
82
|
def set_path(path)
|
85
|
-
|
86
|
-
raise FSSM::FileNotFoundError, "No such file or directory - #{
|
87
|
-
|
88
|
-
@path = @path.realpath
|
83
|
+
path = FSSM::Pathname.for(path)
|
84
|
+
raise FSSM::FileNotFoundError, "No such file or directory - #{path}" unless path.exist?
|
85
|
+
@path = path.expand_path
|
89
86
|
end
|
90
87
|
|
91
88
|
def set_glob(glob)
|
@@ -1,36 +1,502 @@
|
|
1
1
|
require 'fileutils'
|
2
2
|
require 'find'
|
3
|
-
require 'pathname'
|
4
3
|
|
5
4
|
module FSSM
|
6
|
-
class Pathname <
|
7
|
-
|
5
|
+
class Pathname < String
|
6
|
+
SYMLOOP_MAX = 8
|
7
|
+
|
8
|
+
ROOT = '/'.freeze
|
9
|
+
DOT = '.'.freeze
|
10
|
+
DOT_DOT = '..'.freeze
|
8
11
|
|
9
12
|
class << self
|
10
13
|
def for(path)
|
11
|
-
path.is_a?(::FSSM::Pathname) ? path : new(path)
|
14
|
+
path.is_a?(::FSSM::Pathname) ? path : new("#{path}")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(path)
|
19
|
+
raise ArgumentError, "path cannot contain ASCII NULLs" if path =~ %r{\0}
|
20
|
+
super(path)
|
21
|
+
end
|
22
|
+
|
23
|
+
def <=>(other)
|
24
|
+
self.tr('/', "\0").to_s <=> other.to_str.tr('/', "\0")
|
25
|
+
rescue NoMethodError
|
26
|
+
nil
|
27
|
+
end
|
28
|
+
|
29
|
+
def ==(other)
|
30
|
+
left = self.cleanpath.tr('/', "\0").to_s
|
31
|
+
right = self.class.for(other).cleanpath.tr('/', "\0").to_s
|
32
|
+
|
33
|
+
left == right
|
34
|
+
rescue NoMethodError
|
35
|
+
false
|
36
|
+
end
|
37
|
+
|
38
|
+
def +(path)
|
39
|
+
dup << path
|
40
|
+
end
|
41
|
+
|
42
|
+
def <<(path)
|
43
|
+
replace( join(path).cleanpath! )
|
44
|
+
end
|
45
|
+
|
46
|
+
def absolute?
|
47
|
+
self[0, 1].to_s == ROOT
|
48
|
+
end
|
49
|
+
|
50
|
+
def ascend
|
51
|
+
parts = to_a
|
52
|
+
parts.length.downto(1) do |i|
|
53
|
+
yield self.class.join(parts[0, i])
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def children
|
58
|
+
entries[2..-1]
|
59
|
+
end
|
60
|
+
|
61
|
+
def cleanpath!
|
62
|
+
parts = to_a
|
63
|
+
final = []
|
64
|
+
|
65
|
+
parts.each do |part|
|
66
|
+
case part
|
67
|
+
when DOT then
|
68
|
+
next
|
69
|
+
when DOT_DOT then
|
70
|
+
case final.last
|
71
|
+
when ROOT then
|
72
|
+
next
|
73
|
+
when DOT_DOT then
|
74
|
+
final.push(DOT_DOT)
|
75
|
+
when nil then
|
76
|
+
final.push(DOT_DOT)
|
77
|
+
else
|
78
|
+
final.pop
|
79
|
+
end
|
80
|
+
else
|
81
|
+
final.push(part)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
replace(final.empty? ? DOT : self.class.join(*final))
|
86
|
+
end
|
87
|
+
|
88
|
+
def cleanpath
|
89
|
+
dup.cleanpath!
|
90
|
+
end
|
91
|
+
|
92
|
+
def descend
|
93
|
+
parts = to_a
|
94
|
+
1.upto(parts.length) { |i| yield self.class.join(parts[0, i]) }
|
95
|
+
end
|
96
|
+
|
97
|
+
def dot?
|
98
|
+
self == DOT
|
99
|
+
end
|
100
|
+
|
101
|
+
def dot_dot?
|
102
|
+
self == DOT_DOT
|
103
|
+
end
|
104
|
+
|
105
|
+
def each_filename(&blk)
|
106
|
+
to_a.each(&blk)
|
107
|
+
end
|
108
|
+
|
109
|
+
def mountpoint?
|
110
|
+
stat1 = self.lstat
|
111
|
+
stat2 = self.parent.lstat
|
112
|
+
|
113
|
+
stat1.dev != stat2.dev || stat1.ino == stat2.ino
|
114
|
+
rescue Errno::ENOENT
|
115
|
+
false
|
116
|
+
end
|
117
|
+
|
118
|
+
def parent
|
119
|
+
self + '..'
|
120
|
+
end
|
121
|
+
|
122
|
+
def realpath
|
123
|
+
path = self
|
124
|
+
|
125
|
+
SYMLOOP_MAX.times do
|
126
|
+
link = path.readlink
|
127
|
+
link = path.dirname + link if link.relative?
|
128
|
+
path = link
|
129
|
+
end
|
130
|
+
|
131
|
+
raise Errno::ELOOP, self
|
132
|
+
rescue Errno::EINVAL
|
133
|
+
path.expand_path
|
134
|
+
end
|
135
|
+
|
136
|
+
def relative?
|
137
|
+
!absolute?
|
138
|
+
end
|
139
|
+
|
140
|
+
def relative_path_from(base)
|
141
|
+
base = self.class.for(base)
|
142
|
+
|
143
|
+
raise ArgumentError, 'no relative path between a relative and absolute' if self.absolute? != base.absolute?
|
144
|
+
|
145
|
+
return self if base.dot?
|
146
|
+
return self.class.new(DOT) if self == base
|
147
|
+
|
148
|
+
base = base.cleanpath.to_a
|
149
|
+
dest = self.cleanpath.to_a
|
150
|
+
|
151
|
+
while !dest.empty? && !base.empty? && dest[0] == base[0]
|
152
|
+
base.shift
|
153
|
+
dest.shift
|
12
154
|
end
|
13
155
|
|
14
|
-
|
156
|
+
base.shift if base[0] == DOT
|
157
|
+
dest.shift if dest[0] == DOT
|
158
|
+
|
159
|
+
raise ArgumentError, "base directory may not contain '#{DOT_DOT}'" if base.include?(DOT_DOT)
|
160
|
+
|
161
|
+
path = base.fill(DOT_DOT) + dest
|
162
|
+
path = self.class.join(*path)
|
163
|
+
path = self.class.new(DOT) if path.empty?
|
164
|
+
|
165
|
+
path
|
15
166
|
end
|
16
167
|
|
17
|
-
def
|
18
|
-
!!(
|
168
|
+
def root?
|
169
|
+
!!(self =~ %r{^#{ROOT}+$})
|
19
170
|
end
|
20
171
|
|
21
|
-
def
|
22
|
-
|
23
|
-
array = path.split(File::SEPARATOR)
|
172
|
+
def to_a
|
173
|
+
array = to_s.split(File::SEPARATOR)
|
24
174
|
array.delete('')
|
25
|
-
array.insert(0,
|
26
|
-
array[0] += File::SEPARATOR if path[0, 3] =~ SEPARATOR_PAT
|
175
|
+
array.insert(0, ROOT) if absolute?
|
27
176
|
array
|
28
177
|
end
|
29
178
|
|
179
|
+
alias segments to_a
|
180
|
+
|
181
|
+
def to_path
|
182
|
+
self
|
183
|
+
end
|
184
|
+
|
185
|
+
def to_s
|
186
|
+
"#{self}"
|
187
|
+
end
|
188
|
+
|
189
|
+
alias to_str to_s
|
190
|
+
|
191
|
+
def unlink
|
192
|
+
Dir.unlink(self)
|
193
|
+
true
|
194
|
+
rescue Errno::ENOTDIR
|
195
|
+
File.unlink(self)
|
196
|
+
true
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
class Pathname
|
201
|
+
def self.[](pattern)
|
202
|
+
Dir[pattern].map! {|d| FSSM::Pathname.new(d) }
|
203
|
+
end
|
204
|
+
|
205
|
+
def self.pwd
|
206
|
+
FSSM::Pathname.new(Dir.pwd)
|
207
|
+
end
|
208
|
+
|
209
|
+
def entries
|
210
|
+
Dir.entries(self).map! {|e| FSSM::Pathname.new(e) }
|
211
|
+
end
|
212
|
+
|
213
|
+
def mkdir(mode = 0777)
|
214
|
+
Dir.mkdir(self, mode)
|
215
|
+
end
|
216
|
+
|
217
|
+
def opendir(&blk)
|
218
|
+
Dir.open(self, &blk)
|
219
|
+
end
|
220
|
+
|
221
|
+
def rmdir
|
222
|
+
Dir.rmdir(self)
|
223
|
+
end
|
224
|
+
|
225
|
+
def self.glob(pattern, flags = 0)
|
226
|
+
dirs = Dir.glob(pattern, flags)
|
227
|
+
dirs.map! {|path| FSSM::Pathname.new(path) }
|
228
|
+
|
229
|
+
if block_given?
|
230
|
+
dirs.each {|dir| yield dir }
|
231
|
+
nil
|
232
|
+
else
|
233
|
+
dirs
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
30
237
|
def glob(pattern, flags = 0, &block)
|
31
238
|
patterns = [pattern].flatten
|
32
|
-
patterns.map! {
|
239
|
+
patterns.map! {|p| self.class.glob(self.to_s + p, flags, &block) }
|
33
240
|
patterns.flatten
|
34
241
|
end
|
242
|
+
|
243
|
+
def chdir
|
244
|
+
blk = lambda { yield self } if block_given?
|
245
|
+
Dir.chdir(self, &blk)
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
class Pathname
|
250
|
+
def blockdev?
|
251
|
+
FileTest.blockdev?(self)
|
252
|
+
end
|
253
|
+
|
254
|
+
def chardev?
|
255
|
+
FileTest.chardev?(self)
|
256
|
+
end
|
257
|
+
|
258
|
+
def directory?
|
259
|
+
FileTest.directory?(self)
|
260
|
+
end
|
261
|
+
|
262
|
+
def executable?
|
263
|
+
FileTest.executable?(self)
|
264
|
+
end
|
265
|
+
|
266
|
+
def executable_real?
|
267
|
+
FileTest.executable_real?(self)
|
268
|
+
end
|
269
|
+
|
270
|
+
def exists?
|
271
|
+
FileTest.exists?(self)
|
272
|
+
end
|
273
|
+
|
274
|
+
def file?
|
275
|
+
FileTest.file?(self)
|
276
|
+
end
|
277
|
+
|
278
|
+
def grpowned?
|
279
|
+
FileTest.grpowned?(self)
|
280
|
+
end
|
281
|
+
|
282
|
+
def owned?
|
283
|
+
FileTest.owned?(self)
|
284
|
+
end
|
285
|
+
|
286
|
+
def pipe?
|
287
|
+
FileTest.pipe?(self)
|
288
|
+
end
|
289
|
+
|
290
|
+
def readable?
|
291
|
+
FileTest.readable?(self)
|
292
|
+
end
|
293
|
+
|
294
|
+
def readable_real?
|
295
|
+
FileTest.readable_real?(self)
|
296
|
+
end
|
297
|
+
|
298
|
+
def setgid?
|
299
|
+
FileTest.setgit?(self)
|
300
|
+
end
|
301
|
+
|
302
|
+
def setuid?
|
303
|
+
FileTest.setuid?(self)
|
304
|
+
end
|
305
|
+
|
306
|
+
def socket?
|
307
|
+
FileTest.socket?(self)
|
308
|
+
end
|
309
|
+
|
310
|
+
def sticky?
|
311
|
+
FileTest.sticky?(self)
|
312
|
+
end
|
313
|
+
|
314
|
+
def symlink?
|
315
|
+
FileTest.symlink?(self)
|
316
|
+
end
|
317
|
+
|
318
|
+
def world_readable?
|
319
|
+
FileTest.world_readable?(self)
|
320
|
+
end
|
321
|
+
|
322
|
+
def world_writable?
|
323
|
+
FileTest.world_writable?(self)
|
324
|
+
end
|
325
|
+
|
326
|
+
def writable?
|
327
|
+
FileTest.writable?(self)
|
328
|
+
end
|
329
|
+
|
330
|
+
def writable_real?
|
331
|
+
FileTest.writable_real?(self)
|
332
|
+
end
|
333
|
+
|
334
|
+
def zero?
|
335
|
+
FileTest.zero?(self)
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
class Pathname
|
340
|
+
def atime
|
341
|
+
File.atime(self)
|
342
|
+
end
|
343
|
+
|
344
|
+
def ctime
|
345
|
+
File.ctime(self)
|
346
|
+
end
|
347
|
+
|
348
|
+
def ftype
|
349
|
+
File.ftype(self)
|
350
|
+
end
|
351
|
+
|
352
|
+
def lstat
|
353
|
+
File.lstat(self)
|
354
|
+
end
|
355
|
+
|
356
|
+
def mtime
|
357
|
+
File.mtime(self)
|
358
|
+
end
|
359
|
+
|
360
|
+
def stat
|
361
|
+
File.stat(self)
|
362
|
+
end
|
363
|
+
|
364
|
+
def utime(atime, mtime)
|
365
|
+
File.utime(self, atime, mtime)
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
369
|
+
class Pathname
|
370
|
+
def self.join(*parts)
|
371
|
+
last_part = FSSM::Pathname.new(parts.last)
|
372
|
+
return last_part if last_part.absolute?
|
373
|
+
FSSM::Pathname.new(File.join(*parts.reject {|p| p.empty? }))
|
374
|
+
end
|
375
|
+
|
376
|
+
def basename
|
377
|
+
self.class.new(File.basename(self))
|
378
|
+
end
|
379
|
+
|
380
|
+
def chmod(mode)
|
381
|
+
File.chmod(mode, self)
|
382
|
+
end
|
383
|
+
|
384
|
+
def chown(owner, group)
|
385
|
+
File.chown(owner, group, self)
|
386
|
+
end
|
387
|
+
|
388
|
+
def dirname
|
389
|
+
self.class.new(File.dirname(self))
|
390
|
+
end
|
391
|
+
|
392
|
+
def expand_path(from = nil)
|
393
|
+
self.class.new(File.expand_path(self, from))
|
394
|
+
end
|
395
|
+
|
396
|
+
def extname
|
397
|
+
File.extname(self)
|
398
|
+
end
|
399
|
+
|
400
|
+
def fnmatch?(pat, flags = 0)
|
401
|
+
File.fnmatch(pat, self, flags)
|
402
|
+
end
|
403
|
+
|
404
|
+
def join(*parts)
|
405
|
+
self.class.join(self, *parts)
|
406
|
+
end
|
407
|
+
|
408
|
+
def lchmod(mode)
|
409
|
+
File.lchmod(mode, self)
|
410
|
+
end
|
411
|
+
|
412
|
+
def lchown(owner, group)
|
413
|
+
File.lchown(owner, group, self)
|
414
|
+
end
|
415
|
+
|
416
|
+
def link(to)
|
417
|
+
File.link(self, to)
|
418
|
+
end
|
419
|
+
|
420
|
+
def open(mode = 'r', perm = nil, &blk)
|
421
|
+
File.open(self, mode, perm, &blk)
|
422
|
+
end
|
423
|
+
|
424
|
+
def readlink
|
425
|
+
self.class.new(File.readlink(self))
|
426
|
+
end
|
427
|
+
|
428
|
+
def rename(to)
|
429
|
+
File.rename(self, to)
|
430
|
+
replace(to)
|
431
|
+
end
|
432
|
+
|
433
|
+
def size
|
434
|
+
File.size(self)
|
435
|
+
end
|
436
|
+
|
437
|
+
def size?
|
438
|
+
File.size?(self)
|
439
|
+
end
|
440
|
+
|
441
|
+
def split
|
442
|
+
File.split(self).map {|part| FSSM::Pathname.new(part) }
|
443
|
+
end
|
444
|
+
|
445
|
+
def symlink(to)
|
446
|
+
File.symlink(self, to)
|
447
|
+
end
|
448
|
+
|
449
|
+
def truncate
|
450
|
+
File.truncate(self)
|
451
|
+
end
|
452
|
+
end
|
453
|
+
|
454
|
+
class Pathname
|
455
|
+
def mkpath
|
456
|
+
self.class.new(FileUtils.mkpath(self))
|
457
|
+
end
|
458
|
+
|
459
|
+
def rmtree
|
460
|
+
self.class.new(FileUtils.rmtree(self).first)
|
461
|
+
end
|
462
|
+
|
463
|
+
def touch
|
464
|
+
self.class.new(FileUtils.touch(self).first)
|
465
|
+
end
|
466
|
+
end
|
467
|
+
|
468
|
+
class Pathname
|
469
|
+
def each_line(sep = $/, &blk)
|
470
|
+
IO.foreach(self, sep, &blk)
|
471
|
+
end
|
472
|
+
|
473
|
+
def read(len = nil, off = 0)
|
474
|
+
IO.read(self, len, off)
|
475
|
+
end
|
476
|
+
|
477
|
+
def readlines(sep = $/)
|
478
|
+
IO.readlines(self, sep)
|
479
|
+
end
|
480
|
+
|
481
|
+
def sysopen(mode = 'r', perm = nil)
|
482
|
+
IO.sysopen(self, mode, perm)
|
483
|
+
end
|
484
|
+
end
|
485
|
+
|
486
|
+
class Pathname
|
487
|
+
def find
|
488
|
+
Find.find(self) {|path| yield FSSM::Pathname.new(path) }
|
489
|
+
end
|
490
|
+
end
|
491
|
+
|
492
|
+
class Pathname
|
493
|
+
class << self
|
494
|
+
alias getwd pwd
|
495
|
+
end
|
496
|
+
|
497
|
+
alias absolute expand_path
|
498
|
+
alias delete unlink
|
499
|
+
alias exist? exists?
|
500
|
+
alias fnmatch fnmatch?
|
35
501
|
end
|
36
502
|
end
|