From f591c6adacbb38fe76f97c83bd2b2e1cea1b3553 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 30 Sep 2014 12:34:19 -0700 Subject: [PATCH 01/36] Log warning when installing a bundled package --- spec/install-spec.coffee | 19 ++++++++++++++++++- src/install.coffee | 21 ++++++++++++++++++++- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/spec/install-spec.coffee b/spec/install-spec.coffee index 14bfe0ef0..44e1ef619 100644 --- a/spec/install-spec.coffee +++ b/spec/install-spec.coffee @@ -1,4 +1,5 @@ path = require 'path' +CSON = require 'season' fs = require 'fs-plus' temp = require 'temp' express = require 'express' @@ -7,7 +8,7 @@ wrench = require 'wrench' apm = require '../lib/apm-cli' describe 'apm install', -> - atomHome = null + [atomHome, resourcePath] = [] beforeEach -> spyOnToken() @@ -16,6 +17,9 @@ describe 'apm install', -> atomHome = temp.mkdirSync('apm-home-dir-') process.env.ATOM_HOME = atomHome + resourcePath = temp.mkdirSync('atom-resource-path-') + process.env.ATOM_RESOURCE_PATH = resourcePath + describe "when installing an atom package", -> server = null @@ -200,3 +204,16 @@ describe 'apm install', -> runs -> expect(callback.mostRecentCall.args[0]).not.toBeNull() + + describe 'when the package is bundled with Atom', -> + it 'logs a message to standard error', -> + CSON.writeFileSync(path.join(resourcePath, 'package.json'), packageDependencies: 'test-module': '1.0') + + callback = jasmine.createSpy('callback') + apm.run(['install', 'test-module'], callback) + + waitsFor 'waiting for install to complete', 600000, -> + callback.callCount is 1 + + runs -> + expect(console.error.mostRecentCall.args[0].length).toBeGreaterThan 0 diff --git a/src/install.coffee b/src/install.coffee index 51374669c..5f6a97bbb 100644 --- a/src/install.coffee +++ b/src/install.coffee @@ -376,6 +376,21 @@ class Install extends Command packages = fs.readFileSync(filePath, 'utf8') @sanitizePackageNames(packages.split(/\s/)) + getResourcePath: (callback) -> + if @resourcePath + process.nextTick => callback(@resourcePath) + else + config.getResourcePath (@resourcePath) => callback(@resourcePath) + + isBundledPackage: (packageName, callback) -> + @getResourcePath (resourcePath) -> + try + atomMetadata = JSON.parse(fs.readFileSync(path.join(resourcePath, 'package.json'))) + catch error + return callback(false) + + callback(atomMetadata?.packageDependencies?[packageName]?) + run: (options) -> {callback} = options options = @parseOptions(options.commandArgs) @@ -393,7 +408,11 @@ class Install extends Command if atIndex > 0 version = name.substring(atIndex + 1) name = name.substring(0, atIndex) - @installPackage({name, version}, options, callback) + + @isBundledPackage name, (isBundledPackage) => + if isBundledPackage + console.error "The #{name} package is bundled with Atom and should not be explicitly installed.".yellow + @installPackage({name, version}, options, callback) commands = [] if packagesFilePath From 69c4d0af8640a46061dbdc7612d6a45d76dc643b Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 30 Sep 2014 12:50:06 -0700 Subject: [PATCH 02/36] Use hasOwnProperty --- src/install.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/install.coffee b/src/install.coffee index 5f6a97bbb..784553c20 100644 --- a/src/install.coffee +++ b/src/install.coffee @@ -389,7 +389,7 @@ class Install extends Command catch error return callback(false) - callback(atomMetadata?.packageDependencies?[packageName]?) + callback(atomMetadata?.packageDependencies?.hasOwnProperty(packageName)) run: (options) -> {callback} = options From dba32c5ada8b450685e366c18543811ed8fa5153 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 30 Sep 2014 12:57:47 -0700 Subject: [PATCH 03/36] Remove unused variable --- src/install.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/install.coffee b/src/install.coffee index 784553c20..2b8bca731 100644 --- a/src/install.coffee +++ b/src/install.coffee @@ -184,7 +184,7 @@ class Install extends Command message = body.message ? body.error ? body callback("Request for package information failed: #{message}") else - if latestVersion = body.releases.latest + if body.releases.latest callback(null, body) else callback("No releases available for #{packageName}") From b020b43fdb0a0f232a7300e0f035f6d7b9d421fb Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 30 Sep 2014 17:19:02 -0700 Subject: [PATCH 04/36] Always use default lint task --- Gruntfile.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gruntfile.coffee b/Gruntfile.coffee index a1a4b8520..73ca6e420 100644 --- a/Gruntfile.coffee +++ b/Gruntfile.coffee @@ -38,6 +38,6 @@ module.exports = (grunt) -> grunt.file.delete('bin/node_darwin_x64') if grunt.file.exists('bin/node_darwin_x64') grunt.registerTask('lint', ['coffeelint']) - grunt.registerTask('default', ['coffee', 'coffeelint:src']) - grunt.registerTask('test', ['clean', 'default', 'coffeelint:test', 'shell:test']) + grunt.registerTask('default', ['coffee', 'lint']) + grunt.registerTask('test', ['clean', 'default', 'shell:test']) grunt.registerTask('prepublish', ['clean', 'coffee', 'lint']) From caeb41037e5853d13a28a198e7fa3dc1f01c23a3 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 30 Sep 2014 17:54:27 -0700 Subject: [PATCH 05/36] Install latest compatible version --- spec/fixtures/install-multi-version.json | 26 +++++++++++++++++ spec/install-spec.coffee | 17 +++++++++++ src/install.coffee | 37 ++++++++++++++++++++++-- 3 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 spec/fixtures/install-multi-version.json diff --git a/spec/fixtures/install-multi-version.json b/spec/fixtures/install-multi-version.json new file mode 100644 index 000000000..8bcf6134d --- /dev/null +++ b/spec/fixtures/install-multi-version.json @@ -0,0 +1,26 @@ +{ + "releases": { + "latest": "0.4.0" + }, + "name": "multi-module", + "versions": { + "0.4.0": { + "engines": { + "atom": ">=2.0" + } + }, + "0.3.0": { + "engines": { + "atom": ">=1.0" + }, + "dist": { + "tarball": "http://localhost:3000/tarball/test-module-1.0.0.tgz" + } + }, + "0.2.0": { + "engines": { + "atom": ">=1.0" + } + } + } +} diff --git a/spec/install-spec.coffee b/spec/install-spec.coffee index 44e1ef619..852d3d436 100644 --- a/spec/install-spec.coffee +++ b/spec/install-spec.coffee @@ -45,6 +45,8 @@ describe 'apm install', -> response.sendfile path.join(__dirname, 'fixtures', 'test-module-with-symlink-5.0.0.tgz') app.get '/tarball/test-module-with-bin-2.0.0.tgz', (request, response) -> response.sendfile path.join(__dirname, 'fixtures', 'test-module-with-bin-2.0.0.tgz') + app.get '/packages/multi-module', (request, response) -> + response.sendfile path.join(__dirname, 'fixtures', 'install-multi-version.json') server = http.createServer(app) server.listen(3000) @@ -90,6 +92,21 @@ describe 'apm install', -> expect(fs.existsSync(path.join(testModuleDirectory, 'package.json'))).toBeTruthy() expect(callback.mostRecentCall.args[0]).toBeNull() + describe 'when multiple releases are available', -> + it 'installs the latest compatible version', -> + CSON.writeFileSync(path.join(resourcePath, 'package.json'), version: '1.5.0') + packageDirectory = path.join(atomHome, 'packages', 'test-module') + + callback = jasmine.createSpy('callback') + apm.run(['install', 'multi-module'], callback) + + waitsFor 'waiting for install to complete', 600000, -> + callback.callCount is 1 + + runs -> + expect(JSON.parse(fs.readFileSync(path.join(packageDirectory, 'package.json'))).version).toBe "1.0.0" + expect(callback.mostRecentCall.args[0]).toBeNull() + describe 'when multiple package names are specified', -> it 'installs all packages', -> testModuleDirectory = path.join(atomHome, 'packages', 'test-module') diff --git a/src/install.coffee b/src/install.coffee index 2b8bca731..dc0fd1b88 100644 --- a/src/install.coffee +++ b/src/install.coffee @@ -4,6 +4,7 @@ async = require 'async' _ = require 'underscore-plus' optimist = require 'optimist' CSON = require 'season' +semver = require 'semver' temp = require 'temp' config = require './config' @@ -273,14 +274,18 @@ class Install extends Command @logFailure() callback(error) else - commands = [] - packageVersion ?= pack.releases.latest + packageVersion ?= @getLatestCompatibleVersion(pack) + unless packageVersion + @logFailure() + callback("No available version compatible with the installed Atom version: #{@installedAtomVersion}") + {tarball} = pack.versions[packageVersion]?.dist ? {} unless tarball @logFailure() callback("Package version: #{packageVersion} not found") return + commands = [] commands.push (callback) => if packagePath = @getPackageCachePath(packageName, packageVersion) callback(null, packagePath) @@ -391,6 +396,30 @@ class Install extends Command callback(atomMetadata?.packageDependencies?.hasOwnProperty(packageName)) + getLatestCompatibleVersion: (pack) -> + return pack.releases.latest unless @installedAtomVersion + + latestVersion = null + for version, metadata of pack.versions ? {} + continue unless semver.valid(version) + continue unless metadata + + engine = metadata.engines?.atom ? '*' + continue unless semver.validRange(engine) + continue unless semver.satisfies(@installedAtomVersion, engine) + + latestVersion ?= version + latestVersion = version if semver.gt(version, latestVersion) + + latestVersion + + loadInstalledAtomVersion: (callback) -> + @getResourcePath (resourcePath) => + try + {version} = require(path.join(resourcePath, 'package.json')) ? {} + @installedAtomVersion = version if semver.valid(version) + callback() + run: (options) -> {callback} = options options = @parseOptions(options.commandArgs) @@ -414,7 +443,6 @@ class Install extends Command console.error "The #{name} package is bundled with Atom and should not be explicitly installed.".yellow @installPackage({name, version}, options, callback) - commands = [] if packagesFilePath try packageNames = @packageNamesFromPath(packagesFilePath) @@ -423,6 +451,9 @@ class Install extends Command else packageNames = @packageNamesFromArgv(options.argv) packageNames.push('.') if packageNames.length is 0 + + commands = [] + commands.push (callback) => @loadInstalledAtomVersion(callback) packageNames.forEach (packageName) -> commands.push (callback) -> installPackage(packageName, callback) async.waterfall(commands, callback) From 36ec85ffe978cebf5a39317185e0d2b396e15e59 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 30 Sep 2014 17:56:32 -0700 Subject: [PATCH 06/36] Add install spec for no compatible versions --- spec/install-spec.coffee | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/spec/install-spec.coffee b/spec/install-spec.coffee index 852d3d436..a6cdbfb70 100644 --- a/spec/install-spec.coffee +++ b/spec/install-spec.coffee @@ -107,6 +107,20 @@ describe 'apm install', -> expect(JSON.parse(fs.readFileSync(path.join(packageDirectory, 'package.json'))).version).toBe "1.0.0" expect(callback.mostRecentCall.args[0]).toBeNull() + it 'logs an error when no compatible versions are available', -> + CSON.writeFileSync(path.join(resourcePath, 'package.json'), version: '0.9.0') + packageDirectory = path.join(atomHome, 'packages', 'test-module') + + callback = jasmine.createSpy('callback') + apm.run(['install', 'multi-module'], callback) + + waitsFor 'waiting for install to complete', 600000, -> + callback.callCount is 1 + + runs -> + expect(fs.existsSync(packageDirectory)).toBeFalsy() + expect(callback.mostRecentCall.args[0]).not.toBeNull() + describe 'when multiple package names are specified', -> it 'installs all packages', -> testModuleDirectory = path.join(atomHome, 'packages', 'test-module') From 6c9f4691cf1b8f751f69d51197a82505283459bb Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 30 Sep 2014 18:03:39 -0700 Subject: [PATCH 07/36] Add uninstall instructions --- src/install.coffee | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/install.coffee b/src/install.coffee index dc0fd1b88..683679d4f 100644 --- a/src/install.coffee +++ b/src/install.coffee @@ -440,7 +440,10 @@ class Install extends Command @isBundledPackage name, (isBundledPackage) => if isBundledPackage - console.error "The #{name} package is bundled with Atom and should not be explicitly installed.".yellow + console.error """ + The #{name} package is bundled with Atom and should not be explicitly installed. + You can run `apm uninstall #{name}` to uninstall it. + """.yellow @installPackage({name, version}, options, callback) if packagesFilePath From cb416bc290acb42d1154271ec7d4dfc426f741ee Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 1 Oct 2014 11:07:00 -0700 Subject: [PATCH 08/36] Add dedupe modules command with outline --- src/apm-cli.coffee | 1 + src/dedupe-package-modules.coffee | 29 +++++++++++++++++++++++++++++ src/dedupe.coffee | 1 + 3 files changed, 31 insertions(+) create mode 100644 src/dedupe-package-modules.coffee diff --git a/src/apm-cli.coffee b/src/apm-cli.coffee index d5d905396..3a467a593 100644 --- a/src/apm-cli.coffee +++ b/src/apm-cli.coffee @@ -24,6 +24,7 @@ setupTempDirectory() commandClasses = [ require './clean' require './dedupe' + require './dedupe-package-modules' require './develop' require './docs' require './featured' diff --git a/src/dedupe-package-modules.coffee b/src/dedupe-package-modules.coffee new file mode 100644 index 000000000..a5f9c6e3d --- /dev/null +++ b/src/dedupe-package-modules.coffee @@ -0,0 +1,29 @@ +optimist = require 'optimist' +Command = require './command' + +module.exports = +class DedupePackageModules extends Command + @commandNames: ['dedupe-package-modules'] + + parseOptions: (argv) -> + options = optimist(argv) + options.usage """ + + Usage: apm dedupe-package-modules + + Reduce module duplication in packages installed to ~/.atom/packages by + pulling up common dependencies to ~/.atom/package/node_modules + + This command is experimental. + """ + options.alias('h', 'help').describe('help', 'Print this usage message') + + + run: -> + # Move packages to ~/.atom/packages/node_modules + # Build package.json with packages as dependencies to ~/.atom/packages/package.json + # Find all module dependencies + # Dedupe ~/.atom/packages with list of all module dependencies minus package names + # Move packages back to ~/.atom/packages + # Deduped modules will now be in ~/.atom/packages/node_modules + # Delete ~/.atom/packages/package.json diff --git a/src/dedupe.coffee b/src/dedupe.coffee index 3c42f8a16..cb733b050 100644 --- a/src/dedupe.coffee +++ b/src/dedupe.coffee @@ -88,6 +88,7 @@ class Dedupe extends Command env.USERPROFILE = env.HOME if config.isWin32() dedupeOptions = {env} dedupeOptions.cwd = options.cwd if options.cwd + dedupeOptions.streaming = true @fork(@atomNpmPath, dedupeArgs, dedupeOptions, callback) From 627d53096ff9adead6a714670d47a7b94f1041ee Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 1 Oct 2014 11:07:14 -0700 Subject: [PATCH 09/36] :lipstick: Remove extra newline --- src/dedupe-package-modules.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/src/dedupe-package-modules.coffee b/src/dedupe-package-modules.coffee index a5f9c6e3d..7010e451f 100644 --- a/src/dedupe-package-modules.coffee +++ b/src/dedupe-package-modules.coffee @@ -18,7 +18,6 @@ class DedupePackageModules extends Command """ options.alias('h', 'help').describe('help', 'Print this usage message') - run: -> # Move packages to ~/.atom/packages/node_modules # Build package.json with packages as dependencies to ~/.atom/packages/package.json From 5790b2b1075f6f6446df0f841f5ac648292faad7 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 1 Oct 2014 16:51:19 -0700 Subject: [PATCH 10/36] Add initial dedupe modules implementation --- src/dedupe-package-modules.coffee | 100 +++++++++++++++++++++++++++--- src/dedupe.coffee | 3 +- 2 files changed, 94 insertions(+), 9 deletions(-) diff --git a/src/dedupe-package-modules.coffee b/src/dedupe-package-modules.coffee index 7010e451f..04011f263 100644 --- a/src/dedupe-package-modules.coffee +++ b/src/dedupe-package-modules.coffee @@ -1,10 +1,18 @@ +path = require 'path' +CSON = require 'season' optimist = require 'optimist' -Command = require './command' +Command = require './command' +config = require './config' +Dedupe = require './dedupe' +fs = require './fs' module.exports = class DedupePackageModules extends Command @commandNames: ['dedupe-package-modules'] + constructor: -> + @userPackagesDirectory = path.join(config.getAtomDirectory(), 'packages') + parseOptions: (argv) -> options = optimist(argv) options.usage """ @@ -18,11 +26,87 @@ class DedupePackageModules extends Command """ options.alias('h', 'help').describe('help', 'Print this usage message') + getInstalledPackages: -> + packagePaths = [] + for child in fs.list(@userPackagesDirectory) + continue if child is 'node_modules' + + packagePath = path.join(@userPackagesDirectory, child) + continue if fs.isSymbolicLinkSync(packagePath) + continue unless fs.isDirectorySync(packagePath) + packagePaths.push(packagePath) + + packagePaths + + # Move Atom packages from ~/.atom/packages to ~/.atom/packages/node_modules + movePackagesToNodeModulesFolder: (packagePaths) -> + nodeModulesPath = path.join(@userPackagesDirectory, 'node_modules') + fs.mkdirSync(nodeModulesPath) unless fs.isDirectorySync(nodeModulesPath) + + for packagePath in packagePaths + fs.renameSync(packagePath, path.join(nodeModulesPath, path.basename(packagePath))) + + return + + # Move Atom packages from ~/.atom/packages/node_modules to ~/.atom/packages + movePackagesToPackagesFolder: (packagePaths) -> + for packagePath in packagePaths + fs.renameSync(path.join(@userPackagesDirectory, 'node_modules', path.basename(packagePath)), packagePath) + + return + + # Build a package.json with installed Atom packages as dependencies to + # ~/.atom/packages/package.json + createPackageJson: (packagePaths) -> + packageJsonPath = path.join(@userPackagesDirectory, 'package.json') + metadata = + name: 'atom-packages' + version: '1.0.0' + dependencies: {} + for packagePath in packagePaths + packageName = path.basename(packagePath) + packageVersion = CSON.readFileSync(path.join(packagePath, 'package.json')).version + metadata.dependencies[packageName] = packageVersion + fs.writeFileSync(packageJsonPath, JSON.stringify(metadata, null, 2)) + + deletePackageJson: -> + fs.removeSync(path.join(@userPackagesDirectory, 'package.json')) + + getDependencies: (dependencies, modulePath) -> + metadataPath = path.join(modulePath, 'package.json') + return unless fs.isFileSync(metadataPath) + + for dependency, version of CSON.readFileSync(metadataPath)?.dependencies + dependencies[dependency] ?= version + + return + + # Dedupe the module dependencies of the installed Atom packages + dedupeModules: (moduleNames, callback) -> + new Dedupe().run + callback: callback + commandArgs: moduleNames + cwd: @userPackagesDirectory + + # Find the module dependencies of all the installed Atom packages. + getModulesToDedupe: (packagePaths) -> + dependencies = {} + @getDependencies(dependencies, packagePath) for packagePath in packagePaths + Object.keys(dependencies) + + # Remove any package names that are also module names to make sure an Atom + # package is never deduped as a module. + removePackageNames: (packagePaths, moduleNames) -> + for packagePath in packagePaths + delete moduleNames[path.basename(packagePath)] + run: -> - # Move packages to ~/.atom/packages/node_modules - # Build package.json with packages as dependencies to ~/.atom/packages/package.json - # Find all module dependencies - # Dedupe ~/.atom/packages with list of all module dependencies minus package names - # Move packages back to ~/.atom/packages - # Deduped modules will now be in ~/.atom/packages/node_modules - # Delete ~/.atom/packages/package.json + packagePaths = @getInstalledPackages() + @createPackageJson(packagePaths) + modulesToDedupe = @getModulesToDedupe(packagePaths) + @removePackageNames(packagePaths, modulesToDedupe) + @movePackagesToNodeModulesFolder(packagePaths) + + @dedupeModules modulesToDedupe, => + @movePackagesToPackagesFolder(packagePaths) + @deletePackageJson() diff --git a/src/dedupe.coffee b/src/dedupe.coffee index cb733b050..2b6589d93 100644 --- a/src/dedupe.coffee +++ b/src/dedupe.coffee @@ -97,8 +97,9 @@ class Dedupe extends Command fs.makeTreeSync(@atomNodeDirectory) run: (options) -> - {callback} = options + {callback, cwd} = options options = @parseOptions(options.commandArgs) + options.cwd = cwd @createAtomDirectories() From 7a4d8f1106fef7cacb4c9778f2064d4b04fcd1ab Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 1 Oct 2014 16:52:44 -0700 Subject: [PATCH 11/36] Only move folders that exist --- src/dedupe-package-modules.coffee | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/dedupe-package-modules.coffee b/src/dedupe-package-modules.coffee index 04011f263..629370fad 100644 --- a/src/dedupe-package-modules.coffee +++ b/src/dedupe-package-modules.coffee @@ -51,7 +51,10 @@ class DedupePackageModules extends Command # Move Atom packages from ~/.atom/packages/node_modules to ~/.atom/packages movePackagesToPackagesFolder: (packagePaths) -> for packagePath in packagePaths - fs.renameSync(path.join(@userPackagesDirectory, 'node_modules', path.basename(packagePath)), packagePath) + packageName = path.basename(packagePath) + nodeModulesPath = path.join(@userPackagesDirectory, 'node_modules', packageName) + if fs.isDirectorySync(nodeModulesPath) + fs.renameSync(nodeModulesPath, packagePath) return From 36a2c4cee8fdb11669984aca9f60c6b436258529 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 1 Oct 2014 16:54:25 -0700 Subject: [PATCH 12/36] Catch errors moving packages --- src/dedupe-package-modules.coffee | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/dedupe-package-modules.coffee b/src/dedupe-package-modules.coffee index 629370fad..9d15c6d5c 100644 --- a/src/dedupe-package-modules.coffee +++ b/src/dedupe-package-modules.coffee @@ -103,13 +103,24 @@ class DedupePackageModules extends Command for packagePath in packagePaths delete moduleNames[path.basename(packagePath)] - run: -> + run: (options) -> + {callback, cwd} = options + options = @parseOptions(options.commandArgs) + packagePaths = @getInstalledPackages() @createPackageJson(packagePaths) modulesToDedupe = @getModulesToDedupe(packagePaths) @removePackageNames(packagePaths, modulesToDedupe) - @movePackagesToNodeModulesFolder(packagePaths) + + try + @movePackagesToNodeModulesFolder(packagePaths) + catch error + # Move packages back, something went wrong + try + @movePackagesToPackagesFolder(packagePaths) + return callback(error) @dedupeModules modulesToDedupe, => @movePackagesToPackagesFolder(packagePaths) @deletePackageJson() + callback() From fc5cce146d53b4aaaa56cb4ee4ab897fb9468e80 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 1 Oct 2014 16:55:42 -0700 Subject: [PATCH 13/36] Forward dedupe error to root callback --- src/dedupe-package-modules.coffee | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/dedupe-package-modules.coffee b/src/dedupe-package-modules.coffee index 9d15c6d5c..aa95880b7 100644 --- a/src/dedupe-package-modules.coffee +++ b/src/dedupe-package-modules.coffee @@ -120,7 +120,11 @@ class DedupePackageModules extends Command @movePackagesToPackagesFolder(packagePaths) return callback(error) - @dedupeModules modulesToDedupe, => - @movePackagesToPackagesFolder(packagePaths) - @deletePackageJson() - callback() + @dedupeModules modulesToDedupe, (dedupeError) => + try + @movePackagesToPackagesFolder(packagePaths) + @deletePackageJson() + catch error + return callback(error) unless dedupeError? + + callback(dedupeError) From fdad9b7cb7e15b94ea9c1a7b493eecd580fb7ada Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 1 Oct 2014 16:57:07 -0700 Subject: [PATCH 14/36] Ignore dependencies in malformed packages --- src/dedupe-package-modules.coffee | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/dedupe-package-modules.coffee b/src/dedupe-package-modules.coffee index aa95880b7..7e0ebb565 100644 --- a/src/dedupe-package-modules.coffee +++ b/src/dedupe-package-modules.coffee @@ -79,7 +79,12 @@ class DedupePackageModules extends Command metadataPath = path.join(modulePath, 'package.json') return unless fs.isFileSync(metadataPath) - for dependency, version of CSON.readFileSync(metadataPath)?.dependencies + try + metadata = CSON.readFileSync(metadataPath) + catch error + return + + for dependency, version of metadata?.dependencies dependencies[dependency] ?= version return From db8384625fe17a5a7feea570d02b402fa7bc5e99 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 1 Oct 2014 16:58:35 -0700 Subject: [PATCH 15/36] Keep moving packages even after first error --- src/dedupe-package-modules.coffee | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/dedupe-package-modules.coffee b/src/dedupe-package-modules.coffee index 7e0ebb565..04e37abea 100644 --- a/src/dedupe-package-modules.coffee +++ b/src/dedupe-package-modules.coffee @@ -50,12 +50,17 @@ class DedupePackageModules extends Command # Move Atom packages from ~/.atom/packages/node_modules to ~/.atom/packages movePackagesToPackagesFolder: (packagePaths) -> + firstError = null for packagePath in packagePaths packageName = path.basename(packagePath) nodeModulesPath = path.join(@userPackagesDirectory, 'node_modules', packageName) if fs.isDirectorySync(nodeModulesPath) - fs.renameSync(nodeModulesPath, packagePath) + try + fs.renameSync(nodeModulesPath, packagePath) + catch error + firstError ?= error + throw firstError if firstError? return # Build a package.json with installed Atom packages as dependencies to From fc51286da61231d3ffb79da40fa887e779fafc8a Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 1 Oct 2014 16:59:21 -0700 Subject: [PATCH 16/36] :lipstick: --- src/dedupe-package-modules.coffee | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/dedupe-package-modules.coffee b/src/dedupe-package-modules.coffee index 04e37abea..6b39b304d 100644 --- a/src/dedupe-package-modules.coffee +++ b/src/dedupe-package-modules.coffee @@ -57,8 +57,8 @@ class DedupePackageModules extends Command if fs.isDirectorySync(nodeModulesPath) try fs.renameSync(nodeModulesPath, packagePath) - catch error - firstError ?= error + catch moveError + firstError ?= moveError throw firstError if firstError? return @@ -134,7 +134,7 @@ class DedupePackageModules extends Command try @movePackagesToPackagesFolder(packagePaths) @deletePackageJson() - catch error - return callback(error) unless dedupeError? + catch moveError + return callback(moveError) unless dedupeError? callback(dedupeError) From 6a25657dbd4e15f969b5a230155c0c586315c3d2 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 1 Oct 2014 17:02:51 -0700 Subject: [PATCH 17/36] :memo: --- src/dedupe-package-modules.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dedupe-package-modules.coffee b/src/dedupe-package-modules.coffee index 6b39b304d..813e57675 100644 --- a/src/dedupe-package-modules.coffee +++ b/src/dedupe-package-modules.coffee @@ -26,6 +26,7 @@ class DedupePackageModules extends Command """ options.alias('h', 'help').describe('help', 'Print this usage message') + # Get all the packages installed to ~/.atom/packages getInstalledPackages: -> packagePaths = [] for child in fs.list(@userPackagesDirectory) From 5f7d8bdff1d7b8a0e53c7b2061c230c1444db68f Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 1 Oct 2014 17:03:32 -0700 Subject: [PATCH 18/36] Remove unused variable --- src/dedupe-package-modules.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dedupe-package-modules.coffee b/src/dedupe-package-modules.coffee index 813e57675..2e7c8ec93 100644 --- a/src/dedupe-package-modules.coffee +++ b/src/dedupe-package-modules.coffee @@ -115,7 +115,7 @@ class DedupePackageModules extends Command delete moduleNames[path.basename(packagePath)] run: (options) -> - {callback, cwd} = options + {callback} = options options = @parseOptions(options.commandArgs) packagePaths = @getInstalledPackages() From b6ca70f93f959cc50167af5d5ee1fb90fc2ea9f1 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 1 Oct 2014 17:06:42 -0700 Subject: [PATCH 19/36] Mention using bundled version --- src/install.coffee | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/install.coffee b/src/install.coffee index 683679d4f..2526a98a9 100644 --- a/src/install.coffee +++ b/src/install.coffee @@ -442,7 +442,8 @@ class Install extends Command if isBundledPackage console.error """ The #{name} package is bundled with Atom and should not be explicitly installed. - You can run `apm uninstall #{name}` to uninstall it. + You can run `apm uninstall #{name}` to uninstall it and then the version bundled + with Atom will be used. """.yellow @installPackage({name, version}, options, callback) From bad30ffd1d48b1c74bc0f957fd22edb8153a464e Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 1 Oct 2014 17:24:56 -0700 Subject: [PATCH 20/36] Disable streaming since no longer debugging --- src/dedupe.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/src/dedupe.coffee b/src/dedupe.coffee index 2b6589d93..9e4b88041 100644 --- a/src/dedupe.coffee +++ b/src/dedupe.coffee @@ -88,7 +88,6 @@ class Dedupe extends Command env.USERPROFILE = env.HOME if config.isWin32() dedupeOptions = {env} dedupeOptions.cwd = options.cwd if options.cwd - dedupeOptions.streaming = true @fork(@atomNpmPath, dedupeArgs, dedupeOptions, callback) From e4bdb1e0cb2a60ada158cd59653c228e67a2e6c9 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 1 Oct 2014 17:34:59 -0700 Subject: [PATCH 21/36] Log out deduped module names --- src/dedupe-package-modules.coffee | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/dedupe-package-modules.coffee b/src/dedupe-package-modules.coffee index 2e7c8ec93..9cab5db6a 100644 --- a/src/dedupe-package-modules.coffee +++ b/src/dedupe-package-modules.coffee @@ -39,6 +39,17 @@ class DedupePackageModules extends Command packagePaths + # Get all the modules installed to ~/.atom/packages/node_modules + getInstalledModules: -> + modulePaths = [] + nodeModulesPath = path.join(@userPackagesDirectory, 'node_modules') + for child in fs.list(nodeModulesPath) + modulePath = path.join(nodeModulesPath, child) + continue unless fs.isDirectorySync(modulePath) + modulePaths.push(modulePath) + + modulePaths + # Move Atom packages from ~/.atom/packages to ~/.atom/packages/node_modules movePackagesToNodeModulesFolder: (packagePaths) -> nodeModulesPath = path.join(@userPackagesDirectory, 'node_modules') @@ -119,6 +130,7 @@ class DedupePackageModules extends Command options = @parseOptions(options.commandArgs) packagePaths = @getInstalledPackages() + currentModulePaths = @getInstalledModules() @createPackageJson(packagePaths) modulesToDedupe = @getModulesToDedupe(packagePaths) @removePackageNames(packagePaths, modulesToDedupe) @@ -138,4 +150,10 @@ class DedupePackageModules extends Command catch moveError return callback(moveError) unless dedupeError? + unless dedupeError? + updatedModulePaths = @getInstalledModules() + for modulePath in updatedModulePaths + if currentModulePaths.indexOf(modulePath) is -1 + console.log "Deduped #{path.basename(modulePath)}" + callback(dedupeError) From aeb2dee79c32762a14fa72109f93ec72523d22a8 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 1 Oct 2014 17:48:49 -0700 Subject: [PATCH 22/36] Moved instead of deduped --- src/dedupe-package-modules.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dedupe-package-modules.coffee b/src/dedupe-package-modules.coffee index 9cab5db6a..dfecc902a 100644 --- a/src/dedupe-package-modules.coffee +++ b/src/dedupe-package-modules.coffee @@ -154,6 +154,6 @@ class DedupePackageModules extends Command updatedModulePaths = @getInstalledModules() for modulePath in updatedModulePaths if currentModulePaths.indexOf(modulePath) is -1 - console.log "Deduped #{path.basename(modulePath)}" + console.log "Moved #{path.basename(modulePath)} to #{path.join(@userPackagesDirectory, 'node_modules')}" callback(dedupeError) From f77eea0eaa167c62413cb40e3e9a762f8e65978a Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 8 Oct 2014 10:38:02 -0700 Subject: [PATCH 23/36] Build module cache after install --- src/install.coffee | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/install.coffee b/src/install.coffee index 2526a98a9..24c6b6870 100644 --- a/src/install.coffee +++ b/src/install.coffee @@ -126,6 +126,9 @@ class Install extends Command destination = path.join(@atomPackagesDirectory, child) do (source, destination) -> commands.push (callback) -> fs.cp(source, destination, callback) + + commands.push (callback) => @buildModuleCache(pack.name, callback) + async.waterfall commands, (error) => if error? @logFailure() @@ -387,6 +390,14 @@ class Install extends Command else config.getResourcePath (@resourcePath) => callback(@resourcePath) + buildModuleCache: (packageName, callback) -> + packageDirectory = path.join(@atomPackagesDirectory, packageName) + + config.getResourcePath (resourcePath) -> + ModuleCache = require(path.join(resourcePath, 'src', 'module-cache')) + ModuleCache.create(packageDirectory) + callback() + isBundledPackage: (packageName, callback) -> @getResourcePath (resourcePath) -> try From b45f8ecd56a7088f05f89074edf14124ff5eb307 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 8 Oct 2014 10:59:44 -0700 Subject: [PATCH 24/36] Remove dedupe package modules command --- src/apm-cli.coffee | 1 - src/dedupe-package-modules.coffee | 159 ------------------------------ 2 files changed, 160 deletions(-) delete mode 100644 src/dedupe-package-modules.coffee diff --git a/src/apm-cli.coffee b/src/apm-cli.coffee index 3a467a593..d5d905396 100644 --- a/src/apm-cli.coffee +++ b/src/apm-cli.coffee @@ -24,7 +24,6 @@ setupTempDirectory() commandClasses = [ require './clean' require './dedupe' - require './dedupe-package-modules' require './develop' require './docs' require './featured' diff --git a/src/dedupe-package-modules.coffee b/src/dedupe-package-modules.coffee deleted file mode 100644 index dfecc902a..000000000 --- a/src/dedupe-package-modules.coffee +++ /dev/null @@ -1,159 +0,0 @@ -path = require 'path' -CSON = require 'season' -optimist = require 'optimist' -Command = require './command' -config = require './config' -Dedupe = require './dedupe' -fs = require './fs' - -module.exports = -class DedupePackageModules extends Command - @commandNames: ['dedupe-package-modules'] - - constructor: -> - @userPackagesDirectory = path.join(config.getAtomDirectory(), 'packages') - - parseOptions: (argv) -> - options = optimist(argv) - options.usage """ - - Usage: apm dedupe-package-modules - - Reduce module duplication in packages installed to ~/.atom/packages by - pulling up common dependencies to ~/.atom/package/node_modules - - This command is experimental. - """ - options.alias('h', 'help').describe('help', 'Print this usage message') - - # Get all the packages installed to ~/.atom/packages - getInstalledPackages: -> - packagePaths = [] - for child in fs.list(@userPackagesDirectory) - continue if child is 'node_modules' - - packagePath = path.join(@userPackagesDirectory, child) - continue if fs.isSymbolicLinkSync(packagePath) - continue unless fs.isDirectorySync(packagePath) - packagePaths.push(packagePath) - - packagePaths - - # Get all the modules installed to ~/.atom/packages/node_modules - getInstalledModules: -> - modulePaths = [] - nodeModulesPath = path.join(@userPackagesDirectory, 'node_modules') - for child in fs.list(nodeModulesPath) - modulePath = path.join(nodeModulesPath, child) - continue unless fs.isDirectorySync(modulePath) - modulePaths.push(modulePath) - - modulePaths - - # Move Atom packages from ~/.atom/packages to ~/.atom/packages/node_modules - movePackagesToNodeModulesFolder: (packagePaths) -> - nodeModulesPath = path.join(@userPackagesDirectory, 'node_modules') - fs.mkdirSync(nodeModulesPath) unless fs.isDirectorySync(nodeModulesPath) - - for packagePath in packagePaths - fs.renameSync(packagePath, path.join(nodeModulesPath, path.basename(packagePath))) - - return - - # Move Atom packages from ~/.atom/packages/node_modules to ~/.atom/packages - movePackagesToPackagesFolder: (packagePaths) -> - firstError = null - for packagePath in packagePaths - packageName = path.basename(packagePath) - nodeModulesPath = path.join(@userPackagesDirectory, 'node_modules', packageName) - if fs.isDirectorySync(nodeModulesPath) - try - fs.renameSync(nodeModulesPath, packagePath) - catch moveError - firstError ?= moveError - - throw firstError if firstError? - return - - # Build a package.json with installed Atom packages as dependencies to - # ~/.atom/packages/package.json - createPackageJson: (packagePaths) -> - packageJsonPath = path.join(@userPackagesDirectory, 'package.json') - metadata = - name: 'atom-packages' - version: '1.0.0' - dependencies: {} - for packagePath in packagePaths - packageName = path.basename(packagePath) - packageVersion = CSON.readFileSync(path.join(packagePath, 'package.json')).version - metadata.dependencies[packageName] = packageVersion - fs.writeFileSync(packageJsonPath, JSON.stringify(metadata, null, 2)) - - deletePackageJson: -> - fs.removeSync(path.join(@userPackagesDirectory, 'package.json')) - - getDependencies: (dependencies, modulePath) -> - metadataPath = path.join(modulePath, 'package.json') - return unless fs.isFileSync(metadataPath) - - try - metadata = CSON.readFileSync(metadataPath) - catch error - return - - for dependency, version of metadata?.dependencies - dependencies[dependency] ?= version - - return - - # Dedupe the module dependencies of the installed Atom packages - dedupeModules: (moduleNames, callback) -> - new Dedupe().run - callback: callback - commandArgs: moduleNames - cwd: @userPackagesDirectory - - # Find the module dependencies of all the installed Atom packages. - getModulesToDedupe: (packagePaths) -> - dependencies = {} - @getDependencies(dependencies, packagePath) for packagePath in packagePaths - Object.keys(dependencies) - - # Remove any package names that are also module names to make sure an Atom - # package is never deduped as a module. - removePackageNames: (packagePaths, moduleNames) -> - for packagePath in packagePaths - delete moduleNames[path.basename(packagePath)] - - run: (options) -> - {callback} = options - options = @parseOptions(options.commandArgs) - - packagePaths = @getInstalledPackages() - currentModulePaths = @getInstalledModules() - @createPackageJson(packagePaths) - modulesToDedupe = @getModulesToDedupe(packagePaths) - @removePackageNames(packagePaths, modulesToDedupe) - - try - @movePackagesToNodeModulesFolder(packagePaths) - catch error - # Move packages back, something went wrong - try - @movePackagesToPackagesFolder(packagePaths) - return callback(error) - - @dedupeModules modulesToDedupe, (dedupeError) => - try - @movePackagesToPackagesFolder(packagePaths) - @deletePackageJson() - catch moveError - return callback(moveError) unless dedupeError? - - unless dedupeError? - updatedModulePaths = @getInstalledModules() - for modulePath in updatedModulePaths - if currentModulePaths.indexOf(modulePath) is -1 - console.log "Moved #{path.basename(modulePath)} to #{path.join(@userPackagesDirectory, 'node_modules')}" - - callback(dedupeError) From ff9714a72955a357053242a590fb3057441c1ee5 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 8 Oct 2014 13:14:39 -0700 Subject: [PATCH 25/36] Ignore any cache building errors --- src/install.coffee | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/install.coffee b/src/install.coffee index 24c6b6870..9176a489a 100644 --- a/src/install.coffee +++ b/src/install.coffee @@ -394,8 +394,9 @@ class Install extends Command packageDirectory = path.join(@atomPackagesDirectory, packageName) config.getResourcePath (resourcePath) -> - ModuleCache = require(path.join(resourcePath, 'src', 'module-cache')) - ModuleCache.create(packageDirectory) + try + ModuleCache = require(path.join(resourcePath, 'src', 'module-cache')) + ModuleCache.create(packageDirectory) callback() isBundledPackage: (packageName, callback) -> From 4804acc1adcdf2c30a372ddac208c189e07ef069 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 8 Oct 2014 13:15:37 -0700 Subject: [PATCH 26/36] Use local getResourcePath method --- src/install.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/install.coffee b/src/install.coffee index 9176a489a..a174a807a 100644 --- a/src/install.coffee +++ b/src/install.coffee @@ -393,7 +393,7 @@ class Install extends Command buildModuleCache: (packageName, callback) -> packageDirectory = path.join(@atomPackagesDirectory, packageName) - config.getResourcePath (resourcePath) -> + @getResourcePath (resourcePath) -> try ModuleCache = require(path.join(resourcePath, 'src', 'module-cache')) ModuleCache.create(packageDirectory) From aa0cba7f83ab37abf8faacbdc3e6accd6ccbccb1 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 8 Oct 2014 14:29:42 -0700 Subject: [PATCH 27/36] Call back explicitly with null --- src/install.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/install.coffee b/src/install.coffee index a174a807a..1ee4da06b 100644 --- a/src/install.coffee +++ b/src/install.coffee @@ -397,7 +397,7 @@ class Install extends Command try ModuleCache = require(path.join(resourcePath, 'src', 'module-cache')) ModuleCache.create(packageDirectory) - callback() + callback(null) isBundledPackage: (packageName, callback) -> @getResourcePath (resourcePath) -> From b120210888d0f069e5355cc69cfaa879d0d1e5f3 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 8 Oct 2014 14:45:30 -0700 Subject: [PATCH 28/36] Warm compile cache after install This makes it so the next activate call will be able to use the cached versions immediately. --- src/install.coffee | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/install.coffee b/src/install.coffee index 1ee4da06b..2250b29db 100644 --- a/src/install.coffee +++ b/src/install.coffee @@ -128,6 +128,7 @@ class Install extends Command commands.push (callback) -> fs.cp(source, destination, callback) commands.push (callback) => @buildModuleCache(pack.name, callback) + commands.push (callback) => @warmCompileCache(pack.name, callback) async.waterfall commands, (error) => if error? @@ -399,6 +400,22 @@ class Install extends Command ModuleCache.create(packageDirectory) callback(null) + warmCompileCache: (packageName, callback) -> + packageDirectory = path.join(@atomPackagesDirectory, packageName) + + @getResourcePath (resourcePath) -> + try + CoffeeCache = require(path.join(resourcePath, 'src', 'coffee-cache')) + + onDirectory = (directoryPath) -> + path.basename(directoryPath) isnt 'node_modules' + + onFile = (filePath) -> + CoffeeCache.addPathToCache(filePath) + + fs.traverseTreeSync(packageDirectory, onFile, onDirectory) + callback(null) + isBundledPackage: (packageName, callback) -> @getResourcePath (resourcePath) -> try From 014d565469ea9c9949710ad8e352ecac73dee461 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 15 Oct 2014 14:22:11 -0700 Subject: [PATCH 29/36] Call callback at end of links commmand --- src/links.coffee | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/links.coffee b/src/links.coffee index ec8f0cfe7..55e36e984 100644 --- a/src/links.coffee +++ b/src/links.coffee @@ -47,6 +47,9 @@ class Links extends Command realpath = '???'.red "#{path.basename(link).yellow} -> #{realpath}" - run: -> + run: (options) -> + {callback} = options + @logLinks(@devPackagesPath) @logLinks(@packagesPath) + callback() From fb8420df37ab5ae544e228465bdfd5d388510fcc Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 15 Oct 2014 14:22:32 -0700 Subject: [PATCH 30/36] Add rebuild module cache command --- src/apm-cli.coffee | 1 + src/rebuild-module-cache.coffee | 46 +++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 src/rebuild-module-cache.coffee diff --git a/src/apm-cli.coffee b/src/apm-cli.coffee index d5d905396..ee66381a1 100644 --- a/src/apm-cli.coffee +++ b/src/apm-cli.coffee @@ -35,6 +35,7 @@ commandClasses = [ require './login' require './publish' require './rebuild' + require './rebuild-module-cache' require './search' require './star' require './stars' diff --git a/src/rebuild-module-cache.coffee b/src/rebuild-module-cache.coffee new file mode 100644 index 000000000..4995934e5 --- /dev/null +++ b/src/rebuild-module-cache.coffee @@ -0,0 +1,46 @@ +path = require 'path' +async = require 'async' +Command = require './command' +config = require './config' +fs = require './fs' + +module.exports = +class RebuildModuleCache extends Command + @commandNames: ['rebuild-module-cache'] + + constructor: -> + @atomPackagesDirectory = path.join(config.getAtomDirectory(), 'packages') + + getResourcePath: (callback) -> + if @resourcePath + process.nextTick => callback(@resourcePath) + else + config.getResourcePath (@resourcePath) => callback(@resourcePath) + + buildCache: (packageDirectory, callback) -> + @getResourcePath (resourcePath) => + try + @moduleCache ?= require(path.join(resourcePath, 'src', 'module-cache')) + @moduleCache.create(packageDirectory) + catch error + callback(error) + + run: (options) -> + {callback} = options + + commands = [] + for packageName in fs.list(@atomPackagesDirectory) + packageDirectory = path.join(@atomPackagesDirectory, packageName) + continue if fs.isSymbolicLinkSync(packageDirectory) + continue unless fs.isDirectorySync(packageDirectory) + + commands.push (callback) => + process.stdout.write "Rebuilding #{packageName} module cache " + @buildCache packageDirectory, (error) => + if error? + @logFailure() + else + @logSuccess() + callback(error) + + async.waterfall(commands, callback) From 47f29a1a4f2e998ccda7aa04a7c801a5dfce0073 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 15 Oct 2014 14:27:51 -0700 Subject: [PATCH 31/36] Call rebuild module cache command from install command --- src/install.coffee | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/install.coffee b/src/install.coffee index 2250b29db..ed8df776a 100644 --- a/src/install.coffee +++ b/src/install.coffee @@ -10,6 +10,7 @@ temp = require 'temp' config = require './config' Command = require './command' fs = require './fs' +RebuildModuleCache = require './rebuild-module-cache' request = require './request' module.exports = @@ -393,12 +394,7 @@ class Install extends Command buildModuleCache: (packageName, callback) -> packageDirectory = path.join(@atomPackagesDirectory, packageName) - - @getResourcePath (resourcePath) -> - try - ModuleCache = require(path.join(resourcePath, 'src', 'module-cache')) - ModuleCache.create(packageDirectory) - callback(null) + RebuildModuleCache.buildCache packageDirectory, -> callback() warmCompileCache: (packageName, callback) -> packageDirectory = path.join(@atomPackagesDirectory, packageName) From e013328d4819e53b8876d94917fa69ae42073495 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 15 Oct 2014 14:28:33 -0700 Subject: [PATCH 32/36] :memo: Mention ignoring cache errors --- src/install.coffee | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/install.coffee b/src/install.coffee index ed8df776a..8a2ace767 100644 --- a/src/install.coffee +++ b/src/install.coffee @@ -394,7 +394,9 @@ class Install extends Command buildModuleCache: (packageName, callback) -> packageDirectory = path.join(@atomPackagesDirectory, packageName) - RebuildModuleCache.buildCache packageDirectory, -> callback() + RebuildModuleCache.buildCache packageDirectory, -> + # Ignore cache errors and just finish the install + callback() warmCompileCache: (packageName, callback) -> packageDirectory = path.join(@atomPackagesDirectory, packageName) From a3a7380f7121d00d4d401efc02815a149ee5aefd Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 15 Oct 2014 14:42:43 -0700 Subject: [PATCH 33/36] Call rebuild on command instance --- src/install.coffee | 3 ++- src/rebuild-module-cache.coffee | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/install.coffee b/src/install.coffee index 8a2ace767..d382a2daf 100644 --- a/src/install.coffee +++ b/src/install.coffee @@ -394,7 +394,8 @@ class Install extends Command buildModuleCache: (packageName, callback) -> packageDirectory = path.join(@atomPackagesDirectory, packageName) - RebuildModuleCache.buildCache packageDirectory, -> + rebuildCacheCommand = new RebuildModuleCache() + rebuildCacheCommand.rebuild packageDirectory, -> # Ignore cache errors and just finish the install callback() diff --git a/src/rebuild-module-cache.coffee b/src/rebuild-module-cache.coffee index 4995934e5..6a66b58c5 100644 --- a/src/rebuild-module-cache.coffee +++ b/src/rebuild-module-cache.coffee @@ -17,7 +17,7 @@ class RebuildModuleCache extends Command else config.getResourcePath (@resourcePath) => callback(@resourcePath) - buildCache: (packageDirectory, callback) -> + rebuild: (packageDirectory, callback) -> @getResourcePath (resourcePath) => try @moduleCache ?= require(path.join(resourcePath, 'src', 'module-cache')) @@ -36,7 +36,7 @@ class RebuildModuleCache extends Command commands.push (callback) => process.stdout.write "Rebuilding #{packageName} module cache " - @buildCache packageDirectory, (error) => + @rebuild packageDirectory, (error) => if error? @logFailure() else From fb1f9fa9ed4f73fb85a09f53e9a8e901a344cb56 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 15 Oct 2014 14:50:40 -0700 Subject: [PATCH 34/36] Call callback after creating --- src/rebuild-module-cache.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/src/rebuild-module-cache.coffee b/src/rebuild-module-cache.coffee index 6a66b58c5..8325c353d 100644 --- a/src/rebuild-module-cache.coffee +++ b/src/rebuild-module-cache.coffee @@ -22,6 +22,7 @@ class RebuildModuleCache extends Command try @moduleCache ?= require(path.join(resourcePath, 'src', 'module-cache')) @moduleCache.create(packageDirectory) + callback() catch error callback(error) From e0f09b4fd3ce603ae7de83eb89b0aa6efeb89ec6 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 15 Oct 2014 14:50:55 -0700 Subject: [PATCH 35/36] Use forEach to iterate over package folders --- src/rebuild-module-cache.coffee | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rebuild-module-cache.coffee b/src/rebuild-module-cache.coffee index 8325c353d..412b5babc 100644 --- a/src/rebuild-module-cache.coffee +++ b/src/rebuild-module-cache.coffee @@ -30,10 +30,10 @@ class RebuildModuleCache extends Command {callback} = options commands = [] - for packageName in fs.list(@atomPackagesDirectory) + fs.list(@atomPackagesDirectory).forEach (packageName) => packageDirectory = path.join(@atomPackagesDirectory, packageName) - continue if fs.isSymbolicLinkSync(packageDirectory) - continue unless fs.isDirectorySync(packageDirectory) + return if fs.isSymbolicLinkSync(packageDirectory) + return unless fs.isDirectorySync(packageDirectory) commands.push (callback) => process.stdout.write "Rebuilding #{packageName} module cache " From d380f824d91cd65157f895aea4f6c8428d698473 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 15 Oct 2014 14:58:48 -0700 Subject: [PATCH 36/36] Don't catch errors thrown by calling callback --- src/rebuild-module-cache.coffee | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/rebuild-module-cache.coffee b/src/rebuild-module-cache.coffee index 412b5babc..6d7341116 100644 --- a/src/rebuild-module-cache.coffee +++ b/src/rebuild-module-cache.coffee @@ -22,9 +22,10 @@ class RebuildModuleCache extends Command try @moduleCache ?= require(path.join(resourcePath, 'src', 'module-cache')) @moduleCache.create(packageDirectory) - callback() catch error - callback(error) + return callback(error) + + callback() run: (options) -> {callback} = options