Use fs-plus

This commit is contained in:
Kevin Sawicki 2013-10-31 11:48:22 -07:00
parent 60563f46c9
commit 83dcf79bcf
18 changed files with 70 additions and 647 deletions

View File

@ -1,14 +1,13 @@
{Document, Point, Range, Site} = require 'telepath'
_ = require 'underscore-plus'
module.exports =
_: _
_: require 'underscore-plus'
BufferedNodeProcess: require '../src/buffered-node-process'
BufferedProcess: require '../src/buffered-process'
Directory: require '../src/directory'
Document: Document
File: require '../src/file'
fs: require '../src/fs-utils'
fs: require 'fs-plus'
Git: require '../src/git'
Point: Point
Range: Range

View File

@ -1,140 +0,0 @@
{fs} = require 'atom'
path = require 'path'
temp = require 'temp'
describe "fs", ->
fixturesDir = path.join(__dirname, 'fixtures')
describe ".read(path)", ->
it "return contents of file", ->
expect(fs.read(require.resolve("./fixtures/sample.txt"))).toBe "Some text.\n"
it "does not through an exception when the path is a binary file", ->
expect(-> fs.read(require.resolve("./fixtures/binary-file.png"))).not.toThrow()
describe ".isFileSync(path)", ->
it "returns true with a file path", ->
expect(fs.isFileSync(path.join(fixturesDir, 'sample.js'))).toBe true
it "returns false with a directory path", ->
expect(fs.isFileSync(fixturesDir)).toBe false
it "returns false with a non-existent path", ->
expect(fs.isFileSync(path.join(fixturesDir, 'non-existent'))).toBe false
expect(fs.isFileSync(null)).toBe false
describe ".exists(path)", ->
it "returns true when path exsits", ->
expect(fs.exists(fixturesDir)).toBe true
it "returns false when path doesn't exsit", ->
expect(fs.exists(path.join(fixturesDir, "-nope-does-not-exist"))).toBe false
expect(fs.exists("")).toBe false
expect(fs.exists(null)).toBe false
describe ".makeTree(path)", ->
aPath = path.join(temp.dir, 'a')
beforeEach ->
fs.remove(aPath) if fs.exists(aPath)
it "creates all directories in path including any missing parent directories", ->
abcPath = path.join(aPath, 'b', 'c')
fs.makeTree(abcPath)
expect(fs.exists(abcPath)).toBeTruthy()
describe ".traverseTreeSync(path, onFile, onDirectory)", ->
it "calls fn for every path in the tree at the given path", ->
paths = []
onPath = (childPath) ->
paths.push(childPath)
true
fs.traverseTreeSync fixturesDir, onPath, onPath
expect(paths).toEqual fs.listTreeSync(fixturesDir)
it "does not recurse into a directory if it is pruned", ->
paths = []
onPath = (childPath) ->
if childPath.match(/\/dir$/)
false
else
paths.push(childPath)
true
fs.traverseTreeSync fixturesDir, onPath, onPath
expect(paths.length).toBeGreaterThan 0
for filePath in paths
expect(filePath).not.toMatch /\/dir\//
it "returns entries if path is a symlink", ->
symlinkPath = path.join(fixturesDir, 'symlink-to-dir')
symlinkPaths = []
onSymlinkPath = (path) -> symlinkPaths.push(path.substring(symlinkPath.length + 1))
regularPath = path.join(fixturesDir, 'dir')
paths = []
onPath = (path) -> paths.push(path.substring(regularPath.length + 1))
fs.traverseTreeSync(symlinkPath, onSymlinkPath, onSymlinkPath)
fs.traverseTreeSync(regularPath, onPath, onPath)
expect(symlinkPaths).toEqual(paths)
it "ignores missing symlinks", ->
directory = temp.mkdirSync('symlink-in-here')
paths = []
onPath = (childPath) -> paths.push(childPath)
fs.symlinkSync(path.join(directory, 'source'), path.join(directory, 'destination'))
fs.traverseTreeSync(directory, onPath)
expect(paths.length).toBe 0
describe ".md5ForPath(path)", ->
it "returns the MD5 hash of the file at the given path", ->
expect(fs.md5ForPath(require.resolve('./fixtures/sample.js'))).toBe 'dd38087d0d7e3e4802a6d3f9b9745f2b'
describe ".list(path, extensions)", ->
it "returns the absolute paths of entries within the given directory", ->
paths = fs.listSync(project.getPath())
expect(paths).toContain project.resolve('css.css')
expect(paths).toContain project.resolve('coffee.coffee')
expect(paths).toContain project.resolve('two-hundred.txt')
it "returns an empty array for paths that aren't directories or don't exist", ->
expect(fs.listSync(project.resolve('sample.js'))).toEqual []
expect(fs.listSync('/non/existent/directory')).toEqual []
it "can filter the paths by an optional array of file extensions", ->
paths = fs.listSync(project.getPath(), ['.css', 'coffee'])
expect(paths).toContain project.resolve('css.css')
expect(paths).toContain project.resolve('coffee.coffee')
expect(listedPath).toMatch /(css|coffee)$/ for listedPath in paths
describe ".list(path, [extensions,] callback)", ->
paths = null
it "calls the callback with the absolute paths of entries within the given directory", ->
waitsFor (done) ->
fs.list project.getPath(), (err, result) ->
paths = result
done()
runs ->
expect(paths).toContain project.resolve('css.css')
expect(paths).toContain project.resolve('coffee.coffee')
expect(paths).toContain project.resolve('two-hundred.txt')
it "can filter the paths by an optional array of file extensions", ->
waitsFor (done) ->
fs.list project.getPath(), ['css', '.coffee'], (err, result) ->
paths = result
done()
runs ->
expect(paths).toContain project.resolve('css.css')
expect(paths).toContain project.resolve('coffee.coffee')
expect(listedPath).toMatch /(css|coffee)$/ for listedPath in paths
describe ".absolute(relativePath)", ->
it "converts a leading ~ segment to the HOME directory", ->
homeDir = atom.getHomeDirPath()
expect(fs.absolute('~')).toBe fs.realpathSync(homeDir)
expect(fs.absolute(path.join('~', 'does', 'not', 'exist'))).toBe path.join(homeDir, 'does', 'not', 'exist')
expect(fs.absolute('~test')).toBe '~test'

