UNPKG

wr

Version:

watch files and run a command when they change

106 lines (84 loc) 3.78 kB
#------------------------------------------------------------------------------- # Copyright (c) 2012 Patrick Mueller # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. #------------------------------------------------------------------------------- fs = require 'fs' path = require 'path' existsSync = fs.existsSync || path.existsSync #------------------------------------------------------------------------------- module.exports = class FileWatcher #--------------------------------------------------------------------------- @get: (fileSet, opts) -> if opts.poll return new FileWatcherPoll(fileSet, opts) else return new FileWatcherNoPoll(fileSet, opts) #--------------------------------------------------------------------------- constructor: (@fileSet, @opts) -> #--------------------------------------------------------------------------- fileChanged: (fileName) -> if existsSync fileName oldMtime = @fileSet.getMtime(fileName) stats = fs.statSync(fileName) newMtime = stats?.mtime.getTime() || 0 if oldMtime == newMtime return @fileSet.logInfo "file changed: #{fileName}" if fileName @stopWatching() @fileSet.fileChanged() #--------------------------------------------------------------------------- getCB: (fileName) -> => @fileChanged(fileName) #------------------------------------------------------------------------------- class FileWatcherNoPoll extends FileWatcher #--------------------------------------------------------------------------- constructor: (fileSet, opts) -> super #--------------------------------------------------------------------------- watch: (files) -> @watchers = [] for file in files try watcher = fs.watch(file, {persist: true}, @getCB(file)) @watchers.push(watcher) catch e @fileSet.logError "exception watching '#{file}': #{e}" if e.code == "EMFILE" @fileSet.logError "increase available file handles with `ulimit -n <number>`" return #--------------------------------------------------------------------------- stopWatching: () -> for watcher in @watchers watcher.close() @watchers = [] #------------------------------------------------------------------------------- class FileWatcherPoll extends FileWatcher #--------------------------------------------------------------------------- constructor: (fileSet, opts) -> super #--------------------------------------------------------------------------- watch: (@files) -> options = interval: 1000 * @opts.poll persistent: true for file in @files try fs.watchFile(file, options, @getCB(file)) catch e @fileSet.logError "exception watching '#{file}': #{e}" return #--------------------------------------------------------------------------- stopWatching: () -> for file in @files fs.unwatchFile(file)