guard 0.8.0 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,78 +1,78 @@
1
- module Guard
2
-
3
- # The interactor reads user input and triggers
4
- # specific action upon them unless its locked.
5
- #
6
- # Currently the following actions are implemented:
7
- #
8
- # - stop, quit, exit, s, q, e => Exit Guard
9
- # - reload, r, z => Reload Guard
10
- # - pause, p => Pause Guard
11
- # - Everything else => Run all
12
- #
13
- class Interactor
14
-
15
- class LockException < Exception; end
16
- class UnlockException < Exception; end
17
-
18
- attr_reader :locked
19
-
20
- # Initialize the interactor in unlocked state.
21
- #
22
- def initialize
23
- @locked = false
24
- end
25
-
26
- # Start the interactor in its own thread.
27
- #
28
- def start
29
- return if ENV["GUARD_ENV"] == 'test'
30
-
31
- @thread = Thread.new do
32
- loop do
33
- begin
34
- if !@locked && (entry = $stdin.gets)
35
- entry.gsub! /\n/, ''
36
- case entry
37
- when 'stop', 'quit', 'exit', 's', 'q', 'e'
38
- ::Guard.stop
39
- when 'reload', 'r', 'z'
40
- ::Guard::Dsl.reevaluate_guardfile
41
- ::Guard.reload
42
- when 'pause', 'p'
43
- ::Guard.pause
44
- else
45
- ::Guard.run_all
46
- end
47
- end
48
- rescue LockException
49
- lock
50
- rescue UnlockException
51
- unlock
52
- end
53
- end
54
- end
55
- end
56
-
57
- # Lock the interactor.
58
- #
59
- def lock
60
- if !@thread || @thread == Thread.current
61
- @locked = true
62
- else
63
- @thread.raise(LockException)
64
- end
65
- end
66
-
67
- # Unlock the interactor.
68
- #
69
- def unlock
70
- if !@thread || @thread == Thread.current
71
- @locked = false
72
- else
73
- @thread.raise(UnlockException)
74
- end
75
- end
76
-
77
- end
78
- end
1
+ module Guard
2
+
3
+ # The interactor reads user input and triggers
4
+ # specific action upon them unless its locked.
5
+ #
6
+ # Currently the following actions are implemented:
7
+ #
8
+ # - stop, quit, exit, s, q, e => Exit Guard
9
+ # - reload, r, z => Reload Guard
10
+ # - pause, p => Pause Guard
11
+ # - Everything else => Run all
12
+ #
13
+ class Interactor
14
+
15
+ class LockException < Exception; end
16
+ class UnlockException < Exception; end
17
+
18
+ attr_reader :locked
19
+
20
+ # Initialize the interactor in unlocked state.
21
+ #
22
+ def initialize
23
+ @locked = false
24
+ end
25
+
26
+ # Start the interactor in its own thread.
27
+ #
28
+ def start
29
+ return if ENV["GUARD_ENV"] == 'test'
30
+
31
+ @thread = Thread.new do
32
+ loop do
33
+ begin
34
+ if !@locked && (entry = $stdin.gets)
35
+ entry.gsub! /\n/, ''
36
+ case entry
37
+ when 'stop', 'quit', 'exit', 's', 'q', 'e'
38
+ ::Guard.stop
39
+ when 'reload', 'r', 'z'
40
+ ::Guard::Dsl.reevaluate_guardfile
41
+ ::Guard.reload
42
+ when 'pause', 'p'
43
+ ::Guard.pause
44
+ else
45
+ ::Guard.run_all
46
+ end
47
+ end
48
+ rescue LockException
49
+ lock
50
+ rescue UnlockException
51
+ unlock
52
+ end
53
+ end
54
+ end
55
+ end
56
+
57
+ # Lock the interactor.
58
+ #
59
+ def lock
60
+ if !@thread || @thread == Thread.current
61
+ @locked = true
62
+ else
63
+ @thread.raise(LockException)
64
+ end
65
+ end
66
+
67
+ # Unlock the interactor.
68
+ #
69
+ def unlock
70
+ if !@thread || @thread == Thread.current
71
+ @locked = false
72
+ else
73
+ @thread.raise(UnlockException)
74
+ end
75
+ end
76
+
77
+ end
78
+ end
@@ -1,346 +1,346 @@
1
- require 'rbconfig'
2
- require 'digest/sha1'
3
-
4
- module Guard
5
-
6
- autoload :Darwin, 'guard/listeners/darwin'
7
- autoload :Linux, 'guard/listeners/linux'
8
- autoload :Windows, 'guard/listeners/windows'
9
- autoload :Polling, 'guard/listeners/polling'
10
-
11
- # The Listener is the base class for all listener
12
- # implementations.
13
- #
14
- # @abstract
15
- #
16
- class Listener
17
-
18
- # Default paths that gets ignored by the listener
19
- DEFAULT_IGNORE_PATHS = %w[. .. .bundle .git log tmp vendor]
20
-
21
- attr_accessor :changed_files
22
- attr_reader :directory, :ignore_paths, :locked
23
-
24
- # Select the appropriate listener implementation for the
25
- # current OS and initializes it.
26
- #
27
- # @param [Array] args the arguments for the listener
28
- # @return [Guard::Listener] the chosen listener
29
- #
30
- def self.select_and_init(*args)
31
- if mac? && Darwin.usable?
32
- Darwin.new(*args)
33
- elsif linux? && Linux.usable?
34
- Linux.new(*args)
35
- elsif windows? && Windows.usable?
36
- Windows.new(*args)
37
- else
38
- UI.info 'Using polling (Please help us to support your system better than that).'
39
- Polling.new(*args)
40
- end
41
- end
42
-
43
- # Initialize the listener.
44
- #
45
- # @param [String] directory the root directory to listen to
46
- # @option options [Boolean] relativize_paths use only relative paths
47
- # @option options [Array<String>] ignore_paths the paths to ignore by the listener
48
- #
49
- def initialize(directory = Dir.pwd, options = {})
50
- @directory = directory.to_s
51
- @sha1_checksums_hash = {}
52
- @file_timestamp_hash = {}
53
- @relativize_paths = options.fetch(:relativize_paths, true)
54
- @changed_files = []
55
- @locked = false
56
- @ignore_paths = DEFAULT_IGNORE_PATHS
57
- @ignore_paths |= options[:ignore_paths] if options[:ignore_paths]
58
- @watch_all_modifications = options.fetch(:watch_all_modifications, false)
59
-
60
- update_last_event
61
- start_reactor
62
- end
63
-
64
- # Start the listener thread.
65
- #
66
- def start_reactor
67
- return if ENV["GUARD_ENV"] == 'test'
68
-
69
- Thread.new do
70
- loop do
71
- if @changed_files != [] && !@locked
72
- changed_files = @changed_files.dup
73
- clear_changed_files
74
- ::Guard.run_on_change(changed_files)
75
- else
76
- sleep 0.1
77
- end
78
- end
79
- end
80
- end
81
-
82
- # Start watching the root directory.
83
- #
84
- def start
85
- watch(@directory)
86
- timestamp_files
87
- end
88
-
89
- # Stop listening for events.
90
- #
91
- def stop
92
- end
93
-
94
- # Lock the listener to ignore change events.
95
- #
96
- def lock
97
- @locked = true
98
- end
99
-
100
- # Unlock the listener to listen again to change events.
101
- #
102
- def unlock
103
- @locked = false
104
- end
105
-
106
- # Clear the list of changed files.
107
- #
108
- def clear_changed_files
109
- @changed_files.clear
110
- end
111
-
112
- # Store a listener callback.
113
- #
114
- # @param [Block] callback the callback to store
115
- #
116
- def on_change(&callback)
117
- @callback = callback
118
- end
119
-
120
- # Updates the timestamp of the last event.
121
- #
122
- def update_last_event
123
- @last_event = Time.now
124
- end
125
-
126
- # Get the modified files.
127
- #
128
- # If the `:watch_all_modifications` option is true, then moved and
129
- # deleted files are also reported, but prefixed by an exclamation point.
130
- #
131
- # @example Deleted or moved file
132
- # !/home/user/dir/file.rb
133
- #
134
- # @param [Array<String>] dirs the watched directories
135
- # @param [Hash] options the listener options
136
- # @option options [Symbol] all whether to files in sub directories
137
- # @return [Array<String>] paths of files that have been modified
138
- #
139
- def modified_files(dirs, options = {})
140
- last_event = @last_event
141
- files = []
142
- if @watch_all_modifications
143
- deleted_files = @file_timestamp_hash.collect do |path, ts|
144
- unless File.exists?(path)
145
- @sha1_checksums_hash.delete(path)
146
- @file_timestamp_hash.delete(path)
147
- "!#{path}"
148
- end
149
- end
150
- files.concat(deleted_files.compact)
151
- end
152
- update_last_event
153
- files.concat(potentially_modified_files(dirs, options).select { |path| file_modified?(path, last_event) })
154
-
155
- relativize_paths(files)
156
- end
157
-
158
- # Register a directory to watch.
159
- # Must be implemented by the subclasses.
160
- #
161
- # @param [String] directory the directory to watch
162
- #
163
- def watch(directory)
164
- raise NotImplementedError, "do whatever you want here, given the directory as only argument"
165
- end
166
-
167
- # Get all files that are in the watched directory.
168
- #
169
- # @return [Array<String>] the list of files
170
- #
171
- def all_files
172
- potentially_modified_files([@directory], :all => true)
173
- end
174
-
175
- # Scopes all given paths to the current directory.
176
- #
177
- # @param [Array<String>] paths the paths to change
178
- # @return [Array<String>] all paths now relative to the current dir
179
- #
180
- def relativize_paths(paths)
181
- return paths unless relativize_paths?
182
- paths.map do |path|
183
- path.gsub(%r{^(!)?#{ @directory }/},'\1')
184
- end
185
- end
186
-
187
- # Use paths relative to the current directory.
188
- #
189
- # @return [Boolean] whether to use relative or absolute paths
190
- #
191
- def relativize_paths?
192
- !!@relativize_paths
193
- end
194
-
195
- # Populate initial timestamp file hash to watch for deleted or moved files.
196
- #
197
- def timestamp_files
198
- all_files.each {|path| set_file_timestamp_hash(path, file_timestamp(path)) } if @watch_all_modifications
199
- end
200
-
201
- # Removes the ignored paths from the directory list.
202
- #
203
- # @param [Array<String>] dirs the directory to listen to
204
- # @param [Array<String>] ignore_paths the paths to ignore
205
- # @return children of the passed dirs that are not in the ignore_paths list
206
- #
207
- def exclude_ignored_paths(dirs, ignore_paths = self.ignore_paths)
208
- Dir.glob(dirs.map { |d| "#{d.sub(%r{/+$}, '')}/*" }, File::FNM_DOTMATCH).reject do |path|
209
- ignore_paths.include?(File.basename(path))
210
- end
211
- end
212
-
213
- private
214
-
215
- # Gets a list of files that are in the modified directories.
216
- #
217
- # @param [Array<String>] dirs the list of directories
218
- # @param [Hash] options the find file option
219
- # @option options [Symbol] all whether to files in sub directories
220
- #
221
- def potentially_modified_files(dirs, options = {})
222
- paths = exclude_ignored_paths(dirs)
223
-
224
- if options[:all]
225
- paths.inject([]) do |array, path|
226
- if File.file?(path)
227
- array << path
228
- else
229
- array += Dir.glob("#{ path }/**/*", File::FNM_DOTMATCH).select { |p| File.file?(p) }
230
- end
231
- array
232
- end
233
- else
234
- paths.select { |path| File.file?(path) }
235
- end
236
- end
237
-
238
- # Test if the file content has changed.
239
- #
240
- # Depending on the filesystem, mtime/ctime is probably only precise to the second, so round
241
- # both values down to the second for the comparison.
242
- #
243
- # ctime is used only on == comparison to always catches Rails 3.1 Assets pipelined on Mac OSX
244
- #
245
- # @param [String] path the file path
246
- # @param [Time] last_event the time of the last event
247
- # @return [Boolean] Whether the file content has changed or not.
248
- #
249
- def file_modified?(path, last_event)
250
- ctime = File.ctime(path).to_i
251
- mtime = File.mtime(path).to_i
252
- if [mtime, ctime].max == last_event.to_i
253
- file_content_modified?(path, sha1_checksum(path))
254
- elsif mtime > last_event.to_i
255
- set_sha1_checksums_hash(path, sha1_checksum(path))
256
- true
257
- elsif @watch_all_modifications
258
- ts = file_timestamp(path)
259
- if ts != @file_timestamp_hash[path]
260
- set_file_timestamp_hash(path, ts)
261
- true
262
- end
263
- else
264
- false
265
- end
266
- rescue
267
- false
268
- end
269
-
270
- # Tests if the file content has been modified by
271
- # comparing the SHA1 checksum.
272
- #
273
- # @param [String] path the file path
274
- # @param [String] sha1_checksum the checksum of the file
275
- #
276
- def file_content_modified?(path, sha1_checksum)
277
- if @sha1_checksums_hash[path] != sha1_checksum
278
- set_sha1_checksums_hash(path, sha1_checksum)
279
- true
280
- else
281
- false
282
- end
283
- end
284
-
285
- # Set save a files current timestamp
286
- #
287
- # @param [String] path the file path
288
- # @param [Int] file_timestamp the files modified timestamp
289
- #
290
- def set_file_timestamp_hash(path, file_timestamp)
291
- @file_timestamp_hash[path] = file_timestamp
292
- end
293
-
294
- # Set the current checksum of a file.
295
- #
296
- # @param [String] path the file path
297
- # @param [String] sha1_checksum the checksum of the file
298
- #
299
- def set_sha1_checksums_hash(path, sha1_checksum)
300
- @sha1_checksums_hash[path] = sha1_checksum
301
- end
302
-
303
- # Gets a files modified timestamp
304
- #
305
- # @path [String] path the file path
306
- # @return [Int] file modified timestamp
307
- #
308
- def file_timestamp(path)
309
- File.mtime(path).to_i
310
- end
311
-
312
- # Calculates the SHA1 checksum of a file.
313
- #
314
- # @param [String] path the path to the file
315
- # @return [String] the SHA1 checksum
316
- #
317
- def sha1_checksum(path)
318
- Digest::SHA1.file(path).to_s
319
- end
320
-
321
- # Test if the OS is Mac OS X.
322
- #
323
- # @return [Boolean] Whether the OS is Mac OS X
324
- #
325
- def self.mac?
326
- RbConfig::CONFIG['target_os'] =~ /darwin/i
327
- end
328
-
329
- # Test if the OS is Linux.
330
- #
331
- # @return [Boolean] Whether the OS is Linux
332
- #
333
- def self.linux?
334
- RbConfig::CONFIG['target_os'] =~ /linux/i
335
- end
336
-
337
- # Test if the OS is Windows.
338
- #
339
- # @return [Boolean] Whether the OS is Windows
340
- #
341
- def self.windows?
342
- RbConfig::CONFIG['target_os'] =~ /mswin|mingw/i
343
- end
344
-
345
- end
346
- end
1
+ require 'rbconfig'
2
+ require 'digest/sha1'
3
+
4
+ module Guard
5
+
6
+ autoload :Darwin, 'guard/listeners/darwin'
7
+ autoload :Linux, 'guard/listeners/linux'
8
+ autoload :Windows, 'guard/listeners/windows'
9
+ autoload :Polling, 'guard/listeners/polling'
10
+
11
+ # The Listener is the base class for all listener
12
+ # implementations.
13
+ #
14
+ # @abstract
15
+ #
16
+ class Listener
17
+
18
+ # Default paths that gets ignored by the listener
19
+ DEFAULT_IGNORE_PATHS = %w[. .. .bundle .git log tmp vendor]
20
+
21
+ attr_accessor :changed_files
22
+ attr_reader :directory, :ignore_paths, :locked
23
+
24
+ # Select the appropriate listener implementation for the
25
+ # current OS and initializes it.
26
+ #
27
+ # @param [Array] args the arguments for the listener
28
+ # @return [Guard::Listener] the chosen listener
29
+ #
30
+ def self.select_and_init(*args)
31
+ if mac? && Darwin.usable?
32
+ Darwin.new(*args)
33
+ elsif linux? && Linux.usable?
34
+ Linux.new(*args)
35
+ elsif windows? && Windows.usable?
36
+ Windows.new(*args)
37
+ else
38
+ UI.info 'Using polling (Please help us to support your system better than that).'
39
+ Polling.new(*args)
40
+ end
41
+ end
42
+
43
+ # Initialize the listener.
44
+ #
45
+ # @param [String] directory the root directory to listen to
46
+ # @option options [Boolean] relativize_paths use only relative paths
47
+ # @option options [Array<String>] ignore_paths the paths to ignore by the listener
48
+ #
49
+ def initialize(directory = Dir.pwd, options = {})
50
+ @directory = directory.to_s
51
+ @sha1_checksums_hash = {}
52
+ @file_timestamp_hash = {}
53
+ @relativize_paths = options.fetch(:relativize_paths, true)
54
+ @changed_files = []
55
+ @locked = false
56
+ @ignore_paths = DEFAULT_IGNORE_PATHS
57
+ @ignore_paths |= options[:ignore_paths] if options[:ignore_paths]
58
+ @watch_all_modifications = options.fetch(:watch_all_modifications, false)
59
+
60
+ update_last_event
61
+ start_reactor
62
+ end
63
+
64
+ # Start the listener thread.
65
+ #
66
+ def start_reactor
67
+ return if ENV["GUARD_ENV"] == 'test'
68
+
69
+ Thread.new do
70
+ loop do
71
+ if @changed_files != [] && !@locked
72
+ changed_files = @changed_files.dup
73
+ clear_changed_files
74
+ ::Guard.run_on_change(changed_files)
75
+ else
76
+ sleep 0.1
77
+ end
78
+ end
79
+ end
80
+ end
81
+
82
+ # Start watching the root directory.
83
+ #
84
+ def start
85
+ watch(@directory)
86
+ timestamp_files
87
+ end
88
+
89
+ # Stop listening for events.
90
+ #
91
+ def stop
92
+ end
93
+
94
+ # Lock the listener to ignore change events.
95
+ #
96
+ def lock
97
+ @locked = true
98
+ end
99
+
100
+ # Unlock the listener to listen again to change events.
101
+ #
102
+ def unlock
103
+ @locked = false
104
+ end
105
+
106
+ # Clear the list of changed files.
107
+ #
108
+ def clear_changed_files
109
+ @changed_files.clear
110
+ end
111
+
112
+ # Store a listener callback.
113
+ #
114
+ # @param [Block] callback the callback to store
115
+ #
116
+ def on_change(&callback)
117
+ @callback = callback
118
+ end
119
+
120
+ # Updates the timestamp of the last event.
121
+ #
122
+ def update_last_event
123
+ @last_event = Time.now
124
+ end
125
+
126
+ # Get the modified files.
127
+ #
128
+ # If the `:watch_all_modifications` option is true, then moved and
129
+ # deleted files are also reported, but prefixed by an exclamation point.
130
+ #
131
+ # @example Deleted or moved file
132
+ # !/home/user/dir/file.rb
133
+ #
134
+ # @param [Array<String>] dirs the watched directories
135
+ # @param [Hash] options the listener options
136
+ # @option options [Symbol] all whether to files in sub directories
137
+ # @return [Array<String>] paths of files that have been modified
138
+ #
139
+ def modified_files(dirs, options = {})
140
+ last_event = @last_event
141
+ files = []
142
+ if @watch_all_modifications
143
+ deleted_files = @file_timestamp_hash.collect do |path, ts|
144
+ unless File.exists?(path)
145
+ @sha1_checksums_hash.delete(path)
146
+ @file_timestamp_hash.delete(path)
147
+ "!#{path}"
148
+ end
149
+ end
150
+ files.concat(deleted_files.compact)
151
+ end
152
+ update_last_event
153
+ files.concat(potentially_modified_files(dirs, options).select { |path| file_modified?(path, last_event) })
154
+
155
+ relativize_paths(files)
156
+ end
157
+
158
+ # Register a directory to watch.
159
+ # Must be implemented by the subclasses.
160
+ #
161
+ # @param [String] directory the directory to watch
162
+ #
163
+ def watch(directory)
164
+ raise NotImplementedError, "do whatever you want here, given the directory as only argument"
165
+ end
166
+
167
+ # Get all files that are in the watched directory.
168
+ #
169
+ # @return [Array<String>] the list of files
170
+ #
171
+ def all_files
172
+ potentially_modified_files([@directory], :all => true)
173
+ end
174
+
175
+ # Scopes all given paths to the current directory.
176
+ #
177
+ # @param [Array<String>] paths the paths to change
178
+ # @return [Array<String>] all paths now relative to the current dir
179
+ #
180
+ def relativize_paths(paths)
181
+ return paths unless relativize_paths?
182
+ paths.map do |path|
183
+ path.gsub(%r{^(!)?#{ @directory }/},'\1')
184
+ end
185
+ end
186
+
187
+ # Use paths relative to the current directory.
188
+ #
189
+ # @return [Boolean] whether to use relative or absolute paths
190
+ #
191
+ def relativize_paths?
192
+ !!@relativize_paths
193
+ end
194
+
195
+ # Populate initial timestamp file hash to watch for deleted or moved files.
196
+ #
197
+ def timestamp_files
198
+ all_files.each {|path| set_file_timestamp_hash(path, file_timestamp(path)) } if @watch_all_modifications
199
+ end
200
+
201
+ # Removes the ignored paths from the directory list.
202
+ #
203
+ # @param [Array<String>] dirs the directory to listen to
204
+ # @param [Array<String>] ignore_paths the paths to ignore
205
+ # @return children of the passed dirs that are not in the ignore_paths list
206
+ #
207
+ def exclude_ignored_paths(dirs, ignore_paths = self.ignore_paths)
208
+ Dir.glob(dirs.map { |d| "#{d.sub(%r{/+$}, '')}/*" }, File::FNM_DOTMATCH).reject do |path|
209
+ ignore_paths.include?(File.basename(path))
210
+ end
211
+ end
212
+
213
+ private
214
+
215
+ # Gets a list of files that are in the modified directories.
216
+ #
217
+ # @param [Array<String>] dirs the list of directories
218
+ # @param [Hash] options the find file option
219
+ # @option options [Symbol] all whether to files in sub directories
220
+ #
221
+ def potentially_modified_files(dirs, options = {})
222
+ paths = exclude_ignored_paths(dirs)
223
+
224
+ if options[:all]
225
+ paths.inject([]) do |array, path|
226
+ if File.file?(path)
227
+ array << path
228
+ else
229
+ array += Dir.glob("#{ path }/**/*", File::FNM_DOTMATCH).select { |p| File.file?(p) }
230
+ end
231
+ array
232
+ end
233
+ else
234
+ paths.select { |path| File.file?(path) }
235
+ end
236
+ end
237
+
238
+ # Test if the file content has changed.
239
+ #
240
+ # Depending on the filesystem, mtime/ctime is probably only precise to the second, so round
241
+ # both values down to the second for the comparison.
242
+ #
243
+ # ctime is used only on == comparison to always catches Rails 3.1 Assets pipelined on Mac OSX
244
+ #
245
+ # @param [String] path the file path
246
+ # @param [Time] last_event the time of the last event
247
+ # @return [Boolean] Whether the file content has changed or not.
248
+ #
249
+ def file_modified?(path, last_event)
250
+ ctime = File.ctime(path).to_i
251
+ mtime = File.mtime(path).to_i
252
+ if [mtime, ctime].max == last_event.to_i
253
+ file_content_modified?(path, sha1_checksum(path))
254
+ elsif mtime > last_event.to_i
255
+ set_sha1_checksums_hash(path, sha1_checksum(path))
256
+ true
257
+ elsif @watch_all_modifications
258
+ ts = file_timestamp(path)
259
+ if ts != @file_timestamp_hash[path]
260
+ set_file_timestamp_hash(path, ts)
261
+ true
262
+ end
263
+ else
264
+ false
265
+ end
266
+ rescue
267
+ false
268
+ end
269
+
270
+ # Tests if the file content has been modified by
271
+ # comparing the SHA1 checksum.
272
+ #
273
+ # @param [String] path the file path
274
+ # @param [String] sha1_checksum the checksum of the file
275
+ #
276
+ def file_content_modified?(path, sha1_checksum)
277
+ if @sha1_checksums_hash[path] != sha1_checksum
278
+ set_sha1_checksums_hash(path, sha1_checksum)
279
+ true
280
+ else
281
+ false
282
+ end
283
+ end
284
+
285
+ # Set save a files current timestamp
286
+ #
287
+ # @param [String] path the file path
288
+ # @param [Int] file_timestamp the files modified timestamp
289
+ #
290
+ def set_file_timestamp_hash(path, file_timestamp)
291
+ @file_timestamp_hash[path] = file_timestamp
292
+ end
293
+
294
+ # Set the current checksum of a file.
295
+ #
296
+ # @param [String] path the file path
297
+ # @param [String] sha1_checksum the checksum of the file
298
+ #
299
+ def set_sha1_checksums_hash(path, sha1_checksum)
300
+ @sha1_checksums_hash[path] = sha1_checksum
301
+ end
302
+
303
+ # Gets a files modified timestamp
304
+ #
305
+ # @path [String] path the file path
306
+ # @return [Int] file modified timestamp
307
+ #
308
+ def file_timestamp(path)
309
+ File.mtime(path).to_i
310
+ end
311
+
312
+ # Calculates the SHA1 checksum of a file.
313
+ #
314
+ # @param [String] path the path to the file
315
+ # @return [String] the SHA1 checksum
316
+ #
317
+ def sha1_checksum(path)
318
+ Digest::SHA1.file(path).to_s
319
+ end
320
+
321
+ # Test if the OS is Mac OS X.
322
+ #
323
+ # @return [Boolean] Whether the OS is Mac OS X
324
+ #
325
+ def self.mac?
326
+ RbConfig::CONFIG['target_os'] =~ /darwin/i
327
+ end
328
+
329
+ # Test if the OS is Linux.
330
+ #
331
+ # @return [Boolean] Whether the OS is Linux
332
+ #
333
+ def self.linux?
334
+ RbConfig::CONFIG['target_os'] =~ /linux/i
335
+ end
336
+
337
+ # Test if the OS is Windows.
338
+ #
339
+ # @return [Boolean] Whether the OS is Windows
340
+ #
341
+ def self.windows?
342
+ RbConfig::CONFIG['target_os'] =~ /mswin|mingw/i
343
+ end
344
+
345
+ end
346
+ end