View File

@ -1,5 +1,5 @@
path = require 'path'
fsUtils = require '../src/fs-utils'
fs = require 'fs-plus'
{_} = require 'atom'
@ -15,8 +15,8 @@ module.exports =
# Returns nothing.
generateEvilFiles: ->
evilFilesPath = path.join(__dirname, 'fixtures', 'evil-files')
fsUtils.remove(evilFilesPath) if fsUtils.exists(evilFilesPath)
fsUtils.mkdirSync(evilFilesPath)
fs.remove(evilFilesPath) if fs.exists(evilFilesPath)
fs.mkdirSync(evilFilesPath)
if (@isWindows())
filenames = [
@ -34,5 +34,4 @@ module.exports =
]
for filename in filenames
fd = fsUtils.writeFileSync(path.join(evilFilesPath, filename), 'evil file!', flag: 'w')
fd = fs.writeFileSync(path.join(evilFilesPath, filename), 'evil file!', flag: 'w')

View File

@ -1,6 +1,6 @@
TextMateGrammar = require './text-mate-grammar'
Package = require './package'
fsUtils = require './fs-utils'
fs = require 'fs-plus'
path = require 'path'
_ = require 'underscore-plus'
{$} = require './space-pen-extensions'
@ -118,16 +118,16 @@ class AtomPackage extends Package
getKeymapPaths: ->
keymapsDirPath = path.join(@path, 'keymaps')
if @metadata.keymaps
@metadata.keymaps.map (name) -> fsUtils.resolve(keymapsDirPath, name, ['json', 'cson', ''])
@metadata.keymaps.map (name) -> fs.resolve(keymapsDirPath, name, ['json', 'cson', ''])
else
fsUtils.listSync(keymapsDirPath, ['cson', 'json'])
fs.listSync(keymapsDirPath, ['cson', 'json'])
getMenuPaths: ->
menusDirPath = path.join(@path, 'menus')
if @metadata.menus
@metadata.menus.map (name) -> fsUtils.resolve(menusDirPath, name, ['json', 'cson', ''])
@metadata.menus.map (name) -> fs.resolve(menusDirPath, name, ['json', 'cson', ''])
else
fsUtils.listSync(menusDirPath, ['cson', 'json'])
fs.listSync(menusDirPath, ['cson', 'json'])
loadStylesheets: ->
@stylesheets = @getStylesheetPaths().map (stylesheetPath) ->
@ -140,25 +140,25 @@ class AtomPackage extends Package
stylesheetDirPath = @getStylesheetsPath()
if @metadata.stylesheetMain
[fsUtils.resolve(@path, @metadata.stylesheetMain)]
[fs.resolve(@path, @metadata.stylesheetMain)]
else if @metadata.stylesheets
@metadata.stylesheets.map (name) -> fsUtils.resolve(stylesheetDirPath, name, ['css', 'less', ''])
else if indexStylesheet = fsUtils.resolve(@path, 'index', ['css', 'less'])
@metadata.stylesheets.map (name) -> fs.resolve(stylesheetDirPath, name, ['css', 'less', ''])
else if indexStylesheet = fs.resolve(@path, 'index', ['css', 'less'])
[indexStylesheet]
else
fsUtils.listSync(stylesheetDirPath, ['css', 'less'])
fs.listSync(stylesheetDirPath, ['css', 'less'])
loadGrammars: ->
@grammars = []
grammarsDirPath = path.join(@path, 'grammars')
for grammarPath in fsUtils.listSync(grammarsDirPath, ['.json', '.cson'])
for grammarPath in fs.listSync(grammarsDirPath, ['.json', '.cson'])
@grammars.push(TextMateGrammar.loadSync(grammarPath))
loadScopedProperties: ->
@scopedProperties = []
scopedPropertiessDirPath = path.join(@path, 'scoped-properties')
for scopedPropertiesPath in fsUtils.listSync(scopedPropertiessDirPath, ['.json', '.cson'])
for selector, properties of fsUtils.readObjectSync(scopedPropertiesPath)
for scopedPropertiesPath in fs.listSync(scopedPropertiessDirPath, ['.json', '.cson'])
for selector, properties of fs.readObjectSync(scopedPropertiesPath)
@scopedProperties.push([scopedPropertiesPath, selector, properties])
serialize: ->
@ -198,7 +198,7 @@ class AtomPackage extends Package
requireMainModule: ->
return @mainModule if @mainModule?
mainModulePath = @getMainModulePath()
@mainModule = require(mainModulePath) if fsUtils.isFileSync(mainModulePath)
@mainModule = require(mainModulePath) if fs.isFileSync(mainModulePath)
getMainModulePath: ->
return @mainModulePath if @resolvedMainModulePath
@ -208,7 +208,7 @@ class AtomPackage extends Package
path.join(@path, @metadata.main)
else
path.join(@path, 'index')
@mainModulePath = fsUtils.resolveExtension(mainModulePath, ["", _.keys(require.extensions)...])
@mainModulePath = fs.resolveExtension(mainModulePath, ["", _.keys(require.extensions)...])
registerDeferredDeserializers: ->
for deserializerName in @metadata.deferredDeserializers ? []

