From ec759f1322fab123da8785616f290e3623a03661 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 7 Dec 2015 16:49:55 -0800 Subject: [PATCH 1/5] Clear out loaded packages in PackageManager.prototype.reset This way, when the AtomEnvironment is reset, packages will have .load() called on them again, so their config schemas will be registered again. --- src/package-manager.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/src/package-manager.coffee b/src/package-manager.coffee index 5b0264212..5ef0d2a46 100644 --- a/src/package-manager.coffee +++ b/src/package-manager.coffee @@ -62,6 +62,7 @@ class PackageManager reset: -> @serviceHub.clear() @deactivatePackages() + @loadedPackages = {} @packageStates = {} ### From 05e10bfaeb9d22c2d871148f75158ad22d7c156a Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 7 Dec 2015 16:52:33 -0800 Subject: [PATCH 2/5] Register config schemas from package.json in theme packages --- src/theme-package.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/src/theme-package.coffee b/src/theme-package.coffee index 084728869..502fbd52b 100644 --- a/src/theme-package.coffee +++ b/src/theme-package.coffee @@ -14,6 +14,7 @@ class ThemePackage extends Package load: -> @loadTime = 0 + @configSchemaRegisteredOnLoad = @registerConfigSchemaFromMetadata() this activate: -> From 03a2846eb5b741ffe0b6900ee1a41acc1f12bebb Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 7 Dec 2015 17:24:34 -0800 Subject: [PATCH 3/5] Remove redundant unloadPackage call in spec --- spec/package-manager-spec.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/package-manager-spec.coffee b/spec/package-manager-spec.coffee index b504f676f..e7f4214a9 100644 --- a/spec/package-manager-spec.coffee +++ b/spec/package-manager-spec.coffee @@ -167,7 +167,6 @@ describe "PackageManager", -> describe "when a package does not have deserializers, view providers or a config schema in its package.json", -> beforeEach -> - atom.packages.unloadPackage('package-with-main') mockLocalStorage() it "defers loading the package's main module if the package previously used no Atom APIs when its main module was required", -> From 314a1234f498ca4945b80a36c1f44f880c82e2aa Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 8 Dec 2015 11:09:52 -0800 Subject: [PATCH 4/5] Track which packages are in the process of activating This fixes a race condition where a package's activation promise resolves asynchronously after it has been deactivated, causing it to stay in the package manager's @activePackages object. --- src/package-manager.coffee | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/package-manager.coffee b/src/package-manager.coffee index 5ef0d2a46..6772178af 100644 --- a/src/package-manager.coffee +++ b/src/package-manager.coffee @@ -47,6 +47,7 @@ class PackageManager @packagesCache = require('../package.json')?._atomPackages ? {} @loadedPackages = {} @activePackages = {} + @activatingPackages = {} @packageStates = {} @serviceHub = new ServiceHub @@ -437,9 +438,12 @@ class PackageManager if pack = @getActivePackage(name) Promise.resolve(pack) else if pack = @loadPackage(name) + @activatingPackages[pack.name] = pack pack.activate().then => - @activePackages[pack.name] = pack - @emitter.emit 'did-activate-package', pack + if @activatingPackages[pack.name]? + delete @activatingPackages[pack.name] + @activePackages[pack.name] = pack + @emitter.emit 'did-activate-package', pack pack else Promise.reject(new Error("Failed to load package '#{name}'")) @@ -475,6 +479,7 @@ class PackageManager @setPackageState(pack.name, state) if state = pack.serialize?() pack.deactivate() delete @activePackages[pack.name] + delete @activatingPackages[pack.name] @emitter.emit 'did-deactivate-package', pack handleMetadataError: (error, packagePath) -> From d835ac0ac849a398d63ec0beaac1361aec2cd248 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 8 Dec 2015 11:27:20 -0800 Subject: [PATCH 5/5] Add spec for re-registering schema after unloading package --- spec/package-manager-spec.coffee | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/spec/package-manager-spec.coffee b/spec/package-manager-spec.coffee index e7f4214a9..e6848ef03 100644 --- a/spec/package-manager-spec.coffee +++ b/spec/package-manager-spec.coffee @@ -154,7 +154,6 @@ describe "PackageManager", -> it "registers the config schema in the package's metadata, if present", -> pack = atom.packages.loadPackage("package-with-json-config-schema") - expect(atom.config.getSchema('package-with-json-config-schema')).toEqual { type: 'object' properties: { @@ -165,6 +164,18 @@ describe "PackageManager", -> expect(pack.mainModule).toBeNull() + atom.packages.unloadPackage('package-with-json-config-schema') + atom.config.clear() + + pack = atom.packages.loadPackage("package-with-json-config-schema") + expect(atom.config.getSchema('package-with-json-config-schema')).toEqual { + type: 'object' + properties: { + a: {type: 'number', default: 5} + b: {type: 'string', default: 'five'} + } + } + describe "when a package does not have deserializers, view providers or a config schema in its package.json", -> beforeEach -> mockLocalStorage()