@rushstack/package-extractor 0.11.16 → 0.12.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 (58) hide show
  1. package/CHANGELOG.json +32 -0
  2. package/CHANGELOG.md +8 -1
  3. package/dist/scripts/create-links.js +1277 -17204
  4. package/dist/scripts/create-links.js.map +1 -1
  5. package/dist/tsdoc-metadata.json +1 -1
  6. package/package.json +32 -10
  7. package/lib/ArchiveManager.d.ts +0 -13
  8. package/lib/ArchiveManager.d.ts.map +0 -1
  9. package/lib/ArchiveManager.js +0 -64
  10. package/lib/ArchiveManager.js.map +0 -1
  11. package/lib/AssetHandler.d.ts +0 -52
  12. package/lib/AssetHandler.d.ts.map +0 -1
  13. package/lib/AssetHandler.js +0 -171
  14. package/lib/AssetHandler.js.map +0 -1
  15. package/lib/PackageExtractor.d.ts +0 -280
  16. package/lib/PackageExtractor.d.ts.map +0 -1
  17. package/lib/PackageExtractor.js +0 -568
  18. package/lib/PackageExtractor.js.map +0 -1
  19. package/lib/PathConstants.d.ts +0 -4
  20. package/lib/PathConstants.d.ts.map +0 -1
  21. package/lib/PathConstants.js +0 -11
  22. package/lib/PathConstants.js.map +0 -1
  23. package/lib/SymlinkAnalyzer.d.ts +0 -73
  24. package/lib/SymlinkAnalyzer.d.ts.map +0 -1
  25. package/lib/SymlinkAnalyzer.js +0 -159
  26. package/lib/SymlinkAnalyzer.js.map +0 -1
  27. package/lib/Utils.d.ts +0 -30
  28. package/lib/Utils.d.ts.map +0 -1
  29. package/lib/Utils.js +0 -85
  30. package/lib/Utils.js.map +0 -1
  31. package/lib/index.d.ts +0 -3
  32. package/lib/index.d.ts.map +0 -1
  33. package/lib/index.js +0 -8
  34. package/lib/index.js.map +0 -1
  35. package/lib/scripts/createLinks/cli/CreateLinksCommandLineParser.d.ts +0 -8
  36. package/lib/scripts/createLinks/cli/CreateLinksCommandLineParser.d.ts.map +0 -1
  37. package/lib/scripts/createLinks/cli/CreateLinksCommandLineParser.js +0 -35
  38. package/lib/scripts/createLinks/cli/CreateLinksCommandLineParser.js.map +0 -1
  39. package/lib/scripts/createLinks/cli/actions/CreateLinksAction.d.ts +0 -10
  40. package/lib/scripts/createLinks/cli/actions/CreateLinksAction.d.ts.map +0 -1
  41. package/lib/scripts/createLinks/cli/actions/CreateLinksAction.js +0 -91
  42. package/lib/scripts/createLinks/cli/actions/CreateLinksAction.js.map +0 -1
  43. package/lib/scripts/createLinks/cli/actions/RemoveLinksAction.d.ts +0 -10
  44. package/lib/scripts/createLinks/cli/actions/RemoveLinksAction.d.ts.map +0 -1
  45. package/lib/scripts/createLinks/cli/actions/RemoveLinksAction.js +0 -38
  46. package/lib/scripts/createLinks/cli/actions/RemoveLinksAction.js.map +0 -1
  47. package/lib/scripts/createLinks/start.d.ts +0 -2
  48. package/lib/scripts/createLinks/start.d.ts.map +0 -1
  49. package/lib/scripts/createLinks/start.js +0 -10
  50. package/lib/scripts/createLinks/start.js.map +0 -1
  51. package/lib/scripts/createLinks/utilities/CreateLinksUtilities.d.ts +0 -3
  52. package/lib/scripts/createLinks/utilities/CreateLinksUtilities.d.ts.map +0 -1
  53. package/lib/scripts/createLinks/utilities/CreateLinksUtilities.js +0 -14
  54. package/lib/scripts/createLinks/utilities/CreateLinksUtilities.js.map +0 -1
  55. package/lib/scripts/createLinks/utilities/constants.d.ts +0 -34
  56. package/lib/scripts/createLinks/utilities/constants.d.ts.map +0 -1
  57. package/lib/scripts/createLinks/utilities/constants.js +0 -44
  58. package/lib/scripts/createLinks/utilities/constants.js.map +0 -1
