From d6e5ea85642155cf28e224034a558254dd4922fe Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 23 Nov 2015 16:05:32 -0800 Subject: [PATCH] Defer requiring packages' main modules if they use new package.json fields --- .../package-with-deserializers/index.js | 3 ++ .../package-with-deserializers/package.json | 1 + .../package-with-view-providers/index.js | 3 ++ .../package-with-view-providers/package.json | 1 + spec/package-manager-spec.coffee | 36 ++++++++-------- src/package.coffee | 43 +++++++++++-------- 6 files changed, 53 insertions(+), 34 deletions(-) create mode 100644 spec/fixtures/packages/package-with-deserializers/index.js create mode 100644 spec/fixtures/packages/package-with-view-providers/index.js diff --git a/spec/fixtures/packages/package-with-deserializers/index.js b/spec/fixtures/packages/package-with-deserializers/index.js new file mode 100644 index 000000000..19bba5ecb --- /dev/null +++ b/spec/fixtures/packages/package-with-deserializers/index.js @@ -0,0 +1,3 @@ +module.exports = { + activate: function() {} +} diff --git a/spec/fixtures/packages/package-with-deserializers/package.json b/spec/fixtures/packages/package-with-deserializers/package.json index c55e1444a..daa5776bf 100644 --- a/spec/fixtures/packages/package-with-deserializers/package.json +++ b/spec/fixtures/packages/package-with-deserializers/package.json @@ -1,6 +1,7 @@ { "name": "package-with-deserializers", "version": "1.0.0", + "main": "./index", "deserializers": { "Deserializer1": "./deserializer-1.js", "Deserializer2": "./deserializer-2.js" diff --git a/spec/fixtures/packages/package-with-view-providers/index.js b/spec/fixtures/packages/package-with-view-providers/index.js new file mode 100644 index 000000000..19bba5ecb --- /dev/null +++ b/spec/fixtures/packages/package-with-view-providers/index.js @@ -0,0 +1,3 @@ +module.exports = { + activate: function() {} +} diff --git a/spec/fixtures/packages/package-with-view-providers/package.json b/spec/fixtures/packages/package-with-view-providers/package.json index 7f7405c32..989473f95 100644 --- a/spec/fixtures/packages/package-with-view-providers/package.json +++ b/spec/fixtures/packages/package-with-view-providers/package.json @@ -1,5 +1,6 @@ { "name": "package-with-view-providers", + "main": "./index", "version": "1.0.0", "viewProviders": [ "./view-provider-1", diff --git a/spec/package-manager-spec.coffee b/spec/package-manager-spec.coffee index 656b4b691..94a6c43c5 100644 --- a/spec/package-manager-spec.coffee +++ b/spec/package-manager-spec.coffee @@ -80,7 +80,7 @@ describe "PackageManager", -> expect(loadedPackage.name).toBe "package-with-main" it "registers any deserializers specified in the package's package.json", -> - atom.packages.loadPackage("package-with-deserializers") + pack = atom.packages.loadPackage("package-with-deserializers") state1 = {deserializer: 'Deserializer1', a: 'b'} expect(atom.deserializers.deserialize(state1)).toEqual { @@ -94,8 +94,10 @@ describe "PackageManager", -> state: state2 } + expect(pack.mainModule).toBeNull() + it "registers any view providers specified in the package's package.json", -> - atom.packages.loadPackage("package-with-view-providers") + pack = atom.packages.loadPackage("package-with-view-providers") model1 = {worksWithViewProvider1: true} element1 = atom.views.getView(model1) @@ -107,6 +109,21 @@ describe "PackageManager", -> expect(element2 instanceof HTMLDivElement).toBe true expect(element2.dataset.createdBy).toBe 'view-provider-2' + expect(pack.mainModule).toBeNull() + + 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: { + a: {type: 'number', default: 5} + b: {type: 'string', default: 'five'} + } + } + + expect(pack.mainModule).toBeNull() + describe "::unloadPackage(name)", -> describe "when the package is active", -> it "throws an error", -> @@ -194,21 +211,6 @@ describe "PackageManager", -> expect(atom.config.set('package-with-config-schema.numbers.one', '10')).toBe true expect(atom.config.get('package-with-config-schema.numbers.one')).toBe 10 - it "assigns the config schema when the package contains a schema in its package.json", -> - expect(atom.config.get('package-with-json-config-schema')).toBeUndefined() - - waitsForPromise -> - atom.packages.activatePackage('package-with-json-config-schema') - - runs -> - 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 the package metadata includes `activationCommands`", -> [mainModule, promise, workspaceCommandListener, registration] = [] diff --git a/src/package.coffee b/src/package.coffee index b2a87d1d8..b97424d04 100644 --- a/src/package.coffee +++ b/src/package.coffee @@ -86,12 +86,22 @@ class Package @loadStylesheets() @loadDeserializers() @loadViewProviders() + @registerConfigSchemaFromMetadata() @settingsPromise = @loadSettings() - @requireMainModule() unless @mainModule? or @activationShouldBeDeferred() + if @shouldRequireMainModuleOnLoad() and not @mainModule? + @requireMainModule() catch error @handleError("Failed to load the #{@name} package", error) this + shouldRequireMainModuleOnLoad: -> + not ( + @metadata.deserializers? or + @metadata.viewProviders? or + @metadata.configSchema? or + @activationShouldBeDeferred() + ) + reset: -> @stylesheets = [] @keymaps = [] @@ -119,9 +129,11 @@ class Package activateNow: -> try - @activateConfig() + @requireMainModule() unless @mainModule? + @registerConfigSchemaFromMainModule() @activateStylesheets() if @mainModule? and not @mainActivated + @mainModule.activateConfig?() @mainModule.activate?(@packageManager.getPackageState(@name) ? {}) @mainActivated = true @activateServices() @@ -130,18 +142,19 @@ class Package @resolveActivationPromise?() - activateConfig: -> - return if @configActivated - + registerConfigSchemaFromMetadata: -> if configSchema = @metadata.configSchema @config.setSchema @name, {type: 'object', properties: configSchema} - else - @requireMainModule() unless @mainModule? - if @mainModule? - if @mainModule.config? and typeof @mainModule.config is 'object' - @config.setSchema @name, {type: 'object', properties: @mainModule.config} - @mainModule.activateConfig?() - @configActivated = true + @configSchemaRegistered = true + + registerConfigSchemaFromMainModule: -> + return if @configSchemaRegistered + + if @mainModule? + if @mainModule.config? and typeof @mainModule.config is 'object' + @config.setSchema @name, {type: 'object', properties: @mainModule.config} + + @configSchemaRegistered = true activateStylesheets: -> return if @stylesheetsActivated @@ -368,20 +381,16 @@ class Package @resolveActivationPromise = null @activationCommandSubscriptions?.dispose() @deactivateResources() - @deactivateConfig() @deactivateKeymaps() if @mainActivated try @mainModule?.deactivate?() + @mainModule?.deactivateConfig?() @mainActivated = false catch e console.error "Error deactivating package '#{@name}'", e.stack @emitter.emit 'did-deactivate' - deactivateConfig: -> - @mainModule?.deactivateConfig?() - @configActivated = false - deactivateResources: -> grammar.deactivate() for grammar in @grammars settings.deactivate() for settings in @settings