Created
July 3, 2012 10:36
-
-
Save mashihua/3038966 to your computer and use it in GitHub Desktop.
watch file or directory
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env coffee | |
{watch,eventWatch} = require './watch' | |
{spawn} = require 'child_process' | |
less = require 'less' | |
path = require 'path' | |
watch 'lib', {extention: '.coffee'}, (err, file) -> | |
throw err if err | |
coffee = spawn 'coffee', ['-c', '-o', 'lib', "#{file}"] | |
(item.on 'data',(data) -> console.log "#{data}") for item in [coffee.stdout,coffee.stderr] | |
eventWatch 'less', {extention: '.less'}, (event) -> | |
event.on 'error', (error) -> | |
console.log error | |
event.on 'deleted', (file) -> | |
console.log "Deleted less/#{file}" | |
fs.unlinkSync "./less/#{path.basename file, '.less'}.css" | |
for item in ['created','modified'] | |
do (item) -> | |
event.on item, (file) -> | |
options = | |
compress: false | |
yuicompress: false | |
optimization: 1 | |
silent: false | |
paths: [path.resolve process.cwd(), "less"] | |
color: true | |
strictImports: false | |
input = fs.readFileSync "less/#{file}", 'utf8' | |
less.render input, options, (err, css) -> | |
if err | |
less.writeError err | |
else | |
fd = fs.openSync "./less/#{path.basename file, '.less'}.css", 'w' | |
fs.writeSync fd, css, 0, 'utf8' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env coffee | |
### | |
watch file or directory | |
By Shihua Ma | |
Example: | |
watch = require('watch').watch | |
watch __filename | |
watch __dirname, (err, file) -> console.log file | |
watch __dirname, {extention: '.coffee'}, (err, file) -> | |
{spawn} = require 'child_process'; | |
coffee = spawn 'coffee', ['-c', '-o', 'lib', 'src'] | |
(item.on 'data',(data) -> console.log data) for item in [coffee.stdout,coffee.stderr] | |
### | |
fs = require 'fs' | |
util = require 'util' | |
path = require 'path' | |
events = require 'events' | |
map = {} | |
# Watch files in a directory and recursive the sub directory | |
watchFiles = (dir, files, options, callback) -> | |
for filename in files when not options.ignore filename | |
do (filename) -> | |
# The file or directory | |
file = "#{dir}/#{filename}" | |
fs.stat file, (err, stats)-> | |
if err | |
callback err if err.code isnt 'ENOENT' | |
else | |
# Recursive this directory | |
if stats.isDirectory() | |
watchDir file, options, callback | |
# Match the file extention | |
else if stats.isFile() && file[file.length - options.extention.length..] is options.extention | |
# Watch this file | |
fs.watchFile file, (curr, prev) -> | |
# Delete file event | |
if curr.nlink is 0 | |
callback null, file, 'delete' | |
fs.unwatchFile file | |
return | |
# Change file event | |
return if curr.nlink isnt 0 and curr.mtime.getTime() is prev.mtime.getTime() | |
callback null, file, 'change' | |
# Watch the directory | |
watchDir = (dir, options, callback) -> | |
func = -> | |
# Reads the contents of a directory. | |
fs.readdir dir, (err, files) -> | |
if err | |
callback err | |
return | |
else | |
#Insert to a map | |
if not map[dir] | |
map[dir] = files | |
else | |
# New file event | |
newFiles = files.filter ( item )-> | |
if item not in map[dir] and item[item.length - options.extention.length..] is options.extention | |
callback null, item, 'create' | |
item | |
map[dir] = files | |
files = newFiles ? [] | |
# Watch this directory | |
watchFiles dir, files, options, callback | |
# Watch this directory | |
fs.watchFile dir, (curr, prev) -> | |
# Delete directory event | |
if curr.nlink is 0 | |
callback null, dir, 'delete' | |
fs.unwatchFile dir | |
# Rewatch this directory | |
func() if curr.size > prev.size | |
func() | |
# Watch api | |
exports.watch = (dir_name, options, callback) -> | |
# Who is not given callback | |
if not callback | |
callback ?= options ? ()-> | |
options = {} | |
# File extention | |
options.extention ?= "" | |
# Ignore method | |
if not options.ignore | |
options.ignore = (file) -> | |
return /^\./.test file | |
# Directory status | |
fs.stat dir_name, (err, stats) -> | |
if err | |
util.error "Error for reading #{dir_name}" | |
callback err | |
else | |
# Watch the directory | |
if stats.isDirectory() | |
watchDir dir_name, options, callback | |
# Watch the file if file given | |
else if stats.isFile() | |
watchFiles (path.dirname dir_name), [dir_name], options, callback | |
# Watch directory or file, the `callback` argument is a function with `EventEmitter` instance. | |
# The `EventEmitter` have follow event | |
# * `error` , If `fs` api emits an 'error' event - it will forwarded here | |
# * `create`, If file or directory was created | |
# * `change`, If file or directory was changed | |
# * `delete`, If file or directory was delete | |
exports.eventWatch = (dir_name, options, callback) -> | |
em = new events.EventEmitter(); | |
monitor = (err, files, event) -> | |
if err | |
em.emit 'error', err | |
else | |
em.emit event, files | |
exports.watch dir_name, options, monitor | |
callback em |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment