UNPKG

@rushstack/package-extractor

Version:

A library for bundling selected files and dependencies into a deployable package.

91 lines 5.68 kB
"use strict"; // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.CreateLinksAction = void 0; const node_path_1 = __importDefault(require("node:path")); const node_core_library_1 = require("@rushstack/node-core-library"); const ts_command_line_1 = require("@rushstack/ts-command-line"); const Utils_1 = require("../../../../Utils"); const CreateLinksUtilities_1 = require("../../utilities/CreateLinksUtilities"); const constants_1 = require("../../utilities/constants"); const RemoveLinksAction_1 = require("./RemoveLinksAction"); async function createLinksAsync(terminal, targetRootFolder, extractorMetadataObject) { await node_core_library_1.Async.forEachAsync(extractorMetadataObject.links, async (linkInfo) => { // Link to the relative path for symlinks const newLinkPath = node_path_1.default.join(targetRootFolder, linkInfo.linkPath); const linkTargetPath = node_path_1.default.join(targetRootFolder, linkInfo.targetPath); // Make sure the containing folder exists await node_core_library_1.FileSystem.ensureFolderAsync(node_path_1.default.dirname(newLinkPath)); // NOTE: This logic is based on NpmLinkManager._createSymlink() if (linkInfo.kind === 'folderLink') { terminal.writeVerboseLine(`Creating linked folder at path "${newLinkPath}"`); await node_core_library_1.FileSystem.createSymbolicLinkJunctionAsync({ newLinkPath, linkTargetPath }); } else if (linkInfo.kind === 'fileLink') { // Use hardlinks for Windows and symlinks for other platforms since creating a symbolic link // requires administrator permission on Windows. This may cause unexpected behaviour for consumers // of the hardlinked files. If this becomes an issue, we may need to revisit this. terminal.writeVerboseLine(`Creating linked file at path "${newLinkPath}"`); if (process.platform === 'win32') { await node_core_library_1.FileSystem.createHardLinkAsync({ newLinkPath, linkTargetPath }); } else { await node_core_library_1.FileSystem.createSymbolicLinkFileAsync({ newLinkPath, linkTargetPath }); } } }, { concurrency: constants_1.MAX_CONCURRENCY }); } async function realizeFilesAsync(terminal, targetRootFolder, extractorMetadataObject) { await node_core_library_1.Async.forEachAsync(extractorMetadataObject.files, async (relativeFilePath) => { const filePath = `${targetRootFolder}/${relativeFilePath}`; const realFilePath = await node_core_library_1.FileSystem.getRealPathAsync(filePath); if (!node_core_library_1.Path.isEqual(realFilePath, filePath)) { // Delete the existing symlink and create a hardlink to the real file, since creating hardlinks // is less overhead than copying the file. terminal.writeVerboseLine(`Realizing file at path "${filePath}"`); await node_core_library_1.FileSystem.deleteFileAsync(filePath); await node_core_library_1.FileSystem.createHardLinkAsync({ newLinkPath: filePath, linkTargetPath: realFilePath }); } }, { concurrency: constants_1.MAX_CONCURRENCY }); } class CreateLinksAction extends ts_command_line_1.CommandLineAction { constructor(terminal) { super({ actionName: 'create', summary: 'Create symlinks for extraction', documentation: 'This action creates symlinks for the extraction process.' }); this._terminal = terminal; this._realizeFilesParameter = this.defineFlagParameter({ parameterLongName: constants_1.REALIZE_FILES_PARAMETER_NAME, description: 'Realize files instead of creating symlinks' }); this._linkBinsParameter = this.defineFlagParameter({ parameterLongName: constants_1.LINK_BINS_PARAMETER_NAME, description: 'Create the .bin files for extracted packages' }); } async onExecuteAsync() { const extractorMetadataObject = await (0, CreateLinksUtilities_1.getExtractorMetadataAsync)(); const realizeFiles = this._realizeFilesParameter.value; const linkBins = this._linkBinsParameter.value; this._terminal.writeLine(`Creating links for extraction at path "${constants_1.TARGET_ROOT_FOLDER}"`); await (0, RemoveLinksAction_1.removeLinksAsync)(this._terminal, constants_1.TARGET_ROOT_FOLDER, extractorMetadataObject); await createLinksAsync(this._terminal, constants_1.TARGET_ROOT_FOLDER, extractorMetadataObject); if (realizeFiles) { this._terminal.writeLine(`Realizing files for extraction at path "${constants_1.TARGET_ROOT_FOLDER}"`); await realizeFilesAsync(this._terminal, constants_1.TARGET_ROOT_FOLDER, extractorMetadataObject); } if (linkBins) { this._terminal.writeLine(`Linking bins for extraction at path "${constants_1.TARGET_ROOT_FOLDER}"`); const extractedProjectFolderPaths = extractorMetadataObject.projects.map((project) => node_path_1.default.join(constants_1.TARGET_ROOT_FOLDER, project.path)); await (0, Utils_1.makeBinLinksAsync)(this._terminal, extractedProjectFolderPaths); } } } exports.CreateLinksAction = CreateLinksAction; //# sourceMappingURL=CreateLinksAction.js.map