diff --git a/package.json b/package.json index 020fd2f2e..3614b5f26 100644 --- a/package.json +++ b/package.json @@ -84,7 +84,12 @@ "solarized-dark-syntax": "0.35.0", "solarized-light-syntax": "0.21.0", "archive-view": "0.57.0", - "autocomplete": "0.47.0", + "autocomplete-atom-api": "0.9.0", + "autocomplete-css": "0.7.2", + "autocomplete-emojis": "2.2.2", + "autocomplete-html": "0.7.1", + "autocomplete-plus": "2.15.1", + "autocomplete-snippets": "1.6.1", "autoflow": "0.23.0", "autosave": "0.20.0", "background-tips": "0.24.0", diff --git a/spec/package-manager-spec.coffee b/spec/package-manager-spec.coffee index 92dc21a13..1244ab984 100644 --- a/spec/package-manager-spec.coffee +++ b/spec/package-manager-spec.coffee @@ -824,3 +824,37 @@ describe "PackageManager", -> expect(atom.config.get('core.themes')).not.toContain packageName expect(atom.config.get('core.themes')).not.toContain packageName expect(atom.config.get('core.disabledPackages')).not.toContain packageName + + describe "deleting non-bundled autocomplete packages", -> + [autocompleteCSSPath, autocompletePlusPath] = [] + fs = require 'fs-plus' + path = require 'path' + + beforeEach -> + fixturePath = path.resolve(__dirname, './fixtures/packages') + autocompleteCSSPath = path.join(fixturePath, 'autocomplete-css') + autocompletePlusPath = path.join(fixturePath, 'autocomplete-plus') + + try + fs.mkdirSync(autocompleteCSSPath) + fs.writeFileSync(path.join(autocompleteCSSPath, 'package.json'), '{}') + fs.symlinkSync(path.join(fixturePath, 'package-with-main'), autocompletePlusPath, 'dir') + + expect(fs.isDirectorySync(autocompleteCSSPath)).toBe true + expect(fs.isSymbolicLinkSync(autocompletePlusPath)).toBe true + + jasmine.unspy(atom.packages, 'uninstallAutocompletePlus') + + afterEach -> + try + fs.unlink autocompletePlusPath, -> + + it "removes the packages", -> + atom.packages.loadPackages() + + waitsFor -> + not fs.isDirectorySync(autocompleteCSSPath) + + runs -> + expect(fs.isDirectorySync(autocompleteCSSPath)).toBe false + expect(fs.isSymbolicLinkSync(autocompletePlusPath)).toBe true diff --git a/spec/spec-helper.coffee b/spec/spec-helper.coffee index 0112042e2..2e4355a10 100644 --- a/spec/spec-helper.coffee +++ b/spec/spec-helper.coffee @@ -140,6 +140,8 @@ beforeEach -> spyOn(clipboard, 'writeText').andCallFake (text) -> clipboardContent = text spyOn(clipboard, 'readText').andCallFake -> clipboardContent + spyOn(atom.packages, 'uninstallAutocompletePlus') + addCustomMatchers(this) afterEach -> diff --git a/src/package-manager.coffee b/src/package-manager.coffee index 8527188d3..606f72eda 100644 --- a/src/package-manager.coffee +++ b/src/package-manager.coffee @@ -303,6 +303,9 @@ class PackageManager # of the first package isn't skewed by being the first to require atom require '../exports/atom' + # TODO: remove after a few atom versions. + @uninstallAutocompletePlus() + packagePaths = @getAvailablePackagePaths() packagePaths = packagePaths.filter (packagePath) => not @isPackageDisabled(path.basename(packagePath)) packagePaths = _.uniq packagePaths, (packagePath) -> path.basename(packagePath) @@ -409,6 +412,40 @@ class PackageManager message = "Failed to load the #{path.basename(packagePath)} package" atom.notifications.addError(message, {stack, detail, dismissable: true}) + # TODO: remove these autocomplete-plus specific helpers after a few versions. + uninstallAutocompletePlus: -> + packageDir = null + devDir = path.join("dev", "packages") + for packageDirPath in @packageDirPaths + if not packageDirPath.endsWith(devDir) + packageDir = packageDirPath + break + + if packageDir? + dirsToRemove = [ + path.join(packageDir, 'autocomplete-plus') + path.join(packageDir, 'autocomplete-atom-api') + path.join(packageDir, 'autocomplete-css') + path.join(packageDir, 'autocomplete-html') + path.join(packageDir, 'autocomplete-emojis') + path.join(packageDir, 'autocomplete-snippets') + ] + for dirToRemove in dirsToRemove + @uninstallDirectory(dirToRemove) + return + + uninstallDirectory: (directory) -> + symlinkPromise = new Promise (resolve) -> + fs.isSymbolicLink directory, (isSymLink) -> resolve(isSymLink) + + dirPromise = new Promise (resolve) -> + fs.isDirectory directory, (isDir) -> resolve(isDir) + + Promise.all([symlinkPromise, dirPromise]).then (values) -> + [isSymLink, isDir] = values + if not isSymLink and isDir + fs.remove directory, -> + if Grim.includeDeprecatedAPIs EmitterMixin = require('emissary').Emitter EmitterMixin.includeInto(PackageManager)