View File

@ -4,7 +4,7 @@ Emitter::one = (args...) -> @once(args...)
Emitter::trigger = (args...) -> @emit(args...)
Emitter::subscriptionCount = (args...) -> @getSubscriptionCount(args...)
fsUtils = require './fs-utils'
fs = require 'fs-plus'
{$} = require './space-pen-extensions'
_ = require 'underscore-plus'
Package = require './package'
@ -243,7 +243,7 @@ class Atom
# Public: Get the directory path to Atom's configuration area.
getConfigDirPath: ->
@configDirPath ?= fsUtils.absolute('~/.atom')
@configDirPath ?= fs.absolute('~/.atom')
getWindowStatePath: ->
switch @windowMode
@ -267,9 +267,9 @@ class Atom
loadWindowState: ->
if windowStatePath = @getWindowStatePath()
if fsUtils.exists(windowStatePath)
if fs.exists(windowStatePath)
try
documentStateJson = fsUtils.read(windowStatePath)
documentStateJson = fs.read(windowStatePath)
catch error
console.warn "Error reading window state: #{windowStatePath}", error.stack, error
else
@ -316,7 +316,7 @@ class Atom
requireUserInitScript: ->
userInitScriptPath = path.join(@config.configDirPath, "user.coffee")
try
require userInitScriptPath if fsUtils.isFileSync(userInitScriptPath)
require userInitScriptPath if fs.isFileSync(userInitScriptPath)
catch error
console.error "Failed to load `#{userInitScriptPath}`", error.stack, error

View File

@ -1,7 +1,6 @@
{$} = require './space-pen-extensions'
_ = require 'underscore-plus'
fsUtils = require './fs-utils'
fs = require 'fs-plus'
{specificity} = require 'clear-cut'
PEG = require 'pegjs'
@ -18,7 +17,7 @@ class BindingSet
name: null
constructor: (selector, commandsByKeystrokes, @index, @name) ->
BindingSet.parser ?= PEG.buildParser(fsUtils.read(require.resolve './keystroke-pattern.pegjs'))
BindingSet.parser ?= PEG.buildParser(fs.read(require.resolve './keystroke-pattern.pegjs'))
@specificity = specificity(selector)
@selector = selector.replace(/!important/g, '')
@commandsByKeystrokes = @normalizeCommandsByKeystrokes(commandsByKeystrokes)

View File

