UNPKG

@pnpm/core

Version:

Fast, disk space efficient installation engine

143 lines 6.66 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.validateModules = validateModules; const fs_1 = require("fs"); const path_1 = __importDefault(require("path")); const error_1 = require("@pnpm/error"); const logger_1 = require("@pnpm/logger"); const types_1 = require("@pnpm/types"); const rimraf_1 = __importDefault(require("@zkochan/rimraf")); const enquirer_1 = __importDefault(require("enquirer")); const equals_1 = __importDefault(require("ramda/src/equals")); const index_js_1 = require("./checkCompatibility/index.js"); async function validateModules(modules, projects, opts) { const rootProject = projects.find(({ id }) => id === '.'); if (opts.virtualStoreDirMaxLength !== modules.virtualStoreDirMaxLength) { if (opts.forceNewModules && (rootProject != null)) { await purgeModulesDirsOfImporter(opts, rootProject); return { purged: true }; } throw new error_1.PnpmError('VIRTUAL_STORE_DIR_MAX_LENGTH_DIFF', 'This modules directory was created using a different virtual-store-dir-max-length value.' + ' Run "pnpm install" to recreate the modules directory.'); } if (opts.forcePublicHoistPattern && // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing !(0, equals_1.default)(modules.publicHoistPattern, opts.publicHoistPattern || undefined)) { if (opts.forceNewModules && (rootProject != null)) { await purgeModulesDirsOfImporter(opts, rootProject); return { purged: true }; } throw new error_1.PnpmError('PUBLIC_HOIST_PATTERN_DIFF', 'This modules directory was created using a different public-hoist-pattern value.' + ' Run "pnpm install" to recreate the modules directory.'); } const importersToPurge = []; if (opts.forceHoistPattern && (rootProject != null)) { try { // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing if (!(0, equals_1.default)(opts.currentHoistPattern, opts.hoistPattern || undefined)) { throw new error_1.PnpmError('HOIST_PATTERN_DIFF', 'This modules directory was created using a different hoist-pattern value.' + ' Run "pnpm install" to recreate the modules directory.'); } } catch (err) { // eslint-disable-line if (!opts.forceNewModules) throw err; importersToPurge.push(rootProject); } } for (const project of projects) { try { (0, index_js_1.checkCompatibility)(modules, { modulesDir: project.modulesDir, storeDir: opts.storeDir, virtualStoreDir: opts.virtualStoreDir, }); if (opts.lockfileDir !== project.rootDir && (opts.include != null) && modules.included) { for (const depsField of types_1.DEPENDENCIES_FIELDS) { if (opts.include[depsField] !== modules.included[depsField]) { throw new error_1.PnpmError('INCLUDED_DEPS_CONFLICT', `modules directory (at "${opts.lockfileDir}") was installed with ${stringifyIncludedDeps(modules.included)}. ` + `Current install wants ${stringifyIncludedDeps(opts.include)}.`); } } } } catch (err) { // eslint-disable-line if (!opts.forceNewModules) throw err; importersToPurge.push(project); } } if (importersToPurge.length > 0 && (rootProject == null)) { importersToPurge.push({ modulesDir: path_1.default.join(opts.lockfileDir, opts.modulesDir), rootDir: opts.lockfileDir, }); } const purged = importersToPurge.length > 0; if (purged) { await purgeModulesDirsOfImporters(opts, importersToPurge); } return { purged }; } async function purgeModulesDirsOfImporter(opts, importer) { return purgeModulesDirsOfImporters(opts, [importer]); } async function purgeModulesDirsOfImporters(opts, importers) { if (opts.confirmModulesPurge ?? true) { if (!process.stdin.isTTY) { throw new error_1.PnpmError('ABORTED_REMOVE_MODULES_DIR_NO_TTY', 'Aborted removal of modules directory due to no TTY', { hint: 'If you are running pnpm in CI, set the CI environment variable to "true".', }); } const confirmed = await enquirer_1.default.prompt({ type: 'confirm', name: 'question', message: importers.length === 1 ? `The modules directory at "${importers[0].modulesDir}" will be removed and reinstalled from scratch. Proceed?` : 'The modules directories will be removed and reinstalled from scratch. Proceed?', initial: true, }); if (!confirmed.question) { throw new error_1.PnpmError('ABORTED_REMOVE_MODULES_DIR', 'Aborted removal of modules directory'); } } await Promise.all(importers.map(async (importer) => { logger_1.logger.info({ message: `Recreating ${importer.modulesDir}`, prefix: importer.rootDir, }); try { // We don't remove the actual modules directory, just the contents of it. // 1. we will need the directory anyway. // 2. in some setups, pnpm won't even have permission to remove the modules directory. await removeContentsOfDir(importer.modulesDir, opts.virtualStoreDir); } catch (err) { // eslint-disable-line if (err.code !== 'ENOENT') throw err; } })); } async function removeContentsOfDir(dir, virtualStoreDir) { const items = await fs_1.promises.readdir(dir); await Promise.all(items.map(async (item) => { // The non-pnpm related hidden files are kept if (item[0] === '.' && item !== '.bin' && item !== '.modules.yaml' && !dirsAreEqual(path_1.default.join(dir, item), virtualStoreDir)) { return; } await (0, rimraf_1.default)(path_1.default.join(dir, item)); })); } function dirsAreEqual(dir1, dir2) { return path_1.default.relative(dir1, dir2) === ''; } function stringifyIncludedDeps(included) { return types_1.DEPENDENCIES_FIELDS.filter((depsField) => included[depsField]).join(', '); } //# sourceMappingURL=validateModules.js.map