/ src / scan-handler.coffee
scan-handler.coffee
 1  path = require "path"
 2  async = require "async"
 3  {PathSearcher, PathScanner, search} = require 'scandal'
 4  
 5  module.exports = (rootPaths, regexSource, options, searchOptions={}) ->
 6    callback = @async()
 7  
 8    PATHS_COUNTER_SEARCHED_CHUNK = 50
 9    pathsSearched = 0
10  
11    searcher = new PathSearcher(searchOptions)
12  
13    searcher.on 'file-error', ({code, path, message}) ->
14      emit('scan:file-error', {code, path, message})
15  
16    searcher.on 'results-found', (result) ->
17      emit('scan:result-found', result)
18  
19    flags = "g"
20    flags += "i" if options.ignoreCase
21    regex = new RegExp(regexSource, flags)
22  
23    async.each(
24      rootPaths,
25      (rootPath, next) ->
26        options2 = Object.assign {}, options,
27          inclusions: processPaths(rootPath, options.inclusions)
28          globalExclusions: processPaths(rootPath, options.globalExclusions)
29  
30        scanner = new PathScanner(rootPath, options2)
31  
32        scanner.on 'path-found', ->
33          pathsSearched++
34          if pathsSearched % PATHS_COUNTER_SEARCHED_CHUNK is 0
35            emit('scan:paths-searched', pathsSearched)
36  
37        search regex, scanner, searcher, ->
38          emit('scan:paths-searched', pathsSearched)
39          next()
40      callback
41    )
42  
43  processPaths = (rootPath, paths) ->
44    return paths unless paths?.length > 0
45    rootPathBase = path.basename(rootPath)
46    results = []
47    for givenPath in paths
48      segments = givenPath.split(path.sep)
49      firstSegment = segments.shift()
50      results.push(givenPath)
51      if firstSegment is rootPathBase
52        if segments.length is 0
53          results.push(path.join("**", "*"))
54        else
55          results.push(path.join(segments...))
56    results