@ -1,9 +1,8 @@
path = require 'path'
fs = require 'fs'
_ = require 'underscore-plus'
async = require 'async'
fs = require 'fs-plus'
mkdirp = require 'mkdirp'
fsUtils = require './fs-utils'
symlinkCommand = (sourcePath, destinationPath, callback) ->
mkdirp path.dirname(destinationPath), (error) ->
@ -26,7 +25,7 @@ unlinkCommand = (destinationPath, callback) ->
module.exports =
findInstallDirectory: (callback) ->
directories = ['/opt/boxen', '/opt/github', '/usr/local']
async.detect(directories, fsUtils.isDirectory, callback)
async.detect(directories, fs.isDirectory, callback)
install: (commandPath, commandName, callback) ->
if not commandName? or _.isFunction(commandName)

View File

@ -1,8 +1,7 @@
fsUtils = require './fs-utils'
_ = require 'underscore-plus'
fs = require 'fs-plus'
{Emitter} = require 'emissary'
CSON = require 'season'
fs = require 'fs'
path = require 'path'
async = require 'async'
pathWatcher = require 'pathwatcher'
@ -52,25 +51,25 @@ class Config
core: _.clone(require('./root-view').configDefaults)
editor: _.clone(require('./editor').configDefaults)
@settings = {}
@configFilePath = fsUtils.resolve(@configDirPath, 'config', ['json', 'cson'])
@configFilePath = fs.resolve(@configDirPath, 'config', ['json', 'cson'])
@configFilePath ?= path.join(@configDirPath, 'config.cson')
# Private:
initializeConfigDirectory: (done) ->
return if fsUtils.exists(@configDirPath)
return if fs.exists(@configDirPath)
fsUtils.makeTree(@configDirPath)
fs.makeTree(@configDirPath)
queue = async.queue ({sourcePath, destinationPath}, callback) =>
fsUtils.copy(sourcePath, destinationPath, callback)
fs.copy(sourcePath, destinationPath, callback)
queue.drain = done
templateConfigDirPath = fsUtils.resolve(@resourcePath, 'dot-atom')
templateConfigDirPath = fs.resolve(@resourcePath, 'dot-atom')
onConfigDirFile = (sourcePath) =>
relativePath = sourcePath.substring(templateConfigDirPath.length + 1)
destinationPath = path.join(@configDirPath, relativePath)
queue.push({sourcePath, destinationPath})
fsUtils.traverseTree(templateConfigDirPath, onConfigDirFile, (path) -> true)
fs.traverseTree(templateConfigDirPath, onConfigDirFile, (path) -> true)
# Private:
load: ->
@ -80,8 +79,8 @@ class Config
# Private:
loadUserConfig: ->
if !fsUtils.exists(@configFilePath)
fsUtils.makeTree(path.dirname(@configFilePath))
if !fs.exists(@configFilePath)
fs.makeTree(path.dirname(@configFilePath))
CSON.writeFileSync(@configFilePath, {})
try

View File

@ -1,5 +1,5 @@
path = require 'path'
fsUtils = require './fs-utils'
fs = require 'fs-plus'
pathWatcher = require 'pathwatcher'
File = require './file'
{Emitter} = require 'emissary'
@ -44,7 +44,7 @@ class Directory
getRealPath: ->
unless @realPath?
try
@realPath = fsUtils.realpathSync(@path)
@realPath = fs.realpathSync(@path)
catch e
@realPath = @path
@realPath
@ -84,11 +84,11 @@ class Directory
getEntries: ->
directories = []
files = []
for entryPath in fsUtils.listSync(@path)
for entryPath in fs.listSync(@path)
try
stat = fsUtils.lstatSync(entryPath)
stat = fs.lstatSync(entryPath)
symlink = stat.isSymbolicLink()
stat = fsUtils.statSync(entryPath) if symlink
stat = fs.statSync(entryPath) if symlink
catch e
continue
if stat.isDirectory()

View File

@ -1,5 +1,4 @@
_ = require 'underscore-plus'
fsUtils = require './fs-utils'
path = require 'path'
telepath = require 'telepath'
guid = require 'guid'

View File

