From b65e1485a724ebdae79f7e06114633cedd5b7df1 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 23 Apr 2013 18:13:49 -0700 Subject: [PATCH] Copy folders to ~/.atom directory asynchronously --- spec/app/config-spec.coffee | 36 +++++++++++++++++++++++++----------- src/app/config.coffee | 35 +++++++++++++++++++++-------------- src/stdlib/fs-utils.coffee | 23 ++++++++++++++++++++++- 3 files changed, 68 insertions(+), 26 deletions(-) diff --git a/spec/app/config-spec.coffee b/spec/app/config-spec.coffee index 797923af1..ce2540b8d 100644 --- a/spec/app/config-spec.coffee +++ b/spec/app/config-spec.coffee @@ -120,19 +120,33 @@ describe "Config", -> describe "when the configDirPath doesn't exist", -> it "copies the contents of dot-atom to ~/.atom", -> - config.initializeConfigDirectory() - expect(fsUtils.exists(config.configDirPath)).toBeTruthy() - expect(fsUtils.exists(fsUtils.join(config.configDirPath, 'packages'))).toBeTruthy() - expect(fsUtils.exists(fsUtils.join(config.configDirPath, 'snippets'))).toBeTruthy() - expect(fsUtils.exists(fsUtils.join(config.configDirPath, 'themes'))).toBeTruthy() - expect(fsUtils.isFile(fsUtils.join(config.configDirPath, 'config.cson'))).toBeTruthy() + initializationDone = false + jasmine.unspy(window, "setTimeout") + config.initializeConfigDirectory -> + initializationDone = true + + waitsFor -> initializationDone + + runs -> + expect(fsUtils.exists(config.configDirPath)).toBeTruthy() + expect(fsUtils.exists(fsUtils.join(config.configDirPath, 'packages'))).toBeTruthy() + expect(fsUtils.exists(fsUtils.join(config.configDirPath, 'snippets'))).toBeTruthy() + expect(fsUtils.exists(fsUtils.join(config.configDirPath, 'themes'))).toBeTruthy() + expect(fsUtils.isFile(fsUtils.join(config.configDirPath, 'config.cson'))).toBeTruthy() it "copies the bundles themes to ~/.atom", -> - config.initializeConfigDirectory() - expect(fsUtils.isFile(fsUtils.join(config.configDirPath, 'themes/atom-dark-ui/package.cson'))).toBeTruthy() - expect(fsUtils.isFile(fsUtils.join(config.configDirPath, 'themes/atom-light-ui/package.cson'))).toBeTruthy() - expect(fsUtils.isFile(fsUtils.join(config.configDirPath, 'themes/atom-dark-syntax.css'))).toBeTruthy() - expect(fsUtils.isFile(fsUtils.join(config.configDirPath, 'themes/atom-light-syntax.css'))).toBeTruthy() + initializationDone = false + jasmine.unspy(window, "setTimeout") + config.initializeConfigDirectory -> + initializationDone = true + + waitsFor -> initializationDone + + runs -> + expect(fsUtils.isFile(fsUtils.join(config.configDirPath, 'themes/atom-dark-ui/package.cson'))).toBeTruthy() + expect(fsUtils.isFile(fsUtils.join(config.configDirPath, 'themes/atom-light-ui/package.cson'))).toBeTruthy() + expect(fsUtils.isFile(fsUtils.join(config.configDirPath, 'themes/atom-dark-syntax.css'))).toBeTruthy() + expect(fsUtils.isFile(fsUtils.join(config.configDirPath, 'themes/atom-light-syntax.css'))).toBeTruthy() describe "when the config file is not parseable", -> beforeEach -> diff --git a/src/app/config.coffee b/src/app/config.coffee index 5e2633fd0..84b9d2b4b 100644 --- a/src/app/config.coffee +++ b/src/app/config.coffee @@ -2,6 +2,8 @@ fsUtils = require 'fs-utils' _ = require 'underscore' EventEmitter = require 'event-emitter' CSON = require 'cson' +fs = require 'fs' +async = require 'async' configDirPath = fsUtils.absolute("~/.atom") bundledPackagesDirPath = fsUtils.join(resourcePath, "src/packages") @@ -14,7 +16,7 @@ userPackagesDirPath = fsUtils.join(configDirPath, "packages") # Public: Handles all of Atom's configuration details. # # This includes loading and setting default options, as well as reading from the -# user's configuration file. +# user's configuration file. module.exports = class Config configDirPath: configDirPath @@ -38,24 +40,29 @@ class Config @configFilePath = fsUtils.resolve(configDirPath, 'config', ['json', 'cson']) @configFilePath ?= fsUtils.join(configDirPath, 'config.cson') - initializeConfigDirectory: -> + initializeConfigDirectory: (done) -> return if fsUtils.exists(@configDirPath) fsUtils.makeDirectory(@configDirPath) + + queue = async.queue ({sourcePath, destinationPath}, callback) => + fsUtils.copy(sourcePath, destinationPath, callback) + queue.drain = done + templateConfigDirPath = fsUtils.resolve(window.resourcePath, 'dot-atom') - onConfigDirFile = (path) => - relativePath = path.substring(templateConfigDirPath.length + 1) - configPath = fsUtils.join(@configDirPath, relativePath) - fsUtils.write(configPath, fsUtils.read(path)) - fsUtils.traverseTreeSync(templateConfigDirPath, onConfigDirFile, (path) -> true) + onConfigDirFile = (sourcePath) => + relativePath = sourcePath.substring(templateConfigDirPath.length + 1) + destinationPath = fsUtils.join(@configDirPath, relativePath) + queue.push({sourcePath, destinationPath}) + fsUtils.traverseTree(templateConfigDirPath, onConfigDirFile, (path) -> true) configThemeDirPath = fsUtils.join(@configDirPath, 'themes') - onThemeDirFile = (path) -> - relativePath = path.substring(bundledThemesDirPath.length + 1) - configPath = fsUtils.join(configThemeDirPath, relativePath) - fsUtils.write(configPath, fsUtils.read(path)) - fsUtils.traverseTreeSync(bundledThemesDirPath, onThemeDirFile, (path) -> true) + onThemeDirFile = (sourcePath) -> + relativePath = sourcePath.substring(bundledThemesDirPath.length + 1) + destinationPath = fsUtils.join(configThemeDirPath, relativePath) + queue.push({sourcePath, destinationPath}) + fsUtils.traverseTree(bundledThemesDirPath, onThemeDirFile, (path) -> true) load: -> @initializeConfigDirectory() @@ -76,14 +83,14 @@ class Config # keyPath - The {String} name of the key to retrieve # # Returns the value from Atom's default settings, the user's configuration file, - # or `null` if the key doesn't exist in either. + # or `null` if the key doesn't exist in either. get: (keyPath) -> _.valueForKeyPath(@settings, keyPath) ? _.valueForKeyPath(@defaultSettings, keyPath) # Public: Sets the value for a configuration setting. # - # This value is stored in Atom's internal configuration file. + # This value is stored in Atom's internal configuration file. # # keyPath - The {String} name of the key # value - The value of the setting diff --git a/src/stdlib/fs-utils.coffee b/src/stdlib/fs-utils.coffee index d3e46ec44..22bbc834c 100644 --- a/src/stdlib/fs-utils.coffee +++ b/src/stdlib/fs-utils.coffee @@ -165,6 +165,27 @@ module.exports = makeDirectory: (path) -> fs.mkdirSync(path) + copy: (sourcePath, destinationPath, done) -> + mkdirp @directory(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) + # Creates the directory specified by "path" including any missing parent # directories. makeTree: (path) -> @@ -192,7 +213,7 @@ module.exports = traverseTree: (rootPath, onFile, onDirectory, onDone) -> fs.readdir rootPath, (error, files) => if error - onDone() + onDone?() else queue = async.queue (path, callback) => fs.stat path, (error, stats) =>