diff --git a/exports/atom.coffee b/exports/atom.coffee index 2c0bac831..c4dbb75e2 100644 --- a/exports/atom.coffee +++ b/exports/atom.coffee @@ -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 diff --git a/spec/fs-utils-spec.coffee b/spec/fs-utils-spec.coffee deleted file mode 100644 index c86d33512..000000000 --- a/spec/fs-utils-spec.coffee +++ /dev/null @@ -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' diff --git a/spec/spec-helper-platform.coffee b/spec/spec-helper-platform.coffee index db0198e12..233ab66c0 100644 --- a/spec/spec-helper-platform.coffee +++ b/spec/spec-helper-platform.coffee @@ -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') diff --git a/src/atom-package.coffee b/src/atom-package.coffee index 579f17085..772b09761 100644 --- a/src/atom-package.coffee +++ b/src/atom-package.coffee @@ -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 ? [] diff --git a/src/atom.coffee b/src/atom.coffee index 3e2f36176..6667b16cf 100644 --- a/src/atom.coffee +++ b/src/atom.coffee @@ -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 diff --git a/src/binding-set.coffee b/src/binding-set.coffee index 6755f03f9..7573951d8 100644 --- a/src/binding-set.coffee +++ b/src/binding-set.coffee @@ -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) diff --git a/src/command-installer.coffee b/src/command-installer.coffee index d64de8316..77dacc934 100644 --- a/src/command-installer.coffee +++ b/src/command-installer.coffee @@ -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) diff --git a/src/config.coffee b/src/config.coffee index 105c2534c..f453179bc 100644 --- a/src/config.coffee +++ b/src/config.coffee @@ -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 diff --git a/src/directory.coffee b/src/directory.coffee index 8492e4616..9e433a2de 100644 --- a/src/directory.coffee +++ b/src/directory.coffee @@ -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() diff --git a/src/edit-session.coffee b/src/edit-session.coffee index b1bf5f7c5..a23427ce2 100644 --- a/src/edit-session.coffee +++ b/src/edit-session.coffee @@ -1,5 +1,4 @@ _ = require 'underscore-plus' -fsUtils = require './fs-utils' path = require 'path' telepath = require 'telepath' guid = require 'guid' diff --git a/src/editor.coffee b/src/editor.coffee index 1e22132d6..1fefeddcb 100644 --- a/src/editor.coffee +++ b/src/editor.coffee @@ -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: -> [ diff --git a/src/file.coffee b/src/file.coffee index 2a671ed35..8c2052b89 100644 --- a/src/file.coffee +++ b/src/file.coffee @@ -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() diff --git a/src/fs-utils.coffee b/src/fs-utils.coffee deleted file mode 100644 index ffc595396..000000000 --- a/src/fs-utils.coffee +++ /dev/null @@ -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) diff --git a/src/git.coffee b/src/git.coffee index 4d1456bea..c58b06079 100644 --- a/src/git.coffee +++ b/src/git.coffee @@ -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() diff --git a/src/keymap.coffee b/src/keymap.coffee index d64b1f082..2e6902da5 100644 --- a/src/keymap.coffee +++ b/src/keymap.coffee @@ -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)) diff --git a/src/menu-manager.coffee b/src/menu-manager.coffee index 76d171c60..f14790d06 100644 --- a/src/menu-manager.coffee +++ b/src/menu-manager.coffee @@ -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) diff --git a/src/package-manager.coffee b/src/package-manager.coffee index 1d63e290a..2242c43d7 100644 --- a/src/package-manager.coffee +++ b/src/package-manager.coffee @@ -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) diff --git a/src/project.coffee b/src/project.coffee index be797e157..11755a349 100644 --- a/src/project.coffee +++ b/src/project.coffee @@ -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) ->