paths.coffee | |
---|---|
Requires | fs = require('fs')
request = null
balUtilPaths = null
balUtilGroups = require("#{__dirname}/groups.coffee") |
===================================== Paths | balUtilPaths = |
Copy a file next(err) | cp: (src,dst,next) ->
fs.readFile src, 'binary', (err,data) -> |
Error | if err
console.log 'balUtilPaths.cp: cp failed on:',src
return next?(err) |
Success | fs.writeFile dst, data, 'binary', (err) -> |
Forward | if err
console.log 'balUtilPaths.cp: writeFile failed on:',dst
return next?(err) |
Chain | @
|
Get the parent path | getParentPathSync: (p) ->
parentPath = p.replace /[\/\\][^\/\\]+$/, ''
return parentPath
|
Ensure path exists next(err) | ensurePath: (p,next) ->
path = require('path')
p = p.replace /[\/\\]$/, ''
path.exists p, (exists) -> |
Error | return next?() if exists |
Success | parentPath = balUtilPaths.getParentPathSync p
balUtilPaths.ensurePath parentPath, (err) -> |
Error | if err
console.log 'balUtilPaths.ensurePath: failed to ensure the path:',parentPath
return next?(err) |
Success | fs.mkdir p, 0700, (err) ->
path.exists p, (exists) -> |
Error | if not exists
console.log 'balUtilPaths.ensurePath: failed to create the directory:',p
return next?(new Error 'Failed to create the directory '+p) |
Success | next?() |
Chain | @
|
Prefix path | prefixPathSync: (path,parentPath) ->
path = path.replace /[\/\\]$/, ''
if /^([a-zA-Z]\:|\/)/.test(path) is false
path = parentPath + '/' + path
return path
|
Is it a directory? next(err,isDirectory) | isDirectory: (fileFullPath,next) -> |
Stat | fs.stat fileFullPath, (err,fileStat) -> |
Error | if err
console.log 'balUtilPaths.isDirectory: stat failed on:',fileFullPath
return next?(err) |
Success | return next?(null, fileStat.isDirectory())
|
Chain | @
|
Generate a slug for a file | generateSlugSync: (fileFullPath) -> |
Slugify | result = fileFullPath.replace(/[^a-zA-Z0-9]/g,'-').replace(/^-/,'').replace(/-+/,'-') |
Return | return result |
Recursively scan a directory, file, or series of files | scan: (files,fileAction,dirAction,next) -> |
Actions | actions =
directory: =>
@scandir( |
Directory | files |
File Action | fileAction |
Dir Action | dirAction |
Complete Action | next
)
files: => |
Queue | tasks = new balUtilGroups.Group next
tasks.total += files.length
|
Array | for file in files
@scan fileFullPath, fileAction, dirAction, tasks.completer()
|
Done | return true
|
String | if typeof files.charAt isnt 'undefined'
balUtilPaths.isDirectory (err,isDirectory) -> |
Error | if err
return next?(err)
|
Directory | else if isDirectory
actions.directory()
|
File | else
files = [file]
actions.files()
|
Array | else if files instanceof Array
actions.files()
|
Unsupported | else
next?(new Error 'balUtilPaths.scandir: unsupported files type:', typeof files, files) |
Chain | @
|
Scan a directory into a tree next(err,tree) | scantree: (dirPath,next) -> |
Handle | balUtilPaths.scandir(
path: dirPath
readFiles: true
next: (err,list,tree) ->
next?(err,tree)
) |
Chain | @ |
Recursively scan a directory fileAction(fileFullPath,fileRelativePath,next(err,skip)) or false dirAction(fileFullPath,fileRelativePath,next(err,skip)) or false next(err,list,tree) | scandir: (args...) -> |
Prepare | if args.length is 1
{path,parentPath,fileAction,dirAction,next,relativePath,readFiles} = args[0]
else if args.length >= 4
[parentPath,fileAction,dirAction,next] = args
else
err = new Error('balUtilPaths.scandir: unknown arguments')
if next
return next?(err)
else
throw err
|
Prepare defaults | readFiles or= false |
Check needed | if !parentPath and path
parentPath = path
if !parentPath
err = new Error('balUtilPaths.scandir: parentPath is needed')
if next
return next?(err)
else
throw err |
Return | list = {}
tree = {} |
Group | tasks = new balUtilGroups.Group (err) ->
next?(err, list, tree)
|
Cycle | fs.readdir parentPath, (err,files) -> |
Check | if tasks.exited
return |
Error | else if err
console.log 'balUtilPaths.scandir: readdir has failed on:', parentPath
return tasks.exit(err)
|
Empty? | else if !files.length
return tasks.exit()
|
Cycle | else files.forEach (file) -> |
Prepare | ++tasks.total
fileFullPath = parentPath+'/'+file
fileRelativePath = (if relativePath then relativePath+'/' else '')+file |
IsDirectory | balUtilPaths.isDirectory fileFullPath, (err,isDirectory) -> |
Check | if tasks.exited
return
|
Error | else if err
console.log 'balUtilPaths.scandir: isDirectory has failed on:', fileFullPath
return tasks.exit(err)
|
Directory | else if isDirectory |
Prepare | complete = (err,skip,subtreeCallback) -> |
Error | return tasks.exit(err) if err
|
Exited | return tasks.exit() if tasks.exited |
Handle | if skip isnt true |
Append | list[fileRelativePath] = 'dir'
tree[file] = {} |
Recurse | return balUtilPaths.scandir( |
Path | path: fileFullPath |
File | fileAction: fileAction |
Dir | dirAction: dirAction |
Completed | next: (err,_list,_tree) -> |
Merge in children of the parent directory | tree[file] = _tree
for own filePath, fileType of _list
list[filePath] = fileType |
Exited | if tasks.exited
return tasks.exit() |
Error | else if err
console.log 'balUtilPaths.scandir: has failed on:', fileFullPath
return tasks.exit(err) |
Subtree | else if subtreeCallback
return subtreeCallback tasks.completer() |
Complete | else
return tasks.complete() |
Relative Path | relativePath: fileRelativePath |
Read Files | readFiles: readFiles
)
else |
Done | return tasks.complete()
|
Action | if dirAction
return dirAction fileFullPath, fileRelativePath, complete
else if dirAction is false
return complete(err,true)
else
return complete(err,false)
|
File | else |
Prepare | complete = (err,skip) -> |
Error | return tasks.exit(err) if err
|
Exited | return tasks.exit() if tasks.exited |
Handle | if skip |
Done | return tasks.complete()
else |
Append | list[fileRelativePath] = 'file'
if readFiles
fs.readFile fileFullPath, (err,data) ->
return tasks.exit(err) if err |
Append | tree[file] = data.toString() |
Done | return tasks.complete()
else |
Append | tree[file] = true |
Done | return tasks.complete()
|
Action | if fileAction
return fileAction fileFullPath, fileRelativePath, complete
else if fileAction is false
return complete(err,true)
else
return complete(err,false)
|
Chain | @
|
Copy a directory next(err) | cpdir: (srcPath,outPath,next) ->
balUtilPaths.scandir( |
Path | srcPath |
File | (fileSrcPath,fileRelativePath,next) ->
fileOutPath = outPath+'/'+fileRelativePath
balUtilPaths.ensurePath require('path').dirname(fileOutPath), (err) -> |
Error | if err
console.log 'balUtilPaths.cpdir: failed to create the path for the file:',fileSrcPath
return next?(err) |
Success | balUtilPaths.cp fileSrcPath, fileOutPath, (err) -> |
Forward | if err
console.log 'balUtilPaths.cpdir: failed to copy the child file:',fileSrcPath
return next?(err) |
Dir | null |
Completed | next
) |
Chain | @
|
Remove a directory next(err) | rmdir: (parentPath,next) ->
path = require('path')
path.exists parentPath, (exists) -> |
Skip | return next?() unless exists |
Remove | balUtilPaths.scandir( |
Path | parentPath
|
File | (fileFullPath,fileRelativePath,next) ->
fs.unlink fileFullPath, (err) -> |
Forward | if err
console.log 'balUtilPaths.rmdir: failed to remove the child file:', fileFullPath
return next?(err)
|
Dir | (fileFullPath,fileRelativePath,next) ->
next? null, false, (next) ->
fs.rmdir fileFullPath, (err) -> |
Forward | if err
console.log 'balUtilPaths.rmdir: failed to remove the child directory:', fileFullPath
return next?(err)
|
Completed | (err,list,tree) -> |
Error | if err
return next?(err, list, tree) |
Success | fs.rmdir parentPath, (err) -> |
Forward | if err
console.log 'balUtilPaths.rmdir: failed to remove the parent directory:', parentPath
return next?(err, list, tree)
)
|
Chain | @ |
Write tree next(err) | writetree: (dstPath,tree,next) -> |
Group | tasks = new balUtilGroups.Group (err) ->
next?(err)
|
Ensure Destination | balUtilPaths.ensurePath dstPath, (err) -> |
Checks | if err
return tasks.exit err
|
Cycle | for own fileRelativePath, value of tree
++tasks.total
fileFullPath = dstPath+'/'+fileRelativePath.replace(/^\/+/,'')
if typeof value is 'object'
balUtilPaths.writetree fileFullPath, value, tasks.completer()
else
fs.writeFile fileFullPath, value, (err) ->
if err
console.log 'balUtilPaths.writetree: writeFile failed on:',fileFullPath
return tasks.complete err
|
Empty? | if tasks.total is 0
tasks.exit() |
Return | return
|
Chain | @ |
Read path Reads a path be it local or remote next(err,data) | readPath: (filePath,next) ->
if /^http/.test(filePath)
request = require('request') unless request
request filePath, (err,response,data) =>
return next?(err) if err
return next?(null,data)
else
fs.readFile filePath, (err,data) ->
return next?(err) if err
return next?(null,data)
|
Chain | @ |
===================================== Export | module.exports = balUtilPaths
|