From 84e90d140fc684879ffc12e8fecf4e5792ba348b Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 6 Oct 2014 18:00:14 -0700 Subject: [PATCH 01/89] Wire initial module cache --- src/module-cache.coffee | 10 ++++++++++ src/window-bootstrap.coffee | 1 + 2 files changed, 11 insertions(+) create mode 100644 src/module-cache.coffee diff --git a/src/module-cache.coffee b/src/module-cache.coffee new file mode 100644 index 000000000..3a6eb9aee --- /dev/null +++ b/src/module-cache.coffee @@ -0,0 +1,10 @@ +Module = require 'module' +fs = require 'fs-plus' + +originalResolveFilename = Module._resolveFilename + +Module._resolveFilename = (relative, parent) -> + resolved = originalResolveFilename.apply(global, arguments) + if relative[0] isnt '.' and not fs.isAbsolute(relative) and relative isnt resolved + console.log "#{relative} -> #{resolved}" + resolved diff --git a/src/window-bootstrap.coffee b/src/window-bootstrap.coffee index fa7f9d354..6ab56cb22 100644 --- a/src/window-bootstrap.coffee +++ b/src/window-bootstrap.coffee @@ -1,6 +1,7 @@ # Like sands through the hourglass, so are the days of our lives. startTime = Date.now() +require './module-cache' require './window' Atom = require './atom' From dc19fa4baa8610992d028ed01014c55e1b1a9fe0 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 6 Oct 2014 18:45:58 -0700 Subject: [PATCH 02/89] :memo: Add a couple notes --- src/module-cache.coffee | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index 3a6eb9aee..ecea1455a 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -3,6 +3,9 @@ fs = require 'fs-plus' originalResolveFilename = Module._resolveFilename +# Precompute versions of all modules in node_modules +# Precompute the version each file is compatible + Module._resolveFilename = (relative, parent) -> resolved = originalResolveFilename.apply(global, arguments) if relative[0] isnt '.' and not fs.isAbsolute(relative) and relative isnt resolved From d1e966349f2baf49b1b3b2de54468d5b021bd49b Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 6 Oct 2014 18:50:10 -0700 Subject: [PATCH 03/89] Add initial cache lookup method --- src/module-cache.coffee | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index ecea1455a..b0ff7d287 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -6,8 +6,17 @@ originalResolveFilename = Module._resolveFilename # Precompute versions of all modules in node_modules # Precompute the version each file is compatible +getCachedModulePath = (relative, parent) -> + return unless relative + return unless parent?.id + + return if relative[0] is '.' + return if relative[relative.length - 1] is '/' + return if fs.isAbsolute(relative) + + console.log "looking up #{relative} from #{parent.id}" + + undefined + Module._resolveFilename = (relative, parent) -> - resolved = originalResolveFilename.apply(global, arguments) - if relative[0] isnt '.' and not fs.isAbsolute(relative) and relative isnt resolved - console.log "#{relative} -> #{resolved}" - resolved + getCachedModulePath(relative, parent) ? originalResolveFilename(relative, parent) From 5981cfb8c983cf767689be464398d87318d4528c Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 6 Oct 2014 18:55:14 -0700 Subject: [PATCH 04/89] Ignore native modules since they are already cached --- src/module-cache.coffee | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index b0ff7d287..3344a532b 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -1,6 +1,8 @@ Module = require 'module' fs = require 'fs-plus' +nativeModules = process.binding('natives') + originalResolveFilename = Module._resolveFilename # Precompute versions of all modules in node_modules @@ -13,6 +15,7 @@ getCachedModulePath = (relative, parent) -> return if relative[0] is '.' return if relative[relative.length - 1] is '/' return if fs.isAbsolute(relative) + return if nativeModules.hasOwnProperty(relative) console.log "looking up #{relative} from #{parent.id}" From f523c5eb7305a5af7cfaabe325357591965546fb Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 6 Oct 2014 18:55:40 -0700 Subject: [PATCH 05/89] Do hasOwnProperty check first --- src/module-cache.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index 3344a532b..ecdf73c36 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -12,10 +12,10 @@ getCachedModulePath = (relative, parent) -> return unless relative return unless parent?.id + return if nativeModules.hasOwnProperty(relative) return if relative[0] is '.' return if relative[relative.length - 1] is '/' return if fs.isAbsolute(relative) - return if nativeModules.hasOwnProperty(relative) console.log "looking up #{relative} from #{parent.id}" From 7304b9754748da2ff993288ed1bca07d23977b9b Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 6 Oct 2014 19:00:43 -0700 Subject: [PATCH 06/89] Parse resource path for relativizing cache paths --- src/module-cache.coffee | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index ecdf73c36..d61a31dcf 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -3,6 +3,11 @@ fs = require 'fs-plus' nativeModules = process.binding('natives') +try + resourcePath = JSON.parse(decodeURIComponent(location.search.substr(14)))?.resourcePath +catch error + return + originalResolveFilename = Module._resolveFilename # Precompute versions of all modules in node_modules From 5b629e6b2914d768d89b8ce0c3ac8c9360316440 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 6 Oct 2014 19:04:02 -0700 Subject: [PATCH 07/89] :lipstick: --- src/module-cache.coffee | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index d61a31dcf..90612e005 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -13,18 +13,18 @@ originalResolveFilename = Module._resolveFilename # Precompute versions of all modules in node_modules # Precompute the version each file is compatible -getCachedModulePath = (relative, parent) -> - return unless relative - return unless parent?.id +getCachedModulePath = (relativePath, parentModule) -> + return unless relativePath + return unless parentModule?.id - return if nativeModules.hasOwnProperty(relative) - return if relative[0] is '.' - return if relative[relative.length - 1] is '/' - return if fs.isAbsolute(relative) + return if nativeModules.hasOwnProperty(relativePath) + return if relativePath[0] is '.' + return if relativePath[relativePath.length - 1] is '/' + return if fs.isAbsolute(relativePath) - console.log "looking up #{relative} from #{parent.id}" + console.log "looking up #{relative} from #{parentModule.id}" undefined -Module._resolveFilename = (relative, parent) -> - getCachedModulePath(relative, parent) ? originalResolveFilename(relative, parent) +Module._resolveFilename = (relativePath, parentModule) -> + getCachedModulePath(relativePath, parentModule) ? originalResolveFilename(relativePath, parentModule) From b4470a14cb7e3f04e8b2f48662611d9321a50721 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Oct 2014 09:06:18 -0700 Subject: [PATCH 08/89] Explicitly register cache --- src/module-cache.coffee | 10 ++++++++-- src/window-bootstrap.coffee | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index 90612e005..869787b2e 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -26,5 +26,11 @@ getCachedModulePath = (relativePath, parentModule) -> undefined -Module._resolveFilename = (relativePath, parentModule) -> - getCachedModulePath(relativePath, parentModule) ? originalResolveFilename(relativePath, parentModule) +registered = false +exports.register = -> + return if registered + + Module._resolveFilename = (relativePath, parentModule) -> + resolvedPath = getCachedModulePath(relativePath, parentModule) + resolvedPath ? originalResolveFilename(relativePath, parentModule) + registered = true diff --git a/src/window-bootstrap.coffee b/src/window-bootstrap.coffee index 6ab56cb22..7312f99a5 100644 --- a/src/window-bootstrap.coffee +++ b/src/window-bootstrap.coffee @@ -1,7 +1,7 @@ # Like sands through the hourglass, so are the days of our lives. startTime = Date.now() -require './module-cache' +require('./module-cache').register() require './window' Atom = require './atom' From 6ce655345671f9bf560f7464af188dee4e40ce56 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Oct 2014 10:14:24 -0700 Subject: [PATCH 09/89] Add initial task to generate dependencies --- build/tasks/generate-module-cache-task.coffee | 5 ++ src/module-cache.coffee | 70 +++++++++++++++++-- 2 files changed, 70 insertions(+), 5 deletions(-) create mode 100644 build/tasks/generate-module-cache-task.coffee diff --git a/build/tasks/generate-module-cache-task.coffee b/build/tasks/generate-module-cache-task.coffee new file mode 100644 index 000000000..6a21f9545 --- /dev/null +++ b/build/tasks/generate-module-cache-task.coffee @@ -0,0 +1,5 @@ +ModuleCache = require '../../src/module-cache' + +module.exports = (grunt) -> + grunt.registerTask 'generate-module-cache', 'Generate a module cache for all core modules', -> + ModuleCache.generateDependencies(process.cwd()) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index 869787b2e..204cf3580 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -1,17 +1,77 @@ Module = require 'module' +path = require 'path' fs = require 'fs-plus' nativeModules = process.binding('natives') -try - resourcePath = JSON.parse(decodeURIComponent(location.search.substr(14)))?.resourcePath -catch error - return - originalResolveFilename = Module._resolveFilename +loadDependencies = (modulePath, rootPath, rootMetadata, moduleCache) -> + return unless fs.isDirectorySync(modulePath) + + nodeModulesPath = path.join(modulePath, 'node_modules') + return unless fs.isDirectorySync(nodeModulesPath) + + for child in fs.readdirSync(nodeModulesPath) + continue if child is '.bin' + continue if rootPath is modulePath and rootMetadata.packageDependencies?.hasOwnProperty(child) + + childPath = path.join(nodeModulesPath, child) + childMetadatapath = path.join(nodeModulesPath, child, 'package.json') + continue unless fs.isFileSync(childMetadatapath) + + childMetadata = JSON.parse(fs.readFileSync(childMetadatapath)) + if childMetadata?.version + relativePath = path.relative(rootPath, childPath) + moduleCache.dependencies[relativePath] = childMetadata.version + loadDependencies(childPath, rootPath, rootMetadata, moduleCache) + +loadFolderCompatibility = (modulePath, rootPath, rootMetadata, moduleCache) -> + return unless fs.isDirectorySync(modulePath) + + metadataPath = path.join(modulePath, 'package.json') + return unless fs.isFileSync(metadataPath) + + nodeModulesPath = path.join(modulePath, 'node_modules') + dependencies = JSON.parse(fs.readFileSync(metadataPath))?.dependencies ? {} + + onDirectory = (childPath) -> + path.basename(childPath) isnt 'node_modules' + + extensions = Object.keys(require.extensions) + paths = {} + onFile = (childPath) -> + if path.extname(childPath) in extensions + relativePath = path.relative(rootPath, path.dirname(childPath)) + paths[relativePath] = true + fs.traverseTreeSync(modulePath, onFile, onDirectory) + + moduleCache.folders ?= [] + paths = Object.keys(paths) + if paths.length > 0 and Object.keys(dependencies).length > 0 + moduleCache.folders.push({paths, dependencies}) + + if fs.isDirectorySync(nodeModulesPath) + for child in fs.readdirSync(nodeModulesPath) + continue if child is '.bin' + continue if rootPath is modulePath and rootMetadata.packageDependencies?.hasOwnProperty(child) + + loadFolderCompatibility(path.join(nodeModulesPath, child), rootPath, rootMetadata, moduleCache) + # Precompute versions of all modules in node_modules # Precompute the version each file is compatible +exports.generateDependencies = (modulePath) -> + metadataPath = path.join(modulePath, 'package.json') + metadata = JSON.parse(fs.readFileSync(metadataPath)) + + moduleCache = + version: 1 + dependencies: {} + loadDependencies(modulePath, modulePath, metadata, moduleCache) + loadFolderCompatibility(modulePath, modulePath, metadata, moduleCache) + + metadata._atomModuleCache = moduleCache + fs.writeFileSync(metadataPath, JSON.stringify(metadata, null, 2)) getCachedModulePath = (relativePath, parentModule) -> return unless relativePath From 7aa28920cf7fd8f0b12fe094f45546d32d0a160b Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Oct 2014 10:17:20 -0700 Subject: [PATCH 10/89] Use fs.listSync --- src/module-cache.coffee | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index 204cf3580..86f80ce81 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -7,28 +7,21 @@ nativeModules = process.binding('natives') originalResolveFilename = Module._resolveFilename loadDependencies = (modulePath, rootPath, rootMetadata, moduleCache) -> - return unless fs.isDirectorySync(modulePath) - nodeModulesPath = path.join(modulePath, 'node_modules') - return unless fs.isDirectorySync(nodeModulesPath) + for childPath in fs.listSync(nodeModulesPath) + continue if path.basename(childPath) is '.bin' + continue if rootPath is modulePath and rootMetadata.packageDependencies?.hasOwnProperty(path.basename(childPath)) - for child in fs.readdirSync(nodeModulesPath) - continue if child is '.bin' - continue if rootPath is modulePath and rootMetadata.packageDependencies?.hasOwnProperty(child) + childMetadataPath = path.join(childPath, 'package.json') + continue unless fs.isFileSync(childMetadataPath) - childPath = path.join(nodeModulesPath, child) - childMetadatapath = path.join(nodeModulesPath, child, 'package.json') - continue unless fs.isFileSync(childMetadatapath) - - childMetadata = JSON.parse(fs.readFileSync(childMetadatapath)) + childMetadata = JSON.parse(fs.readFileSync(childMetadataPath)) if childMetadata?.version relativePath = path.relative(rootPath, childPath) moduleCache.dependencies[relativePath] = childMetadata.version loadDependencies(childPath, rootPath, rootMetadata, moduleCache) loadFolderCompatibility = (modulePath, rootPath, rootMetadata, moduleCache) -> - return unless fs.isDirectorySync(modulePath) - metadataPath = path.join(modulePath, 'package.json') return unless fs.isFileSync(metadataPath) @@ -51,12 +44,11 @@ loadFolderCompatibility = (modulePath, rootPath, rootMetadata, moduleCache) -> if paths.length > 0 and Object.keys(dependencies).length > 0 moduleCache.folders.push({paths, dependencies}) - if fs.isDirectorySync(nodeModulesPath) - for child in fs.readdirSync(nodeModulesPath) - continue if child is '.bin' - continue if rootPath is modulePath and rootMetadata.packageDependencies?.hasOwnProperty(child) + for childPath in fs.listSync(nodeModulesPath) + continue if path.basename(childPath) is '.bin' + continue if rootPath is modulePath and rootMetadata.packageDependencies?.hasOwnProperty(path.basename(childPath)) - loadFolderCompatibility(path.join(nodeModulesPath, child), rootPath, rootMetadata, moduleCache) + loadFolderCompatibility(childPath, rootPath, rootMetadata, moduleCache) # Precompute versions of all modules in node_modules # Precompute the version each file is compatible From 944ac14be7c4afa8c2426bc06b8d553ab051d836 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Oct 2014 10:33:05 -0700 Subject: [PATCH 11/89] Make dependencies an array of objects --- src/module-cache.coffee | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index 86f80ce81..b2641c472 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -18,7 +18,10 @@ loadDependencies = (modulePath, rootPath, rootMetadata, moduleCache) -> childMetadata = JSON.parse(fs.readFileSync(childMetadataPath)) if childMetadata?.version relativePath = path.relative(rootPath, childPath) - moduleCache.dependencies[relativePath] = childMetadata.version + moduleCache.dependencies.push + name: childMetadata.name + version: childMetadata.version + path: relativePath loadDependencies(childPath, rootPath, rootMetadata, moduleCache) loadFolderCompatibility = (modulePath, rootPath, rootMetadata, moduleCache) -> @@ -39,7 +42,6 @@ loadFolderCompatibility = (modulePath, rootPath, rootMetadata, moduleCache) -> paths[relativePath] = true fs.traverseTreeSync(modulePath, onFile, onDirectory) - moduleCache.folders ?= [] paths = Object.keys(paths) if paths.length > 0 and Object.keys(dependencies).length > 0 moduleCache.folders.push({paths, dependencies}) @@ -58,7 +60,8 @@ exports.generateDependencies = (modulePath) -> moduleCache = version: 1 - dependencies: {} + dependencies: [] + folders: [] loadDependencies(modulePath, modulePath, metadata, moduleCache) loadFolderCompatibility(modulePath, modulePath, metadata, moduleCache) From 0e7e24ca6b7020d433146abe9e606f4917a45b9a Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Oct 2014 10:36:07 -0700 Subject: [PATCH 12/89] relative -> relativePath --- src/module-cache.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index b2641c472..d000fcccb 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -77,7 +77,7 @@ getCachedModulePath = (relativePath, parentModule) -> return if relativePath[relativePath.length - 1] is '/' return if fs.isAbsolute(relativePath) - console.log "looking up #{relative} from #{parentModule.id}" + console.log "looking up #{relativePath} from #{parentModule.id}" undefined From 1154490a9730477c9ccf7c064e56f6f7a60ddc9b Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Oct 2014 14:27:46 -0700 Subject: [PATCH 13/89] Store main path of module This is the key in Module._cache --- src/module-cache.coffee | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index d000fcccb..1270e1e5c 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -17,11 +17,17 @@ loadDependencies = (modulePath, rootPath, rootMetadata, moduleCache) -> childMetadata = JSON.parse(fs.readFileSync(childMetadataPath)) if childMetadata?.version - relativePath = path.relative(rootPath, childPath) - moduleCache.dependencies.push - name: childMetadata.name - version: childMetadata.version - path: relativePath + try + mainPath = require.resolve(childPath) + catch error + console.log "Skipping #{childPath}, no main module" + + if mainPath + moduleCache.dependencies.push + name: childMetadata.name + version: childMetadata.version + path: path.relative(rootPath, mainPath) + loadDependencies(childPath, rootPath, rootMetadata, moduleCache) loadFolderCompatibility = (modulePath, rootPath, rootMetadata, moduleCache) -> From 4da6513fb57307b6f95ed729546d46b443563da8 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Oct 2014 14:29:24 -0700 Subject: [PATCH 14/89] Add initial cache of resource path module --- src/module-cache.coffee | 15 +++++++++++++++ src/window-bootstrap.coffee | 5 ++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index 1270e1e5c..6fff2ace2 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -95,3 +95,18 @@ exports.register = -> resolvedPath = getCachedModulePath(relativePath, parentModule) resolvedPath ? originalResolveFilename(relativePath, parentModule) registered = true + +dependencies = {} +folders = {} + +global.mc = {dependencies, folders} + +exports.add = (directoryPath) -> + cache = require(path.join(directoryPath, 'package.json'))?._atomModuleCache + for dependency in cache?.dependencies ? [] + dependencies[dependency.name] ?= {} + dependencies[dependency.name][dependency.version] = path.join(directoryPath, dependency.path) + + for entry in cache?.folders ? [] + for folderPath in entry.paths + folders[path.join(directoryPath, folderPath)] = entry.dependencies diff --git a/src/window-bootstrap.coffee b/src/window-bootstrap.coffee index 7312f99a5..bf0aabb3a 100644 --- a/src/window-bootstrap.coffee +++ b/src/window-bootstrap.coffee @@ -1,7 +1,10 @@ # Like sands through the hourglass, so are the days of our lives. startTime = Date.now() -require('./module-cache').register() +ModuleCache = require('./module-cache') +ModuleCache.add(JSON.parse(decodeURIComponent(location.search.substr(14))).resourcePath) +ModuleCache.register() + require './window' Atom = require './atom' From 5ad54bbe925212268d1ee62bbbf1fb666d3f84b4 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Oct 2014 15:02:15 -0700 Subject: [PATCH 15/89] Wire up cache to Module._resolveFilename --- package.json | 2 +- src/module-cache.coffee | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 1fde259c4..fed1bd296 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "scoped-property-store": "^0.13.2", "scrollbar-style": "^1.0.2", "season": "^1.0.2", - "semver": "1.1.4", + "semver": "2.2.1", "serializable": "^1", "space-pen": "3.8.0", "temp": "0.7.0", diff --git a/src/module-cache.coffee b/src/module-cache.coffee index 6fff2ace2..7e3bacfe7 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -1,11 +1,10 @@ Module = require 'module' path = require 'path' fs = require 'fs-plus' +semver = require 'semver' nativeModules = process.binding('natives') -originalResolveFilename = Module._resolveFilename - loadDependencies = (modulePath, rootPath, rootMetadata, moduleCache) -> nodeModulesPath = path.join(modulePath, 'node_modules') for childPath in fs.listSync(nodeModulesPath) @@ -58,8 +57,6 @@ loadFolderCompatibility = (modulePath, rootPath, rootMetadata, moduleCache) -> loadFolderCompatibility(childPath, rootPath, rootMetadata, moduleCache) -# Precompute versions of all modules in node_modules -# Precompute the version each file is compatible exports.generateDependencies = (modulePath) -> metadataPath = path.join(modulePath, 'package.json') metadata = JSON.parse(fs.readFileSync(metadataPath)) @@ -68,6 +65,7 @@ exports.generateDependencies = (modulePath) -> version: 1 dependencies: [] folders: [] + loadDependencies(modulePath, modulePath, metadata, moduleCache) loadFolderCompatibility(modulePath, modulePath, metadata, moduleCache) @@ -83,7 +81,17 @@ getCachedModulePath = (relativePath, parentModule) -> return if relativePath[relativePath.length - 1] is '/' return if fs.isAbsolute(relativePath) - console.log "looking up #{relativePath} from #{parentModule.id}" + folderPath = path.dirname(parentModule.id) + + dependency = folders[folderPath]?[relativePath] + return unless dependency? + + candidates = dependencies[relativePath] + return unless candidates? + + for version, resolvedPath of candidates + if Module._cache[resolvedPath] and semver.satisfies(version, dependency) + return resolvedPath undefined @@ -91,6 +99,7 @@ registered = false exports.register = -> return if registered + originalResolveFilename = Module._resolveFilename Module._resolveFilename = (relativePath, parentModule) -> resolvedPath = getCachedModulePath(relativePath, parentModule) resolvedPath ? originalResolveFilename(relativePath, parentModule) From 508a30efb10b9dd69370ba23ca9fe06d070b6ba8 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Oct 2014 15:12:03 -0700 Subject: [PATCH 16/89] Return when package.json can't be required --- src/module-cache.coffee | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index 7e3bacfe7..c7e2c0b87 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -5,6 +5,10 @@ semver = require 'semver' nativeModules = process.binding('natives') +cache = + dependencies: {} + folders: {} + loadDependencies = (modulePath, rootPath, rootMetadata, moduleCache) -> nodeModulesPath = path.join(modulePath, 'node_modules') for childPath in fs.listSync(nodeModulesPath) @@ -83,10 +87,10 @@ getCachedModulePath = (relativePath, parentModule) -> folderPath = path.dirname(parentModule.id) - dependency = folders[folderPath]?[relativePath] + dependency = cache.folders[folderPath]?[relativePath] return unless dependency? - candidates = dependencies[relativePath] + candidates = cache.dependencies[relativePath] return unless candidates? for version, resolvedPath of candidates @@ -101,21 +105,23 @@ exports.register = -> originalResolveFilename = Module._resolveFilename Module._resolveFilename = (relativePath, parentModule) -> - resolvedPath = getCachedModulePath(relativePath, parentModule) - resolvedPath ? originalResolveFilename(relativePath, parentModule) + # resolvedPath = getCachedModulePath(relativePath, parentModule) + originalResolveFilename(relativePath, parentModule) registered = true -dependencies = {} -folders = {} - -global.mc = {dependencies, folders} - exports.add = (directoryPath) -> - cache = require(path.join(directoryPath, 'package.json'))?._atomModuleCache - for dependency in cache?.dependencies ? [] - dependencies[dependency.name] ?= {} - dependencies[dependency.name][dependency.version] = path.join(directoryPath, dependency.path) + try + metadata = require(path.join(directoryPath, 'package.json')) + catch error + return - for entry in cache?.folders ? [] + cacheToAdd = metadata?._atomModuleCache + for dependency in cacheToAdd?.dependencies ? [] + cache.dependencies[dependency.name] ?= {} + cache.dependencies[dependency.name][dependency.version] = path.join(directoryPath, dependency.path) + + for entry in cacheToAdd?.folders ? [] for folderPath in entry.paths - folders[path.join(directoryPath, folderPath)] = entry.dependencies + cache.folders[path.join(directoryPath, folderPath)] = entry.dependencies + + undefined From 245c77869fa23d6cf94fcb30adce6b7e5dc0cf40 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Oct 2014 15:12:44 -0700 Subject: [PATCH 17/89] Add require time and load count tracking --- src/module-cache.coffee | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index c7e2c0b87..8ef68c011 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -99,6 +99,24 @@ getCachedModulePath = (relativePath, parentModule) -> undefined +debug = false +if debug + global.loadCount = 0 + global.requireTime = 0 + + originalLoad = Module::load + Module::load = -> + global.loadCount++ + originalLoad.apply(this, arguments) + + + originalRequire = Module::require + Module::require = -> + startTime = Date.now() + exports = originalRequire.apply(this, arguments) + global.requireTime += Date.now() - startTime + exports + registered = false exports.register = -> return if registered From 8c204bb60ed5ab5538148f9607e9ed4e404739fe Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Oct 2014 15:13:59 -0700 Subject: [PATCH 18/89] Restore cache --- src/module-cache.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index 8ef68c011..01f70ae0e 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -123,8 +123,8 @@ exports.register = -> originalResolveFilename = Module._resolveFilename Module._resolveFilename = (relativePath, parentModule) -> - # resolvedPath = getCachedModulePath(relativePath, parentModule) - originalResolveFilename(relativePath, parentModule) + resolvedPath = getCachedModulePath(relativePath, parentModule) + resolvedPath ? originalResolveFilename(relativePath, parentModule) registered = true exports.add = (directoryPath) -> From e0a84232c3fd3ce9fa4c4e03b3fd8dd6b28b0eea Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Oct 2014 15:17:09 -0700 Subject: [PATCH 19/89] :lipstick: --- src/module-cache.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index 01f70ae0e..35e0f46d5 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -103,13 +103,13 @@ debug = false if debug global.loadCount = 0 global.requireTime = 0 + global.moduleCache = cache originalLoad = Module::load Module::load = -> global.loadCount++ originalLoad.apply(this, arguments) - originalRequire = Module::require Module::require = -> startTime = Date.now() From 1bf8f516c360b4773bed73d680075236b5c8c666 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Oct 2014 15:35:35 -0700 Subject: [PATCH 20/89] Cache parsed ranges --- src/module-cache.coffee | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index 35e0f46d5..a67fe745d 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -8,6 +8,7 @@ nativeModules = process.binding('natives') cache = dependencies: {} folders: {} + ranges: {} loadDependencies = (modulePath, rootPath, rootMetadata, moduleCache) -> nodeModulesPath = path.join(modulePath, 'node_modules') @@ -40,6 +41,15 @@ loadFolderCompatibility = (modulePath, rootPath, rootMetadata, moduleCache) -> nodeModulesPath = path.join(modulePath, 'node_modules') dependencies = JSON.parse(fs.readFileSync(metadataPath))?.dependencies ? {} + for name, version of dependencies + try + new semver.Range(version) + catch error + invalidVersion = version + version = JSON.parse(fs.readFileSync(path.join(nodeModulesPath, name, 'package.json')))?.version + dependencies[name] = version + console.log "Normalized #{name}: #{invalidVersion} -> #{version}" + onDirectory = (childPath) -> path.basename(childPath) isnt 'node_modules' @@ -76,6 +86,12 @@ exports.generateDependencies = (modulePath) -> metadata._atomModuleCache = moduleCache fs.writeFileSync(metadataPath, JSON.stringify(metadata, null, 2)) +satisfies = (version, rawRange) -> + unless parsedRange = cache.ranges[rawRange] + parsedRange = new semver.Range(rawRange) + cache.ranges[rawRange] = parsedRange + parsedRange.test(version) + getCachedModulePath = (relativePath, parentModule) -> return unless relativePath return unless parentModule?.id @@ -87,14 +103,14 @@ getCachedModulePath = (relativePath, parentModule) -> folderPath = path.dirname(parentModule.id) - dependency = cache.folders[folderPath]?[relativePath] - return unless dependency? + range = cache.folders[folderPath]?[relativePath] + return unless range? candidates = cache.dependencies[relativePath] return unless candidates? for version, resolvedPath of candidates - if Module._cache[resolvedPath] and semver.satisfies(version, dependency) + if Module._cache[resolvedPath] and satisfies(version, range) return resolvedPath undefined From 2954aacb1c27e93aa0b8bed44b3b32d55f3b8f00 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Oct 2014 15:37:47 -0700 Subject: [PATCH 21/89] Ignore invalid ranges They cannot be cache since multiple commits/branches may map to the same version number which would lead to unpredictable results. --- src/module-cache.coffee | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index a67fe745d..ce11c8c28 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -45,10 +45,8 @@ loadFolderCompatibility = (modulePath, rootPath, rootMetadata, moduleCache) -> try new semver.Range(version) catch error - invalidVersion = version - version = JSON.parse(fs.readFileSync(path.join(nodeModulesPath, name, 'package.json')))?.version - dependencies[name] = version - console.log "Normalized #{name}: #{invalidVersion} -> #{version}" + delete dependencies[name] + console.log "Ignoring invalid range: #{name} #{version}" onDirectory = (childPath) -> path.basename(childPath) isnt 'node_modules' From 495fa43753f30d067d0e6dbad5da78c6edc4818e Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 8 Oct 2014 08:29:00 -0700 Subject: [PATCH 22/89] Allow passing in metadata to ModuleCache.add --- src/module-cache.coffee | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index ce11c8c28..aef565917 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -34,6 +34,8 @@ loadDependencies = (modulePath, rootPath, rootMetadata, moduleCache) -> loadDependencies(childPath, rootPath, rootMetadata, moduleCache) + undefined + loadFolderCompatibility = (modulePath, rootPath, rootMetadata, moduleCache) -> metadataPath = path.join(modulePath, 'package.json') return unless fs.isFileSync(metadataPath) @@ -69,6 +71,8 @@ loadFolderCompatibility = (modulePath, rootPath, rootMetadata, moduleCache) -> loadFolderCompatibility(childPath, rootPath, rootMetadata, moduleCache) + undefined + exports.generateDependencies = (modulePath) -> metadataPath = path.join(modulePath, 'package.json') metadata = JSON.parse(fs.readFileSync(metadataPath)) @@ -83,6 +87,7 @@ exports.generateDependencies = (modulePath) -> metadata._atomModuleCache = moduleCache fs.writeFileSync(metadataPath, JSON.stringify(metadata, null, 2)) + undefined satisfies = (version, rawRange) -> unless parsedRange = cache.ranges[rawRange] @@ -141,11 +146,14 @@ exports.register = -> resolvedPath ? originalResolveFilename(relativePath, parentModule) registered = true -exports.add = (directoryPath) -> - try - metadata = require(path.join(directoryPath, 'package.json')) - catch error - return + undefined + +exports.add = (directoryPath, metadata) -> + unless metadata? + try + metadata = require(path.join(directoryPath, 'package.json')) + catch error + return cacheToAdd = metadata?._atomModuleCache for dependency in cacheToAdd?.dependencies ? [] From 93c5b4be7b3c333d64c4a3b55898ec11a22e2634 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 8 Oct 2014 08:32:53 -0700 Subject: [PATCH 23/89] Generate cache for bundled packages --- build/tasks/generate-module-cache-task.coffee | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/build/tasks/generate-module-cache-task.coffee b/build/tasks/generate-module-cache-task.coffee index 6a21f9545..f38e2f9c6 100644 --- a/build/tasks/generate-module-cache-task.coffee +++ b/build/tasks/generate-module-cache-task.coffee @@ -1,5 +1,11 @@ +path = require 'path' ModuleCache = require '../../src/module-cache' module.exports = (grunt) -> - grunt.registerTask 'generate-module-cache', 'Generate a module cache for all core modules', -> + grunt.registerTask 'generate-module-cache', 'Generate a module cache for all core modules and packages', -> + {packageDependencies} = grunt.file.readJSON('package.json') + + for packageName, version of packageDependencies + ModuleCache.generateDependencies(path.join(process.cwd(), 'node_modules', packageName)) + ModuleCache.generateDependencies(process.cwd()) From 36ff22e30ae34f395aab958560bec481a3e4e850 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 8 Oct 2014 08:33:40 -0700 Subject: [PATCH 24/89] generateDependencies -> create --- build/tasks/generate-module-cache-task.coffee | 4 ++-- src/module-cache.coffee | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build/tasks/generate-module-cache-task.coffee b/build/tasks/generate-module-cache-task.coffee index f38e2f9c6..ea959c64c 100644 --- a/build/tasks/generate-module-cache-task.coffee +++ b/build/tasks/generate-module-cache-task.coffee @@ -6,6 +6,6 @@ module.exports = (grunt) -> {packageDependencies} = grunt.file.readJSON('package.json') for packageName, version of packageDependencies - ModuleCache.generateDependencies(path.join(process.cwd(), 'node_modules', packageName)) + ModuleCache.create(path.join(process.cwd(), 'node_modules', packageName)) - ModuleCache.generateDependencies(process.cwd()) + ModuleCache.create(process.cwd()) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index aef565917..d6e981a5b 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -73,7 +73,7 @@ loadFolderCompatibility = (modulePath, rootPath, rootMetadata, moduleCache) -> undefined -exports.generateDependencies = (modulePath) -> +exports.create = (modulePath) -> metadataPath = path.join(modulePath, 'package.json') metadata = JSON.parse(fs.readFileSync(metadataPath)) From 26df31aa1fa103ca3d388ab9283e6bac525aa6a7 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 8 Oct 2014 08:37:57 -0700 Subject: [PATCH 25/89] :lipstick: Group exported methods --- src/module-cache.coffee | 32 ++++++++++++++++---------------- src/package.coffee | 2 ++ 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index d6e981a5b..378cf900c 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -73,22 +73,6 @@ loadFolderCompatibility = (modulePath, rootPath, rootMetadata, moduleCache) -> undefined -exports.create = (modulePath) -> - metadataPath = path.join(modulePath, 'package.json') - metadata = JSON.parse(fs.readFileSync(metadataPath)) - - moduleCache = - version: 1 - dependencies: [] - folders: [] - - loadDependencies(modulePath, modulePath, metadata, moduleCache) - loadFolderCompatibility(modulePath, modulePath, metadata, moduleCache) - - metadata._atomModuleCache = moduleCache - fs.writeFileSync(metadataPath, JSON.stringify(metadata, null, 2)) - undefined - satisfies = (version, rawRange) -> unless parsedRange = cache.ranges[rawRange] parsedRange = new semver.Range(rawRange) @@ -136,6 +120,22 @@ if debug global.requireTime += Date.now() - startTime exports +exports.create = (modulePath) -> + metadataPath = path.join(modulePath, 'package.json') + metadata = JSON.parse(fs.readFileSync(metadataPath)) + + moduleCache = + version: 1 + dependencies: [] + folders: [] + + loadDependencies(modulePath, modulePath, metadata, moduleCache) + loadFolderCompatibility(modulePath, modulePath, metadata, moduleCache) + + metadata._atomModuleCache = moduleCache + fs.writeFileSync(metadataPath, JSON.stringify(metadata, null, 2)) + undefined + registered = false exports.register = -> return if registered diff --git a/src/package.coffee b/src/package.coffee index 91ea89175..1ec35b601 100644 --- a/src/package.coffee +++ b/src/package.coffee @@ -10,6 +10,7 @@ Q = require 'q' {deprecate} = require 'grim' $ = null # Defer require in case this is in the window-less browser process +ModuleCache = require './module-cache' ScopedProperties = require './scoped-properties' # Loads and activates a package's main module and resources such as @@ -47,6 +48,7 @@ class Package @emitter = new Emitter @metadata ?= Package.loadMetadata(@path) @name = @metadata?.name ? path.basename(@path) + ModuleCache.add(@path, @metadata) @reset() ### From 7b8a293f30335e1ddc2f9695b291e257e75610dd Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 8 Oct 2014 08:38:33 -0700 Subject: [PATCH 26/89] Inline path to listSync call --- src/module-cache.coffee | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index 378cf900c..26b98309b 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -11,8 +11,7 @@ cache = ranges: {} loadDependencies = (modulePath, rootPath, rootMetadata, moduleCache) -> - nodeModulesPath = path.join(modulePath, 'node_modules') - for childPath in fs.listSync(nodeModulesPath) + for childPath in fs.listSync(path.join(modulePath, 'node_modules')) continue if path.basename(childPath) is '.bin' continue if rootPath is modulePath and rootMetadata.packageDependencies?.hasOwnProperty(path.basename(childPath)) @@ -40,7 +39,6 @@ loadFolderCompatibility = (modulePath, rootPath, rootMetadata, moduleCache) -> metadataPath = path.join(modulePath, 'package.json') return unless fs.isFileSync(metadataPath) - nodeModulesPath = path.join(modulePath, 'node_modules') dependencies = JSON.parse(fs.readFileSync(metadataPath))?.dependencies ? {} for name, version of dependencies @@ -65,7 +63,7 @@ loadFolderCompatibility = (modulePath, rootPath, rootMetadata, moduleCache) -> if paths.length > 0 and Object.keys(dependencies).length > 0 moduleCache.folders.push({paths, dependencies}) - for childPath in fs.listSync(nodeModulesPath) + for childPath in fs.listSync(path.join(modulePath, 'node_modules')) continue if path.basename(childPath) is '.bin' continue if rootPath is modulePath and rootMetadata.packageDependencies?.hasOwnProperty(path.basename(childPath)) From b91c25186f30b7667f1eb83c6ef71dece04cd06d Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 8 Oct 2014 08:38:54 -0700 Subject: [PATCH 27/89] Use hasOwnProperty --- src/module-cache.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index 26b98309b..f340b340d 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -95,7 +95,7 @@ getCachedModulePath = (relativePath, parentModule) -> return unless candidates? for version, resolvedPath of candidates - if Module._cache[resolvedPath] and satisfies(version, range) + if Module._cache.hasOwnProperty(resolvedPath) and satisfies(version, range) return resolvedPath undefined From 0df5045edb87ea3dd435c99de768a03ff35d74e1 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 8 Oct 2014 08:39:59 -0700 Subject: [PATCH 28/89] Move registered property into cache object --- src/module-cache.coffee | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index f340b340d..da789028a 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -9,6 +9,7 @@ cache = dependencies: {} folders: {} ranges: {} + registered: false loadDependencies = (modulePath, rootPath, rootMetadata, moduleCache) -> for childPath in fs.listSync(path.join(modulePath, 'node_modules')) @@ -134,15 +135,14 @@ exports.create = (modulePath) -> fs.writeFileSync(metadataPath, JSON.stringify(metadata, null, 2)) undefined -registered = false exports.register = -> - return if registered + return if cache.registered originalResolveFilename = Module._resolveFilename Module._resolveFilename = (relativePath, parentModule) -> resolvedPath = getCachedModulePath(relativePath, parentModule) resolvedPath ? originalResolveFilename(relativePath, parentModule) - registered = true + cache.registered = true undefined From 2c737b892765f6afd760921d93a141c8ab5c5cea Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 8 Oct 2014 08:43:47 -0700 Subject: [PATCH 29/89] Move debug property into cache object --- src/module-cache.coffee | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index da789028a..536f763dc 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -6,6 +6,7 @@ semver = require 'semver' nativeModules = process.binding('natives') cache = + debug: true dependencies: {} folders: {} ranges: {} @@ -101,22 +102,21 @@ getCachedModulePath = (relativePath, parentModule) -> undefined -debug = false -if debug - global.loadCount = 0 - global.requireTime = 0 +if cache.debug + cache.loadCount = 0 + cache.requireTime = 0 global.moduleCache = cache originalLoad = Module::load Module::load = -> - global.loadCount++ + cache.loadCount++ originalLoad.apply(this, arguments) originalRequire = Module::require Module::require = -> startTime = Date.now() exports = originalRequire.apply(this, arguments) - global.requireTime += Date.now() - startTime + cache.requireTime += Date.now() - startTime exports exports.create = (modulePath) -> From 20f64892324dcdabc4c3399843998427e5e6b590 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 8 Oct 2014 08:45:56 -0700 Subject: [PATCH 30/89] Disable debug mode --- src/module-cache.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index 536f763dc..5df5f254c 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -6,7 +6,7 @@ semver = require 'semver' nativeModules = process.binding('natives') cache = - debug: true + debug: false dependencies: {} folders: {} ranges: {} From 87d2026e636200dafb77a1b2bacdcb32f80587be Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 8 Oct 2014 09:59:26 -0700 Subject: [PATCH 31/89] Generate module cache during build --- build/tasks/build-task.coffee | 2 +- build/tasks/generate-module-cache-task.coffee | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/build/tasks/build-task.coffee b/build/tasks/build-task.coffee index 44200a0b6..1aefcd6f5 100644 --- a/build/tasks/build-task.coffee +++ b/build/tasks/build-task.coffee @@ -153,7 +153,7 @@ module.exports = (grunt) -> fs.writeFileSync path.join(appDir, 'node_modules', 'symbols-view', 'vendor', 'ctags-win32.exe.ignore'), '' fs.writeFileSync path.join(shellAppDir, 'atom.exe.gui'), '' - dependencies = ['compile', "generate-license:save"] + dependencies = ['compile', 'generate-license:save', 'generate-module-cache'] dependencies.push('copy-info-plist') if process.platform is 'darwin' dependencies.push('set-exe-icon') if process.platform is 'win32' grunt.task.run(dependencies...) diff --git a/build/tasks/generate-module-cache-task.coffee b/build/tasks/generate-module-cache-task.coffee index ea959c64c..384d01f58 100644 --- a/build/tasks/generate-module-cache-task.coffee +++ b/build/tasks/generate-module-cache-task.coffee @@ -3,9 +3,11 @@ ModuleCache = require '../../src/module-cache' module.exports = (grunt) -> grunt.registerTask 'generate-module-cache', 'Generate a module cache for all core modules and packages', -> + appDir = grunt.config.get('atom.appDir') + {packageDependencies} = grunt.file.readJSON('package.json') for packageName, version of packageDependencies - ModuleCache.create(path.join(process.cwd(), 'node_modules', packageName)) + ModuleCache.create(path.join(appDir, 'node_modules', packageName)) - ModuleCache.create(process.cwd()) + ModuleCache.create(appDir) From 0a297d7642a0fc855bfc52764211307c0a9186ee Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 8 Oct 2014 10:00:13 -0700 Subject: [PATCH 32/89] Load module cache in index.js --- src/window-bootstrap.coffee | 4 ---- static/index.js | 5 +++++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/window-bootstrap.coffee b/src/window-bootstrap.coffee index bf0aabb3a..fa7f9d354 100644 --- a/src/window-bootstrap.coffee +++ b/src/window-bootstrap.coffee @@ -1,10 +1,6 @@ # Like sands through the hourglass, so are the days of our lives. startTime = Date.now() -ModuleCache = require('./module-cache') -ModuleCache.add(JSON.parse(decodeURIComponent(location.search.substr(14))).resourcePath) -ModuleCache.register() - require './window' Atom = require './atom' diff --git a/static/index.js b/static/index.js index 179026a66..5963863be 100644 --- a/static/index.js +++ b/static/index.js @@ -17,6 +17,11 @@ window.onload = function() { require('vm-compatibility-layer'); require('coffee-script').register(); require(path.resolve(__dirname, '..', 'src', 'coffee-cache')).register(); + + ModuleCache = require('./module-cache'); + ModuleCache.add(loadSettings.resourcePath); + ModuleCache.register(); + require(loadSettings.bootstrapScript); ipc.sendChannel('window-command', 'window:loaded') } From d877872c71cbb11fe9a13290d58858cf164902c8 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 8 Oct 2014 10:08:37 -0700 Subject: [PATCH 33/89] Use right require path --- static/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/index.js b/static/index.js index 5963863be..3304edb8c 100644 --- a/static/index.js +++ b/static/index.js @@ -18,7 +18,7 @@ window.onload = function() { require('coffee-script').register(); require(path.resolve(__dirname, '..', 'src', 'coffee-cache')).register(); - ModuleCache = require('./module-cache'); + ModuleCache = require(path.resolve(__dirname, '..', 'src', 'module-cache')); ModuleCache.add(loadSettings.resourcePath); ModuleCache.register(); From 472a48092dcb3919efcf020026acdf8d95637c4f Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 8 Oct 2014 10:09:02 -0700 Subject: [PATCH 34/89] Export cache for debugging purposes --- src/module-cache.coffee | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index 5df5f254c..de4257bfc 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -163,3 +163,5 @@ exports.add = (directoryPath, metadata) -> cache.folders[path.join(directoryPath, folderPath)] = entry.dependencies undefined + +exports.cache = cache From bdebe575b7d5faeafcc2b99f598904328bfa2fbd Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 8 Oct 2014 10:09:51 -0700 Subject: [PATCH 35/89] :lipstick: Use regular require paths --- static/index.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/static/index.js b/static/index.js index 3304edb8c..073d8d7d3 100644 --- a/static/index.js +++ b/static/index.js @@ -1,5 +1,4 @@ window.onload = function() { - var path = require('path'); var ipc = require('ipc'); try { // Skip "?loadSettings=". @@ -16,9 +15,9 @@ window.onload = function() { require('vm-compatibility-layer'); require('coffee-script').register(); - require(path.resolve(__dirname, '..', 'src', 'coffee-cache')).register(); + require('../src/coffee-cache')).register(); - ModuleCache = require(path.resolve(__dirname, '..', 'src', 'module-cache')); + ModuleCache = require('../src/module-cache'); ModuleCache.add(loadSettings.resourcePath); ModuleCache.register(); From 8a0755340ff24cb15cffb249cbd0073000a80474 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 8 Oct 2014 10:11:51 -0700 Subject: [PATCH 36/89] Remove extra ) --- static/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/index.js b/static/index.js index 073d8d7d3..ff9d19809 100644 --- a/static/index.js +++ b/static/index.js @@ -15,7 +15,7 @@ window.onload = function() { require('vm-compatibility-layer'); require('coffee-script').register(); - require('../src/coffee-cache')).register(); + require('../src/coffee-cache').register(); ModuleCache = require('../src/module-cache'); ModuleCache.add(loadSettings.resourcePath); From 9bd6891ac2d777e767ef958de4657b88d59806c6 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 8 Oct 2014 10:24:24 -0700 Subject: [PATCH 37/89] Use realpath so path.relative works right --- src/module-cache.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index de4257bfc..fafe14587 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -120,6 +120,7 @@ if cache.debug exports exports.create = (modulePath) -> + modulePath = fs.realpathSync(modulePath) metadataPath = path.join(modulePath, 'package.json') metadata = JSON.parse(fs.readFileSync(metadataPath)) From 65a1fafaf7826362ece0a77316021ae18dad9b39 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 8 Oct 2014 10:57:36 -0700 Subject: [PATCH 38/89] Ensure CoffeeScript is registered when caching This ensures folders with .coffee files are includes in the folders array --- src/module-cache.coffee | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index fafe14587..965aec4ee 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -3,6 +3,11 @@ path = require 'path' fs = require 'fs-plus' semver = require 'semver' +# Make sure CoffeeScript is required when this file is required directly +# by apm +unless require.extensions['.coffee'] + require('coffee-script').register() + nativeModules = process.binding('natives') cache = From 827a8ba107c17c484dfbf773f02d3b6c1d4b80bf Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 8 Oct 2014 10:57:53 -0700 Subject: [PATCH 39/89] First dependency version added wins --- src/module-cache.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index 965aec4ee..7d320a688 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -162,7 +162,7 @@ exports.add = (directoryPath, metadata) -> cacheToAdd = metadata?._atomModuleCache for dependency in cacheToAdd?.dependencies ? [] cache.dependencies[dependency.name] ?= {} - cache.dependencies[dependency.name][dependency.version] = path.join(directoryPath, dependency.path) + cache.dependencies[dependency.name][dependency.version] ?= path.join(directoryPath, dependency.path) for entry in cacheToAdd?.folders ? [] for folderPath in entry.paths From d9c758b9407ed9f3981f86d9360a39eb44d846b3 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 8 Oct 2014 13:13:39 -0700 Subject: [PATCH 40/89] Remove no main module logging --- src/module-cache.coffee | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index 7d320a688..fe02d1d2f 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -29,8 +29,6 @@ loadDependencies = (modulePath, rootPath, rootMetadata, moduleCache) -> if childMetadata?.version try mainPath = require.resolve(childPath) - catch error - console.log "Skipping #{childPath}, no main module" if mainPath moduleCache.dependencies.push From 440866d79ec7ea84a3337653ed570eacfa3c59ae Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 8 Oct 2014 13:13:54 -0700 Subject: [PATCH 41/89] Remove invalid range logging --- src/module-cache.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index fe02d1d2f..031258de8 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -51,7 +51,6 @@ loadFolderCompatibility = (modulePath, rootPath, rootMetadata, moduleCache) -> new semver.Range(version) catch error delete dependencies[name] - console.log "Ignoring invalid range: #{name} #{version}" onDirectory = (childPath) -> path.basename(childPath) isnt 'node_modules' From 7926531330e7750b45e7d00367bc4b31df28ce8f Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 8 Oct 2014 13:43:14 -0700 Subject: [PATCH 42/89] Whitelist folders path from core There are several folders bundled in the app that aren't needed in the require cache list so it is simpler to opt-in the folders that should be part of the cache. --- build/tasks/generate-module-cache-task.coffee | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/build/tasks/generate-module-cache-task.coffee b/build/tasks/generate-module-cache-task.coffee index 384d01f58..5c54401ef 100644 --- a/build/tasks/generate-module-cache-task.coffee +++ b/build/tasks/generate-module-cache-task.coffee @@ -11,3 +11,19 @@ module.exports = (grunt) -> ModuleCache.create(path.join(appDir, 'node_modules', packageName)) ModuleCache.create(appDir) + + metadata = grunt.file.readJSON(path.join(appDir, 'package.json')) + + metadata._atomModuleCache.folders.forEach (folder) -> + if '' in folder.paths + folder.paths = [ + '' + 'exports' + 'spec' + 'src' + 'src/browser' + 'static' + 'vendor' + ] + + grunt.file.write(path.join(appDir, 'package.json'), JSON.stringify(metadata, null, 2)) From 171411823f6f43dfbb2f17772ed465cee37065ee Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 8 Oct 2014 14:15:24 -0700 Subject: [PATCH 43/89] :racehorse: Resolve uncached core dependencies Trust modules under the resource path to be there without stat-ing and verifying. --- src/module-cache.coffee | 9 ++++++--- static/index.js | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index 031258de8..be1d3e8dd 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -16,6 +16,7 @@ cache = folders: {} ranges: {} registered: false + resourcePath: null loadDependencies = (modulePath, rootPath, rootMetadata, moduleCache) -> for childPath in fs.listSync(path.join(modulePath, 'node_modules')) @@ -99,8 +100,8 @@ getCachedModulePath = (relativePath, parentModule) -> return unless candidates? for version, resolvedPath of candidates - if Module._cache.hasOwnProperty(resolvedPath) and satisfies(version, range) - return resolvedPath + if Module._cache.hasOwnProperty(resolvedPath) or resolvedPath.indexOf(cache.resourcePath) is 0 + return resolvedPath if satisfies(version, range) undefined @@ -138,14 +139,16 @@ exports.create = (modulePath) -> fs.writeFileSync(metadataPath, JSON.stringify(metadata, null, 2)) undefined -exports.register = -> +exports.register = (resourcePath) -> return if cache.registered originalResolveFilename = Module._resolveFilename Module._resolveFilename = (relativePath, parentModule) -> resolvedPath = getCachedModulePath(relativePath, parentModule) resolvedPath ? originalResolveFilename(relativePath, parentModule) + cache.registered = true + cache.resourcePath = resourcePath undefined diff --git a/static/index.js b/static/index.js index ff9d19809..839ad7850 100644 --- a/static/index.js +++ b/static/index.js @@ -18,8 +18,8 @@ window.onload = function() { require('../src/coffee-cache').register(); ModuleCache = require('../src/module-cache'); + ModuleCache.register(loadSettings.resourcePath); ModuleCache.add(loadSettings.resourcePath); - ModuleCache.register(); require(loadSettings.bootstrapScript); ipc.sendChannel('window-command', 'window:loaded') From bdc0341eb3f8e092b7f7a9b737d8b9cf259d2af5 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 8 Oct 2014 14:17:53 -0700 Subject: [PATCH 44/89] undefined -> return --- src/module-cache.coffee | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index be1d3e8dd..5670dee5e 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -39,7 +39,7 @@ loadDependencies = (modulePath, rootPath, rootMetadata, moduleCache) -> loadDependencies(childPath, rootPath, rootMetadata, moduleCache) - undefined + return loadFolderCompatibility = (modulePath, rootPath, rootMetadata, moduleCache) -> metadataPath = path.join(modulePath, 'package.json') @@ -74,7 +74,7 @@ loadFolderCompatibility = (modulePath, rootPath, rootMetadata, moduleCache) -> loadFolderCompatibility(childPath, rootPath, rootMetadata, moduleCache) - undefined + return satisfies = (version, rawRange) -> unless parsedRange = cache.ranges[rawRange] @@ -103,7 +103,7 @@ getCachedModulePath = (relativePath, parentModule) -> if Module._cache.hasOwnProperty(resolvedPath) or resolvedPath.indexOf(cache.resourcePath) is 0 return resolvedPath if satisfies(version, range) - undefined + return if cache.debug cache.loadCount = 0 @@ -137,7 +137,8 @@ exports.create = (modulePath) -> metadata._atomModuleCache = moduleCache fs.writeFileSync(metadataPath, JSON.stringify(metadata, null, 2)) - undefined + + return exports.register = (resourcePath) -> return if cache.registered @@ -150,7 +151,7 @@ exports.register = (resourcePath) -> cache.registered = true cache.resourcePath = resourcePath - undefined + return exports.add = (directoryPath, metadata) -> unless metadata? @@ -168,6 +169,6 @@ exports.add = (directoryPath, metadata) -> for folderPath in entry.paths cache.folders[path.join(directoryPath, folderPath)] = entry.dependencies - undefined + return exports.cache = cache From d1f3d7d51e41c39f474eea70af12ff5619130aaf Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 8 Oct 2014 14:17:57 -0700 Subject: [PATCH 45/89] Mention plain return --- CONTRIBUTING.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f4250463d..2a43aac18 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -62,6 +62,8 @@ For more information on how to work with Atom's official packages, see * Use `path.join()` to concatenate filenames. * Use `os.tmpdir()` rather than `/tmp` when you need to reference the temporary directory. +* Using a plain `return` when returning explicitly at the end of a function. + * Not `return null`, `return undefined`, `null`, or `undefined` ## Git Commit Messages From f0cffcbd84bc3cf4e2d7cb20c7f9bd723221cec7 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 8 Oct 2014 14:44:39 -0700 Subject: [PATCH 46/89] Add addPathToCache helper for apm to warm using --- src/coffee-cache.coffee | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/coffee-cache.coffee b/src/coffee-cache.coffee index 136350b60..30e598cf5 100644 --- a/src/coffee-cache.coffee +++ b/src/coffee-cache.coffee @@ -45,3 +45,11 @@ module.exports = writable: false value: requireCoffeeScript }) + addPathToCache: (filePath) -> + extension = path.extname(filePath) + if extension is '.coffee' + content = fs.readFileSync(filePath, 'utf8') + cachePath = getCachePath(coffee) + compileCoffeeScript(coffee, filePath, cachePath) + else if extension is '.cson' + CSON.readFileSync(filePath) From 086be13ac485e566635f6c592cce3c9710dcec0b Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 8 Oct 2014 18:58:40 -0700 Subject: [PATCH 47/89] Add Module._findPath debug timing and count --- src/module-cache.coffee | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index 5670dee5e..c39672532 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -13,6 +13,7 @@ nativeModules = process.binding('natives') cache = debug: false dependencies: {} + extensions: {} folders: {} ranges: {} registered: false @@ -106,6 +107,8 @@ getCachedModulePath = (relativePath, parentModule) -> return if cache.debug + cache.findPathCount = 0 + cache.findPathTime = 0 cache.loadCount = 0 cache.requireTime = 0 global.moduleCache = cache @@ -122,6 +125,15 @@ if cache.debug cache.requireTime += Date.now() - startTime exports + originalFindPath = Module._findPath + Module._findPath = (request, paths) -> + cacheKey = JSON.stringify({request, paths}); + cache.findPathCount++ unless Module._pathCache[cacheKey] + startTime = Date.now() + foundPath = originalFindPath.apply(global, arguments) + cache.findPathTime += Date.now() - startTime + foundPath + exports.create = (modulePath) -> modulePath = fs.realpathSync(modulePath) metadataPath = path.join(modulePath, 'package.json') From d7cb1550bf92729a7da8b436abb47dece414250e Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 8 Oct 2014 19:01:43 -0700 Subject: [PATCH 48/89] Remove semicolon --- src/module-cache.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index c39672532..77fc635d0 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -127,7 +127,7 @@ if cache.debug originalFindPath = Module._findPath Module._findPath = (request, paths) -> - cacheKey = JSON.stringify({request, paths}); + cacheKey = JSON.stringify({request, paths}) cache.findPathCount++ unless Module._pathCache[cacheKey] startTime = Date.now() foundPath = originalFindPath.apply(global, arguments) From 76187f176c1b5f2f06d1338c9bdbfe7f4dfa7466 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 9 Oct 2014 09:38:41 -0700 Subject: [PATCH 49/89] Add core cache of pre-resolved paths This reduces the number of calls to Module._findPath for relative paths since they can be resolved without stating --- build/tasks/generate-module-cache-task.coffee | 20 +++++++++++++++ src/module-cache.coffee | 25 +++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/build/tasks/generate-module-cache-task.coffee b/build/tasks/generate-module-cache-task.coffee index 5c54401ef..f1402083a 100644 --- a/build/tasks/generate-module-cache-task.coffee +++ b/build/tasks/generate-module-cache-task.coffee @@ -1,4 +1,5 @@ path = require 'path' +fs = require 'fs-plus' ModuleCache = require '../../src/module-cache' module.exports = (grunt) -> @@ -26,4 +27,23 @@ module.exports = (grunt) -> 'vendor' ] + validExtensions = ['.js', '.coffee', '.json', '.node'] + + extensions = {} + onFile = (filePath) -> + filePath = path.relative(appDir, filePath) + segments = filePath.split(path.sep) + return if segments.length > 1 and not (segments[0] in ['exports', 'node_modules', 'src', 'static', 'vendor']) + + extension = path.extname(filePath) + if extension in validExtensions + extensions[extension] ?= [] + extensions[extension].push(filePath) + + onDirectory = -> true + + files = fs.traverseTreeSync(appDir, onFile, onDirectory) + + metadata._atomModuleCache.extensions = extensions + grunt.file.write(path.join(appDir, 'package.json'), JSON.stringify(metadata, null, 2)) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index 77fc635d0..e3ef33672 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -83,6 +83,23 @@ satisfies = (version, rawRange) -> cache.ranges[rawRange] = parsedRange parsedRange.test(version) +resolveFilePath = (relativePath, parentModule) -> + return unless relativePath + return unless parentModule?.id + return if relativePath[relativePath.length - 1] is '/' + + resolvedPath = path.resolve(path.dirname(parentModule.id), relativePath) + if resolvedPath.indexOf(cache.resourcePath) is 0 + extension = path.extname(resolvedPath) + if extension + return resolvedPath if cache.extensions[extension]?.has(resolvedPath) + else + for extension, paths of cache.extensions + resolvedPathWithExtension = "#{resolvedPath}#{extension}" + return resolvedPathWithExtension if paths.has(resolvedPathWithExtension) + + return + getCachedModulePath = (relativePath, parentModule) -> return unless relativePath return unless parentModule?.id @@ -129,6 +146,7 @@ if cache.debug Module._findPath = (request, paths) -> cacheKey = JSON.stringify({request, paths}) cache.findPathCount++ unless Module._pathCache[cacheKey] + startTime = Date.now() foundPath = originalFindPath.apply(global, arguments) cache.findPathTime += Date.now() - startTime @@ -158,6 +176,7 @@ exports.register = (resourcePath) -> originalResolveFilename = Module._resolveFilename Module._resolveFilename = (relativePath, parentModule) -> resolvedPath = getCachedModulePath(relativePath, parentModule) + resolvedPath ?= resolveFilePath(relativePath, parentModule) resolvedPath ? originalResolveFilename(relativePath, parentModule) cache.registered = true @@ -181,6 +200,12 @@ exports.add = (directoryPath, metadata) -> for folderPath in entry.paths cache.folders[path.join(directoryPath, folderPath)] = entry.dependencies + if directoryPath is cache.resourcePath + for extension, paths of cacheToAdd?.extensions + cache.extensions[extension] ?= new Set() + for filePath in paths + cache.extensions[extension].add(path.join(directoryPath, filePath)) + return exports.cache = cache From f495db41e715b96db037eb1ee0efa6c8e74327df Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 9 Oct 2014 09:39:42 -0700 Subject: [PATCH 50/89] getCachedModulePath -> resolveModulePath --- src/module-cache.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index e3ef33672..d0f5afd83 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -100,7 +100,7 @@ resolveFilePath = (relativePath, parentModule) -> return -getCachedModulePath = (relativePath, parentModule) -> +resolveModulePath = (relativePath, parentModule) -> return unless relativePath return unless parentModule?.id @@ -175,7 +175,7 @@ exports.register = (resourcePath) -> originalResolveFilename = Module._resolveFilename Module._resolveFilename = (relativePath, parentModule) -> - resolvedPath = getCachedModulePath(relativePath, parentModule) + resolvedPath = resolveModulePath(relativePath, parentModule) resolvedPath ?= resolveFilePath(relativePath, parentModule) resolvedPath ? originalResolveFilename(relativePath, parentModule) From 41598af2b2ec5bb0c6d40a83a52d4adb88722098 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 9 Oct 2014 09:50:53 -0700 Subject: [PATCH 51/89] Add pre-resolved path to require('atom') --- src/module-cache.coffee | 10 +++++++++- static/index.js | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index d0f5afd83..1976626d9 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -12,6 +12,7 @@ nativeModules = process.binding('natives') cache = debug: false + atomExportsPath: null dependencies: {} extensions: {} folders: {} @@ -101,6 +102,8 @@ resolveFilePath = (relativePath, parentModule) -> return resolveModulePath = (relativePath, parentModule) -> + return cache.atomExportsPath if relativePath is 'atom' + return unless relativePath return unless parentModule?.id @@ -170,7 +173,7 @@ exports.create = (modulePath) -> return -exports.register = (resourcePath) -> +exports.register = ({resourcePath, devMode}={}) -> return if cache.registered originalResolveFilename = Module._resolveFilename @@ -182,6 +185,11 @@ exports.register = (resourcePath) -> cache.registered = true cache.resourcePath = resourcePath + if devMode + cache.atomExportsPath = path.join(resourcePath, 'exports', 'atom.coffee') + else + cache.atomExportsPath = path.join(resourcePath, 'exports', 'atom.js') + return exports.add = (directoryPath, metadata) -> diff --git a/static/index.js b/static/index.js index 839ad7850..544be45fb 100644 --- a/static/index.js +++ b/static/index.js @@ -18,7 +18,7 @@ window.onload = function() { require('../src/coffee-cache').register(); ModuleCache = require('../src/module-cache'); - ModuleCache.register(loadSettings.resourcePath); + ModuleCache.register(loadSettings); ModuleCache.add(loadSettings.resourcePath); require(loadSettings.bootstrapScript); From b0aea54544fa40d790d006049abb9d06849d215e Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 9 Oct 2014 11:08:45 -0700 Subject: [PATCH 52/89] Check cache before atom require short-circuit --- src/module-cache.coffee | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index 1976626d9..dd5a79939 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -102,8 +102,6 @@ resolveFilePath = (relativePath, parentModule) -> return resolveModulePath = (relativePath, parentModule) -> - return cache.atomExportsPath if relativePath is 'atom' - return unless relativePath return unless parentModule?.id @@ -115,7 +113,11 @@ resolveModulePath = (relativePath, parentModule) -> folderPath = path.dirname(parentModule.id) range = cache.folders[folderPath]?[relativePath] - return unless range? + unless range? + if relativePath is 'atom' + return cache.atomExportsPath + else + return candidates = cache.dependencies[relativePath] return unless candidates? From d7a8dfb209217198a895637a0f1434237e20661f Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 9 Oct 2014 12:06:55 -0700 Subject: [PATCH 53/89] Add Atom Shell builtins to cache --- src/module-cache.coffee | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index dd5a79939..1931154d4 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -12,7 +12,7 @@ nativeModules = process.binding('natives') cache = debug: false - atomExportsPath: null + builtins: {} dependencies: {} extensions: {} folders: {} @@ -114,8 +114,8 @@ resolveModulePath = (relativePath, parentModule) -> range = cache.folders[folderPath]?[relativePath] unless range? - if relativePath is 'atom' - return cache.atomExportsPath + if builtinPath = cache.builtins[relativePath] + return builtinPath else return @@ -128,6 +128,24 @@ resolveModulePath = (relativePath, parentModule) -> return +registerBuiltins = (devMode) -> + if devMode + cache.builtins.atom = path.join(cache.resourcePath, 'exports', 'atom.coffee') + else + cache.builtins.atom = path.join(cache.resourcePath, 'exports', 'atom.js') + + atomShellRoot = path.resolve(window.location.pathname, '..', '..', '..', 'atom') + + commonRoot = path.join(atomShellRoot, 'common', 'api', 'lib') + commonBuiltins = ['callbacks-registry', 'screen', 'shell'] + for builtin in commonBuiltins + cache.builtins[builtin] = path.join(commonRoot, "#{builtin}.js") + + rendererRoot = path.join(atomShellRoot, 'renderer', 'api', 'lib') + rendererBuiltins = ['ipc', 'remote'] + for builtin in rendererBuiltins + cache.builtins[builtin] = path.join(rendererRoot, "#{builtin}.js") + if cache.debug cache.findPathCount = 0 cache.findPathTime = 0 @@ -186,11 +204,7 @@ exports.register = ({resourcePath, devMode}={}) -> cache.registered = true cache.resourcePath = resourcePath - - if devMode - cache.atomExportsPath = path.join(resourcePath, 'exports', 'atom.coffee') - else - cache.atomExportsPath = path.join(resourcePath, 'exports', 'atom.js') + registerBuiltins(devMode) return From 3e3de50eb35ccde5275198b64bd20756145d1b52 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 9 Oct 2014 12:12:50 -0700 Subject: [PATCH 54/89] :lipstick: --- src/module-cache.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index 1931154d4..7e3624e18 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -11,8 +11,8 @@ unless require.extensions['.coffee'] nativeModules = process.binding('natives') cache = - debug: false builtins: {} + debug: false dependencies: {} extensions: {} folders: {} From 6e1bdbbed700270e4f15b3233ede102414bcc9b5 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 9 Oct 2014 13:31:50 -0700 Subject: [PATCH 55/89] Verify that file path is absolute or relative --- src/module-cache.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index 7e3624e18..527e1abb7 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -87,6 +87,7 @@ satisfies = (version, rawRange) -> resolveFilePath = (relativePath, parentModule) -> return unless relativePath return unless parentModule?.id + return unless relativePath[0] is '.' or fs.isAbsolute(relativePath) return if relativePath[relativePath.length - 1] is '/' resolvedPath = path.resolve(path.dirname(parentModule.id), relativePath) From 06ac206707bc79813c4e5b5dedd1b9b3381f9f60 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 9 Oct 2014 13:36:19 -0700 Subject: [PATCH 56/89] Add clipboard to cache --- src/module-cache.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index 527e1abb7..173451222 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -138,7 +138,7 @@ registerBuiltins = (devMode) -> atomShellRoot = path.resolve(window.location.pathname, '..', '..', '..', 'atom') commonRoot = path.join(atomShellRoot, 'common', 'api', 'lib') - commonBuiltins = ['callbacks-registry', 'screen', 'shell'] + commonBuiltins = ['callbacks-registry', 'clipboard', 'screen', 'shell'] for builtin in commonBuiltins cache.builtins[builtin] = path.join(commonRoot, "#{builtin}.js") From 934c0720d882387e801a95f5f276731cab75ee92 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 9 Oct 2014 13:44:35 -0700 Subject: [PATCH 57/89] Require ipc when needed --- static/index.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/static/index.js b/static/index.js index 544be45fb..588b126ea 100644 --- a/static/index.js +++ b/static/index.js @@ -1,5 +1,4 @@ window.onload = function() { - var ipc = require('ipc'); try { // Skip "?loadSettings=". var loadSettings = JSON.parse(decodeURIComponent(location.search.substr(14))); @@ -22,7 +21,7 @@ window.onload = function() { ModuleCache.add(loadSettings.resourcePath); require(loadSettings.bootstrapScript); - ipc.sendChannel('window-command', 'window:loaded') + require('ipc').sendChannel('window-command', 'window:loaded') } catch (error) { var currentWindow = require('remote').getCurrentWindow(); From b9d89cbf5d392747bcb9de965d04b4463e5cda97 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 9 Oct 2014 13:58:12 -0700 Subject: [PATCH 58/89] Inline valid extensions to check for --- src/module-cache.coffee | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index 173451222..f454ad2e0 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -3,11 +3,6 @@ path = require 'path' fs = require 'fs-plus' semver = require 'semver' -# Make sure CoffeeScript is required when this file is required directly -# by apm -unless require.extensions['.coffee'] - require('coffee-script').register() - nativeModules = process.binding('natives') cache = @@ -58,7 +53,7 @@ loadFolderCompatibility = (modulePath, rootPath, rootMetadata, moduleCache) -> onDirectory = (childPath) -> path.basename(childPath) isnt 'node_modules' - extensions = Object.keys(require.extensions) + extensions = ['.js', '.coffee', '.json', '.node'] paths = {} onFile = (childPath) -> if path.extname(childPath) in extensions From d745b9ef5f0a494bcdf4502aa6742ebebc166d05 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 9 Oct 2014 14:05:23 -0700 Subject: [PATCH 59/89] Register module cache as early as possible --- static/index.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/static/index.js b/static/index.js index 588b126ea..b1a38c601 100644 --- a/static/index.js +++ b/static/index.js @@ -3,6 +3,10 @@ window.onload = function() { // Skip "?loadSettings=". var loadSettings = JSON.parse(decodeURIComponent(location.search.substr(14))); + ModuleCache = require('../src/module-cache'); + ModuleCache.register(loadSettings); + ModuleCache.add(loadSettings.resourcePath); + // Start the crash reporter before anything else. require('crash-reporter').start({ productName: 'Atom', @@ -16,10 +20,6 @@ window.onload = function() { require('coffee-script').register(); require('../src/coffee-cache').register(); - ModuleCache = require('../src/module-cache'); - ModuleCache.register(loadSettings); - ModuleCache.add(loadSettings.resourcePath); - require(loadSettings.bootstrapScript); require('ipc').sendChannel('window-command', 'window:loaded') } From 67d430d1009fe0cb0d9dc041bc561a31ef367b5f Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 9 Oct 2014 14:05:54 -0700 Subject: [PATCH 60/89] Add crash-reporter to cache --- src/module-cache.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index f454ad2e0..39073a2a5 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -133,7 +133,7 @@ registerBuiltins = (devMode) -> atomShellRoot = path.resolve(window.location.pathname, '..', '..', '..', 'atom') commonRoot = path.join(atomShellRoot, 'common', 'api', 'lib') - commonBuiltins = ['callbacks-registry', 'clipboard', 'screen', 'shell'] + commonBuiltins = ['callbacks-registry', 'clipboard', 'crash-reporter', 'screen', 'shell'] for builtin in commonBuiltins cache.builtins[builtin] = path.join(commonRoot, "#{builtin}.js") From 7dffc58c5ba254e65b0062cb77dd933a7f807591 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 9 Oct 2014 14:21:38 -0700 Subject: [PATCH 61/89] Use Module's filename instead of id --- src/module-cache.coffee | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index 39073a2a5..ec7dc6369 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -81,11 +81,11 @@ satisfies = (version, rawRange) -> resolveFilePath = (relativePath, parentModule) -> return unless relativePath - return unless parentModule?.id + return unless parentModule?.filename return unless relativePath[0] is '.' or fs.isAbsolute(relativePath) return if relativePath[relativePath.length - 1] is '/' - resolvedPath = path.resolve(path.dirname(parentModule.id), relativePath) + resolvedPath = path.resolve(path.dirname(parentModule.filename), relativePath) if resolvedPath.indexOf(cache.resourcePath) is 0 extension = path.extname(resolvedPath) if extension @@ -99,14 +99,14 @@ resolveFilePath = (relativePath, parentModule) -> resolveModulePath = (relativePath, parentModule) -> return unless relativePath - return unless parentModule?.id + return unless parentModule?.filename return if nativeModules.hasOwnProperty(relativePath) return if relativePath[0] is '.' return if relativePath[relativePath.length - 1] is '/' return if fs.isAbsolute(relativePath) - folderPath = path.dirname(parentModule.id) + folderPath = path.dirname(parentModule.filename) range = cache.folders[folderPath]?[relativePath] unless range? From 40c5289e2bdba3de2e784de043ec8843430acb11 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 9 Oct 2014 14:39:16 -0700 Subject: [PATCH 62/89] Defer requires until the cache is populated --- src/module-cache.coffee | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index ec7dc6369..142395626 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -1,7 +1,8 @@ Module = require 'module' path = require 'path' -fs = require 'fs-plus' -semver = require 'semver' + +fs = null # Defer so the cache is used +semver = null # Defer so the cache is used nativeModules = process.binding('natives') @@ -15,6 +16,10 @@ cache = registered: false resourcePath: null +requireDependencies = -> + fs ?= require 'fs-plus' + semver ?= require 'semver' + loadDependencies = (modulePath, rootPath, rootMetadata, moduleCache) -> for childPath in fs.listSync(path.join(modulePath, 'node_modules')) continue if path.basename(childPath) is '.bin' @@ -172,6 +177,8 @@ if cache.debug foundPath exports.create = (modulePath) -> + requireDependencies() + modulePath = fs.realpathSync(modulePath) metadataPath = path.join(modulePath, 'package.json') metadata = JSON.parse(fs.readFileSync(metadataPath)) @@ -201,6 +208,7 @@ exports.register = ({resourcePath, devMode}={}) -> cache.registered = true cache.resourcePath = resourcePath registerBuiltins(devMode) + requireDependencies() return From a6866656b75f69eabcf8cdb97579d0e3a0b048e2 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 9 Oct 2014 15:23:17 -0700 Subject: [PATCH 63/89] Inline isAbsolute method This allows fs-plus to be required through the cache --- src/module-cache.coffee | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index 142395626..a9ea00ddd 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -20,6 +20,15 @@ requireDependencies = -> fs ?= require 'fs-plus' semver ?= require 'semver' +# isAbsolute is inlined from fs-plus so that fs-plust itself can be required +# from this cache. +if process.platform is 'win32' + isAbsolute = (pathToCheck) -> + pathToCheck and (pathToCheck[1] is ':' or (pathToCheck[0] is '\\' and pathToCheck[1] is '\\')) +else + isAbsolute = (pathToCheck) -> + pathToCheck and pathToCheck[0] is '/' + loadDependencies = (modulePath, rootPath, rootMetadata, moduleCache) -> for childPath in fs.listSync(path.join(modulePath, 'node_modules')) continue if path.basename(childPath) is '.bin' @@ -87,7 +96,7 @@ satisfies = (version, rawRange) -> resolveFilePath = (relativePath, parentModule) -> return unless relativePath return unless parentModule?.filename - return unless relativePath[0] is '.' or fs.isAbsolute(relativePath) + return unless relativePath[0] is '.' or isAbsolute(relativePath) return if relativePath[relativePath.length - 1] is '/' resolvedPath = path.resolve(path.dirname(parentModule.filename), relativePath) @@ -109,7 +118,7 @@ resolveModulePath = (relativePath, parentModule) -> return if nativeModules.hasOwnProperty(relativePath) return if relativePath[0] is '.' return if relativePath[relativePath.length - 1] is '/' - return if fs.isAbsolute(relativePath) + return if isAbsolute(relativePath) folderPath = path.dirname(parentModule.filename) From db627f5cdea5b0b52f989fd93cf3f4da2a0777ca Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 9 Oct 2014 15:24:04 -0700 Subject: [PATCH 64/89] :racehorse: Join paths manually path.join calls path.normalize and with the number of paths being pushed through the cache it is faster to require them manually since they are already normalized --- src/module-cache.coffee | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index a9ea00ddd..9238bdcde 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -222,26 +222,29 @@ exports.register = ({resourcePath, devMode}={}) -> return exports.add = (directoryPath, metadata) -> + # path.join isn't used in this function for speed since path.join calls + # path.normalize and all the paths are already normalized here. + unless metadata? try - metadata = require(path.join(directoryPath, 'package.json')) + metadata = require("#{directoryPath}#{path.sep}package.json") catch error return cacheToAdd = metadata?._atomModuleCache for dependency in cacheToAdd?.dependencies ? [] cache.dependencies[dependency.name] ?= {} - cache.dependencies[dependency.name][dependency.version] ?= path.join(directoryPath, dependency.path) + cache.dependencies[dependency.name][dependency.version] ?= "#{directoryPath}#{path.sep}#{dependency.path}" for entry in cacheToAdd?.folders ? [] for folderPath in entry.paths - cache.folders[path.join(directoryPath, folderPath)] = entry.dependencies + cache.folders["#{directoryPath}#{path.sep}#{folderPath}"] = entry.dependencies if directoryPath is cache.resourcePath for extension, paths of cacheToAdd?.extensions cache.extensions[extension] ?= new Set() for filePath in paths - cache.extensions[extension].add(path.join(directoryPath, filePath)) + cache.extensions[extension].add("#{directoryPath}#{path.sep}#{filePath}") return From 948f96dd6f99b0b84f428b696e6c3bc032f12228 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 9 Oct 2014 15:35:35 -0700 Subject: [PATCH 65/89] Only load fs-plus when creating a cache --- src/module-cache.coffee | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index 9238bdcde..2805fc355 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -1,8 +1,6 @@ Module = require 'module' path = require 'path' - -fs = null # Defer so the cache is used -semver = null # Defer so the cache is used +semver = require 'semver' nativeModules = process.binding('natives') @@ -16,10 +14,6 @@ cache = registered: false resourcePath: null -requireDependencies = -> - fs ?= require 'fs-plus' - semver ?= require 'semver' - # isAbsolute is inlined from fs-plus so that fs-plust itself can be required # from this cache. if process.platform is 'win32' @@ -30,6 +24,8 @@ else pathToCheck and pathToCheck[0] is '/' loadDependencies = (modulePath, rootPath, rootMetadata, moduleCache) -> + fs = require 'fs-plus' + for childPath in fs.listSync(path.join(modulePath, 'node_modules')) continue if path.basename(childPath) is '.bin' continue if rootPath is modulePath and rootMetadata.packageDependencies?.hasOwnProperty(path.basename(childPath)) @@ -53,6 +49,8 @@ loadDependencies = (modulePath, rootPath, rootMetadata, moduleCache) -> return loadFolderCompatibility = (modulePath, rootPath, rootMetadata, moduleCache) -> + fs = require 'fs-plus' + metadataPath = path.join(modulePath, 'package.json') return unless fs.isFileSync(metadataPath) @@ -186,7 +184,7 @@ if cache.debug foundPath exports.create = (modulePath) -> - requireDependencies() + fs = require 'fs-plus' modulePath = fs.realpathSync(modulePath) metadataPath = path.join(modulePath, 'package.json') From f4ddc05b9c021a4cf09cfe068175b15a78dfa8e2 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 9 Oct 2014 15:42:06 -0700 Subject: [PATCH 66/89] Remove call to removed function --- src/module-cache.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index 2805fc355..dc62fcae1 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -215,7 +215,6 @@ exports.register = ({resourcePath, devMode}={}) -> cache.registered = true cache.resourcePath = resourcePath registerBuiltins(devMode) - requireDependencies() return From 105fc302ea70da484de73465c315335a36d0effc Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 9 Oct 2014 15:54:05 -0700 Subject: [PATCH 67/89] Upgrade to text-buffer@3.2.9 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fed1bd296..abdfb6611 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ "serializable": "^1", "space-pen": "3.8.0", "temp": "0.7.0", - "text-buffer": "^3.2.8", + "text-buffer": "^3.2.9", "theorist": "^1.0.2", "underscore-plus": "^1.5.1", "vm-compatibility-layer": "0.1.0" From 0cfd37acd009be841a70595d181c1124c7b7406d Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 9 Oct 2014 16:43:43 -0700 Subject: [PATCH 68/89] Special case reactionary in cache --- build/tasks/generate-module-cache-task.coffee | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/build/tasks/generate-module-cache-task.coffee b/build/tasks/generate-module-cache-task.coffee index f1402083a..bb4475479 100644 --- a/build/tasks/generate-module-cache-task.coffee +++ b/build/tasks/generate-module-cache-task.coffee @@ -27,6 +27,15 @@ module.exports = (grunt) -> 'vendor' ] + # Reactionary does not have an explicit react dependency + metadata._atomModuleCache.folders.push + paths: [ + 'node_modules/reactionary-atom-fork/lib' + ] + dependencies: { + 'react-atom-fork': metadata.dependencies['react-atom-fork'] + } + validExtensions = ['.js', '.coffee', '.json', '.node'] extensions = {} From dfd7bcae7fbfdaf27f2e0b8ceb9b383c20a5b903 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 9 Oct 2014 16:56:52 -0700 Subject: [PATCH 69/89] Use process.resourcesPath to find Atom shell root --- src/module-cache.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index dc62fcae1..80d2b55da 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -142,7 +142,7 @@ registerBuiltins = (devMode) -> else cache.builtins.atom = path.join(cache.resourcePath, 'exports', 'atom.js') - atomShellRoot = path.resolve(window.location.pathname, '..', '..', '..', 'atom') + atomShellRoot = path.join(process.resourcesPath, 'atom') commonRoot = path.join(atomShellRoot, 'common', 'api', 'lib') commonBuiltins = ['callbacks-registry', 'clipboard', 'crash-reporter', 'screen', 'shell'] From 289f17b119386fbb93589ce22a9452ee7fcf3720 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 9 Oct 2014 16:57:08 -0700 Subject: [PATCH 70/89] Require coffee before module cache in dev mode --- static/index.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/static/index.js b/static/index.js index b1a38c601..e82d0978a 100644 --- a/static/index.js +++ b/static/index.js @@ -3,6 +3,11 @@ window.onload = function() { // Skip "?loadSettings=". var loadSettings = JSON.parse(decodeURIComponent(location.search.substr(14))); + // Require before the module cache in dev mode + if (loadSettings.devMode) { + require('coffee-script').register(); + } + ModuleCache = require('../src/module-cache'); ModuleCache.register(loadSettings); ModuleCache.add(loadSettings.resourcePath); @@ -17,7 +22,11 @@ window.onload = function() { }); require('vm-compatibility-layer'); - require('coffee-script').register(); + + if (!loadSettings.devMode) { + require('coffee-script').register(); + } + require('../src/coffee-cache').register(); require(loadSettings.bootstrapScript); From 4c17c9eae6d24a5a4cff095026639aca53506bc3 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 9 Oct 2014 17:07:52 -0700 Subject: [PATCH 71/89] fs-plust -> fs-plus --- src/module-cache.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index 80d2b55da..5e5e3fd1d 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -14,7 +14,7 @@ cache = registered: false resourcePath: null -# isAbsolute is inlined from fs-plus so that fs-plust itself can be required +# isAbsolute is inlined from fs-plus so that fs-plus itself can be required # from this cache. if process.platform is 'win32' isAbsolute = (pathToCheck) -> From bb92b8697d05401ed2a7fc8c6b4be30e5dfb22ca Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 9 Oct 2014 17:17:12 -0700 Subject: [PATCH 72/89] Add isCorePath helper --- src/module-cache.coffee | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index 5e5e3fd1d..d5f08e078 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -13,6 +13,7 @@ cache = ranges: {} registered: false resourcePath: null + resourcePathWithTrailingSlash: null # isAbsolute is inlined from fs-plus so that fs-plus itself can be required # from this cache. @@ -23,6 +24,9 @@ else isAbsolute = (pathToCheck) -> pathToCheck and pathToCheck[0] is '/' +isCorePath = (pathToCheck) -> + pathToCheck.indexOf(cache.resourcePathWithTrailingSlash) is 0 + loadDependencies = (modulePath, rootPath, rootMetadata, moduleCache) -> fs = require 'fs-plus' @@ -98,14 +102,15 @@ resolveFilePath = (relativePath, parentModule) -> return if relativePath[relativePath.length - 1] is '/' resolvedPath = path.resolve(path.dirname(parentModule.filename), relativePath) - if resolvedPath.indexOf(cache.resourcePath) is 0 - extension = path.extname(resolvedPath) - if extension - return resolvedPath if cache.extensions[extension]?.has(resolvedPath) - else - for extension, paths of cache.extensions - resolvedPathWithExtension = "#{resolvedPath}#{extension}" - return resolvedPathWithExtension if paths.has(resolvedPathWithExtension) + return unless isCorePath(resolvedPath) + + extension = path.extname(resolvedPath) + if extension + return resolvedPath if cache.extensions[extension]?.has(resolvedPath) + else + for extension, paths of cache.extensions + resolvedPathWithExtension = "#{resolvedPath}#{extension}" + return resolvedPathWithExtension if paths.has(resolvedPathWithExtension) return @@ -131,7 +136,7 @@ resolveModulePath = (relativePath, parentModule) -> return unless candidates? for version, resolvedPath of candidates - if Module._cache.hasOwnProperty(resolvedPath) or resolvedPath.indexOf(cache.resourcePath) is 0 + if Module._cache.hasOwnProperty(resolvedPath) or isCorePath(resolvedPath) return resolvedPath if satisfies(version, range) return @@ -214,6 +219,7 @@ exports.register = ({resourcePath, devMode}={}) -> cache.registered = true cache.resourcePath = resourcePath + cache.resourcePathWithTrailingSlash = "#{resourcePath}#{path.sep}" registerBuiltins(devMode) return From f0b922f643e56092d37df8df8f308012fa674e26 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 9 Oct 2014 18:16:44 -0700 Subject: [PATCH 73/89] Use String::startsWith --- src/module-cache.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index d5f08e078..256a9d8b6 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -25,7 +25,7 @@ else pathToCheck and pathToCheck[0] is '/' isCorePath = (pathToCheck) -> - pathToCheck.indexOf(cache.resourcePathWithTrailingSlash) is 0 + pathToCheck.startsWith(cache.resourcePathWithTrailingSlash) loadDependencies = (modulePath, rootPath, rootMetadata, moduleCache) -> fs = require 'fs-plus' From 9d1db0f3de24057b32f8a8de674b4c21be51b012 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 9 Oct 2014 18:17:26 -0700 Subject: [PATCH 74/89] Remove unneeded trailing slash check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Package names don’t have these anyway and file paths won’t be ending with them. --- src/module-cache.coffee | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index 256a9d8b6..bbb3ec18b 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -99,7 +99,6 @@ resolveFilePath = (relativePath, parentModule) -> return unless relativePath return unless parentModule?.filename return unless relativePath[0] is '.' or isAbsolute(relativePath) - return if relativePath[relativePath.length - 1] is '/' resolvedPath = path.resolve(path.dirname(parentModule.filename), relativePath) return unless isCorePath(resolvedPath) @@ -120,7 +119,6 @@ resolveModulePath = (relativePath, parentModule) -> return if nativeModules.hasOwnProperty(relativePath) return if relativePath[0] is '.' - return if relativePath[relativePath.length - 1] is '/' return if isAbsolute(relativePath) folderPath = path.dirname(parentModule.filename) From 42040f8a9da55bc21c2191a142eec2cbb4a68980 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 9 Oct 2014 18:26:24 -0700 Subject: [PATCH 75/89] Return early when no candidates exist --- src/module-cache.coffee | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index bbb3ec18b..666531d4b 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -121,6 +121,9 @@ resolveModulePath = (relativePath, parentModule) -> return if relativePath[0] is '.' return if isAbsolute(relativePath) + candidates = cache.dependencies[relativePath] + return unless candidates? + folderPath = path.dirname(parentModule.filename) range = cache.folders[folderPath]?[relativePath] @@ -130,9 +133,6 @@ resolveModulePath = (relativePath, parentModule) -> else return - candidates = cache.dependencies[relativePath] - return unless candidates? - for version, resolvedPath of candidates if Module._cache.hasOwnProperty(resolvedPath) or isCorePath(resolvedPath) return resolvedPath if satisfies(version, range) From 6a6c7b1852e54c3d126aa248d1c272090e0458e3 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 13 Oct 2014 11:17:26 -0400 Subject: [PATCH 76/89] Calculate load time in index.js Do it previously in window-bootstrap caused several things to not be included such as requiring coffee script and atom shell modules. Now it is a much more accurate representation of on load time. --- src/window-bootstrap.coffee | 4 ---- static/index.js | 9 ++++++++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/window-bootstrap.coffee b/src/window-bootstrap.coffee index fa7f9d354..886ba26dc 100644 --- a/src/window-bootstrap.coffee +++ b/src/window-bootstrap.coffee @@ -1,14 +1,10 @@ # Like sands through the hourglass, so are the days of our lives. -startTime = Date.now() - require './window' Atom = require './atom' window.atom = Atom.loadOrCreate('editor') atom.initialize() atom.startEditorWindow() -window.atom.loadTime = Date.now() - startTime -console.log "Window load time: #{atom.getWindowLoadTime()}ms" # Workaround for focus getting cleared upon window creation windowFocused = -> diff --git a/static/index.js b/static/index.js index e82d0978a..f21a346c8 100644 --- a/static/index.js +++ b/static/index.js @@ -1,5 +1,7 @@ window.onload = function() { try { + var startTime = Date.now(); + // Skip "?loadSettings=". var loadSettings = JSON.parse(decodeURIComponent(location.search.substr(14))); @@ -30,7 +32,12 @@ window.onload = function() { require('../src/coffee-cache').register(); require(loadSettings.bootstrapScript); - require('ipc').sendChannel('window-command', 'window:loaded') + require('ipc').sendChannel('window-command', 'window:loaded'); + + if (global.atom) { + global.atom.loadTime = Date.now() - startTime; + console.log('Window load time: ' + global.atom.getWindowLoadTime() + 'ms'); + } } catch (error) { var currentWindow = require('remote').getCurrentWindow(); From a0ae52601710cc410d2fdd21079711a118eeb0b1 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 13 Oct 2014 16:21:40 -0400 Subject: [PATCH 77/89] Check candidates after ranges MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This way builtins are checked for correctly when the range isn’t found --- src/module-cache.coffee | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index 666531d4b..bbb3ec18b 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -121,9 +121,6 @@ resolveModulePath = (relativePath, parentModule) -> return if relativePath[0] is '.' return if isAbsolute(relativePath) - candidates = cache.dependencies[relativePath] - return unless candidates? - folderPath = path.dirname(parentModule.filename) range = cache.folders[folderPath]?[relativePath] @@ -133,6 +130,9 @@ resolveModulePath = (relativePath, parentModule) -> else return + candidates = cache.dependencies[relativePath] + return unless candidates? + for version, resolvedPath of candidates if Module._cache.hasOwnProperty(resolvedPath) or isCorePath(resolvedPath) return resolvedPath if satisfies(version, range) From 8334bba4848c712b7e57dff2e150337cdbb27374 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 13 Oct 2014 16:22:03 -0400 Subject: [PATCH 78/89] Add initial ModuleCache spec --- spec/module-cache-spec.coffee | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 spec/module-cache-spec.coffee diff --git a/spec/module-cache-spec.coffee b/spec/module-cache-spec.coffee new file mode 100644 index 000000000..2f0b85eac --- /dev/null +++ b/spec/module-cache-spec.coffee @@ -0,0 +1,10 @@ +path = require 'path' +Module = require 'module' + +describe 'ModuleCache', -> + beforeEach -> + spyOn(Module, '_findPath').andCallThrough() + + it 'resolves atom shell module paths without hitting the filesystem', -> + require.resolve('shell') + expect(Module._findPath.callCount).toBe 0 From 826681b6c299b7120d858dfe4534eba177365707 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 13 Oct 2014 16:25:58 -0400 Subject: [PATCH 79/89] Add relative path cache spec --- spec/fixtures/module-cache/file.json | 3 +++ spec/module-cache-spec.coffee | 12 ++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 spec/fixtures/module-cache/file.json diff --git a/spec/fixtures/module-cache/file.json b/spec/fixtures/module-cache/file.json new file mode 100644 index 000000000..c8c4105eb --- /dev/null +++ b/spec/fixtures/module-cache/file.json @@ -0,0 +1,3 @@ +{ + "foo": "bar" +} diff --git a/spec/module-cache-spec.coffee b/spec/module-cache-spec.coffee index 2f0b85eac..5b3805640 100644 --- a/spec/module-cache-spec.coffee +++ b/spec/module-cache-spec.coffee @@ -1,5 +1,6 @@ path = require 'path' Module = require 'module' +ModuleCache = require '../src/module-cache' describe 'ModuleCache', -> beforeEach -> @@ -8,3 +9,14 @@ describe 'ModuleCache', -> it 'resolves atom shell module paths without hitting the filesystem', -> require.resolve('shell') expect(Module._findPath.callCount).toBe 0 + + it 'resolves relative core paths without hitting the filesystem', -> + ModuleCache.add atom.getLoadSettings().resourcePath, { + _atomModuleCache: + extensions: + '.json': [ + path.join('spec', 'fixtures', 'module-cache', 'file.json') + ] + } + expect(require('./fixtures/module-cache/file.json').foo).toBe 'bar' + expect(Module._findPath.callCount).toBe 0 From 5052aaca955f1a7cffffebf0dafa742b654b54bc Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 13 Oct 2014 16:51:32 -0400 Subject: [PATCH 80/89] Don't leave empty paths with a trailing slash --- src/module-cache.coffee | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index bbb3ec18b..f1f3c2a54 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -239,7 +239,10 @@ exports.add = (directoryPath, metadata) -> for entry in cacheToAdd?.folders ? [] for folderPath in entry.paths - cache.folders["#{directoryPath}#{path.sep}#{folderPath}"] = entry.dependencies + if folderPath + cache.folders["#{directoryPath}#{path.sep}#{folderPath}"] = entry.dependencies + else + cache.folders["#{directoryPath}"] = entry.dependencies if directoryPath is cache.resourcePath for extension, paths of cacheToAdd?.extensions From fc44662ba3fab11aa373f4a6f991f7626d4c4b8d Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 13 Oct 2014 16:51:59 -0400 Subject: [PATCH 81/89] Add spec for resolving compatible module paths --- spec/module-cache-spec.coffee | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/spec/module-cache-spec.coffee b/spec/module-cache-spec.coffee index 5b3805640..b36c80afc 100644 --- a/spec/module-cache-spec.coffee +++ b/spec/module-cache-spec.coffee @@ -1,5 +1,7 @@ path = require 'path' Module = require 'module' +fs = require 'fs-plus' +temp = require 'temp' ModuleCache = require '../src/module-cache' describe 'ModuleCache', -> @@ -20,3 +22,34 @@ describe 'ModuleCache', -> } expect(require('./fixtures/module-cache/file.json').foo).toBe 'bar' expect(Module._findPath.callCount).toBe 0 + + it 'resolves module paths to a compatible version provided by core', -> + packagePath = fs.realpathSync(temp.mkdirSync('atom-package')) + ModuleCache.add packagePath, { + _atomModuleCache: + folders: [{ + paths: [ + "" + ] + dependencies: + 'underscore-plus': '*' + }] + } + ModuleCache.add atom.getLoadSettings().resourcePath, { + _atomModuleCache: + dependencies: [{ + name: 'underscore-plus' + version: require('underscore-plus/package.json').version + path: path.join('node_modules', 'underscore-plus', 'lib', 'underscore-plus.js') + }] + } + + indexPath = path.join(packagePath, 'index.js') + fs.writeFileSync indexPath, """ + exports.load = function() {require('underscore-plus');}; + """ + + packageMain = require(indexPath) + Module._findPath.reset() + packageMain.load() + expect(Module._findPath.callCount).toBe 0 From 7f01a163e50f417377f0dea1dfdd4374a31256ea Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 13 Oct 2014 16:52:23 -0400 Subject: [PATCH 82/89] :lipstick: --- spec/module-cache-spec.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/module-cache-spec.coffee b/spec/module-cache-spec.coffee index b36c80afc..1315404a1 100644 --- a/spec/module-cache-spec.coffee +++ b/spec/module-cache-spec.coffee @@ -46,7 +46,7 @@ describe 'ModuleCache', -> indexPath = path.join(packagePath, 'index.js') fs.writeFileSync indexPath, """ - exports.load = function() {require('underscore-plus');}; + exports.load = function() { require('underscore-plus'); }; """ packageMain = require(indexPath) From 88f0183352fb92fd0897800d05ae18e64c4e0c03 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 13 Oct 2014 16:55:03 -0400 Subject: [PATCH 83/89] Remove unneeded quotes --- src/module-cache.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index f1f3c2a54..78413f18e 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -242,7 +242,7 @@ exports.add = (directoryPath, metadata) -> if folderPath cache.folders["#{directoryPath}#{path.sep}#{folderPath}"] = entry.dependencies else - cache.folders["#{directoryPath}"] = entry.dependencies + cache.folders[directoryPath] = entry.dependencies if directoryPath is cache.resourcePath for extension, paths of cacheToAdd?.extensions From 739a62955240fff186dc587f0666172a669dbad1 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 13 Oct 2014 16:56:50 -0400 Subject: [PATCH 84/89] :lipstick: --- spec/module-cache-spec.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/module-cache-spec.coffee b/spec/module-cache-spec.coffee index 1315404a1..1314cef5f 100644 --- a/spec/module-cache-spec.coffee +++ b/spec/module-cache-spec.coffee @@ -29,7 +29,7 @@ describe 'ModuleCache', -> _atomModuleCache: folders: [{ paths: [ - "" + '' ] dependencies: 'underscore-plus': '*' From d2c7a2caca705078b2eafc637ea958b51f870110 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 13 Oct 2014 16:58:59 -0400 Subject: [PATCH 85/89] Return early when cache to add is missing --- src/module-cache.coffee | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index 78413f18e..162852d52 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -233,11 +233,13 @@ exports.add = (directoryPath, metadata) -> return cacheToAdd = metadata?._atomModuleCache - for dependency in cacheToAdd?.dependencies ? [] + return unless cacheToAdd? + + for dependency in cacheToAdd.dependencies ? [] cache.dependencies[dependency.name] ?= {} cache.dependencies[dependency.name][dependency.version] ?= "#{directoryPath}#{path.sep}#{dependency.path}" - for entry in cacheToAdd?.folders ? [] + for entry in cacheToAdd.folders ? [] for folderPath in entry.paths if folderPath cache.folders["#{directoryPath}#{path.sep}#{folderPath}"] = entry.dependencies @@ -245,7 +247,7 @@ exports.add = (directoryPath, metadata) -> cache.folders[directoryPath] = entry.dependencies if directoryPath is cache.resourcePath - for extension, paths of cacheToAdd?.extensions + for extension, paths of cacheToAdd.extensions cache.extensions[extension] ?= new Set() for filePath in paths cache.extensions[extension].add("#{directoryPath}#{path.sep}#{filePath}") From e02af51a046a3450911382aadaf5b96cf9f363e3 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 13 Oct 2014 17:12:58 -0400 Subject: [PATCH 86/89] :racehorse: Extend range to memoize matched versions --- src/module-cache.coffee | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/module-cache.coffee b/src/module-cache.coffee index 162852d52..4e857158e 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -2,6 +2,19 @@ Module = require 'module' path = require 'path' semver = require 'semver' +# Extend semver.Range to memoize matched versions for speed +class Range extends semver.Range + constructor: -> + super + @matchedVersions = new Set() + + test: (version) -> + return true if @matchedVersions.has(version) + + matches = super + @matchedVersions.add(version) if matches + matches + nativeModules = process.binding('natives') cache = @@ -91,7 +104,7 @@ loadFolderCompatibility = (modulePath, rootPath, rootMetadata, moduleCache) -> satisfies = (version, rawRange) -> unless parsedRange = cache.ranges[rawRange] - parsedRange = new semver.Range(rawRange) + parsedRange = new Range(rawRange) cache.ranges[rawRange] = parsedRange parsedRange.test(version) From e09d7159bc4992dee8545186172d6121b564a797 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 13 Oct 2014 17:17:49 -0400 Subject: [PATCH 87/89] Add spec for no compatible module version available --- spec/module-cache-spec.coffee | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/spec/module-cache-spec.coffee b/spec/module-cache-spec.coffee index 1314cef5f..0b236fbdb 100644 --- a/spec/module-cache-spec.coffee +++ b/spec/module-cache-spec.coffee @@ -23,7 +23,7 @@ describe 'ModuleCache', -> expect(require('./fixtures/module-cache/file.json').foo).toBe 'bar' expect(Module._findPath.callCount).toBe 0 - it 'resolves module paths to a compatible version provided by core', -> + it 'resolves module paths when a compatible version is provided by core', -> packagePath = fs.realpathSync(temp.mkdirSync('atom-package')) ModuleCache.add packagePath, { _atomModuleCache: @@ -53,3 +53,34 @@ describe 'ModuleCache', -> Module._findPath.reset() packageMain.load() expect(Module._findPath.callCount).toBe 0 + + it 'does not resolve module paths when no compatible version is provided by core', -> + packagePath = fs.realpathSync(temp.mkdirSync('atom-package')) + ModuleCache.add packagePath, { + _atomModuleCache: + folders: [{ + paths: [ + '' + ] + dependencies: + 'underscore-plus': '0.0.1' + }] + } + ModuleCache.add atom.getLoadSettings().resourcePath, { + _atomModuleCache: + dependencies: [{ + name: 'underscore-plus' + version: require('underscore-plus/package.json').version + path: path.join('node_modules', 'underscore-plus', 'lib', 'underscore-plus.js') + }] + } + + indexPath = path.join(packagePath, 'index.js') + fs.writeFileSync indexPath, """ + exports.load = function() { require('underscore-plus'); }; + """ + + packageMain = require(indexPath) + Module._findPath.reset() + expect(-> packageMain.load()).toThrow() + expect(Module._findPath.callCount).toBe 1 From 677949d61c15af58349c5acec3b153539b2b8595 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 14 Oct 2014 17:47:08 -0700 Subject: [PATCH 88/89] Check that all builtins resolve without hitting fs --- spec/module-cache-spec.coffee | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/spec/module-cache-spec.coffee b/spec/module-cache-spec.coffee index 0b236fbdb..e75a1cf56 100644 --- a/spec/module-cache-spec.coffee +++ b/spec/module-cache-spec.coffee @@ -9,7 +9,12 @@ describe 'ModuleCache', -> spyOn(Module, '_findPath').andCallThrough() it 'resolves atom shell module paths without hitting the filesystem', -> - require.resolve('shell') + builtins = ModuleCache.cache.builtins + expect(Object.keys(builtins).length).toBeGreaterThan 0 + + for builtinName, builtinPath of builtins + expect(require.resolve(builtinName)).toBe builtinPath + expect(Module._findPath.callCount).toBe 0 it 'resolves relative core paths without hitting the filesystem', -> From 57fc3deaeda3f169e4d7fe4a2b41a9bfe07b31fb Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 15 Oct 2014 13:12:42 -0700 Subject: [PATCH 89/89] Assert that resolved atom shell module paths exist --- spec/module-cache-spec.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/module-cache-spec.coffee b/spec/module-cache-spec.coffee index e75a1cf56..5cf6bd2fd 100644 --- a/spec/module-cache-spec.coffee +++ b/spec/module-cache-spec.coffee @@ -14,6 +14,7 @@ describe 'ModuleCache', -> for builtinName, builtinPath of builtins expect(require.resolve(builtinName)).toBe builtinPath + expect(fs.isFileSync(require.resolve(builtinName))) expect(Module._findPath.callCount).toBe 0