@@ -1,568 +0,0 @@
1
- "use strict";
2
- // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
3
- // See LICENSE in the project root for license information.
4
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
5
- if (k2 === undefined) k2 = k;
6
- var desc = Object.getOwnPropertyDescriptor(m, k);
7
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
8
- desc = { enumerable: true, get: function() { return m[k]; } };
9
- }
10
- Object.defineProperty(o, k2, desc);
11
- }) : (function(o, m, k, k2) {
12
- if (k2 === undefined) k2 = k;
13
- o[k2] = m[k];
14
- }));
15
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
16
- Object.defineProperty(o, "default", { enumerable: true, value: v });
17
- }) : function(o, v) {
18
- o["default"] = v;
19
- });
20
- var __importStar = (this && this.__importStar) || (function () {
21
- var ownKeys = function(o) {
22
- ownKeys = Object.getOwnPropertyNames || function (o) {
23
- var ar = [];
24
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
25
- return ar;
26
- };
27
- return ownKeys(o);
28
- };
29
- return function (mod) {
30
- if (mod && mod.__esModule) return mod;
31
- var result = {};
32
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
33
- __setModuleDefault(result, mod);
34
- return result;
35
- };
36
- })();
37
- var __importDefault = (this && this.__importDefault) || function (mod) {
38
- return (mod && mod.__esModule) ? mod : { "default": mod };
39
- };
40
- Object.defineProperty(exports, "__esModule", { value: true });
41
- exports.PackageExtractor = exports.TARGET_ROOT_SCRIPT_RELATIVE_PATH_TEMPLATE_STRING = void 0;
42
- const path = __importStar(require("node:path"));
43
- const minimatch_1 = require("minimatch");
44
- const semver_1 = __importDefault(require("semver"));
45
- const npm_packlist_1 = __importDefault(require("npm-packlist"));
46
- const ignore_1 = __importDefault(require("ignore"));
47
- const node_core_library_1 = require("@rushstack/node-core-library");
48
- const terminal_1 = require("@rushstack/terminal");
49
- const SymlinkAnalyzer_1 = require("./SymlinkAnalyzer");
50
- const AssetHandler_1 = require("./AssetHandler");
51
- const Utils_1 = require("./Utils");
52
- const PathConstants_1 = require("./PathConstants");
53
- const constants_1 = require("./scripts/createLinks/utilities/constants");
54
- exports.TARGET_ROOT_SCRIPT_RELATIVE_PATH_TEMPLATE_STRING = '{TARGET_ROOT_SCRIPT_RELATIVE_PATH}';
55
- /**
56
- * Manages the business logic for the "rush deploy" command.
57
- *
58
- * @public
59
- */
60
- class PackageExtractor {
61
- /**
62
- * Get a list of files that would be included in a package created from the provided package root path.
63
- *
64
- * @beta
65
- */
66
- static async getPackageIncludedFilesAsync(packageRootPath) {
67
- // Use npm-packlist to filter the files. Using the Walker class (instead of the default API) ensures
68
- // that "bundledDependencies" are not included.
69
- const walkerPromise = new Promise((resolve, reject) => {
70
- const walker = new npm_packlist_1.default.Walker({
71
- path: packageRootPath
72
- });
73
- walker.on('done', resolve).on('error', reject).start();
74
- });
75
- const npmPackFiles = await walkerPromise;
76
- return npmPackFiles;
77
- }
78
- /**
79
- * Extract a package using the provided options
80
- */
81
- async extractAsync(options) {
82
- options = PackageExtractor._normalizeOptions(options);
83
- const { terminal, projectConfigurations, sourceRootFolder, targetRootFolder, mainProjectName, overwriteExisting, dependencyConfigurations, linkCreation } = options;
84
- terminal.writeLine(terminal_1.Colorize.cyan(`Extracting to target folder: ${targetRootFolder}`));
85
- terminal.writeLine(terminal_1.Colorize.cyan(`Main project for extraction: ${mainProjectName}`));
86
- await node_core_library_1.FileSystem.ensureFolderAsync(targetRootFolder);
87
- const existingExtraction = (await node_core_library_1.FileSystem.readFolderItemNamesAsync(targetRootFolder)).length > 0;
88
- if (existingExtraction) {
89
- if (!overwriteExisting) {
90
- throw new Error('The extraction target folder is not empty. Overwrite must be explicitly requested');
91
- }
92
- terminal.writeLine('Deleting target folder contents...');
93
- terminal.writeLine('');
94
- await node_core_library_1.FileSystem.ensureEmptyFolderAsync(targetRootFolder);
95
- }
96
- // Create a new state for each run
97
- const symlinkAnalyzer = new SymlinkAnalyzer_1.SymlinkAnalyzer({
98
- requiredSourceParentPath: sourceRootFolder
99
- });
100
- const state = {
101
- symlinkAnalyzer,
102
- assetHandler: new AssetHandler_1.AssetHandler({ ...options, symlinkAnalyzer }),
103
- foldersToCopy: new Set(),
104
- packageJsonByPath: new Map(),
105
- projectConfigurationsByName: new Map(projectConfigurations.map((p) => [p.projectName, p])),
106
- projectConfigurationsByPath: new Map(projectConfigurations.map((p) => [p.projectFolder, p])),
107
- dependencyConfigurationsByName: new Map()
108
- };
109
- // set state dependencyConfigurationsByName
110
- for (const dependencyConfiguration of dependencyConfigurations || []) {
111
- const { dependencyName } = dependencyConfiguration;
112
- let existingDependencyConfigurations = state.dependencyConfigurationsByName.get(dependencyName);
113
- if (!existingDependencyConfigurations) {
114
- existingDependencyConfigurations = [];
115
- state.dependencyConfigurationsByName.set(dependencyName, existingDependencyConfigurations);
116
- }
117
- existingDependencyConfigurations.push(dependencyConfiguration);
118
- }
119
- await this._performExtractionAsync(options, state);
120
- await state.assetHandler.finalizeAsync({
121
- onAfterExtractSymlinksAsync: async () => {
122
- // We need the symlinks to be created before attempting to create the bin links, since it requires
123
- // the node_modules folder to be realized. While we're here, we may as well perform some specific
124
- // link creation tasks and write the extractor-metadata.json file before the asset handler finalizes.
125
- if (linkCreation === 'default') {
126
- await this._makeBinLinksAsync(options, state);
127
- }
128
- else if (linkCreation === 'script') {
129
- await this._writeCreateLinksScriptAsync(options, state);
130
- }
131
- terminal.writeLine('Creating extractor-metadata.json');
132
- await this._writeExtractorMetadataAsync(options, state);
133
- }
134
- });
135
- }
136
- static _normalizeOptions(options) {
137
- if (options.subspaces) {
138
- if (options.pnpmInstallFolder !== undefined) {
139
- throw new Error('IExtractorOptions.pnpmInstallFolder cannot be combined with IExtractorOptions.subspaces');
140
- }
141
- if (options.transformPackageJson !== undefined) {
142
- throw new Error('IExtractorOptions.transformPackageJson cannot be combined with IExtractorOptions.subspaces');
143
- }
144
- return options;
145
- }
146
- const normalizedOptions = { ...options };
147
- delete normalizedOptions.pnpmInstallFolder;
148
- delete normalizedOptions.transformPackageJson;
149
- normalizedOptions.subspaces = [
150
- {
151
- subspaceName: 'default',
152
- pnpmInstallFolder: options.pnpmInstallFolder,
153
- transformPackageJson: options.transformPackageJson
154
- }
155
- ];
156
- return normalizedOptions;
157
- }
158
- async _performExtractionAsync(options, state) {
159
- const { terminal, mainProjectName, sourceRootFolder, targetRootFolder, folderToCopy: additionalFolderToCopy, createArchiveOnly } = options;
160
- const { projectConfigurationsByName, foldersToCopy } = state;
161
- const mainProjectConfiguration = projectConfigurationsByName.get(mainProjectName);
162
- if (!mainProjectConfiguration) {
163
- throw new Error(`Main project "${mainProjectName}" was not found in the list of projects`);
164
- }
165
- // Calculate the set with additionalProjectsToInclude
166
- const includedProjectsSet = new Set([mainProjectConfiguration]);
167
- for (const { additionalProjectsToInclude } of includedProjectsSet) {
168
- if (additionalProjectsToInclude) {
169
- for (const additionalProjectNameToInclude of additionalProjectsToInclude) {
170
- const additionalProjectToInclude = projectConfigurationsByName.get(additionalProjectNameToInclude);
171
- if (!additionalProjectToInclude) {
172
- throw new Error(`Project "${additionalProjectNameToInclude}" was not found in the list of projects.`);
173
- }
174
- includedProjectsSet.add(additionalProjectToInclude);
175
- }
176
- }
177
- }
178
- for (const { projectName, projectFolder } of includedProjectsSet) {
179
- terminal.writeLine(terminal_1.Colorize.cyan(`Analyzing project: ${projectName}`));
180
- await this._collectFoldersAsync(projectFolder, options, state);
181
- }
182
- if (!createArchiveOnly) {
183
- terminal.writeLine(`Copying folders to target folder "${targetRootFolder}"`);
184
- }
185
- await node_core_library_1.Async.forEachAsync(foldersToCopy, async (folderToCopy) => {
186
- await this._extractFolderAsync(folderToCopy, options, state);
187
- }, {
188
- concurrency: constants_1.MAX_CONCURRENCY
189
- });
190
- if (additionalFolderToCopy) {
191
- // Copy the additional folder directly into the root of the target folder by setting the sourceRootFolder
192
- // to the root of the folderToCopy
193
- const additionalFolderPath = path.resolve(sourceRootFolder, additionalFolderToCopy);
194
- const additionalFolderExtractorOptions = {
195
- ...options,
196
- sourceRootFolder: additionalFolderPath,
197
- targetRootFolder
198
- };
199
- await this._extractFolderAsync(additionalFolderPath, additionalFolderExtractorOptions, state);
200
- }
201
- }
202
- /**
203
- * Recursively crawl the node_modules dependencies and collect the result in IExtractorState.foldersToCopy.
204
- */
205
- async _collectFoldersAsync(packageJsonFolder, options, state) {
206
- const { terminal, subspaces } = options;
207
- const { projectConfigurationsByPath } = state;
208
- const packageJsonFolderPathQueue = new node_core_library_1.AsyncQueue([packageJsonFolder]);
209
- await node_core_library_1.Async.forEachAsync(packageJsonFolderPathQueue, async ([packageJsonFolderPath, callback]) => {
210
- var _a, _b;
211
- const packageJsonRealFolderPath = await node_core_library_1.FileSystem.getRealPathAsync(packageJsonFolderPath);
212
- if (state.foldersToCopy.has(packageJsonRealFolderPath)) {
213
- // we've already seen this folder
214
- callback();
215
- return;
216
- }
217
- state.foldersToCopy.add(packageJsonRealFolderPath);
218
- const originalPackageJson = await node_core_library_1.JsonFile.loadAsync(path.join(packageJsonRealFolderPath, 'package.json'));
219
- const targetSubspace = subspaces === null || subspaces === void 0 ? void 0 : subspaces.find((subspace) => subspace.pnpmInstallFolder && node_core_library_1.Path.isUnder(packageJsonFolderPath, subspace.pnpmInstallFolder));
220
- // Transform packageJson using the provided transformer, if requested
221
- const packageJson = (_b = (_a = targetSubspace === null || targetSubspace === void 0 ? void 0 : targetSubspace.transformPackageJson) === null || _a === void 0 ? void 0 : _a.call(targetSubspace, originalPackageJson)) !== null && _b !== void 0 ? _b : originalPackageJson;
222
- state.packageJsonByPath.set(packageJsonRealFolderPath, packageJson);
223
- // Union of keys from regular dependencies, peerDependencies, optionalDependencies
224
- // (and possibly devDependencies if includeDevDependencies=true)
225
- const dependencyNamesToProcess = new Set();
226
- // Just the keys from optionalDependencies and peerDependencies
227
- const optionalDependencyNames = new Set();
228
- for (const name of Object.keys(packageJson.dependencies || {})) {
229
- dependencyNamesToProcess.add(name);
230
- }
231
- for (const name of Object.keys(packageJson.peerDependencies || {})) {
232
- dependencyNamesToProcess.add(name);
233
- optionalDependencyNames.add(name); // consider peers optional, since they are so frequently broken
234
- }
235
- for (const name of Object.keys(packageJson.optionalDependencies || {})) {
236
- dependencyNamesToProcess.add(name);
237
- optionalDependencyNames.add(name);
238
- }
239
- // Check to see if this is a local project
240
- const projectConfiguration = projectConfigurationsByPath.get(packageJsonRealFolderPath);
241
- if (projectConfiguration) {
242
- if (options.includeDevDependencies) {
243
- for (const name of Object.keys(packageJson.devDependencies || {})) {
244
- dependencyNamesToProcess.add(name);
245
- }
246
- }
247
- this._applyDependencyFilters(terminal, dependencyNamesToProcess, projectConfiguration.additionalDependenciesToInclude, projectConfiguration.dependenciesToExclude);
248
- }
249
- for (const dependencyPackageName of dependencyNamesToProcess) {
250
- try {
251
- const dependencyPackageFolderPath = await node_core_library_1.Import.resolvePackageAsync({
252
- packageName: dependencyPackageName,
253
- baseFolderPath: packageJsonRealFolderPath,
254
- getRealPathAsync: async (filePath) => {
255
- try {
256
- return (await state.symlinkAnalyzer.analyzePathAsync({ inputPath: filePath })).nodePath;
257
- }
258
- catch (error) {
259
- if (node_core_library_1.FileSystem.isFileDoesNotExistError(error)) {
260
- return filePath;
261
- }
262
- throw error;
263
- }
264
- }
265
- });
266
- packageJsonFolderPathQueue.push(dependencyPackageFolderPath);
267
- }
268
- catch (resolveErr) {
269
- if (optionalDependencyNames.has(dependencyPackageName)) {
270
- // Ignore missing optional dependency
271
- continue;
272
- }
273
- throw resolveErr;
274
- }
275
- }
276
- // Replicate the links to the virtual store. Note that if the package has not been hoisted by
277
- // PNPM, the package will not be resolvable from here.
278
- // Only apply this logic for packages that were actually installed under the common/temp folder.
279
- const realPnpmInstallFolder = targetSubspace === null || targetSubspace === void 0 ? void 0 : targetSubspace.pnpmInstallFolder;
280
- if (realPnpmInstallFolder && node_core_library_1.Path.isUnder(packageJsonFolderPath, realPnpmInstallFolder)) {
281
- try {
282
- // The PNPM virtual store links are created in this folder. We will resolve the current package
283
- // from that location and collect any additional links encountered along the way.
284
- // TODO: This can be configured via NPMRC. We should support that.
285
- const pnpmDotFolderPath = path.join(realPnpmInstallFolder, 'node_modules', '.pnpm');
286
- // TODO: Investigate how package aliases are handled by PNPM in this case. For example:
287
- //
288
- // "dependencies": {
289
- // "alias-name": "npm:real-name@^1.2.3"
290
- // }
291
- const dependencyPackageFolderPath = await node_core_library_1.Import.resolvePackageAsync({
292
- packageName: packageJson.name,
293
- baseFolderPath: pnpmDotFolderPath,
294
- getRealPathAsync: async (filePath) => {
295
- try {
296
- return (await state.symlinkAnalyzer.analyzePathAsync({ inputPath: filePath })).nodePath;
297
- }
298
- catch (error) {
299
- if (node_core_library_1.FileSystem.isFileDoesNotExistError(error)) {
300
- return filePath;
301
- }
302
- throw error;
303
- }
304
- }
305
- });
306
- packageJsonFolderPathQueue.push(dependencyPackageFolderPath);
307
- }
308
- catch (resolveErr) {
309
- // The virtual store link isn't guaranteed to exist, so ignore if it's missing
310
- // NOTE: If you encounter this warning a lot, please report it to the Rush maintainers.
311
- // eslint-disable-next-line no-console
312
- console.log('Ignoring missing PNPM virtual store link for ' + packageJsonFolderPath);
313
- }
314
- }
315
- callback();
316
- }, {
317
- concurrency: constants_1.MAX_CONCURRENCY
318
- });
319
- }
320
- _applyDependencyFilters(terminal, allDependencyNames, additionalDependenciesToInclude = [], dependenciesToExclude = []) {
321
- // Track packages that got added/removed for reporting purposes
322
- const extraIncludedPackageNames = [];
323
- const extraExcludedPackageNames = [];
324
- for (const patternWithStar of dependenciesToExclude) {
325
- for (const dependency of allDependencyNames) {
326
- if ((0, Utils_1.matchesWithStar)(patternWithStar, dependency)) {
327
- if (allDependencyNames.delete(dependency)) {
328
- extraExcludedPackageNames.push(dependency);
329
- }
330
- }
331
- }
332
- }
333
- for (const dependencyToInclude of additionalDependenciesToInclude) {
334
- if (!allDependencyNames.has(dependencyToInclude)) {
335
- allDependencyNames.add(dependencyToInclude);
336
- extraIncludedPackageNames.push(dependencyToInclude);
337
- }
338
- }
339
- if (extraIncludedPackageNames.length > 0) {
340
- extraIncludedPackageNames.sort();
341
- terminal.writeLine(`Extra dependencies included by settings: ${extraIncludedPackageNames.join(', ')}`);
342
- }
343
- if (extraExcludedPackageNames.length > 0) {
344
- extraExcludedPackageNames.sort();
345
- terminal.writeLine(`Extra dependencies excluded by settings: ${extraExcludedPackageNames.join(', ')}`);
346
- }
347
- return allDependencyNames;
348
- }
349
- /**
350
- * Copy one package folder to the extractor target folder.
351
- */
352
- async _extractFolderAsync(sourceFolderPath, options, state) {
353
- const { includeNpmIgnoreFiles } = options;
354
- const { projectConfigurationsByPath, packageJsonByPath, dependencyConfigurationsByName, assetHandler } = state;
355
- let useNpmIgnoreFilter = false;
356
- const sourceFolderRealPath = await node_core_library_1.FileSystem.getRealPathAsync(sourceFolderPath);
357
- const sourceProjectConfiguration = projectConfigurationsByPath.get(sourceFolderRealPath);
358
- const packagesJson = packageJsonByPath.get(sourceFolderRealPath);
359
- // As this function will be used to copy folder for both project inside monorepo and third party
360
- // dependencies insides node_modules. Third party dependencies won't have project configurations
361
- const isLocalProject = !!sourceProjectConfiguration;
362
- // Function to filter files inside local project or third party dependencies.
363
- const isFileExcluded = (filePath) => {
364
- // Encapsulate exclude logic into a function, so it can be reused.
365
- const excludeFileByPatterns = (patternsToInclude, patternsToExclude) => {
366
- let includeFilters;
367
- let excludeFilters;
368
- if (patternsToInclude === null || patternsToInclude === void 0 ? void 0 : patternsToInclude.length) {
369
- includeFilters = patternsToInclude === null || patternsToInclude === void 0 ? void 0 : patternsToInclude.map((p) => new minimatch_1.Minimatch(p, { dot: true }));
370
- }
371
- if (patternsToExclude === null || patternsToExclude === void 0 ? void 0 : patternsToExclude.length) {
372
- excludeFilters = patternsToExclude === null || patternsToExclude === void 0 ? void 0 : patternsToExclude.map((p) => new minimatch_1.Minimatch(p, { dot: true }));
373
- }
374
- // If there are no filters, then we can't exclude anything.
375
- if (!includeFilters && !excludeFilters) {
376
- return false;
377
- }
378
- const isIncluded = !includeFilters || includeFilters.some((m) => m.match(filePath));
379
- // If the file is not included, then we don't need to check the excludeFilter. If it is included
380
- // and there is no exclude filter, then we know that the file is not excluded. If it is included
381
- // and there is an exclude filter, then we need to check for a match.
382
- return !isIncluded || !!(excludeFilters === null || excludeFilters === void 0 ? void 0 : excludeFilters.some((m) => m.match(filePath)));
383
- };
384
- if (isLocalProject) {
385
- return excludeFileByPatterns(sourceProjectConfiguration === null || sourceProjectConfiguration === void 0 ? void 0 : sourceProjectConfiguration.patternsToInclude, sourceProjectConfiguration === null || sourceProjectConfiguration === void 0 ? void 0 : sourceProjectConfiguration.patternsToExclude);
386
- }
387
- else {
388
- if (!packagesJson) {
389
- return false;
390
- }
391
- const dependenciesConfigurations = dependencyConfigurationsByName.get(packagesJson.name);
392
- if (!dependenciesConfigurations) {
393
- return false;
394
- }
395
- const matchedDependenciesConfigurations = dependenciesConfigurations.filter((d) => semver_1.default.satisfies(packagesJson.version, d.dependencyVersionRange));
396
- return matchedDependenciesConfigurations.some((d) => excludeFileByPatterns(d.patternsToInclude, d.patternsToExclude));
397
- }
398
- };
399
- if (sourceProjectConfiguration && !includeNpmIgnoreFiles) {
400
- // Only use the npmignore filter if the project configuration explicitly asks for it
401
- useNpmIgnoreFilter = true;
402
- }
403
- const targetFolderPath = (0, Utils_1.remapSourcePathForTargetFolder)({
404
- ...options,
405
- sourcePath: sourceFolderPath
406
- });
407
- if (useNpmIgnoreFilter) {
408
- const npmPackFiles = await PackageExtractor.getPackageIncludedFilesAsync(sourceFolderPath);
409
- await node_core_library_1.Async.forEachAsync(npmPackFiles, async (npmPackFile) => {
410
- // In issue https://github.com/microsoft/rushstack/issues/2121 we found that npm-packlist sometimes returns
411
- // duplicate file paths, for example:
412
- //
413
- // 'dist//index.js'
414
- // 'dist/index.js'
415
- //
416
- // Filter out files that are excluded by the project configuration or dependency configuration.
417
- if (isFileExcluded(npmPackFile)) {
418
- return;
419
- }
420
- const sourceFilePath = path.resolve(sourceFolderPath, npmPackFile);
421
- const { kind, linkStats: sourceFileStats } = await state.symlinkAnalyzer.analyzePathAsync({
422
- inputPath: sourceFilePath
423
- });
424
- if (kind === 'file') {
425
- const targetFilePath = path.resolve(targetFolderPath, npmPackFile);
426
- await assetHandler.includeAssetAsync({
427
- sourceFilePath,
428
- sourceFileStats,
429
- targetFilePath
430
- });
431
- }
432
- }, {
433
- concurrency: constants_1.MAX_CONCURRENCY
434
- });
435
- }
436
- else {
437
- // use a simplistic "ignore" ruleset to filter the files
438
- const ignoreFilter = (0, ignore_1.default)();
439
- ignoreFilter.add([
440
- // The top-level node_modules folder is always excluded
441
- '/node_modules',
442
- // Also exclude well-known folders that can contribute a lot of unnecessary files
443
- '**/.git',
444
- '**/.svn',
445
- '**/.hg',
446
- '**/.DS_Store'
447
- ]);
448
- // Do a breadth-first search of the source folder, copying each file to the target folder
449
- const queue = new node_core_library_1.AsyncQueue([sourceFolderPath]);
450
- await node_core_library_1.Async.forEachAsync(queue, async ([sourcePath, callback]) => {
451
- const relativeSourcePath = path.relative(sourceFolderPath, sourcePath);
452
- if (relativeSourcePath !== '' && ignoreFilter.ignores(relativeSourcePath)) {
453
- callback();
454
- return;
455
- }
456
- const sourcePathNode = await state.symlinkAnalyzer.analyzePathAsync({
457
- inputPath: sourcePath,
458
- // Treat all links to external paths as if they are files for this scenario. In the future, we may
459
- // want to explore the target of the external link to see if all files within the target are
460
- // excluded, and throw if they are not.
461
- shouldIgnoreExternalLink: (linkSourcePath) => {
462
- // Ignore the provided linkSourcePath since it may not be the first link in the chain. Instead,
463
- // we will consider only the relativeSourcePath, since that would be our entrypoint into the
464
- // link chain.
465
- return isFileExcluded(relativeSourcePath);
466
- }
467
- });
468
- if (sourcePathNode === undefined) {
469
- // The target was a symlink that is excluded. We don't need to do anything.
470
- callback();
471
- return;
472
- }
473
- else if (sourcePathNode.kind === 'file') {
474
- // Only ignore files and not folders to ensure that we traverse the contents of all folders. This is
475
- // done so that we can match against subfolder patterns, ex. "src/subfolder/**/*"
476
- if (relativeSourcePath !== '' && isFileExcluded(relativeSourcePath)) {
477
- callback();
478
- return;
479
- }
480
- const targetFilePath = path.resolve(targetFolderPath, relativeSourcePath);
481
- await assetHandler.includeAssetAsync({
482
- sourceFilePath: sourcePath,
483
- sourceFileStats: sourcePathNode.linkStats,
484
- targetFilePath
485
- });
486
- }
487
- else if (sourcePathNode.kind === 'folder') {
488
- const children = await node_core_library_1.FileSystem.readFolderItemNamesAsync(sourcePath);
489
- for (const child of children) {
490
- queue.push(path.join(sourcePath, child));
491
- }
492
- }
493
- callback();
494
- }, {
495
- concurrency: constants_1.MAX_CONCURRENCY
496
- });
497
- }
498
- }
499
- /**
500
- * Write the common/deploy/deploy-metadata.json file.
501
- */
502
- async _writeExtractorMetadataAsync(options, state) {
503
- const { mainProjectName, sourceRootFolder, targetRootFolder, linkCreation, linkCreationScriptPath } = options;
504
- const { projectConfigurationsByPath } = state;
505
- const extractorMetadataFolderPath = linkCreation === 'script' && linkCreationScriptPath
506
- ? path.dirname(path.resolve(targetRootFolder, linkCreationScriptPath))
507
- : targetRootFolder;
508
- const extractorMetadataFilePath = path.join(extractorMetadataFolderPath, PathConstants_1.EXTRACTOR_METADATA_FILENAME);
509
- const extractorMetadataJson = {
510
- mainProjectName,
511
- projects: [],
512
- links: [],
513
- files: []
514
- };
515
- for (const { projectFolder, projectName } of projectConfigurationsByPath.values()) {
516
- if (state.foldersToCopy.has(projectFolder)) {
517
- extractorMetadataJson.projects.push({
518
- projectName,
519
- path: (0, Utils_1.remapPathForExtractorMetadata)(sourceRootFolder, projectFolder)
520
- });
521
- }
522
- }
523
- // Remap the links to be relative to target folder
524
- for (const { kind, linkPath, targetPath } of state.symlinkAnalyzer.reportSymlinks()) {
525
- extractorMetadataJson.links.push({
526
- kind,
527
- linkPath: (0, Utils_1.remapPathForExtractorMetadata)(sourceRootFolder, linkPath),
528
- targetPath: (0, Utils_1.remapPathForExtractorMetadata)(sourceRootFolder, targetPath)
529
- });
530
- }
531
- for (const assetPath of state.assetHandler.assetPaths) {
532
- extractorMetadataJson.files.push((0, Utils_1.remapPathForExtractorMetadata)(targetRootFolder, assetPath));
533
- }
534
- const extractorMetadataFileContent = JSON.stringify(extractorMetadataJson, undefined, 0);
535
- await state.assetHandler.includeAssetAsync({
536
- sourceFileContent: extractorMetadataFileContent,
537
- targetFilePath: extractorMetadataFilePath
538
- });
539
- }
540
- async _makeBinLinksAsync(options, state) {
541
- const { terminal } = options;
542
- const extractedProjectFolderPaths = [];
543
- for (const folderPath of state.projectConfigurationsByPath.keys()) {
544
- if (state.foldersToCopy.has(folderPath)) {
545
- extractedProjectFolderPaths.push((0, Utils_1.remapSourcePathForTargetFolder)({ ...options, sourcePath: folderPath }));
546
- }
547
- }
548
- const binFilePaths = await (0, Utils_1.makeBinLinksAsync)(terminal, extractedProjectFolderPaths);
549
- await node_core_library_1.Async.forEachAsync(binFilePaths, (targetFilePath) => state.assetHandler.includeAssetAsync({ targetFilePath }), {
550
- concurrency: constants_1.MAX_CONCURRENCY
551
- });
552
- }
553
- async _writeCreateLinksScriptAsync(options, state) {
554
- const { terminal, targetRootFolder, linkCreationScriptPath } = options;
555
- const { assetHandler } = state;
556
- terminal.writeLine(`Creating ${PathConstants_1.CREATE_LINKS_SCRIPT_FILENAME}`);
557
- const createLinksSourceFilePath = `${PathConstants_1.SCRIPTS_FOLDER_PATH}/${PathConstants_1.CREATE_LINKS_SCRIPT_FILENAME}`;
558
- const createLinksTargetFilePath = path.resolve(targetRootFolder, linkCreationScriptPath || PathConstants_1.CREATE_LINKS_SCRIPT_FILENAME);
559
- let createLinksScriptContent = await node_core_library_1.FileSystem.readFileAsync(createLinksSourceFilePath);
560
- createLinksScriptContent = createLinksScriptContent.replace(exports.TARGET_ROOT_SCRIPT_RELATIVE_PATH_TEMPLATE_STRING, node_core_library_1.Path.convertToSlashes(path.relative(path.dirname(createLinksTargetFilePath), targetRootFolder)));
561
- await assetHandler.includeAssetAsync({
562
- sourceFileContent: createLinksScriptContent,
563
- targetFilePath: createLinksTargetFilePath
564
- });
565
- }
566
- }
567
- exports.PackageExtractor = PackageExtractor;
568
- //# sourceMappingURL=PackageExtractor.js.map