compass 0.8.16
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.markdown +551 -0
- data/LICENSE.markdown +29 -0
- data/README.markdown +44 -0
- data/REVISION +1 -0
- data/Rakefile +127 -0
- data/VERSION.yml +4 -0
- data/bin/compass +8 -0
- data/deps.rip +1 -0
- data/examples/README.markdown +4 -0
- data/examples/blueprint_default/config.rb +7 -0
- data/examples/blueprint_default/images/grid.png +0 -0
- data/examples/blueprint_default/index.html.haml +85 -0
- data/examples/blueprint_default/parts/elements.html.haml +282 -0
- data/examples/blueprint_default/parts/forms.html.haml +190 -0
- data/examples/blueprint_default/parts/grid.html.haml +274 -0
- data/examples/blueprint_default/parts/test-small.jpg +0 -0
- data/examples/blueprint_default/parts/test.jpg +0 -0
- data/examples/blueprint_default/parts/valid.png +0 -0
- data/examples/blueprint_default/src/ie.sass +3 -0
- data/examples/blueprint_default/src/images/grid.png +0 -0
- data/examples/blueprint_default/src/print.sass +3 -0
- data/examples/blueprint_default/src/screen.sass +8 -0
- data/examples/blueprint_plugins/config.rb +8 -0
- data/examples/blueprint_plugins/images/buttons/cross.png +0 -0
- data/examples/blueprint_plugins/images/buttons/key.png +0 -0
- data/examples/blueprint_plugins/images/buttons/tick.png +0 -0
- data/examples/blueprint_plugins/images/grid.png +0 -0
- data/examples/blueprint_plugins/images/link_icons/doc.png +0 -0
- data/examples/blueprint_plugins/images/link_icons/email.png +0 -0
- data/examples/blueprint_plugins/images/link_icons/external.png +0 -0
- data/examples/blueprint_plugins/images/link_icons/feed.png +0 -0
- data/examples/blueprint_plugins/images/link_icons/im.png +0 -0
- data/examples/blueprint_plugins/images/link_icons/pdf.png +0 -0
- data/examples/blueprint_plugins/images/link_icons/visited.png +0 -0
- data/examples/blueprint_plugins/images/link_icons/xls.png +0 -0
- data/examples/blueprint_plugins/images/test-small.jpg +0 -0
- data/examples/blueprint_plugins/images/test.jpg +0 -0
- data/examples/blueprint_plugins/images/valid.png +0 -0
- data/examples/blueprint_plugins/index.html.haml +96 -0
- data/examples/blueprint_plugins/plugins/buttons.html.haml +67 -0
- data/examples/blueprint_plugins/plugins/fancy_type.html.haml +100 -0
- data/examples/blueprint_plugins/plugins/link_icons.html.haml +61 -0
- data/examples/blueprint_plugins/plugins/rtl.html.haml +100 -0
- data/examples/blueprint_plugins/src/buttons.sass +49 -0
- data/examples/blueprint_plugins/src/ie.sass +3 -0
- data/examples/blueprint_plugins/src/images/grid.png +0 -0
- data/examples/blueprint_plugins/src/link_icons.sass +13 -0
- data/examples/blueprint_plugins/src/print.sass +3 -0
- data/examples/blueprint_plugins/src/rtl_screen.sass +13 -0
- data/examples/blueprint_plugins/src/screen.sass +11 -0
- data/examples/blueprint_scoped/images/grid.png +0 -0
- data/examples/blueprint_scoped/src/ie.sass +3 -0
- data/examples/blueprint_scoped/src/print.sass +3 -0
- data/examples/blueprint_scoped/src/screen.sass +4 -0
- data/examples/blueprint_scoped_form/images/grid.png +0 -0
- data/examples/blueprint_scoped_form/src/ie.sass +3 -0
- data/examples/blueprint_scoped_form/src/print.sass +3 -0
- data/examples/blueprint_scoped_form/src/screen.sass +10 -0
- data/examples/blueprint_semantic/config.rb +7 -0
- data/examples/blueprint_semantic/images/grid.png +0 -0
- data/examples/blueprint_semantic/index.html.haml +86 -0
- data/examples/blueprint_semantic/parts/fancy_type.html.haml +100 -0
- data/examples/blueprint_semantic/parts/liquid.html.haml +100 -0
- data/examples/blueprint_semantic/parts/test-small.jpg +0 -0
- data/examples/blueprint_semantic/parts/test.jpg +0 -0
- data/examples/blueprint_semantic/parts/valid.png +0 -0
- data/examples/blueprint_semantic/src/ie.sass +3 -0
- data/examples/blueprint_semantic/src/images/grid.png +0 -0
- data/examples/blueprint_semantic/src/liquid.sass +70 -0
- data/examples/blueprint_semantic/src/print.sass +3 -0
- data/examples/blueprint_semantic/src/screen.sass +71 -0
- data/examples/compass/compass.html.haml +39 -0
- data/examples/compass/config.rb +7 -0
- data/examples/compass/images/blue_arrow.gif +0 -0
- data/examples/compass/src/compass.sass +47 -0
- data/examples/compass/src/images/blue_arrow.gif +0 -0
- data/examples/compass/src/sticky_footer.sass +11 -0
- data/examples/compass/src/utilities.sass +108 -0
- data/examples/compass/sticky_footer.html.haml +14 -0
- data/examples/compass/utilities.html.haml +189 -0
- data/examples/logo/logo.html.haml +40 -0
- data/examples/logo/src/ie.sass +6 -0
- data/examples/logo/src/print.sass +6 -0
- data/examples/logo/src/screen.sass +29 -0
- data/examples/yui/divisions.html.haml +179 -0
- data/examples/yui/index.html.haml +19 -0
- data/examples/yui/src/screen.sass +13 -0
- data/examples/yui/sub_divisions.html.haml +169 -0
- data/examples/yui/templates.html.haml +54 -0
- data/examples/yui/test.jpg +0 -0
- data/examples/yui/typography.html.haml +132 -0
- data/frameworks/blueprint.rb +2 -0
- data/frameworks/blueprint/stylesheets/_blueprint.sass +3 -0
- data/frameworks/blueprint/stylesheets/blueprint/_ie.sass +93 -0
- data/frameworks/blueprint/stylesheets/blueprint/_print.sass +83 -0
- data/frameworks/blueprint/stylesheets/blueprint/_reset.sass +3 -0
- data/frameworks/blueprint/stylesheets/blueprint/_screen.sass +15 -0
- data/frameworks/blueprint/stylesheets/blueprint/modules/_buttons.sass +84 -0
- data/frameworks/blueprint/stylesheets/blueprint/modules/_colors.sass +33 -0
- data/frameworks/blueprint/stylesheets/blueprint/modules/_debug.sass +9 -0
- data/frameworks/blueprint/stylesheets/blueprint/modules/_fancy_type.sass +82 -0
- data/frameworks/blueprint/stylesheets/blueprint/modules/_form.sass +55 -0
- data/frameworks/blueprint/stylesheets/blueprint/modules/_grid.sass +178 -0
- data/frameworks/blueprint/stylesheets/blueprint/modules/_interaction.sass +58 -0
- data/frameworks/blueprint/stylesheets/blueprint/modules/_link_icons.sass +44 -0
- data/frameworks/blueprint/stylesheets/blueprint/modules/_liquid.sass +141 -0
- data/frameworks/blueprint/stylesheets/blueprint/modules/_reset.sass +56 -0
- data/frameworks/blueprint/stylesheets/blueprint/modules/_rtl.sass +104 -0
- data/frameworks/blueprint/stylesheets/blueprint/modules/_scaffolding.sass +47 -0
- data/frameworks/blueprint/stylesheets/blueprint/modules/_typography.sass +155 -0
- data/frameworks/blueprint/stylesheets/blueprint/modules/_utilities.sass +37 -0
- data/frameworks/blueprint/templates/buttons/buttons.sass +49 -0
- data/frameworks/blueprint/templates/buttons/buttons/cross.png +0 -0
- data/frameworks/blueprint/templates/buttons/buttons/key.png +0 -0
- data/frameworks/blueprint/templates/buttons/buttons/tick.png +0 -0
- data/frameworks/blueprint/templates/buttons/manifest.rb +5 -0
- data/frameworks/blueprint/templates/link_icons/link_icons.sass +13 -0
- data/frameworks/blueprint/templates/link_icons/link_icons/doc.png +0 -0
- data/frameworks/blueprint/templates/link_icons/link_icons/email.png +0 -0
- data/frameworks/blueprint/templates/link_icons/link_icons/external.png +0 -0
- data/frameworks/blueprint/templates/link_icons/link_icons/feed.png +0 -0
- data/frameworks/blueprint/templates/link_icons/link_icons/im.png +0 -0
- data/frameworks/blueprint/templates/link_icons/link_icons/pdf.png +0 -0
- data/frameworks/blueprint/templates/link_icons/link_icons/visited.png +0 -0
- data/frameworks/blueprint/templates/link_icons/link_icons/xls.png +0 -0
- data/frameworks/blueprint/templates/link_icons/manifest.rb +10 -0
- data/frameworks/blueprint/templates/project/grid.png +0 -0
- data/frameworks/blueprint/templates/project/ie.sass +15 -0
- data/frameworks/blueprint/templates/project/manifest.rb +6 -0
- data/frameworks/blueprint/templates/project/partials/_base.sass +11 -0
- data/frameworks/blueprint/templates/project/print.sass +3 -0
- data/frameworks/blueprint/templates/project/screen.sass +40 -0
- data/frameworks/compass.rb +2 -0
- data/frameworks/compass/stylesheets/_compass.sass +1 -0
- data/frameworks/compass/stylesheets/compass/_layout.sass +1 -0
- data/frameworks/compass/stylesheets/compass/_misc.sass +24 -0
- data/frameworks/compass/stylesheets/compass/_reset.sass +3 -0
- data/frameworks/compass/stylesheets/compass/_utilities.sass +6 -0
- data/frameworks/compass/stylesheets/compass/layout/_sticky_footer.sass +17 -0
- data/frameworks/compass/stylesheets/compass/utilities/_general.sass +6 -0
- data/frameworks/compass/stylesheets/compass/utilities/_links.sass +3 -0
- data/frameworks/compass/stylesheets/compass/utilities/_lists.sass +3 -0
- data/frameworks/compass/stylesheets/compass/utilities/_print.sass +24 -0
- data/frameworks/compass/stylesheets/compass/utilities/_sprites.sass +1 -0
- data/frameworks/compass/stylesheets/compass/utilities/_tables.sass +3 -0
- data/frameworks/compass/stylesheets/compass/utilities/_text.sass +2 -0
- data/frameworks/compass/stylesheets/compass/utilities/general/_clearfix.sass +24 -0
- data/frameworks/compass/stylesheets/compass/utilities/general/_float.sass +17 -0
- data/frameworks/compass/stylesheets/compass/utilities/general/_hacks.sass +6 -0
- data/frameworks/compass/stylesheets/compass/utilities/general/_inline_block.sass +6 -0
- data/frameworks/compass/stylesheets/compass/utilities/general/_reset.sass +134 -0
- data/frameworks/compass/stylesheets/compass/utilities/general/_tabs.sass +0 -0
- data/frameworks/compass/stylesheets/compass/utilities/general/_tag_cloud.sass +19 -0
- data/frameworks/compass/stylesheets/compass/utilities/links/_hover_link.sass +5 -0
- data/frameworks/compass/stylesheets/compass/utilities/links/_link_colors.sass +24 -0
- data/frameworks/compass/stylesheets/compass/utilities/links/_unstyled_link.sass +5 -0
- data/frameworks/compass/stylesheets/compass/utilities/lists/_bullets.sass +21 -0
- data/frameworks/compass/stylesheets/compass/utilities/lists/_horizontal_list.sass +52 -0
- data/frameworks/compass/stylesheets/compass/utilities/lists/_inline_list.sass +29 -0
- data/frameworks/compass/stylesheets/compass/utilities/sprites/_sprite_img.sass +12 -0
- data/frameworks/compass/stylesheets/compass/utilities/tables/_alternating_rows_and_columns.sass +20 -0
- data/frameworks/compass/stylesheets/compass/utilities/tables/_borders.sass +27 -0
- data/frameworks/compass/stylesheets/compass/utilities/tables/_scaffolding.sass +9 -0
- data/frameworks/compass/stylesheets/compass/utilities/text/_ellipsis.sass +13 -0
- data/frameworks/compass/stylesheets/compass/utilities/text/_nowrap.sass +3 -0
- data/frameworks/compass/stylesheets/compass/utilities/text/_replacement.sass +17 -0
- data/frameworks/compass/templates/ellipsis/ellipsis.sass +6 -0
- data/frameworks/compass/templates/ellipsis/manifest.rb +2 -0
- data/frameworks/compass/templates/ellipsis/xml/ellipsis.xml +14 -0
- data/frameworks/compass/templates/project/ie.sass +6 -0
- data/frameworks/compass/templates/project/manifest.rb +3 -0
- data/frameworks/compass/templates/project/print.sass +6 -0
- data/frameworks/compass/templates/project/screen.sass +13 -0
- data/frameworks/yui.rb +2 -0
- data/frameworks/yui/stylesheets/_yui.sass +7 -0
- data/frameworks/yui/stylesheets/yui/modules/_base.sass +60 -0
- data/frameworks/yui/stylesheets/yui/modules/_fonts.sass +38 -0
- data/frameworks/yui/stylesheets/yui/modules/_grids.sass +341 -0
- data/frameworks/yui/stylesheets/yui/modules/_reset.sass +61 -0
- data/frameworks/yui/templates/project/manifest.rb +1 -0
- data/frameworks/yui/templates/project/screen.sass +4 -0
- data/lib/compass.rb +23 -0
- data/lib/compass/actions.rb +110 -0
- data/lib/compass/app_integration.rb +5 -0
- data/lib/compass/app_integration/merb.rb +43 -0
- data/lib/compass/app_integration/rails.rb +12 -0
- data/lib/compass/app_integration/rails/action_controller.rb +15 -0
- data/lib/compass/app_integration/rails/sass_plugin.rb +5 -0
- data/lib/compass/app_integration/rails/templates/compass-install-rails.rb +80 -0
- data/lib/compass/app_integration/rails/urls.rb +14 -0
- data/lib/compass/commands/base.rb +33 -0
- data/lib/compass/commands/create_project.rb +19 -0
- data/lib/compass/commands/generate_grid_background.rb +24 -0
- data/lib/compass/commands/installer_command.rb +31 -0
- data/lib/compass/commands/list_frameworks.rb +16 -0
- data/lib/compass/commands/print_version.rb +23 -0
- data/lib/compass/commands/project_base.rb +112 -0
- data/lib/compass/commands/stamp_pattern.rb +33 -0
- data/lib/compass/commands/update_project.rb +34 -0
- data/lib/compass/commands/validate_project.rb +21 -0
- data/lib/compass/commands/watch_project.rb +64 -0
- data/lib/compass/commands/write_configuration.rb +28 -0
- data/lib/compass/compiler.rb +54 -0
- data/lib/compass/configuration.rb +324 -0
- data/lib/compass/core_ext.rb +14 -0
- data/lib/compass/dependencies.rb +10 -0
- data/lib/compass/errors.rb +7 -0
- data/lib/compass/exec.rb +251 -0
- data/lib/compass/frameworks.rb +29 -0
- data/lib/compass/grid_builder.rb +72 -0
- data/lib/compass/installers.rb +5 -0
- data/lib/compass/installers/base.rb +158 -0
- data/lib/compass/installers/manifest.rb +58 -0
- data/lib/compass/installers/rails.rb +135 -0
- data/lib/compass/installers/stand_alone.rb +60 -0
- data/lib/compass/logger.rb +42 -0
- data/lib/compass/sass_extensions.rb +5 -0
- data/lib/compass/sass_extensions/functions.rb +19 -0
- data/lib/compass/sass_extensions/functions/display.rb +22 -0
- data/lib/compass/sass_extensions/functions/enumerate.rb +6 -0
- data/lib/compass/sass_extensions/functions/inline_image.rb +35 -0
- data/lib/compass/sass_extensions/functions/selectors.rb +39 -0
- data/lib/compass/sass_extensions/functions/urls.rb +105 -0
- data/lib/compass/sass_extensions/monkey_patches.rb +3 -0
- data/lib/compass/sass_extensions/monkey_patches/stylesheet_updating.rb +23 -0
- data/lib/compass/test_case.rb +38 -0
- data/lib/compass/validator.rb +10 -0
- data/lib/compass/version.rb +57 -0
- data/lib/vendor/fssm.rb +41 -0
- data/lib/vendor/fssm/backends/fsevents.rb +37 -0
- data/lib/vendor/fssm/backends/polling.rb +26 -0
- data/lib/vendor/fssm/cache.rb +193 -0
- data/lib/vendor/fssm/ext.rb +37 -0
- data/lib/vendor/fssm/fsevents.rb +129 -0
- data/lib/vendor/fssm/monitor.rb +25 -0
- data/lib/vendor/fssm/path.rb +91 -0
- data/lib/vendor/fssm/state.rb +54 -0
- data/lib/vendor/fssm/support.rb +22 -0
- data/lib/vendor/fssm/tree.rb +176 -0
- data/test/command_line_helper.rb +102 -0
- data/test/command_line_test.rb +66 -0
- data/test/compass_test.rb +141 -0
- data/test/configuration_test.rb +118 -0
- data/test/fixtures/stylesheets/blueprint/config.rb +9 -0
- data/test/fixtures/stylesheets/blueprint/css/typography.css +158 -0
- data/test/fixtures/stylesheets/blueprint/images/grid.png +0 -0
- data/test/fixtures/stylesheets/blueprint/sass/ie.sass +3 -0
- data/test/fixtures/stylesheets/blueprint/sass/print.sass +3 -0
- data/test/fixtures/stylesheets/blueprint/sass/screen.sass +17 -0
- data/test/fixtures/stylesheets/blueprint/sass/typography.sass +3 -0
- data/test/fixtures/stylesheets/compass/config.rb +9 -0
- data/test/fixtures/stylesheets/compass/css/layout.css +13 -0
- data/test/fixtures/stylesheets/compass/css/print.css +18 -0
- data/test/fixtures/stylesheets/compass/css/reset.css +60 -0
- data/test/fixtures/stylesheets/compass/css/utilities.css +17 -0
- data/test/fixtures/stylesheets/compass/sass/layout.sass +3 -0
- data/test/fixtures/stylesheets/compass/sass/print.sass +5 -0
- data/test/fixtures/stylesheets/compass/sass/reset.sass +10 -0
- data/test/fixtures/stylesheets/compass/sass/utilities.sass +6 -0
- data/test/fixtures/stylesheets/image_urls/config.rb +17 -0
- data/test/fixtures/stylesheets/image_urls/css/screen.css +3 -0
- data/test/fixtures/stylesheets/image_urls/images/grid.png +0 -0
- data/test/fixtures/stylesheets/image_urls/sass/screen.sass +6 -0
- data/test/fixtures/stylesheets/yui/config.rb +9 -0
- data/test/fixtures/stylesheets/yui/css/mixins.css +13 -0
- data/test/fixtures/stylesheets/yui/sass/base.sass +3 -0
- data/test/fixtures/stylesheets/yui/sass/fonts.sass +3 -0
- data/test/fixtures/stylesheets/yui/sass/grids.sass +3 -0
- data/test/fixtures/stylesheets/yui/sass/mixins.sass +16 -0
- data/test/rails_integration_test.rb +83 -0
- data/test/sass_extensions_test.rb +31 -0
- data/test/test_case_helper.rb +13 -0
- data/test/test_helper.rb +21 -0
- data/test/test_rails_helper.rb +20 -0
- metadata +372 -0
@@ -0,0 +1,129 @@
|
|
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
|
+
def initialize(fsevents_object, id, path)
|
10
|
+
@fsevents_object, @id, @path = fsevents_object, id, path
|
11
|
+
end
|
12
|
+
|
13
|
+
# Returns an array of the files/dirs in the path that the event occurred in.
|
14
|
+
# The files are sorted by the modification time, the first entry is the last modified file.
|
15
|
+
def files
|
16
|
+
Dir.glob("#{File.expand_path(path)}/*").sort_by {|f| File.mtime(f) }.reverse
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns the last modified file in the path that the event occurred in.
|
20
|
+
def last_modified_file
|
21
|
+
files.first
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class StreamError < StandardError; end
|
26
|
+
|
27
|
+
attr_reader :paths
|
28
|
+
attr_reader :stream
|
29
|
+
|
30
|
+
attr_accessor :allocator
|
31
|
+
attr_accessor :context
|
32
|
+
attr_accessor :since
|
33
|
+
attr_accessor :latency
|
34
|
+
attr_accessor :flags
|
35
|
+
|
36
|
+
# Initializes a new FSEvents `watchdog` object and starts watching the directories you specify for events. The
|
37
|
+
# block is used as a handler for events, which are passed as the block's argument. This method is the easiest
|
38
|
+
# way to start watching some directories if you don't care about the details of setting up the event stream.
|
39
|
+
#
|
40
|
+
# Rucola::FSEvents.start_watching('/tmp') do |events|
|
41
|
+
# events.each { |event| log.debug("#{event.files.inspect} were changed.") }
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
# Rucola::FSEvents.start_watching('/var/log/system.log', '/var/log/secure.log', :since => last_id, :latency => 5) do
|
45
|
+
# Growl.notify("Something was added to your log files!")
|
46
|
+
# end
|
47
|
+
#
|
48
|
+
# Note that the method also returns the FSEvents object. This enables you to control the event stream if you want to.
|
49
|
+
#
|
50
|
+
# fsevents = Rucola::FSEvents.start_watching('/Volumes') do |events|
|
51
|
+
# events.each { |event| Growl.notify("Volume changes: #{event.files.to_sentence}") }
|
52
|
+
# end
|
53
|
+
# fsevents.stop
|
54
|
+
def self.start_watching(*params, &block)
|
55
|
+
fsevents = new(*params, &block)
|
56
|
+
fsevents.create_stream
|
57
|
+
fsevents.start
|
58
|
+
fsevents
|
59
|
+
end
|
60
|
+
|
61
|
+
# Creates a new FSEvents `watchdog` object. You can specify a list of paths to watch and options to control the
|
62
|
+
# behaviour of the watchdog. The block you pass serves as a callback when an event is generated on one of the
|
63
|
+
# specified paths.
|
64
|
+
#
|
65
|
+
# fsevents = FSEvents.new('/etc/passwd') { Mailer.send_mail("Someone touched the password file!") }
|
66
|
+
# fsevents.create_stream
|
67
|
+
# fsevents.start
|
68
|
+
#
|
69
|
+
# fsevents = FSEvents.new('/home/upload', :since => UploadWatcher.last_event_id) do |events|
|
70
|
+
# events.each do |event|
|
71
|
+
# UploadWatcher.last_event_id = event.id
|
72
|
+
# event.files.each do |file|
|
73
|
+
# UploadWatcher.logfile.append("#{file} was changed")
|
74
|
+
# end
|
75
|
+
# end
|
76
|
+
# end
|
77
|
+
#
|
78
|
+
# *:since: The service will report events that have happened after the supplied event ID. Never use 0 because that
|
79
|
+
# will cause every fsevent since the "beginning of time" to be reported. Use OSX::KFSEventStreamEventIdSinceNow
|
80
|
+
# if you want to receive events that have happened after this call. (Default: OSX::KFSEventStreamEventIdSinceNow).
|
81
|
+
# You can find the ID's passed with :since in the events passed to your block.
|
82
|
+
# *:latency: Number of seconds to wait until an FSEvent is reported, this allows the service to bundle events. (Default: 0.0)
|
83
|
+
#
|
84
|
+
# Please refer to the Cocoa documentation for the rest of the options.
|
85
|
+
def initialize(*params, &block)
|
86
|
+
raise ArgumentError, 'No callback block was specified.' unless block_given?
|
87
|
+
|
88
|
+
options = params.last.kind_of?(Hash) ? params.pop : {}
|
89
|
+
@paths = params.flatten
|
90
|
+
|
91
|
+
paths.each { |path| raise ArgumentError, "The specified path (#{path}) does not exist." unless File.exist?(path) }
|
92
|
+
|
93
|
+
@allocator = options[:allocator] || OSX::KCFAllocatorDefault
|
94
|
+
@context = options[:context] || nil
|
95
|
+
@since = options[:since] || OSX::KFSEventStreamEventIdSinceNow
|
96
|
+
@latency = options[:latency] || 0.0
|
97
|
+
@flags = options[:flags] || 0
|
98
|
+
@stream = options[:stream] || nil
|
99
|
+
|
100
|
+
@user_callback = block
|
101
|
+
@callback = Proc.new do |stream, client_callback_info, number_of_events, paths_pointer, event_flags, event_ids|
|
102
|
+
paths_pointer.regard_as('*')
|
103
|
+
events = []
|
104
|
+
number_of_events.times {|i| events << Rucola::FSEvents::FSEvent.new(self, event_ids[i], paths_pointer[i]) }
|
105
|
+
@user_callback.call(events)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# Create the stream.
|
110
|
+
# Raises a Rucola::FSEvents::StreamError if the stream could not be created.
|
111
|
+
def create_stream
|
112
|
+
@stream = OSX.FSEventStreamCreate(@allocator, @callback, @context, @paths, @since, @latency, @flags)
|
113
|
+
raise(StreamError, 'Unable to create FSEvents stream.') unless @stream
|
114
|
+
OSX.FSEventStreamScheduleWithRunLoop(@stream, OSX.CFRunLoopGetCurrent, OSX::KCFRunLoopDefaultMode)
|
115
|
+
end
|
116
|
+
|
117
|
+
# Start the stream.
|
118
|
+
# Raises a Rucola::FSEvents::StreamError if the stream could not be started.
|
119
|
+
def start
|
120
|
+
raise(StreamError, 'Unable to start FSEvents stream.') unless OSX.FSEventStreamStart(@stream)
|
121
|
+
end
|
122
|
+
|
123
|
+
# Stop the stream.
|
124
|
+
# You can resume it by calling `start` again.
|
125
|
+
def stop
|
126
|
+
OSX.FSEventStreamStop(@stream)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class FSSM::Monitor
|
2
|
+
def initialize(options={})
|
3
|
+
@options = options
|
4
|
+
@backend = FSSM::Backends::Default.new
|
5
|
+
end
|
6
|
+
|
7
|
+
def path(*args, &block)
|
8
|
+
path = FSSM::Path.new(*args)
|
9
|
+
|
10
|
+
if block_given?
|
11
|
+
if block.arity == 1
|
12
|
+
block.call(path)
|
13
|
+
else
|
14
|
+
path.instance_eval(&block)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
@backend.add_path(path)
|
19
|
+
path
|
20
|
+
end
|
21
|
+
|
22
|
+
def run
|
23
|
+
@backend.run
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
class FSSM::Path
|
2
|
+
def initialize(path=nil, glob=nil, &block)
|
3
|
+
set_path(path || '.')
|
4
|
+
set_glob(glob || '**/*')
|
5
|
+
init_callbacks
|
6
|
+
|
7
|
+
if block_given?
|
8
|
+
if block.arity == 1
|
9
|
+
block.call(self)
|
10
|
+
else
|
11
|
+
self.instance_eval(&block)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_s
|
17
|
+
@path.to_s
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_pathname
|
21
|
+
@path
|
22
|
+
end
|
23
|
+
|
24
|
+
def glob(value=nil)
|
25
|
+
return @glob if value.nil?
|
26
|
+
set_glob(value)
|
27
|
+
end
|
28
|
+
|
29
|
+
def create(callback_or_path=nil, &block)
|
30
|
+
callback_action(:create, (block_given? ? block : callback_or_path))
|
31
|
+
end
|
32
|
+
|
33
|
+
def update(callback_or_path=nil, &block)
|
34
|
+
callback_action(:update, (block_given? ? block : callback_or_path))
|
35
|
+
end
|
36
|
+
|
37
|
+
def delete(callback_or_path=nil, &block)
|
38
|
+
callback_action(:delete, (block_given? ? block : callback_or_path))
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def init_callbacks
|
44
|
+
do_nothing = lambda {|base, relative|}
|
45
|
+
@callbacks = Hash.new(do_nothing)
|
46
|
+
end
|
47
|
+
|
48
|
+
def callback_action(type, arg=nil)
|
49
|
+
if arg.is_a?(Proc)
|
50
|
+
set_callback(type, arg)
|
51
|
+
elsif arg.nil?
|
52
|
+
get_callback(type)
|
53
|
+
else
|
54
|
+
run_callback(type, arg)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def set_callback(type, arg)
|
59
|
+
raise ArgumentError, "Proc expected" unless arg.is_a?(Proc)
|
60
|
+
@callbacks[type] = arg
|
61
|
+
end
|
62
|
+
|
63
|
+
def get_callback(type)
|
64
|
+
@callbacks[type]
|
65
|
+
end
|
66
|
+
|
67
|
+
def run_callback(type, arg)
|
68
|
+
base, relative = split_path(arg)
|
69
|
+
|
70
|
+
begin
|
71
|
+
@callbacks[type].call(base, relative)
|
72
|
+
rescue Exception => e
|
73
|
+
raise FSSM::CallbackError, "#{type} - #{base.join(relative)}: #{e.message}", e.backtrace
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def split_path(path)
|
78
|
+
path = Pathname.for(path)
|
79
|
+
[@path, (path.relative? ? path : path.relative_path_from(@path))]
|
80
|
+
end
|
81
|
+
|
82
|
+
def set_path(path)
|
83
|
+
path = Pathname.for(path)
|
84
|
+
raise FSSM::FileNotFoundError, "#{path}" unless path.exist?
|
85
|
+
@path = path.realpath
|
86
|
+
end
|
87
|
+
|
88
|
+
def set_glob(glob)
|
89
|
+
@glob = glob.is_a?(Array) ? glob : [glob]
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
class FSSM::State
|
3
|
+
def initialize(path)
|
4
|
+
@path = path
|
5
|
+
@cache = FSSM::Tree::Cache.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def refresh(base=nil, skip_callbacks=false)
|
9
|
+
previous, current = recache(base || @path.to_pathname)
|
10
|
+
|
11
|
+
unless skip_callbacks
|
12
|
+
deleted(previous, current)
|
13
|
+
created(previous, current)
|
14
|
+
modified(previous, current)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def created(previous, current)
|
21
|
+
(current.keys - previous.keys).each {|created| @path.create(created)}
|
22
|
+
end
|
23
|
+
|
24
|
+
def deleted(previous, current)
|
25
|
+
(previous.keys - current.keys).each {|deleted| @path.delete(deleted)}
|
26
|
+
end
|
27
|
+
|
28
|
+
def modified(previous, current)
|
29
|
+
(current.keys & previous.keys).each do |file|
|
30
|
+
@path.update(file) if (current[file] <=> previous[file]) != 0
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def recache(base)
|
35
|
+
base = Pathname.for(base)
|
36
|
+
previous = @cache.files
|
37
|
+
snapshot(base)
|
38
|
+
current = @cache.files
|
39
|
+
[previous, current]
|
40
|
+
end
|
41
|
+
|
42
|
+
def snapshot(base)
|
43
|
+
base = Pathname.for(base)
|
44
|
+
@cache.unset(base)
|
45
|
+
@path.glob.each {|glob| add_glob(base, glob)}
|
46
|
+
end
|
47
|
+
|
48
|
+
def add_glob(base, glob)
|
49
|
+
Pathname.glob(base.join(glob)).each do |fn|
|
50
|
+
@cache.set(fn)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module FSSM::Support
|
2
|
+
class << self
|
3
|
+
def backend
|
4
|
+
(mac? && carbon_core?) ? 'FSEvents' : 'Polling'
|
5
|
+
end
|
6
|
+
|
7
|
+
def mac?
|
8
|
+
@@mac ||= RUBY_PLATFORM =~ /darwin/i
|
9
|
+
end
|
10
|
+
|
11
|
+
def carbon_core?
|
12
|
+
@@carbon_core ||= begin
|
13
|
+
require 'osx/foundation'
|
14
|
+
OSX.require_framework '/System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework'
|
15
|
+
true
|
16
|
+
rescue LoadError
|
17
|
+
false
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,176 @@
|
|
1
|
+
module FSSM::Tree
|
2
|
+
module NodeBase
|
3
|
+
def initialize
|
4
|
+
@children = {}
|
5
|
+
end
|
6
|
+
|
7
|
+
protected
|
8
|
+
|
9
|
+
def child(segment)
|
10
|
+
@children["#{segment}"]
|
11
|
+
end
|
12
|
+
|
13
|
+
def child!(segment)
|
14
|
+
(@children["#{segment}"] ||= Node.new)
|
15
|
+
end
|
16
|
+
|
17
|
+
def has_child?(segment)
|
18
|
+
@children.has_key?("#{segment}")
|
19
|
+
end
|
20
|
+
|
21
|
+
def remove_child(segment)
|
22
|
+
@children.delete("#{segment}")
|
23
|
+
end
|
24
|
+
|
25
|
+
def remove_children
|
26
|
+
@children.clear
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
module NodeEnumerable
|
31
|
+
include NodeBase
|
32
|
+
include Enumerable
|
33
|
+
|
34
|
+
def each(prefix=nil, &block)
|
35
|
+
@children.each do |segment, node|
|
36
|
+
cprefix = prefix ?
|
37
|
+
Pathname.for(prefix).join(segment) :
|
38
|
+
Pathname.for(segment)
|
39
|
+
block.call(cprefix, node)
|
40
|
+
node.each(cprefix, &block)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
module NodeInsertion
|
46
|
+
include NodeBase
|
47
|
+
|
48
|
+
def unset(path)
|
49
|
+
key = key_segments(path)
|
50
|
+
|
51
|
+
if key.empty?
|
52
|
+
remove_children
|
53
|
+
return nil
|
54
|
+
end
|
55
|
+
|
56
|
+
segment = key.pop
|
57
|
+
node = descendant(key)
|
58
|
+
|
59
|
+
return unless node
|
60
|
+
|
61
|
+
node.remove_child(segment)
|
62
|
+
|
63
|
+
nil
|
64
|
+
end
|
65
|
+
|
66
|
+
def set(path)
|
67
|
+
node = descendant!(path)
|
68
|
+
node.from_path(path).mtime
|
69
|
+
end
|
70
|
+
|
71
|
+
protected
|
72
|
+
|
73
|
+
def key_segments(key)
|
74
|
+
return key if key.is_a?(Array)
|
75
|
+
Pathname.for(key).segments
|
76
|
+
end
|
77
|
+
|
78
|
+
def descendant(path)
|
79
|
+
recurse(path, false)
|
80
|
+
end
|
81
|
+
|
82
|
+
def descendant!(path)
|
83
|
+
recurse(path, true)
|
84
|
+
end
|
85
|
+
|
86
|
+
def recurse(key, create=false)
|
87
|
+
key = key_segments(key)
|
88
|
+
node = self
|
89
|
+
|
90
|
+
until key.empty?
|
91
|
+
segment = key.shift
|
92
|
+
node = create ? node.child!(segment) : node.child(segment)
|
93
|
+
return nil unless node
|
94
|
+
end
|
95
|
+
|
96
|
+
node
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
module CacheDebug
|
101
|
+
def set(path)
|
102
|
+
FSSM.dbg("Cache#set(#{path})")
|
103
|
+
super
|
104
|
+
end
|
105
|
+
|
106
|
+
def unset(path)
|
107
|
+
FSSM.dbg("Cache#unset(#{path})")
|
108
|
+
super
|
109
|
+
end
|
110
|
+
|
111
|
+
def ftype(ft)
|
112
|
+
FSSM.dbg("Cache#ftype(#{ft})")
|
113
|
+
super
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
class Node
|
118
|
+
include NodeBase
|
119
|
+
include NodeEnumerable
|
120
|
+
|
121
|
+
attr_accessor :mtime
|
122
|
+
attr_accessor :ftype
|
123
|
+
|
124
|
+
def <=>(other)
|
125
|
+
return unless other.is_a?(::FSSM::Tree::Node)
|
126
|
+
self.mtime <=> other.mtime
|
127
|
+
end
|
128
|
+
|
129
|
+
def from_path(path)
|
130
|
+
path = Pathname.for(path)
|
131
|
+
@ftype = path.ftype
|
132
|
+
# this handles bad symlinks without failing. why handle bad symlinks at
|
133
|
+
# all? well, we could still be interested in their creation and deletion.
|
134
|
+
@mtime = path.symlink? ? Time.at(0) : path.mtime
|
135
|
+
self
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
class Cache
|
140
|
+
include NodeBase
|
141
|
+
include NodeEnumerable
|
142
|
+
include NodeInsertion
|
143
|
+
include CacheDebug if $DEBUG
|
144
|
+
|
145
|
+
def set(path)
|
146
|
+
# all paths set from this level need to be absolute
|
147
|
+
# realpath will fail on broken links
|
148
|
+
path = Pathname.for(path).expand_path
|
149
|
+
super(path)
|
150
|
+
end
|
151
|
+
|
152
|
+
def files
|
153
|
+
ftype('file')
|
154
|
+
end
|
155
|
+
|
156
|
+
def directories
|
157
|
+
ftype('directory')
|
158
|
+
end
|
159
|
+
|
160
|
+
def links
|
161
|
+
ftype('link')
|
162
|
+
end
|
163
|
+
alias symlinks links
|
164
|
+
|
165
|
+
private
|
166
|
+
|
167
|
+
def ftype(ft)
|
168
|
+
inject({}) do |hash, entry|
|
169
|
+
path, node = entry
|
170
|
+
hash["#{path}"] = node.mtime if node.ftype == ft
|
171
|
+
hash
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
end
|