ember-cli 4.0.0-beta.4 → 4.1.0

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.
Files changed (118) hide show
  1. package/.github/workflows/ci.yml +4 -4
  2. package/CHANGELOG.md +28 -17
  3. package/bin/ember +0 -0
  4. package/blueprints/addon/additional-dev-dependencies.json +1 -1
  5. package/blueprints/addon/files/.github/workflows/ci.yml +5 -1
  6. package/blueprints/addon/files/.travis.yml +1 -1
  7. package/blueprints/addon/files/README.md +2 -2
  8. package/blueprints/addon/files/addon-config/ember-try.js +4 -4
  9. package/blueprints/app/files/.github/workflows/ci.yml +4 -0
  10. package/blueprints/app/files/package.json +8 -8
  11. package/blueprints/in-repo-addon/files/__root__/__name__/index.js +0 -0
  12. package/blueprints/in-repo-addon/index.js +0 -0
  13. package/blueprints/lib/index.js +0 -0
  14. package/docs/build/data.json +413 -413
  15. package/lib/models/host-info-cache.js +3 -5
  16. package/lib/models/per-bundle-addon-cache/index.js +2 -3
  17. package/lib/tasks/npm-task.js +1 -1
  18. package/lib/utilities/get-lang-arg.js +45 -45
  19. package/package.json +25 -25
  20. package/.github/ISSUE_TEMPLATE.md +0 -12
  21. package/.github/dependabot.yml +0 -15
  22. package/.github/workflows/coverage.yml +0 -31
  23. package/docs/analytics.md +0 -44
  24. package/docs/architecture.md +0 -316
  25. package/docs/assets/architecture/Ember-CLI architecture.png +0 -0
  26. package/docs/assets/architecture/Ember-CLI architecture.xml +0 -1
  27. package/docs/assets/architecture/README.md +0 -5
  28. package/docs/brocfile-transition.md +0 -46
  29. package/docs/build/api.js +0 -44
  30. package/docs/build/assets/css/external-small.png +0 -0
  31. package/docs/build/assets/css/logo.png +0 -0
  32. package/docs/build/assets/css/main.css +0 -555
  33. package/docs/build/assets/favicon.ico +0 -0
  34. package/docs/build/assets/img/spinner.gif +0 -0
  35. package/docs/build/assets/index.html +0 -10
  36. package/docs/build/assets/js/api-filter.js +0 -56
  37. package/docs/build/assets/js/api-list.js +0 -255
  38. package/docs/build/assets/js/api-search.js +0 -98
  39. package/docs/build/assets/js/apidocs.js +0 -376
  40. package/docs/build/assets/js/yui-prettify.js +0 -17
  41. package/docs/build/assets/vendor/prettify/CHANGES.html +0 -130
  42. package/docs/build/assets/vendor/prettify/COPYING +0 -202
  43. package/docs/build/assets/vendor/prettify/README.html +0 -203
  44. package/docs/build/assets/vendor/prettify/prettify-min.css +0 -1
  45. package/docs/build/assets/vendor/prettify/prettify-min.js +0 -1
  46. package/docs/build/classes/Addon.html +0 -4318
  47. package/docs/build/classes/AmdTransformAddon.html +0 -202
  48. package/docs/build/classes/Blueprint.html +0 -4796
  49. package/docs/build/classes/Builder.html +0 -611
  50. package/docs/build/classes/CLI.html +0 -810
  51. package/docs/build/classes/Command.html +0 -1655
  52. package/docs/build/classes/DefaultPackager.html +0 -202
  53. package/docs/build/classes/EmberAddon.html +0 -2207
  54. package/docs/build/classes/EmberApp.html +0 -2225
  55. package/docs/build/classes/HardwareInfo.html +0 -620
  56. package/docs/build/classes/HistorySupportAddon.html +0 -203
  57. package/docs/build/classes/Instrumentation.html +0 -695
  58. package/docs/build/classes/NodeModulesList.html +0 -460
  59. package/docs/build/classes/NpmTask.html +0 -333
  60. package/docs/build/classes/PackageInfo.html +0 -1390
  61. package/docs/build/classes/PackageInfoCache.html +0 -963
  62. package/docs/build/classes/PerBundleAddonCache {.html +0 -1010
  63. package/docs/build/classes/Project.html +0 -2083
  64. package/docs/build/classes/ServeFilesAddon.html +0 -260
  65. package/docs/build/classes/TestsServerAddon.html +0 -203
  66. package/docs/build/classes/WatcherAddon.html +0 -204
  67. package/docs/build/classes/WindowsSymlinkChecker.html +0 -1505
  68. package/docs/build/files/lib_broccoli_default-packager.js.html +0 -1426
  69. package/docs/build/files/lib_broccoli_ember-addon.js.html +0 -159
  70. package/docs/build/files/lib_broccoli_ember-app.js.html +0 -1913
  71. package/docs/build/files/lib_cli_cli.js.html +0 -417
  72. package/docs/build/files/lib_models_addon-info.js.html +0 -112
  73. package/docs/build/files/lib_models_addon.js.html +0 -1866
  74. package/docs/build/files/lib_models_blueprint.js.html +0 -1678
  75. package/docs/build/files/lib_models_builder.js.html +0 -417
  76. package/docs/build/files/lib_models_command.js.html +0 -804
  77. package/docs/build/files/lib_models_hardware-info.js.html +0 -479
  78. package/docs/build/files/lib_models_host-info-cache.js.html +0 -428
  79. package/docs/build/files/lib_models_installation-checker.js.html +0 -181
  80. package/docs/build/files/lib_models_instantiate-addons.js.html +0 -191
  81. package/docs/build/files/lib_models_instrumentation.js.html +0 -433
  82. package/docs/build/files/lib_models_package-info-cache_index.js.html +0 -793
  83. package/docs/build/files/lib_models_package-info-cache_node-modules-list.js.html +0 -208
  84. package/docs/build/files/lib_models_package-info-cache_package-info.js.html +0 -661
  85. package/docs/build/files/lib_models_per-bundle-addon-cache_addon-proxy.js.html +0 -252
  86. package/docs/build/files/lib_models_per-bundle-addon-cache_index.js.html +0 -485
  87. package/docs/build/files/lib_models_per-bundle-addon-cache_target-instance.js.html +0 -108
  88. package/docs/build/files/lib_models_project.js.html +0 -913
  89. package/docs/build/files/lib_models_task.js.html +0 -117
  90. package/docs/build/files/lib_tasks_build-watch.js.html +0 -157
  91. package/docs/build/files/lib_tasks_npm-task.js.html +0 -463
  92. package/docs/build/files/lib_tasks_serve.js.html +0 -207
  93. package/docs/build/files/lib_tasks_server_middleware_broccoli-serve-files_index.js.html +0 -127
  94. package/docs/build/files/lib_tasks_server_middleware_broccoli-watcher_index.js.html +0 -158
  95. package/docs/build/files/lib_tasks_server_middleware_history-support_index.js.html +0 -181
  96. package/docs/build/files/lib_tasks_server_middleware_tests-server_index.js.html +0 -171
  97. package/docs/build/files/lib_tasks_test-server.js.html +0 -167
  98. package/docs/build/files/lib_tasks_transforms_amd_index.js.html +0 -143
  99. package/docs/build/files/lib_utilities_ember-app-utils.js.html +0 -292
  100. package/docs/build/files/lib_utilities_insert-into-file.js.html +0 -219
  101. package/docs/build/files/lib_utilities_is-lazy-engine.js.html +0 -125
  102. package/docs/build/files/lib_utilities_is-yarn-project.js.html +0 -120
  103. package/docs/build/files/lib_utilities_valid-project-name.js.html +0 -142
  104. package/docs/build/files/lib_utilities_will-interrupt-process.js.html +0 -290
  105. package/docs/build/files/lib_utilities_windows-admin.js.html +0 -230
  106. package/docs/build/index.html +0 -125
  107. package/docs/build/modules/ember-cli.html +0 -152
  108. package/docs/build/modules/is-lazy-engine.html +0 -106
  109. package/docs/build-concurrency.md +0 -15
  110. package/docs/build-pipeline-debugging.md +0 -33
  111. package/docs/code-coverage.md +0 -14
  112. package/docs/error-propagation.md +0 -136
  113. package/docs/experiments.md +0 -53
  114. package/docs/node-support.md +0 -43
  115. package/docs/perf-guide.md +0 -250
  116. package/docs/project_version_preprocessor.js +0 -8
  117. package/docs/sourcemaps.md +0 -60
  118. 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-beta.4-beta-724190cca6
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
- &#x27;use strict&#x27;;
84
-
85
- /*
86
- * Performance cache for information about packages (projects/addons/&quot;apps&quot;/modules)
87
- * under an initial root directory and resolving addon/dependency links to other packages.
88
- */
89
-
90
- const fs = require(&#x27;fs-extra&#x27;);
91
- const path = require(&#x27;path&#x27;);
92
- const ErrorList = require(&#x27;./error-list&#x27;);
93
- const Errors = require(&#x27;./errors&#x27;);
94
- const PackageInfo = require(&#x27;./package-info&#x27;);
95
- const NodeModulesList = require(&#x27;./node-modules-list&#x27;);
96
- const logger = require(&#x27;heimdalljs-logger&#x27;)(&#x27;ember-cli:package-info-cache&#x27;);
97
- const resolvePackagePath = require(&#x27;resolve-package-path&#x27;);
98
-
99
- const getRealFilePath = resolvePackagePath.getRealFilePath;
100
- const getRealDirectoryPath = resolvePackagePath.getRealDirectoryPath;
101
- const _resetCache = resolvePackagePath._resetCache;
102
-
103
- const PACKAGE_JSON = &#x27;package.json&#x27;;
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) =&gt; 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) =&gt; {
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&#x27;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&#x27;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 &amp;&amp; errorEntries[0].type === Errors.ERROR_PACKAGE_DIR_MISSING)) {
179
- return;
180
- }
181
-
182
- logger.info(&#x27;&#x27;);
183
- let rootPath;
184
-
185
- if (obj instanceof PackageInfoCache) {
186
- logger.info(&#x27;Top level errors:&#x27;);
187
- rootPath = this.realPath || &#x27;&#x27;;
188
- } else {
189
- let typeName = obj.project ? &#x27;project&#x27; : &#x27;addon&#x27;;
190
-
191
- logger.info(&#x60;The &#x27;package.json&#x27; file for the ${typeName} at ${obj.realPath}&#x60;);
192
- rootPath = obj.realPath;
193
- }
194
-
195
- errorEntries.forEach((errorEntry) =&gt; {
196
- switch (errorEntry.type) {
197
- case Errors.ERROR_PACKAGE_JSON_MISSING:
198
- logger.info(&#x60; does not exist&#x60;);
199
- break;
200
- case Errors.ERROR_PACKAGE_JSON_PARSE:
201
- logger.info(&#x60; could not be parsed&#x60;);
202
- break;
203
- case Errors.ERROR_EMBER_ADDON_MAIN_MISSING:
204
- logger.info(
205
- &#x60; specifies a missing ember-addon &#x27;main&#x27; file at relative path &#x27;${path.relative(
206
- rootPath,
207
- errorEntry.data
208
- )}&#x27;&#x60;
209
- );
210
- break;
211
- case Errors.ERROR_DEPENDENCIES_MISSING:
212
- if (errorEntry.data.length === 1) {
213
- logger.info(&#x60; specifies a missing dependency &#x27;${errorEntry.data[0]}&#x27;&#x60;);
214
- } else {
215
- logger.info(&#x60; specifies some missing dependencies:&#x60;);
216
- errorEntry.data.forEach((dependencyName) =&gt; {
217
- logger.info(&#x60; ${dependencyName}&#x60;);
218
- });
219
- }
220
- break;
221
- case Errors.ERROR_NODEMODULES_ENTRY_MISSING:
222
- logger.info(&#x60; specifies a missing &#x27;node_modules/${errorEntry.data}&#x27; directory&#x60;);
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(&#x27;Loading project at %o...&#x27;, 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 &amp;&amp; projectInstance.cli.root) {
263
- logger.info(&#x27;Reading package for &quot;ember-cli&quot;: %o&#x27;, 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&#x27;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) =&gt; {
273
- if (getRealDirectoryPath(internalAddonPath)) {
274
- logger.info(&#x27;Reading package for internal addon: %o&#x27;, 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&#x27;s not trivial to flush only the data related to a
291
- * given project.
292
- * - If an &#x27;ember-build-cli.js&#x27; 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) =&gt; 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&#x27;t set &#x60;packageRoot&#x60;
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&#x27;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&#x27;t want to reprocess any packages that happen to be common
351
- * between them. We&#x27;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(&#x27;Resolving dependencies...&#x27;);
359
-
360
- let packageInfos = this._getPackageInfos();
361
- packageInfos.forEach((pkgInfo) =&gt; {
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) =&gt; {
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 &#x27;node_modules&#x27; to each directory and
432
- * seeing if the directory exists and has the relevant entry.
433
- *
434
- * We&#x27;ll do things a little differently, though, for speed.
435
- *
436
- * If there is no cache entry, we&#x27;ll try to use _readNodeModulesList to create
437
- * a new cache entry and its contents. If the directory does not exist,
438
- * We&#x27;ll create a NodeModulesList cache entry anyway, just so we don&#x27;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) === &#x27;node_modules&#x27;;
458
-
459
- let nodeModulesPath = endsWithNodeModules ? currPath : &#x60;${currPath}${path.sep}node_modules&#x60;;
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&#x27;s possible that the path given to the packageDir is not actually valid,
483
- * we&#x27;ll just use the path.resolve() version of that path to search for the
484
- * path in the cache, before trying to get the &#x27;real&#x27; 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&#x27;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&#x27;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&#x27;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&#x27;ll load these into the object once it&#x27;s created.
525
- let setupErrors = new ErrorList();
526
-
527
- // We don&#x27;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&#x27;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&#x27;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&#x27;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&#x27;t have a pkg
556
- // object already, we need to be able to read one, unless we also don&#x27;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(&#x27;Creating new PackageInfo instance for %o at %o&#x27;, 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(&#x27;%s is an addon&#x27;, pkg.name);
600
-
601
- // Note: when we have both &#x27;main&#x27; and ember-addon:main, the latter takes precedence
602
- let main = (pkg[&#x27;ember-addon&#x27;] &amp;&amp; pkg[&#x27;ember-addon&#x27;].main) || pkg[&#x27;main&#x27;];
603
-
604
- if (!main || main === &#x27;.&#x27; || main === &#x27;./&#x27;) {
605
- main = &#x27;index.js&#x27;;
606
- } else if (!path.extname(main)) {
607
- main = &#x60;${main}.js&#x60;;
608
- }
609
-
610
- logger.info(&#x27;Addon entry point is %o&#x27;, 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 &quot;complete&quot;, though we have not
625
- // yet dealt with any of its &quot;child&quot; packages. Add it to the
626
- // cache
627
- this._addEntry(realPath, pkgInfo);
628
-
629
- let emberAddonInfo = pkg[&#x27;ember-addon&#x27;];
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) =&gt; {
637
- let addonPath = path.join(realPath, p); // real path, though may not exist.
638
- logger.info(&#x27;Adding in-repo-addon at %o&#x27;, 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(&#x27;Reading &quot;node_modules&quot; for %o&#x27;, realPath);
647
-
648
- // read addon modules from node_modules. We read the whole directory
649
- // because it&#x27;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 &#x27;real&#x27; error
652
- // if we find an issue, if nobody below is actually invoking the addon.
653
- let nodeModules = this._readNodeModulesList(path.join(realPath, &#x27;node_modules&#x27;));
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&#x27;t have to hit the file system more
672
- * often than necessary--it&#x27;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&#x27;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&#x27;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&#x27;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(&#x27;Creating new NodeModulesList instance for %o&#x27;, realPath);
721
- nodeModulesList = new NodeModulesList(realPath, this);
722
-
723
- const entries = fs.readdirSync(realPath).filter((fileName) =&gt; {
724
- if (fileName.startsWith(&#x27;.&#x27;) || fileName.startsWith(&#x27;_&#x27;)) {
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(&#x27;@&#x27;)) {
729
- return true;
730
- } else if (!fs.existsSync(&#x60;${realPath}/${fileName}/package.json&#x60;)) {
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) =&gt; {
739
- // entries should be either a package or a scoping directory. I think
740
- // there can also be files, but we&#x27;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&#x27;s an error on this NodeModulesList.
753
- let entryVal;
754
-
755
- if (entryName.startsWith(&#x27;@&#x27;)) {
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>