Created
May 1, 2014 00:28
-
-
Save statico/4a04da4265e09688606e to your computer and use it in GitHub Desktop.
Multi-threaded CoffeeScript syntactical grep
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 | |
# {{{1 Cluster fun! | |
{walk} = require 'walk' | |
cs = require 'coffee-script' | |
pathlib = require 'path' | |
fs = require 'fs' | |
cluster = require 'cluster' | |
NUM_WORKERS = require('os').cpus().length | |
if cluster.isMaster | |
debug = (args...) -> | |
console.log('[MASTER]', args...) if process.env.DEBUG | |
workers = [] | |
filesFound = 0 | |
filesDone = 0 | |
process.execPath = 'coffee' | |
cluster.on 'online', (worker) -> | |
debug "worker #{ worker.id } online" | |
worker.on 'message', (msg) -> | |
if msg.ready | |
workers.push worker | |
debug "#{ workers.length } workers ready" | |
begin() if workers.length == NUM_WORKERS | |
else if msg.text? | |
process.stdout.write msg.text | |
filesDone++ | |
debug "filesDone=", filesDone | |
process.exit() if filesDone == filesFound | |
else | |
console.error "unknown message: #{ JSON.stringify msg }" | |
[1..NUM_WORKERS].forEach (i) -> | |
debug "forking worker #{ i }" | |
cluster.fork() | |
begin = -> | |
dir = process.argv[2] ? '.' | |
debug "beginning walk of #{ dir }..." | |
walker = walk dir, | |
followLinks: false | |
filters: ['node_modules'] | |
walker.on 'file', (root, stats, next) -> | |
return next() if not /\.coffee$/.test stats.name | |
return next() if /^\./.test stats.name | |
path = pathlib.join root, stats.name | |
workers[Math.floor(Math.random() * workers.length)].send path | |
filesFound++ | |
debug "filesFound =", filesFound | |
next() | |
else | |
debug = (args...) -> | |
console.log("[WORKER #{ cluster.worker.id }]", args...) if process.env.DEBUG | |
debug 'hello' | |
process.send ready: true | |
process.on 'message', (path) -> | |
debug "processing #{ path }" | |
content = fs.readFileSync path, 'utf8' | |
try | |
root = cs.nodes content | |
catch e | |
console.error "Could not read #{ path }: #{ e }" | |
return next() | |
log = "" | |
# }}} | |
root.traverseChildren true, (node) -> | |
cls = node.variable?.base?.value | |
method = node.variable?.properties?[0]?.name?.compile?() | |
arglen = node.args?.length | |
line = node.locationData?.first_line + 1 | |
try | |
js = node.compile() | |
catch e | |
js = "[can't compile]" | |
report = -> log += "#{ path }:#{line}:#{js}\n" | |
return unless node.constructor.name is 'Call' | |
return unless cls in ['Vec2', 'Vec3', 'Vec4', 'Mat3', 'Mat4', 'Quat'] | |
report() if method is 'fromDirectionVecPair' #and arglen != 2 | |
# {{{1 More cluster fun! | |
process.send text: log | |
# }}} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment