guard 0.8.0 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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