@ -5,7 +5,7 @@ Gutter = require './gutter'
EditSession = require './edit-session'
CursorView = require './cursor-view'
SelectionView = require './selection-view'
fsUtils = require './fs-utils'
fs = require 'fs-plus'
_ = require 'underscore-plus'
MeasureRange = document.createRange()
@ -1824,7 +1824,7 @@ class Editor extends View
saveDebugSnapshot: ->
atom.showSaveDialog (path) =>
fsUtils.writeSync(path, @getDebugSnapshot()) if path
fs.writeSync(path, @getDebugSnapshot()) if path
getDebugSnapshot: ->
[

View File

@ -4,7 +4,7 @@ pathWatcher = require 'pathwatcher'
Q = require 'q'
{Emitter} = require 'emissary'
_ = require 'underscore-plus'
fsUtils = require './fs-utils'
fs = require 'fs-plus'
# Public: Represents an individual file.
#
@ -24,7 +24,7 @@ class File
# * symlink:
# A Boolean indicating if the path is a symlink (default: false)
constructor: (@path, @symlink=false) ->
throw new Error("#{@path} is a directory") if fsUtils.isDirectorySync(@path)
throw new Error("#{@path} is a directory") if fs.isDirectorySync(@path)
@handleEventSubscriptions()
@ -57,7 +57,7 @@ class File
write: (text) ->
previouslyExisted = @exists()
@cachedContents = text
fsUtils.writeSync(@getPath(), text)
fs.writeSync(@getPath(), text)
@subscribeToNativeChangeEvents() if not previouslyExisted and @subscriptionCount() > 0
# Private: Deprecated
@ -65,7 +65,7 @@ class File
if not @exists()
@cachedContents = null
else if not @cachedContents? or flushCache
@cachedContents = fsUtils.read(@getPath())
@cachedContents = fs.read(@getPath())
else
@cachedContents
@ -83,7 +83,7 @@ class File
if not @exists()
promise = Q(null)
else if not @cachedContents? or flushCache
if fsUtils.statSyncNoException(@getPath()).size >= 1048576 # 1MB
if fs.getSizeSync(@getPath()) >= 1048576 # 1MB
throw new Error("Atom can only handle files < 1MB, for now.")
deferred = Q.defer()

View File

@ -1,431 +0,0 @@
_ = require 'underscore-plus'
fs = require 'fs'
mkdirp = require 'mkdirp'
Module = require 'module'
async = require 'async'
rimraf = require 'rimraf'
path = require 'path'
# Public: Useful extensions to node's built-in fs module
#
# Important, this extends Node's builtin in ['fs' module][fs], which means that you
# can do anything that you can do with Node's 'fs' module plus a few extra
# functions that we've found to be helpful.
#
# [fs]: http://nodejs.org/api/fs.html
fsExtensions =
# Public: Make the given path absolute by resolving it against the current
# working directory.
#
# * relativePath:
# The String containing the relative path. If the path is prefixed with
# '~', it will be expanded to the current user's home directory.
#
# Returns the absolute path or the relative path if it's unable to determine
# it's realpath.
absolute: (relativePath) ->
return null unless relativePath?
homeDir = process.env[if process.platform is 'win32' then 'USERPROFILE' else 'HOME']
if relativePath is '~'
relativePath = homeDir
else if relativePath.indexOf('~/') is 0
relativePath = "#{homeDir}#{relativePath.substring(1)}"
try
fs.realpathSync(relativePath)
catch e
relativePath
# Public: Is the given path absolute?
#
# * pathToCheck:
# The relative or absolute path to check.
#
# Returns true if the path is absolute, false otherwise.
isAbsolute: (pathToCheck='') ->
if process.platform is 'win32'
pathToCheck[1] is ':' # C:\ style
else
pathToCheck[0] is '/' # /usr style
# Public: Returns true if a file or folder at the specified path exists.
exists: (pathToCheck) ->
# TODO: rename to existsSync
pathToCheck? and fs.statSyncNoException(pathToCheck) isnt false
# Public: Returns true if the given path exists and is a directory.
isDirectorySync: (directoryPath) ->
return false unless directoryPath?.length > 0
if stat = fs.statSyncNoException(directoryPath)
stat.isDirectory()
else
false
# Public: Asynchronously checks that the given path exists and is a directory.
isDirectory: (directoryPath, done) ->
return done(false) unless directoryPath?.length > 0
fs.exists directoryPath, (exists) ->
if exists
fs.stat directoryPath, (error, stat) ->
if error?
done(false)
else
done(stat.isDirectory())
else
done(false)
# Public: Returns true if the specified path exists and is a file.
isFileSync: (filePath) ->
return false unless filePath?.length > 0
if stat = fs.statSyncNoException(filePath)
stat.isFile()
else
false
# Public: Returns true if the specified path is executable.
isExecutableSync: (pathToCheck) ->
return false unless pathToCheck?.length > 0
if stat = fs.statSyncNoException(pathToCheck)
(stat.mode & 0o777 & 1) isnt 0
else
false
# Public: Returns an Array with the paths of the files and directories
# contained within the directory path. It is not recursive.
#
# * rootPath:
# The absolute path to the directory to list.
# * extensions:
# An array of extensions to filter the results by. If none are given, none
# are filtered (optional).
listSync: (rootPath, extensions) ->
return [] unless @isDirectorySync(rootPath)
paths = fs.readdirSync(rootPath)
paths = @filterExtensions(paths, extensions) if extensions
paths = paths.map (childPath) -> path.join(rootPath, childPath)
paths
# Public: Asynchronously lists the files and directories in the given path.
# The listing is not recursive.
#
# * rootPath:
# The absolute path to the directory to list.
# * extensions:
# An array of extensions to filter the results by. If none are given, none
# are filtered (optional)
# * callback:
# The function to call
list: (rootPath, rest...) ->
extensions = rest.shift() if rest.length > 1
done = rest.shift()
fs.readdir rootPath, (error, paths) =>
if error?
done(error)
else
paths = @filterExtensions(paths, extensions) if extensions
paths = paths.map (childPath) -> path.join(rootPath, childPath)
done(null, paths)
# Private: Returns only the paths which end with one of the given extensions.
filterExtensions: (paths, extensions) ->
extensions = extensions.map (ext) ->
if ext is ''
ext
else
'.' + ext.replace(/^\./, '')
paths.filter (pathToCheck) -> _.include(extensions, path.extname(pathToCheck))
# Deprecated: No one currently uses this.
listTreeSync: (rootPath) ->
paths = []
onPath = (childPath) ->
paths.push(childPath)
true
@traverseTreeSync(rootPath, onPath, onPath)
paths
# Public: Moves the file or directory to the target synchronously.
move: (source, target) ->
# TODO: This should be renamed to moveSync
fs.renameSync(source, target)
# Public: Removes the file or directory at the given path synchronously.
remove: (pathToRemove) ->
# TODO: This should be renamed to removeSync
rimraf.sync(pathToRemove)
# Public: Open, read, and close a file, returning the file's contents
# synchronously.
read: (filePath) ->
# TODO: This should be renamed to readSync
fs.readFileSync(filePath, 'utf8')
# Public: Open, write, flush, and close a file, writing the given content
# synchronously.
#
# It also creates the necessary parent directories.
writeSync: (filePath, content) ->
mkdirp.sync(path.dirname(filePath))
fs.writeFileSync(filePath, content)
# Public: Open, write, flush, and close a file, writing the given content
# asynchronously.
#
# It also creates the necessary parent directories.
write: (filePath, content, callback) ->
mkdirp path.dirname(filePath), (error) ->
if error?
callback?(error)
else
fs.writeFile(filePath, content, callback)
# Public: Copies the given path asynchronously.
copy: (sourcePath, destinationPath, done) ->
mkdirp path.dirname(destinationPath), (error) ->
if error?
done?(error)
return
sourceStream = fs.createReadStream(sourcePath)
sourceStream.on 'error', (error) ->
done?(error)
done = null
destinationStream = fs.createWriteStream(destinationPath)
destinationStream.on 'error', (error) ->
done?(error)
done = null
destinationStream.on 'close', ->
done?()
done = null
sourceStream.pipe(destinationStream)
# Public: Create a directory at the specified path including any missing
# parent directories synchronously.
makeTree: (directoryPath) ->
# TODO: rename to makeTreeSync
mkdirp.sync(directoryPath) if directoryPath and not @exists(directoryPath)
# Public: Recursively walk the given path and execute the given functions
# synchronously.
#
# * rootPath:
# The String containing the directory to recurse into.
# * onFile:
# The function to execute on each file, receives a single argument the
# absolute path.
# * onDirectory:
# The function to execute on each directory, receives a single argument the
# absolute path (defaults to onFile)
traverseTreeSync: (rootPath, onFile, onDirectory=onFile) ->
return unless @isDirectorySync(rootPath)
traverse = (directoryPath, onFile, onDirectory) ->
for file in fs.readdirSync(directoryPath)
childPath = path.join(directoryPath, file)
stats = fs.lstatSync(childPath)
if stats.isSymbolicLink()
if linkStats = fs.statSyncNoException(childPath)
stats = linkStats
if stats.isDirectory()
traverse(childPath, onFile, onDirectory) if onDirectory(childPath)
else if stats.isFile()
onFile(childPath)
traverse(rootPath, onFile, onDirectory)
# Public: Recursively walk the given path and execute the given functions
# asynchronously.
#
# * rootPath:
# The String containing the directory to recurse into.
# * onFile:
# The function to execute on each file, receives a single argument the
# absolute path.
# * onDirectory:
# The function to execute on each directory, receives a single argument the
# absolute path (defaults to onFile)
traverseTree: (rootPath, onFile, onDirectory, onDone) ->
fs.readdir rootPath, (error, files) ->
if error
onDone?()
else
queue = async.queue (childPath, callback) ->
fs.stat childPath, (error, stats) ->
if error
callback(error)
else if stats.isFile()
onFile(childPath)
callback()
else if stats.isDirectory()
if onDirectory(childPath)
fs.readdir childPath, (error, files) ->
if error
callback(error)
else
for file in files
queue.unshift(path.join(childPath, file))
callback()
else
callback()
queue.concurrency = 1
queue.drain = onDone
queue.push(path.join(rootPath, file)) for file in files
# Public: Hashes the contents of the given file.
#
# * pathToDigest:
# The String containing the absolute path.
#
# Returns a String containing the MD5 hexadecimal hash.
md5ForPath: (pathToDigest) ->
contents = fs.readFileSync(pathToDigest)
require('crypto').createHash('md5').update(contents).digest('hex')
# Public: Finds a relative path among the given array of paths.
#
# * loadPaths:
# An Array of absolute and relative paths to search.
# * pathToResolve:
# The string containing the path to resolve.
# * extensions:
# An array of extensions to pass to {resolveExtensions} in which case
# pathToResolve should not contain an extension (optional).
#
# Returns the absolute path of the file to be resolved if it's found and
# undefined otherwise.
resolve: (args...) ->
extensions = args.pop() if _.isArray(_.last(args))
pathToResolve = args.pop()
loadPaths = args
if @isAbsolute(pathToResolve)
if extensions and resolvedPath = @resolveExtension(pathToResolve, extensions)
return resolvedPath
else
return pathToResolve if @exists(pathToResolve)
for loadPath in loadPaths
candidatePath = path.join(loadPath, pathToResolve)
if extensions
if resolvedPath = @resolveExtension(candidatePath, extensions)
return resolvedPath
else
return @absolute(candidatePath) if @exists(candidatePath)
undefined
# Deprecated:
resolveOnLoadPath: (args...) ->
loadPaths = Module.globalPaths.concat(module.paths)
@resolve(loadPaths..., args...)
# Public: Finds the first file in the given path which matches the extension
# in the order given.
#
# * pathToResolve:
# The String containing relative or absolute path of the file in question
# without the extension or '.'.
# * extensions:
# The ordered Array of extensions to try.
#
# Returns the absolute path of the file if it exists with any of the given
# extensions, otherwise it's undefined.
resolveExtension: (pathToResolve, extensions) ->
for extension in extensions
if extension == ""
return @absolute(pathToResolve) if @exists(pathToResolve)
else
pathWithExtension = pathToResolve + "." + extension.replace(/^\./, "")
return @absolute(pathWithExtension) if @exists(pathWithExtension)
undefined
# Public: Returns true for extensions associated with compressed files.
isCompressedExtension: (ext) ->
_.indexOf([
'.gz'
'.jar'
'.tar'
'.tgz'
'.zip'
], ext, true) >= 0
# Public: Returns true for extensions associated with image files.
isImageExtension: (ext) ->
_.indexOf([
'.gif'
'.jpeg'
'.jpg'
'.png'
'.tiff'
], ext, true) >= 0
# Public: Returns true for extensions associated with pdf files.
isPdfExtension: (ext) ->
ext is '.pdf'
# Public: Returns true for extensions associated with binary files.
isBinaryExtension: (ext) ->
_.indexOf([
'.DS_Store'
'.a'
'.o'
'.so'
'.woff'
], ext, true) >= 0
# Public: Returns true for files named similarily to 'README'
isReadmePath: (readmePath) ->
extension = path.extname(readmePath)
base = path.basename(readmePath, extension).toLowerCase()
base is 'readme' and (extension is '' or @isMarkdownExtension(extension))
# Private: Used by isReadmePath.
isMarkdownExtension: (ext) ->
_.indexOf([
'.markdown'
'.md'
'.mdown'
'.mkd'
'.mkdown'
'.ron'
], ext, true) >= 0
# Public: Reads and returns CSON, JSON or Plist files and returns the
# corresponding Object.
readObjectSync: (objectPath) ->
CSON = require 'season'
if CSON.isObjectPath(objectPath)
CSON.readFileSync(objectPath)
else
@readPlistSync(objectPath)
# Public: Reads and returns CSON, JSON or Plist files and calls the specified
# callback with the corresponding Object.
readObject: (objectPath, done) ->
CSON = require 'season'
if CSON.isObjectPath(objectPath)
CSON.readFile(objectPath, done)
else
@readPlist(objectPath, done)
# Private: Used by readObjectSync.
readPlistSync: (plistPath) ->
plist = require 'plist'
plist.parseStringSync(@read(plistPath))
# Private: Used by readObject.
readPlist: (plistPath, done) ->
plist = require 'plist'
fs.readFile plistPath, 'utf8', (error, contents) ->
if error?
done(error)
else
try
done(null, plist.parseStringSync(contents))
catch parseError
done(parseError)
module.exports = _.extend({}, fs, fsExtensions)

View File

@ -1,5 +1,5 @@
_ = require 'underscore-plus'
fsUtils = require './fs-utils'
fs = require 'fs-plus'
Task = require './task'
{Emitter, Subscriber} = require 'emissary'
GitUtils = require 'git-utils'
@ -106,7 +106,7 @@ class Git
# Public: Returns the path of the repository.
getPath: ->
@path ?= fsUtils.absolute(@getRepo().getPath())
@path ?= fs.absolute(@getRepo().getPath())
# Public: Returns the working directory of the repository.
getWorkingDirectory: -> @getRepo().getWorkingDirectory()

View File

@ -1,6 +1,6 @@
{$} = require './space-pen-extensions'
_ = require 'underscore-plus'
fsUtils = require './fs-utils'
fs = require 'fs-plus'
path = require 'path'
CSON = require 'season'
BindingSet = require './binding-set'
@ -41,7 +41,7 @@ class Keymap
@load(userKeymapPath) if userKeymapPath
loadDirectory: (directoryPath) ->
@load(filePath) for filePath in fsUtils.listSync(directoryPath, ['.cson', '.json'])
@load(filePath) for filePath in fs.listSync(directoryPath, ['.cson', '.json'])
load: (path) ->
@add(path, CSON.readFileSync(path))

View File

@ -3,8 +3,7 @@ path = require 'path'
_ = require 'underscore-plus'
ipc = require 'ipc'
CSON = require 'season'
fsUtils = require './fs-utils'
fs = require 'fs-plus'
# Public: Provides a registry for menu items that you'd like to appear in the
# application menu.
@ -37,7 +36,7 @@ class MenuManager
# Private
loadCoreItems: ->
menuPaths = fsUtils.listSync(atom.config.bundledMenusDirPath, ['cson', 'json'])
menuPaths = fs.listSync(atom.config.bundledMenusDirPath, ['cson', 'json'])
for menuPath in menuPaths
data = CSON.readFileSync(menuPath)
@add(data.menu)

View File

@ -1,5 +1,5 @@
{Emitter} = require 'emissary'
fsUtils = require './fs-utils'
fs = require 'fs-plus'
_ = require 'underscore-plus'
Package = require './package'
path = require 'path'
@ -173,10 +173,10 @@ class PackageManager
pack for pack in @getLoadedPackages() when pack.getType() in types
resolvePackagePath: (name) ->
return name if fsUtils.isDirectorySync(name)
return name if fs.isDirectorySync(name)
packagePath = fsUtils.resolve(@packageDirPaths..., name)
return packagePath if fsUtils.isDirectorySync(packagePath)
packagePath = fs.resolve(@packageDirPaths..., name)
return packagePath if fs.isDirectorySync(packagePath)
packagePath = path.join(@resourcePath, 'node_modules', name)
return packagePath if @isInternalPackage(packagePath)
@ -192,16 +192,16 @@ class PackageManager
packagePaths = []
for packageDirPath in @packageDirPaths
for packagePath in fsUtils.listSync(packageDirPath)
packagePaths.push(packagePath) if fsUtils.isDirectorySync(packagePath)
for packagePath in fs.listSync(packageDirPath)
packagePaths.push(packagePath) if fs.isDirectorySync(packagePath)
try
metadataPath = path.join(@resourcePath, 'package.json')
{packageDependencies} = JSON.parse(fsUtils.read(metadataPath)) ? {}
{packageDependencies} = JSON.parse(fs.read(metadataPath)) ? {}
packagesPath = path.join(@resourcePath, 'node_modules')
for packageName, packageVersion of packageDependencies ? {}
packagePath = path.join(packagesPath, packageName)
packagePaths.push(packagePath) if fsUtils.isDirectorySync(packagePath)
packagePaths.push(packagePath) if fs.isDirectorySync(packagePath)
_.uniq(packagePaths)

View File

@ -1,11 +1,12 @@
fsUtils = require './fs-utils'
path = require 'path'
url = require 'url'
Q = require 'q'
_ = require 'underscore-plus'
fs = require 'fs-plus'
Q = require 'q'
telepath = require 'telepath'
{Range} = telepath
TextBuffer = require './text-buffer'
EditSession = require './edit-session'
{Emitter} = require 'emissary'
@ -116,7 +117,7 @@ class Project
@destroyRepo()
if projectPath?
directory = if fsUtils.isDirectorySync(projectPath) then projectPath else path.dirname(projectPath)
directory = if fs.isDirectorySync(projectPath) then projectPath else path.dirname(projectPath)
@rootDirectory = new Directory(directory)
if @repo = Git.open(projectPath, project: this)
@repo.refreshIndex()
@ -159,8 +160,8 @@ class Project
if uri?.match(/[A-Za-z0-9+-.]+:\/\//) # leave path alone if it has a scheme
uri
else
uri = path.join(@getPath(), uri) unless fsUtils.isAbsolute(uri)
fsUtils.absolute uri
uri = path.join(@getPath(), uri) unless fs.isAbsolute(uri)
fs.absolute uri
# Public: Make the given path relative to the project directory.
relativize: (fullPath) ->