ember-cli 4.0.0 → 4.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/ci.yml +4 -4
- package/CHANGELOG.md +42 -2
- package/blueprints/addon/additional-dev-dependencies.json +1 -1
- package/blueprints/addon/files/.github/workflows/ci.yml +0 -1
- package/blueprints/addon/files/.travis.yml +0 -1
- package/blueprints/addon/files/addon-config/ember-try.js +0 -13
- package/blueprints/app/files/config/environment.js +1 -1
- package/blueprints/app/files/package.json +6 -6
- package/docs/build/data.json +3 -3
- package/lib/models/host-info-cache.js +3 -5
- package/lib/models/per-bundle-addon-cache/index.js +2 -3
- package/lib/tasks/npm-task.js +1 -1
- package/lib/utilities/get-lang-arg.js +45 -45
- package/package.json +25 -25
- package/tests/helpers/mock-project.js +1 -1
- package/.github/ISSUE_TEMPLATE.md +0 -12
- package/.github/dependabot.yml +0 -15
- package/.github/workflows/coverage.yml +0 -31
- package/docs/analytics.md +0 -44
- package/docs/architecture.md +0 -316
- package/docs/assets/architecture/Ember-CLI architecture.png +0 -0
- package/docs/assets/architecture/Ember-CLI architecture.xml +0 -1
- package/docs/assets/architecture/README.md +0 -5
- package/docs/brocfile-transition.md +0 -46
- package/docs/build/api.js +0 -44
- package/docs/build/assets/css/external-small.png +0 -0
- package/docs/build/assets/css/logo.png +0 -0
- package/docs/build/assets/css/main.css +0 -555
- package/docs/build/assets/favicon.ico +0 -0
- package/docs/build/assets/img/spinner.gif +0 -0
- package/docs/build/assets/index.html +0 -10
- package/docs/build/assets/js/api-filter.js +0 -56
- package/docs/build/assets/js/api-list.js +0 -255
- package/docs/build/assets/js/api-search.js +0 -98
- package/docs/build/assets/js/apidocs.js +0 -376
- package/docs/build/assets/js/yui-prettify.js +0 -17
- package/docs/build/assets/vendor/prettify/CHANGES.html +0 -130
- package/docs/build/assets/vendor/prettify/COPYING +0 -202
- package/docs/build/assets/vendor/prettify/README.html +0 -203
- package/docs/build/assets/vendor/prettify/prettify-min.css +0 -1
- package/docs/build/assets/vendor/prettify/prettify-min.js +0 -1
- package/docs/build/classes/Addon.html +0 -4318
- package/docs/build/classes/AmdTransformAddon.html +0 -202
- package/docs/build/classes/Blueprint.html +0 -4796
- package/docs/build/classes/Builder.html +0 -611
- package/docs/build/classes/CLI.html +0 -810
- package/docs/build/classes/Command.html +0 -1655
- package/docs/build/classes/DefaultPackager.html +0 -202
- package/docs/build/classes/EmberAddon.html +0 -2207
- package/docs/build/classes/EmberApp.html +0 -2225
- package/docs/build/classes/HardwareInfo.html +0 -620
- package/docs/build/classes/HistorySupportAddon.html +0 -203
- package/docs/build/classes/Instrumentation.html +0 -695
- package/docs/build/classes/NodeModulesList.html +0 -460
- package/docs/build/classes/NpmTask.html +0 -333
- package/docs/build/classes/PackageInfo.html +0 -1390
- package/docs/build/classes/PackageInfoCache.html +0 -963
- package/docs/build/classes/PerBundleAddonCache {.html +0 -1010
- package/docs/build/classes/Project.html +0 -2083
- package/docs/build/classes/ServeFilesAddon.html +0 -260
- package/docs/build/classes/TestsServerAddon.html +0 -203
- package/docs/build/classes/WatcherAddon.html +0 -204
- package/docs/build/classes/WindowsSymlinkChecker.html +0 -1505
- package/docs/build/files/lib_broccoli_default-packager.js.html +0 -1426
- package/docs/build/files/lib_broccoli_ember-addon.js.html +0 -159
- package/docs/build/files/lib_broccoli_ember-app.js.html +0 -1913
- package/docs/build/files/lib_cli_cli.js.html +0 -417
- package/docs/build/files/lib_models_addon-info.js.html +0 -112
- package/docs/build/files/lib_models_addon.js.html +0 -1866
- package/docs/build/files/lib_models_blueprint.js.html +0 -1678
- package/docs/build/files/lib_models_builder.js.html +0 -417
- package/docs/build/files/lib_models_command.js.html +0 -804
- package/docs/build/files/lib_models_hardware-info.js.html +0 -479
- package/docs/build/files/lib_models_host-info-cache.js.html +0 -428
- package/docs/build/files/lib_models_installation-checker.js.html +0 -181
- package/docs/build/files/lib_models_instantiate-addons.js.html +0 -191
- package/docs/build/files/lib_models_instrumentation.js.html +0 -433
- package/docs/build/files/lib_models_package-info-cache_index.js.html +0 -793
- package/docs/build/files/lib_models_package-info-cache_node-modules-list.js.html +0 -208
- package/docs/build/files/lib_models_package-info-cache_package-info.js.html +0 -661
- package/docs/build/files/lib_models_per-bundle-addon-cache_addon-proxy.js.html +0 -252
- package/docs/build/files/lib_models_per-bundle-addon-cache_index.js.html +0 -485
- package/docs/build/files/lib_models_per-bundle-addon-cache_target-instance.js.html +0 -108
- package/docs/build/files/lib_models_project.js.html +0 -913
- package/docs/build/files/lib_models_task.js.html +0 -117
- package/docs/build/files/lib_tasks_build-watch.js.html +0 -157
- package/docs/build/files/lib_tasks_npm-task.js.html +0 -463
- package/docs/build/files/lib_tasks_serve.js.html +0 -207
- package/docs/build/files/lib_tasks_server_middleware_broccoli-serve-files_index.js.html +0 -127
- package/docs/build/files/lib_tasks_server_middleware_broccoli-watcher_index.js.html +0 -158
- package/docs/build/files/lib_tasks_server_middleware_history-support_index.js.html +0 -181
- package/docs/build/files/lib_tasks_server_middleware_tests-server_index.js.html +0 -171
- package/docs/build/files/lib_tasks_test-server.js.html +0 -167
- package/docs/build/files/lib_tasks_transforms_amd_index.js.html +0 -143
- package/docs/build/files/lib_utilities_ember-app-utils.js.html +0 -292
- package/docs/build/files/lib_utilities_insert-into-file.js.html +0 -219
- package/docs/build/files/lib_utilities_is-lazy-engine.js.html +0 -125
- package/docs/build/files/lib_utilities_is-yarn-project.js.html +0 -120
- package/docs/build/files/lib_utilities_valid-project-name.js.html +0 -142
- package/docs/build/files/lib_utilities_will-interrupt-process.js.html +0 -290
- package/docs/build/files/lib_utilities_windows-admin.js.html +0 -230
- package/docs/build/index.html +0 -125
- package/docs/build/modules/ember-cli.html +0 -152
- package/docs/build/modules/is-lazy-engine.html +0 -106
- package/docs/build-concurrency.md +0 -15
- package/docs/build-pipeline-debugging.md +0 -33
- package/docs/code-coverage.md +0 -14
- package/docs/error-propagation.md +0 -136
- package/docs/experiments.md +0 -53
- package/docs/node-support.md +0 -43
- package/docs/perf-guide.md +0 -250
- package/docs/project_version_preprocessor.js +0 -8
- package/docs/sourcemaps.md +0 -60
- package/docs/yuidoc.json +0 -13
|
@@ -1,793 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8">
|
|
5
|
-
<title>lib/models/package-info-cache/index.js - ember-cli</title>
|
|
6
|
-
<link rel="stylesheet" href="../assets/vendor/prettify/prettify-min.css">
|
|
7
|
-
<link rel="stylesheet" href="../assets/css/main.css" id="site_styles">
|
|
8
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/yui/3.18.0/yui/yui-min.js"></script>
|
|
9
|
-
</head>
|
|
10
|
-
<body class="yui3-skin-sam">
|
|
11
|
-
|
|
12
|
-
<div id="doc">
|
|
13
|
-
<div class="yui3-g">
|
|
14
|
-
<div id="sidebar" class="yui3-u">
|
|
15
|
-
<div class="logo">
|
|
16
|
-
<a href="../index.html">
|
|
17
|
-
<img src="https://ember-cli.com/assets/images/ember-cli-logo-small-dark.png">
|
|
18
|
-
</a>
|
|
19
|
-
</div>
|
|
20
|
-
|
|
21
|
-
<div id="modules" class="sidebox">
|
|
22
|
-
<div class="hd">
|
|
23
|
-
<h2 class="no-toc">Modules</h2>
|
|
24
|
-
</div>
|
|
25
|
-
<div class="bd">
|
|
26
|
-
<ul>
|
|
27
|
-
<li><a href="../modules/ember-cli.html">ember-cli</a>
|
|
28
|
-
</li>
|
|
29
|
-
<li><a href="../modules/is-lazy-engine.html">is-lazy-engine</a>
|
|
30
|
-
</li>
|
|
31
|
-
</ul>
|
|
32
|
-
</div>
|
|
33
|
-
</div>
|
|
34
|
-
|
|
35
|
-
<div id="classes" class="sidebox">
|
|
36
|
-
<div class="hd">
|
|
37
|
-
<h2 class="no-toc">Classes</h2>
|
|
38
|
-
</div>
|
|
39
|
-
<div class="bd">
|
|
40
|
-
<ul>
|
|
41
|
-
<li><a href="../classes/Addon.html">Addon</a></li>
|
|
42
|
-
<li><a href="../classes/AmdTransformAddon.html">AmdTransformAddon</a></li>
|
|
43
|
-
<li><a href="../classes/Blueprint.html">Blueprint</a></li>
|
|
44
|
-
<li><a href="../classes/Builder.html">Builder</a></li>
|
|
45
|
-
<li><a href="../classes/CLI.html">CLI</a></li>
|
|
46
|
-
<li><a href="../classes/Command.html">Command</a></li>
|
|
47
|
-
<li><a href="../classes/DefaultPackager.html">DefaultPackager</a></li>
|
|
48
|
-
<li><a href="../classes/EmberAddon.html">EmberAddon</a></li>
|
|
49
|
-
<li><a href="../classes/EmberApp.html">EmberApp</a></li>
|
|
50
|
-
<li><a href="../classes/HardwareInfo.html">HardwareInfo</a></li>
|
|
51
|
-
<li><a href="../classes/HistorySupportAddon.html">HistorySupportAddon</a></li>
|
|
52
|
-
<li><a href="../classes/Instrumentation.html">Instrumentation</a></li>
|
|
53
|
-
<li><a href="../classes/NodeModulesList.html">NodeModulesList</a></li>
|
|
54
|
-
<li><a href="../classes/NpmTask.html">NpmTask</a></li>
|
|
55
|
-
<li><a href="../classes/PackageInfo.html">PackageInfo</a></li>
|
|
56
|
-
<li><a href="../classes/PackageInfoCache.html">PackageInfoCache</a></li>
|
|
57
|
-
<li><a href="../classes/PerBundleAddonCache {.html">PerBundleAddonCache {</a></li>
|
|
58
|
-
<li><a href="../classes/Project.html">Project</a></li>
|
|
59
|
-
<li><a href="../classes/ServeFilesAddon.html">ServeFilesAddon</a></li>
|
|
60
|
-
<li><a href="../classes/TestsServerAddon.html">TestsServerAddon</a></li>
|
|
61
|
-
<li><a href="../classes/WatcherAddon.html">WatcherAddon</a></li>
|
|
62
|
-
<li><a href="../classes/WindowsSymlinkChecker.html">WindowsSymlinkChecker</a></li>
|
|
63
|
-
</ul>
|
|
64
|
-
</div>
|
|
65
|
-
</div>
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
<div class="version-info">
|
|
72
|
-
Version: 4.0.0-release-b4cbb1029f
|
|
73
|
-
</div>
|
|
74
|
-
|
|
75
|
-
</div>
|
|
76
|
-
|
|
77
|
-
<div id="main" class="yui3-u">
|
|
78
|
-
<div class="content"><div class="title">
|
|
79
|
-
<h1 class="file-name">lib/models/package-info-cache/index.js</h1>
|
|
80
|
-
</div>
|
|
81
|
-
|
|
82
|
-
<pre class="code prettyprint linenums">
|
|
83
|
-
'use strict';
|
|
84
|
-
|
|
85
|
-
/*
|
|
86
|
-
* Performance cache for information about packages (projects/addons/"apps"/modules)
|
|
87
|
-
* under an initial root directory and resolving addon/dependency links to other packages.
|
|
88
|
-
*/
|
|
89
|
-
|
|
90
|
-
const fs = require('fs-extra');
|
|
91
|
-
const path = require('path');
|
|
92
|
-
const ErrorList = require('./error-list');
|
|
93
|
-
const Errors = require('./errors');
|
|
94
|
-
const PackageInfo = require('./package-info');
|
|
95
|
-
const NodeModulesList = require('./node-modules-list');
|
|
96
|
-
const logger = require('heimdalljs-logger')('ember-cli:package-info-cache');
|
|
97
|
-
const resolvePackagePath = require('resolve-package-path');
|
|
98
|
-
|
|
99
|
-
const getRealFilePath = resolvePackagePath.getRealFilePath;
|
|
100
|
-
const getRealDirectoryPath = resolvePackagePath.getRealDirectoryPath;
|
|
101
|
-
const _resetCache = resolvePackagePath._resetCache;
|
|
102
|
-
|
|
103
|
-
const PACKAGE_JSON = 'package.json';
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Class that stores entries that are either PackageInfo or NodeModulesList objects.
|
|
107
|
-
* The entries are stored in a map keyed by real directory path.
|
|
108
|
-
*
|
|
109
|
-
* @public
|
|
110
|
-
* @class PackageInfoCache
|
|
111
|
-
*/
|
|
112
|
-
class PackageInfoCache {
|
|
113
|
-
constructor(ui) {
|
|
114
|
-
this.ui = ui; // a console-ui instance
|
|
115
|
-
this._clear();
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Clear the cache information.
|
|
120
|
-
*
|
|
121
|
-
* @private
|
|
122
|
-
* @method _clear
|
|
123
|
-
*/
|
|
124
|
-
_clear() {
|
|
125
|
-
this.entries = Object.create(null);
|
|
126
|
-
this.projects = [];
|
|
127
|
-
_resetCache();
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* Indicates if there is at least one error in any object in the cache.
|
|
132
|
-
*
|
|
133
|
-
* @public
|
|
134
|
-
* @method hasErrors
|
|
135
|
-
* @return true if there are any errors in the cache, for any entries, else false.
|
|
136
|
-
*/
|
|
137
|
-
hasErrors() {
|
|
138
|
-
let paths = Object.keys(this.entries);
|
|
139
|
-
|
|
140
|
-
if (paths.find((entryPath) => this.getEntry(entryPath).hasErrors())) {
|
|
141
|
-
return true;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
return false;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Gather all the errors in the PIC and any cached objects, then dump them
|
|
149
|
-
* out to the ui-console.
|
|
150
|
-
*
|
|
151
|
-
* @public
|
|
152
|
-
* @method showErrors
|
|
153
|
-
*/
|
|
154
|
-
showErrors() {
|
|
155
|
-
let paths = Object.keys(this.entries).sort();
|
|
156
|
-
|
|
157
|
-
paths.forEach((entryPath) => {
|
|
158
|
-
this._showObjErrors(this.getEntry(entryPath));
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* Dump all the errors for a single object in the cache out to the ui-console.
|
|
164
|
-
*
|
|
165
|
-
* Special case: because package-info-cache also creates PackageInfo objects for entries
|
|
166
|
-
* that do not actually exist (to allow simplifying the code), if there's a case where
|
|
167
|
-
* an object has only the single error ERROR_PACKAGE_DIR_MISSING, do not print
|
|
168
|
-
* anything. The package will have been found as a reference from some other
|
|
169
|
-
* addon or the root project, and we'll print a reference error there. Having
|
|
170
|
-
* both is just confusing to users.
|
|
171
|
-
*
|
|
172
|
-
* @private
|
|
173
|
-
* @method _showObjErrors
|
|
174
|
-
*/
|
|
175
|
-
_showObjErrors(obj) {
|
|
176
|
-
let errorEntries = obj.hasErrors() ? obj.errors.getErrors() : null;
|
|
177
|
-
|
|
178
|
-
if (!errorEntries || (errorEntries.length === 1 && errorEntries[0].type === Errors.ERROR_PACKAGE_DIR_MISSING)) {
|
|
179
|
-
return;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
logger.info('');
|
|
183
|
-
let rootPath;
|
|
184
|
-
|
|
185
|
-
if (obj instanceof PackageInfoCache) {
|
|
186
|
-
logger.info('Top level errors:');
|
|
187
|
-
rootPath = this.realPath || '';
|
|
188
|
-
} else {
|
|
189
|
-
let typeName = obj.project ? 'project' : 'addon';
|
|
190
|
-
|
|
191
|
-
logger.info(`The 'package.json' file for the ${typeName} at ${obj.realPath}`);
|
|
192
|
-
rootPath = obj.realPath;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
errorEntries.forEach((errorEntry) => {
|
|
196
|
-
switch (errorEntry.type) {
|
|
197
|
-
case Errors.ERROR_PACKAGE_JSON_MISSING:
|
|
198
|
-
logger.info(` does not exist`);
|
|
199
|
-
break;
|
|
200
|
-
case Errors.ERROR_PACKAGE_JSON_PARSE:
|
|
201
|
-
logger.info(` could not be parsed`);
|
|
202
|
-
break;
|
|
203
|
-
case Errors.ERROR_EMBER_ADDON_MAIN_MISSING:
|
|
204
|
-
logger.info(
|
|
205
|
-
` specifies a missing ember-addon 'main' file at relative path '${path.relative(
|
|
206
|
-
rootPath,
|
|
207
|
-
errorEntry.data
|
|
208
|
-
)}'`
|
|
209
|
-
);
|
|
210
|
-
break;
|
|
211
|
-
case Errors.ERROR_DEPENDENCIES_MISSING:
|
|
212
|
-
if (errorEntry.data.length === 1) {
|
|
213
|
-
logger.info(` specifies a missing dependency '${errorEntry.data[0]}'`);
|
|
214
|
-
} else {
|
|
215
|
-
logger.info(` specifies some missing dependencies:`);
|
|
216
|
-
errorEntry.data.forEach((dependencyName) => {
|
|
217
|
-
logger.info(` ${dependencyName}`);
|
|
218
|
-
});
|
|
219
|
-
}
|
|
220
|
-
break;
|
|
221
|
-
case Errors.ERROR_NODEMODULES_ENTRY_MISSING:
|
|
222
|
-
logger.info(` specifies a missing 'node_modules/${errorEntry.data}' directory`);
|
|
223
|
-
break;
|
|
224
|
-
}
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
/**
|
|
229
|
-
* Process the root directory of a project, given a
|
|
230
|
-
* Project object (we need the object in order to find the internal addons).
|
|
231
|
-
* _readPackage takes care of the general processing of the root directory
|
|
232
|
-
* and common locations for addons, filling the cache with each. Once it
|
|
233
|
-
* returns, we take care of the locations for addons that are specific to
|
|
234
|
-
* projects, not other packages (e.g. internal addons, cli root).
|
|
235
|
-
*
|
|
236
|
-
* Once all the project processing is done, go back through all cache entries
|
|
237
|
-
* to create references between the packageInfo objects.
|
|
238
|
-
*
|
|
239
|
-
* @public
|
|
240
|
-
* @method loadProject
|
|
241
|
-
* @param projectInstance the instance of the Project object to load package data
|
|
242
|
-
* about into the cache.
|
|
243
|
-
* @return {PackageInfo} the PackageInfo object for the given Project object.
|
|
244
|
-
* Note that if the project path is already in the cache, that will be returned.
|
|
245
|
-
* No copy is made.
|
|
246
|
-
*/
|
|
247
|
-
loadProject(projectInstance) {
|
|
248
|
-
logger.info('Loading project at %o...', projectInstance.root);
|
|
249
|
-
|
|
250
|
-
let pkgInfo = this._readPackage(projectInstance.root, projectInstance.pkg, true);
|
|
251
|
-
|
|
252
|
-
// NOTE: the returned val may contain errors, or may contain
|
|
253
|
-
// other packages that have errors. We will try to process
|
|
254
|
-
// things anyway.
|
|
255
|
-
if (!pkgInfo.processed) {
|
|
256
|
-
this.projects.push(projectInstance);
|
|
257
|
-
|
|
258
|
-
// projects are a bit different than standard addons, in that they have
|
|
259
|
-
// possibly a CLI addon and internal addons. Add those now.
|
|
260
|
-
pkgInfo.project = projectInstance;
|
|
261
|
-
|
|
262
|
-
if (projectInstance.cli && projectInstance.cli.root) {
|
|
263
|
-
logger.info('Reading package for "ember-cli": %o', projectInstance.cli.root);
|
|
264
|
-
pkgInfo.cliInfo = this._readPackage(projectInstance.cli.root);
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
// add any internal addons in the project. Since internal addons are
|
|
268
|
-
// optional (and only used some of the time anyway), we don't want to
|
|
269
|
-
// create a PackageInfo unless there is really a directory at the
|
|
270
|
-
// suggested location. The created addon may internally have errors,
|
|
271
|
-
// as with any other PackageInfo.
|
|
272
|
-
projectInstance.supportedInternalAddonPaths().forEach((internalAddonPath) => {
|
|
273
|
-
if (getRealDirectoryPath(internalAddonPath)) {
|
|
274
|
-
logger.info('Reading package for internal addon: %o', internalAddonPath);
|
|
275
|
-
pkgInfo.addInternalAddon(this._readPackage(internalAddonPath));
|
|
276
|
-
}
|
|
277
|
-
});
|
|
278
|
-
|
|
279
|
-
this._resolveDependencies();
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
return pkgInfo;
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
/**
|
|
286
|
-
* To support the project.reloadPkg method, we need the ability to flush
|
|
287
|
-
* the cache and reload from the updated package.json.
|
|
288
|
-
* There are some issues with doing this:
|
|
289
|
-
* - Because of the possible relationship between projects and their addons
|
|
290
|
-
* due to symlinks, it's not trivial to flush only the data related to a
|
|
291
|
-
* given project.
|
|
292
|
-
* - If an 'ember-build-cli.js' dynamically adds new projects to the cache,
|
|
293
|
-
* we will not necessarily get called again to redo the loading of those
|
|
294
|
-
* projects.
|
|
295
|
-
* The solution, implemented here:
|
|
296
|
-
* - Keep track of the Project objects whose packages are loaded into the cache.
|
|
297
|
-
* - If a project is reloaded, flush the cache, then do loadPackage again
|
|
298
|
-
* for all the known Projects.
|
|
299
|
-
*
|
|
300
|
-
* @public
|
|
301
|
-
* @method reloadProjects
|
|
302
|
-
* @return null
|
|
303
|
-
*/
|
|
304
|
-
reloadProjects() {
|
|
305
|
-
let projects = this.projects.slice();
|
|
306
|
-
this._clear();
|
|
307
|
-
projects.forEach((project) => this.loadProject(project));
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
/**
|
|
311
|
-
* Do the actual processing of the root directory of an addon, when the addon
|
|
312
|
-
* object already exists (i.e. the addon is acting as the root object of a
|
|
313
|
-
* tree, like project does). We need the object in order to find the internal addons.
|
|
314
|
-
* _readPackage takes care of the general processing of the root directory
|
|
315
|
-
* and common locations for addons, filling the cache with each.
|
|
316
|
-
*
|
|
317
|
-
* Once all the addon processing is done, go back through all cache entries
|
|
318
|
-
* to create references between the packageInfo objects.
|
|
319
|
-
*
|
|
320
|
-
* @public
|
|
321
|
-
* @method loadAddon
|
|
322
|
-
* @param addonInstance the instance of the Addon object to load package data
|
|
323
|
-
* about into the cache.
|
|
324
|
-
* @return {PackageInfo} the PackageInfo object for the given Addon object.
|
|
325
|
-
* Note that if the addon path is already in the cache, that will be returned.
|
|
326
|
-
* No copy is made.
|
|
327
|
-
*/
|
|
328
|
-
loadAddon(addonInstance) {
|
|
329
|
-
// to maintain backwards compatibility for consumers who create a new instance
|
|
330
|
-
// of the base addon model class directly and don't set `packageRoot`
|
|
331
|
-
let pkgInfo = this._readPackage(addonInstance.packageRoot || addonInstance.root, addonInstance.pkg);
|
|
332
|
-
|
|
333
|
-
// NOTE: the returned pkgInfo may contain errors, or may contain
|
|
334
|
-
// other packages that have errors. We will try to process
|
|
335
|
-
// things anyway.
|
|
336
|
-
if (!pkgInfo.processed) {
|
|
337
|
-
pkgInfo.addon = addonInstance;
|
|
338
|
-
this._resolveDependencies();
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
return pkgInfo;
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
/**
|
|
345
|
-
* Resolve the node_module dependencies across all packages after they have
|
|
346
|
-
* been loaded into the cache, because we don't know when a particular package
|
|
347
|
-
* will enter the cache.
|
|
348
|
-
*
|
|
349
|
-
* Since loadProject can be called multiple times for different projects,
|
|
350
|
-
* we don't want to reprocess any packages that happen to be common
|
|
351
|
-
* between them. We'll handle this by marking any packageInfo once it
|
|
352
|
-
* has been processed here, then ignore it in any later processing.
|
|
353
|
-
*
|
|
354
|
-
* @private
|
|
355
|
-
* @method _resolveDependencies
|
|
356
|
-
*/
|
|
357
|
-
_resolveDependencies() {
|
|
358
|
-
logger.info('Resolving dependencies...');
|
|
359
|
-
|
|
360
|
-
let packageInfos = this._getPackageInfos();
|
|
361
|
-
packageInfos.forEach((pkgInfo) => {
|
|
362
|
-
if (!pkgInfo.processed) {
|
|
363
|
-
let pkgs = pkgInfo.addDependencies(pkgInfo.pkg.dependencies);
|
|
364
|
-
if (pkgs) {
|
|
365
|
-
pkgInfo.dependencyPackages = pkgs;
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
// for Projects only, we also add the devDependencies
|
|
369
|
-
if (pkgInfo.project) {
|
|
370
|
-
pkgs = pkgInfo.addDependencies(pkgInfo.pkg.devDependencies);
|
|
371
|
-
if (pkgs) {
|
|
372
|
-
pkgInfo.devDependencyPackages = pkgs;
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
pkgInfo.processed = true;
|
|
377
|
-
}
|
|
378
|
-
});
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
/**
|
|
382
|
-
* Add an entry to the cache.
|
|
383
|
-
*
|
|
384
|
-
* @private
|
|
385
|
-
* @method _addEntry
|
|
386
|
-
*/
|
|
387
|
-
_addEntry(path, entry) {
|
|
388
|
-
this.entries[path] = entry;
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
/**
|
|
392
|
-
* Retrieve an entry from the cache.
|
|
393
|
-
*
|
|
394
|
-
* @public
|
|
395
|
-
* @method getEntry
|
|
396
|
-
* @param {String} path the real path whose PackageInfo or NodeModulesList is desired.
|
|
397
|
-
* @return {PackageInfo} or {NodeModulesList} the desired entry.
|
|
398
|
-
*/
|
|
399
|
-
getEntry(path) {
|
|
400
|
-
return this.entries[path];
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
/**
|
|
404
|
-
* Indicate if an entry for a given path exists in the cache.
|
|
405
|
-
*
|
|
406
|
-
* @public
|
|
407
|
-
* @method contains
|
|
408
|
-
* @param {String} path the real path to check for in the cache.
|
|
409
|
-
* @return true if the entry is present for the given path, false otherwise.
|
|
410
|
-
*/
|
|
411
|
-
contains(path) {
|
|
412
|
-
return this.entries[path] !== undefined;
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
_getPackageInfos() {
|
|
416
|
-
let result = [];
|
|
417
|
-
|
|
418
|
-
Object.keys(this.entries).forEach((path) => {
|
|
419
|
-
let entry = this.entries[path];
|
|
420
|
-
if (entry instanceof PackageInfo) {
|
|
421
|
-
result.push(entry);
|
|
422
|
-
}
|
|
423
|
-
});
|
|
424
|
-
|
|
425
|
-
return result;
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
/*
|
|
429
|
-
* Find a PackageInfo cache entry with the given path. If there is
|
|
430
|
-
* no entry in the startPath, do as done in resolve.sync() - travel up
|
|
431
|
-
* the directory hierarchy, attaching 'node_modules' to each directory and
|
|
432
|
-
* seeing if the directory exists and has the relevant entry.
|
|
433
|
-
*
|
|
434
|
-
* We'll do things a little differently, though, for speed.
|
|
435
|
-
*
|
|
436
|
-
* If there is no cache entry, we'll try to use _readNodeModulesList to create
|
|
437
|
-
* a new cache entry and its contents. If the directory does not exist,
|
|
438
|
-
* We'll create a NodeModulesList cache entry anyway, just so we don't have
|
|
439
|
-
* to check with the file system more than once for that directory (we
|
|
440
|
-
* waste a bit of space, but gain speed by not hitting the file system
|
|
441
|
-
* again for that path).
|
|
442
|
-
* Once we have a NodeModulesList, check for the package name, and continue
|
|
443
|
-
* up the path until we hit the root or the PackageInfo is found.
|
|
444
|
-
*
|
|
445
|
-
* @private
|
|
446
|
-
* @method _findPackage
|
|
447
|
-
* @param {String} packageName the name/path of the package to search for
|
|
448
|
-
* @param {String} the path of the directory to start searching from
|
|
449
|
-
*/
|
|
450
|
-
_findPackage(packageName, startPath) {
|
|
451
|
-
let parsedPath = path.parse(startPath);
|
|
452
|
-
let root = parsedPath.root;
|
|
453
|
-
|
|
454
|
-
let currPath = startPath;
|
|
455
|
-
|
|
456
|
-
while (currPath !== root) {
|
|
457
|
-
let endsWithNodeModules = path.basename(currPath) === 'node_modules';
|
|
458
|
-
|
|
459
|
-
let nodeModulesPath = endsWithNodeModules ? currPath : `${currPath}${path.sep}node_modules`;
|
|
460
|
-
|
|
461
|
-
let nodeModulesList = this._readNodeModulesList(nodeModulesPath);
|
|
462
|
-
|
|
463
|
-
// _readNodeModulesList only returns a NodeModulesList or null
|
|
464
|
-
if (nodeModulesList) {
|
|
465
|
-
let pkg = nodeModulesList.findPackage(packageName);
|
|
466
|
-
if (pkg) {
|
|
467
|
-
return pkg;
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
currPath = path.dirname(currPath);
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
return null;
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
/**
|
|
478
|
-
* Given a directory that supposedly contains a package, create a PackageInfo
|
|
479
|
-
* object and try to fill it out, EVEN IF the package.json is not readable.
|
|
480
|
-
* Errors will then be stored in the PackageInfo for anything with the package
|
|
481
|
-
* that might be wrong.
|
|
482
|
-
* Because it's possible that the path given to the packageDir is not actually valid,
|
|
483
|
-
* we'll just use the path.resolve() version of that path to search for the
|
|
484
|
-
* path in the cache, before trying to get the 'real' path (which also then
|
|
485
|
-
* resolves links). The cache itself is keyed on either the realPath, if the
|
|
486
|
-
* packageDir is actually a real valid directory path, or the normalized path (before
|
|
487
|
-
* path.resolve()), if it is not.
|
|
488
|
-
*
|
|
489
|
-
* NOTE: the cache is also used to store the NULL_PROJECT project object,
|
|
490
|
-
* which actually has no package.json or other files, but does have an empty
|
|
491
|
-
* package object. Because of that, and to speed up processing, loadProject()
|
|
492
|
-
* will pass in both the package root directory path and the project's package
|
|
493
|
-
* object, if there is one. If the package object is present, we will use that
|
|
494
|
-
* in preference to trying to find a package.json file.
|
|
495
|
-
*
|
|
496
|
-
* If there is no package object, and there is no package.json or the package.json
|
|
497
|
-
* is bad or the package is an addon with
|
|
498
|
-
* no main, the only thing we can do is return an ErrorEntry to the caller.
|
|
499
|
-
* Once past all those problems, if any error occurs with any of the contents
|
|
500
|
-
* of the package, they'll be cached in the PackageInfo itself.
|
|
501
|
-
*
|
|
502
|
-
* In summary, only PackageInfo or ErrorEntry will be returned.
|
|
503
|
-
*
|
|
504
|
-
* @private
|
|
505
|
-
* @method _readPackage
|
|
506
|
-
* @param {String} pkgDir the path of the directory to read the package.json from and
|
|
507
|
-
* process the contents and create a new cache entry or entries.
|
|
508
|
-
* @param {Boolean} isRoot, for when this is to be considered the root
|
|
509
|
-
* package, whose dependencies we must all consider for discovery.
|
|
510
|
-
*/
|
|
511
|
-
_readPackage(packageDir, pkg, isRoot) {
|
|
512
|
-
let normalizedPackageDir = path.normalize(packageDir);
|
|
513
|
-
|
|
514
|
-
// Most of the time, normalizedPackageDir is already a real path (i.e. fs.realpathSync
|
|
515
|
-
// will return the same value as normalizedPackageDir if the dir actually exists).
|
|
516
|
-
// Because of that, we'll assume we can test for normalizedPackageDir first and return
|
|
517
|
-
// if we find it.
|
|
518
|
-
let pkgInfo = this.getEntry(normalizedPackageDir);
|
|
519
|
-
if (pkgInfo) {
|
|
520
|
-
return pkgInfo;
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
// collect errors we hit while trying to create the PackageInfo object.
|
|
524
|
-
// We'll load these into the object once it's created.
|
|
525
|
-
let setupErrors = new ErrorList();
|
|
526
|
-
|
|
527
|
-
// We don't already have an entry (bad or otherwise) at normalizedPackageDir. See if
|
|
528
|
-
// we can actually find a real path (including resolving links if needed).
|
|
529
|
-
let pathFailed = false;
|
|
530
|
-
|
|
531
|
-
let realPath = getRealDirectoryPath(normalizedPackageDir);
|
|
532
|
-
|
|
533
|
-
if (realPath) {
|
|
534
|
-
if (realPath !== normalizedPackageDir) {
|
|
535
|
-
// getRealDirectoryPath actually changed something in the path (e.g.
|
|
536
|
-
// by resolving a symlink), so see if we have this entry.
|
|
537
|
-
pkgInfo = this.getEntry(realPath);
|
|
538
|
-
if (pkgInfo) {
|
|
539
|
-
return pkgInfo;
|
|
540
|
-
}
|
|
541
|
-
} else {
|
|
542
|
-
// getRealDirectoryPath is same as normalizedPackageDir, and we know already we
|
|
543
|
-
// don't have an entry there, so we need to create one.
|
|
544
|
-
}
|
|
545
|
-
} else {
|
|
546
|
-
// no realPath, so either nothing is at the path or it's not a directory.
|
|
547
|
-
// We need to use normalizedPackageDir as the real path.
|
|
548
|
-
pathFailed = true;
|
|
549
|
-
setupErrors.addError(Errors.ERROR_PACKAGE_DIR_MISSING, normalizedPackageDir);
|
|
550
|
-
realPath = normalizedPackageDir;
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
// at this point we have realPath set, we don't already have a PackageInfo
|
|
554
|
-
// for the path, and the path may or may not actually correspond to a
|
|
555
|
-
// valid directory (pathFailed tells us which). If we don't have a pkg
|
|
556
|
-
// object already, we need to be able to read one, unless we also don't
|
|
557
|
-
// have a path.
|
|
558
|
-
if (!pkg) {
|
|
559
|
-
if (!pathFailed) {
|
|
560
|
-
// we have a valid realPath
|
|
561
|
-
let packageJsonPath = path.join(realPath, PACKAGE_JSON);
|
|
562
|
-
let pkgfile = getRealFilePath(packageJsonPath);
|
|
563
|
-
if (pkgfile) {
|
|
564
|
-
try {
|
|
565
|
-
pkg = fs.readJsonSync(pkgfile);
|
|
566
|
-
} catch (e) {
|
|
567
|
-
setupErrors.addError(Errors.ERROR_PACKAGE_JSON_PARSE, pkgfile);
|
|
568
|
-
}
|
|
569
|
-
} else {
|
|
570
|
-
setupErrors.addError(Errors.ERROR_PACKAGE_JSON_MISSING, packageJsonPath);
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
|
-
|
|
574
|
-
// Some error has occurred resulting in no pkg object, so just
|
|
575
|
-
// create an empty one so we have something to use below.
|
|
576
|
-
if (!pkg) {
|
|
577
|
-
pkg = Object.create(null);
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
|
|
581
|
-
// For storage, force the pkg.root to the calculated path. This will
|
|
582
|
-
// save us from issues where we have a package for a non-existing
|
|
583
|
-
// path and other stuff.
|
|
584
|
-
pkg.root = realPath;
|
|
585
|
-
|
|
586
|
-
// Create a new PackageInfo and load any errors as needed.
|
|
587
|
-
// Note that pkg may be an empty object here.
|
|
588
|
-
logger.info('Creating new PackageInfo instance for %o at %o', pkg.name, realPath);
|
|
589
|
-
pkgInfo = new PackageInfo(pkg, realPath, this, isRoot);
|
|
590
|
-
|
|
591
|
-
if (setupErrors.hasErrors()) {
|
|
592
|
-
pkgInfo.errors = setupErrors;
|
|
593
|
-
pkgInfo.valid = false;
|
|
594
|
-
}
|
|
595
|
-
|
|
596
|
-
// If we have an ember-addon, check that the main exists and points
|
|
597
|
-
// to a valid file.
|
|
598
|
-
if (pkgInfo.isForAddon()) {
|
|
599
|
-
logger.info('%s is an addon', pkg.name);
|
|
600
|
-
|
|
601
|
-
// Note: when we have both 'main' and ember-addon:main, the latter takes precedence
|
|
602
|
-
let main = (pkg['ember-addon'] && pkg['ember-addon'].main) || pkg['main'];
|
|
603
|
-
|
|
604
|
-
if (!main || main === '.' || main === './') {
|
|
605
|
-
main = 'index.js';
|
|
606
|
-
} else if (!path.extname(main)) {
|
|
607
|
-
main = `${main}.js`;
|
|
608
|
-
}
|
|
609
|
-
|
|
610
|
-
logger.info('Addon entry point is %o', main);
|
|
611
|
-
pkg.main = main;
|
|
612
|
-
|
|
613
|
-
let mainPath = path.join(realPath, main);
|
|
614
|
-
let mainRealPath = getRealFilePath(mainPath);
|
|
615
|
-
|
|
616
|
-
if (mainRealPath) {
|
|
617
|
-
pkgInfo.addonMainPath = mainRealPath;
|
|
618
|
-
} else {
|
|
619
|
-
pkgInfo.addError(Errors.ERROR_EMBER_ADDON_MAIN_MISSING, mainPath);
|
|
620
|
-
this.valid = false;
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
// The packageInfo itself is now "complete", though we have not
|
|
625
|
-
// yet dealt with any of its "child" packages. Add it to the
|
|
626
|
-
// cache
|
|
627
|
-
this._addEntry(realPath, pkgInfo);
|
|
628
|
-
|
|
629
|
-
let emberAddonInfo = pkg['ember-addon'];
|
|
630
|
-
|
|
631
|
-
// Set up packageInfos for any in-repo addons
|
|
632
|
-
if (emberAddonInfo) {
|
|
633
|
-
let paths = emberAddonInfo.paths;
|
|
634
|
-
|
|
635
|
-
if (paths) {
|
|
636
|
-
paths.forEach((p) => {
|
|
637
|
-
let addonPath = path.join(realPath, p); // real path, though may not exist.
|
|
638
|
-
logger.info('Adding in-repo-addon at %o', addonPath);
|
|
639
|
-
let addonPkgInfo = this._readPackage(addonPath); // may have errors in the addon package.
|
|
640
|
-
pkgInfo.addInRepoAddon(addonPkgInfo);
|
|
641
|
-
});
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
|
-
|
|
645
|
-
if (pkgInfo.mayHaveAddons) {
|
|
646
|
-
logger.info('Reading "node_modules" for %o', realPath);
|
|
647
|
-
|
|
648
|
-
// read addon modules from node_modules. We read the whole directory
|
|
649
|
-
// because it's assumed that npm/yarn may have placed addons in the
|
|
650
|
-
// directory from lower down in the project tree, and we want to get
|
|
651
|
-
// the data into the cache ASAP. It may not necessarily be a 'real' error
|
|
652
|
-
// if we find an issue, if nobody below is actually invoking the addon.
|
|
653
|
-
let nodeModules = this._readNodeModulesList(path.join(realPath, 'node_modules'));
|
|
654
|
-
|
|
655
|
-
if (nodeModules) {
|
|
656
|
-
pkgInfo.nodeModules = nodeModules;
|
|
657
|
-
}
|
|
658
|
-
} else {
|
|
659
|
-
// will not have addons, so even if there are node_modules here, we can
|
|
660
|
-
// simply pretend there are none.
|
|
661
|
-
pkgInfo.nodeModules = NodeModulesList.NULL;
|
|
662
|
-
}
|
|
663
|
-
|
|
664
|
-
return pkgInfo;
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
/**
|
|
668
|
-
* Process a directory of modules in a given package directory.
|
|
669
|
-
*
|
|
670
|
-
* We will allow cache entries for node_modules that actually
|
|
671
|
-
* have no contents, just so we don't have to hit the file system more
|
|
672
|
-
* often than necessary--it's much quicker to check an in-memory object.
|
|
673
|
-
* object.
|
|
674
|
-
*
|
|
675
|
-
* Note: only a NodeModulesList or null is returned.
|
|
676
|
-
*
|
|
677
|
-
* @private
|
|
678
|
-
* @method _readModulesList
|
|
679
|
-
* @param {String} nodeModulesDir the path of the node_modules directory
|
|
680
|
-
* to read the package.json from and process the contents and create a
|
|
681
|
-
* new cache entry or entries.
|
|
682
|
-
*/
|
|
683
|
-
_readNodeModulesList(nodeModulesDir) {
|
|
684
|
-
let normalizedNodeModulesDir = path.normalize(nodeModulesDir);
|
|
685
|
-
|
|
686
|
-
// Much of the time, normalizedNodeModulesDir is already a real path (i.e.
|
|
687
|
-
// fs.realpathSync will return the same value as normalizedNodeModulesDir, if
|
|
688
|
-
// the directory actually exists). Because of that, we'll assume
|
|
689
|
-
// we can test for normalizedNodeModulesDir first and return if we find it.
|
|
690
|
-
let nodeModulesList = this.getEntry(normalizedNodeModulesDir);
|
|
691
|
-
if (nodeModulesList) {
|
|
692
|
-
return nodeModulesList;
|
|
693
|
-
}
|
|
694
|
-
|
|
695
|
-
// NOTE: because we call this when searching for objects in node_modules
|
|
696
|
-
// directories that may not exist, we'll just return null here if the
|
|
697
|
-
// directory is not real. If it actually is an error in some case,
|
|
698
|
-
// the caller can create the error there.
|
|
699
|
-
let realPath = getRealDirectoryPath(normalizedNodeModulesDir);
|
|
700
|
-
|
|
701
|
-
if (!realPath) {
|
|
702
|
-
return null;
|
|
703
|
-
}
|
|
704
|
-
|
|
705
|
-
// realPath may be different than the original normalizedNodeModulesDir, so
|
|
706
|
-
// we need to check the cache again.
|
|
707
|
-
if (realPath !== normalizedNodeModulesDir) {
|
|
708
|
-
nodeModulesList = this.getEntry(realPath);
|
|
709
|
-
if (nodeModulesList) {
|
|
710
|
-
return nodeModulesList;
|
|
711
|
-
}
|
|
712
|
-
} else {
|
|
713
|
-
// getRealDirectoryPath is same as normalizedPackageDir, and we know already we
|
|
714
|
-
// don't have an entry there, so we need to create one.
|
|
715
|
-
}
|
|
716
|
-
|
|
717
|
-
// At this point we know the directory node_modules exists and we can
|
|
718
|
-
// process it. Further errors will be recorded here, or in the objects
|
|
719
|
-
// that correspond to the node_modules entries.
|
|
720
|
-
logger.info('Creating new NodeModulesList instance for %o', realPath);
|
|
721
|
-
nodeModulesList = new NodeModulesList(realPath, this);
|
|
722
|
-
|
|
723
|
-
const entries = fs.readdirSync(realPath).filter((fileName) => {
|
|
724
|
-
if (fileName.startsWith('.') || fileName.startsWith('_')) {
|
|
725
|
-
// we explicitly want to ignore these, according to the
|
|
726
|
-
// definition of a valid package name.
|
|
727
|
-
return false;
|
|
728
|
-
} else if (fileName.startsWith('@')) {
|
|
729
|
-
return true;
|
|
730
|
-
} else if (!fs.existsSync(`${realPath}/${fileName}/package.json`)) {
|
|
731
|
-
// a node_module is only valid if it contains a package.json
|
|
732
|
-
return false;
|
|
733
|
-
} else {
|
|
734
|
-
return true;
|
|
735
|
-
}
|
|
736
|
-
}); // should not fail because getRealDirectoryPath passed
|
|
737
|
-
|
|
738
|
-
entries.forEach((entryName) => {
|
|
739
|
-
// entries should be either a package or a scoping directory. I think
|
|
740
|
-
// there can also be files, but we'll ignore those.
|
|
741
|
-
|
|
742
|
-
let entryPath = path.join(realPath, entryName);
|
|
743
|
-
|
|
744
|
-
if (getRealFilePath(entryPath)) {
|
|
745
|
-
// we explicitly want to ignore valid regular files in node_modules.
|
|
746
|
-
// This is a bit slower than just checking for directories, but we need to be sure.
|
|
747
|
-
return;
|
|
748
|
-
}
|
|
749
|
-
|
|
750
|
-
// At this point we have an entry name that should correspond to
|
|
751
|
-
// a directory, which should turn into either a NodeModulesList or
|
|
752
|
-
// PackageInfo. If not, it's an error on this NodeModulesList.
|
|
753
|
-
let entryVal;
|
|
754
|
-
|
|
755
|
-
if (entryName.startsWith('@')) {
|
|
756
|
-
// we should have a scoping directory.
|
|
757
|
-
entryVal = this._readNodeModulesList(entryPath);
|
|
758
|
-
|
|
759
|
-
// readModulesDir only returns NodeModulesList or null
|
|
760
|
-
if (entryVal instanceof NodeModulesList) {
|
|
761
|
-
nodeModulesList.addEntry(entryName, entryVal);
|
|
762
|
-
} else {
|
|
763
|
-
// This (null return) really should not occur, unless somehow the
|
|
764
|
-
// dir disappears between the time of fs.readdirSync and now.
|
|
765
|
-
nodeModulesList.addError(Errors.ERROR_NODEMODULES_ENTRY_MISSING, entryName);
|
|
766
|
-
}
|
|
767
|
-
} else {
|
|
768
|
-
// we should have a package. We will always get a PackageInfo
|
|
769
|
-
// back, though it may contain errors.
|
|
770
|
-
entryVal = this._readPackage(entryPath);
|
|
771
|
-
nodeModulesList.addEntry(entryName, entryVal);
|
|
772
|
-
}
|
|
773
|
-
});
|
|
774
|
-
|
|
775
|
-
this._addEntry(realPath, nodeModulesList);
|
|
776
|
-
|
|
777
|
-
return nodeModulesList;
|
|
778
|
-
}
|
|
779
|
-
}
|
|
780
|
-
|
|
781
|
-
module.exports = PackageInfoCache;
|
|
782
|
-
|
|
783
|
-
</pre>
|
|
784
|
-
|
|
785
|
-
</div>
|
|
786
|
-
</div>
|
|
787
|
-
</div>
|
|
788
|
-
</div>
|
|
789
|
-
<script src="../assets/vendor/prettify/prettify-min.js"></script>
|
|
790
|
-
<script>prettyPrint();</script>
|
|
791
|
-
<script src="../assets/js/yui-prettify.js"></script>
|
|
792
|
-
</body>
|
|
793
|
-
</html>
|