Skip to content
This repository has been archived by the owner on Dec 15, 2022. It is now read-only.

Fix and optimize load-paths-handler.coffee #103

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 61 additions & 53 deletions lib/load-paths-handler.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -9,77 +9,85 @@ PathsChunkSize = 100

class PathLoader
constructor: (@rootPath, ignoreVcsIgnores, @traverseSymlinkDirectories, @ignoredNames) ->
@paths = []
@realPathCache = {}
@repo = null
if ignoreVcsIgnores
repo = GitRepository.open(@rootPath, refreshOnWindowFocus: false)
@repo = repo if repo?.relativize(path.join(@rootPath, 'test')) is 'test'

load: (done) ->
@loadPath @rootPath, =>
@flushPaths()
@repo?.destroy()
done()

isIgnored: (loadedPath) ->
relativePath = path.relative(@rootPath, loadedPath)
emitPaths: (paths) ->
emit('load-paths:paths-found', paths)

isPathIgnored: (pathStr) ->
relativePath = path.relative(@rootPath, pathStr)
if @repo?.isPathIgnored(relativePath)
true
return true
else
for ignoredName in @ignoredNames
return true if ignoredName.match(relativePath)

pathLoaded: (loadedPath, done) ->
@paths.push(loadedPath) unless @isIgnored(loadedPath)
if @paths.length is PathsChunkSize
@flushPaths()
done()
loadPath: (pathToLoad, done) ->
visitedDirs = {}
paths = []
counter = 0

flushPaths: ->
emit('load-paths:paths-found', @paths)
@paths = []
appendPath = (path) =>
paths[counter] = path
counter = (counter + 1) % PathsChunkSize
@emitPaths paths if counter is 0
return

loadPath: (pathToLoad, done) ->
return done() if @isIgnored(pathToLoad)
fs.lstat pathToLoad, (error, stats) =>
return done() if error?
if stats.isSymbolicLink()
@isInternalSymlink pathToLoad, (isInternal) =>
return done() if isInternal
fs.stat pathToLoad, (error, stats) =>
return done() if error?
if stats.isFile()
@pathLoaded(pathToLoad, done)
else if stats.isDirectory()
if @traverseSymlinkDirectories
@loadFolder(pathToLoad, done)
else
done()
else
done()
else if stats.isDirectory()
@loadFolder(pathToLoad, done)
else if stats.isFile()
@pathLoaded(pathToLoad, done)
else
done()
traverseRecursively = (root, realRoot) =>
try
children = fs.readdirSync root
catch error
return
for child in children
childPath = path.join root, child
if @isPathIgnored childPath
continue
try
fileStat = fs.lstatSync childPath
catch error
continue
if fileStat.isSymbolicLink()
try
symlinkTargetStat = fs.statSync childPath
catch error
continue
try
childRealPath = fs.realpathSync childPath
catch error
continue
if symlinkTargetStat.isFile() and childRealPath.startsWith(realPathToLoad)
continue
else if symlinkTargetStat.isDirectory() and not @traverseSymlinkDirectories
continue
fileStat = symlinkTargetStat
else
childRealPath = path.join realRoot, child
if fileStat.isDirectory()
if childRealPath of visitedDirs
continue
else
visitedDirs[childRealPath] = true
traverseRecursively childPath, childRealPath
else if fileStat.isFile()
appendPath childPath
return

realPathToLoad = fs.realpathSync pathToLoad
traverseRecursively pathToLoad, realPathToLoad

paths.length = counter
@emitPaths paths if paths.length

loadFolder: (folderPath, done) ->
fs.readdir folderPath, (error, children=[]) =>
async.each(
children,
(childName, next) =>
@loadPath(path.join(folderPath, childName), next)
done
)
return done()

isInternalSymlink: (pathToLoad, done) ->
fs.realpath pathToLoad, @realPathCache, (err, realPath) =>
if err
done(false)
else
done(realPath.search(@rootPath) is 0)

module.exports = (rootPaths, followSymlinks, ignoreVcsIgnores, ignores=[]) ->
ignoredNames = []
Expand All @@ -90,7 +98,7 @@ module.exports = (rootPaths, followSymlinks, ignoreVcsIgnores, ignores=[]) ->
console.warn "Error parsing ignore pattern (#{ignore}): #{error.message}"

async.each(
rootPaths,
rootPaths.reverse(),
(rootPath, next) ->
new PathLoader(
rootPath,
Expand Down