UNPKG

@ts-common/azure-js-dev-tools

Version:

Developer dependencies for TypeScript related projects

466 lines 27.2 kB
"use strict"; /** * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for * license information. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.changeClonedDependenciesTo = exports.findPackage = void 0; var tslib_1 = require("tslib"); var arrays_1 = require("./arrays"); var commandLine_1 = require("./commandLine"); var fileSystem2_1 = require("./fileSystem2"); var logger_1 = require("./logger"); var npm_1 = require("./npm"); var packageJson_1 = require("./packageJson"); var path_1 = require("./path"); /** * Update the provided dependencies using the provided dependencyType then return the dependencies * that were changed. */ function updateDependencies(clonedPackage, dependencies, dependencyType, clonedPackages, logger) { return tslib_1.__awaiter(this, void 0, void 0, function () { var changed, _a, _b, dependencyName, dependencyVersion, dependencyTargetVersion, e_1_1; var e_1, _c; return tslib_1.__generator(this, function (_d) { switch (_d.label) { case 0: changed = []; if (!dependencies) return [3 /*break*/, 9]; _d.label = 1; case 1: _d.trys.push([1, 7, 8, 9]); _a = tslib_1.__values(Object.keys(dependencies)), _b = _a.next(); _d.label = 2; case 2: if (!!_b.done) return [3 /*break*/, 6]; dependencyName = _b.value; if (!arrays_1.contains(clonedPackage.dependenciesToIgnore, dependencyName)) return [3 /*break*/, 3]; logger.logVerbose(" Not updating " + dependencyName + " because it has been marked as ignored."); return [3 /*break*/, 5]; case 3: logger.logVerbose(" Attempting to update dependency version for " + dependencyName + "..."); dependencyVersion = dependencies[dependencyName]; logger.logVerbose(" Current dependency version: " + dependencyVersion); return [4 /*yield*/, getDependencyTargetVersion(clonedPackage, dependencyName, dependencyType, clonedPackages, logger)]; case 4: dependencyTargetVersion = _d.sent(); logger.logVerbose(" Target dependency version: " + dependencyTargetVersion); if (!dependencyTargetVersion) { logger.logVerbose(" No target dependency version found."); } else if (dependencyVersion === dependencyTargetVersion) { logger.logVerbose(" The target dependency version is already the current dependency version."); } else { logger.logInfo(" Changing \"" + dependencyName + "\" from \"" + dependencyVersion + "\" to \"" + dependencyTargetVersion + "\"..."); dependencies[dependencyName] = dependencyTargetVersion; changed.push(dependencyName); } _d.label = 5; case 5: _b = _a.next(); return [3 /*break*/, 2]; case 6: return [3 /*break*/, 9]; case 7: e_1_1 = _d.sent(); e_1 = { error: e_1_1 }; return [3 /*break*/, 9]; case 8: try { if (_b && !_b.done && (_c = _a.return)) _c.call(_a); } finally { if (e_1) throw e_1.error; } return [7 /*endfinally*/]; case 9: return [2 /*return*/, changed]; } }); }); } /** * Find the path to the folder that contains a package.json file with the provided package name. */ function findPackage(packageName, startPath, clonedPackages, logger) { return tslib_1.__awaiter(this, void 0, void 0, function () { var result, normalizedStartPath, visitedFolders_1, foldersToVisit_1, addFolderToVisit, folderPath, packageJsonFilePath, packageJson, parentFolderPath, _a, _b, childFolderPath, e_2_1; var e_2, _c; return tslib_1.__generator(this, function (_d) { switch (_d.label) { case 0: if (!(clonedPackages && packageName in clonedPackages)) return [3 /*break*/, 1]; result = clonedPackages[packageName]; return [3 /*break*/, 16]; case 1: normalizedStartPath = path_1.normalizePath(startPath); visitedFolders_1 = []; foldersToVisit_1 = []; addFolderToVisit = function (folderPath) { if (!arrays_1.contains(visitedFolders_1, folderPath) && !arrays_1.contains(foldersToVisit_1, folderPath)) { foldersToVisit_1.push(folderPath); } }; return [4 /*yield*/, fileSystem2_1.fileExists(normalizedStartPath)]; case 2: if (!_d.sent()) return [3 /*break*/, 3]; foldersToVisit_1.push(path_1.getParentFolderPath(normalizedStartPath)); return [3 /*break*/, 5]; case 3: return [4 /*yield*/, fileSystem2_1.folderExists(normalizedStartPath)]; case 4: if (_d.sent()) { foldersToVisit_1.push(normalizedStartPath); } _d.label = 5; case 5: if (!(foldersToVisit_1.length > 0)) return [3 /*break*/, 15]; folderPath = foldersToVisit_1.shift(); visitedFolders_1.push(folderPath); packageJsonFilePath = path_1.joinPath(folderPath, "package.json"); logger && logger.logVerbose("Looking for package \"" + packageName + "\" at \"" + packageJsonFilePath + "\"..."); return [4 /*yield*/, fileSystem2_1.fileExists(packageJsonFilePath)]; case 6: if (_d.sent()) { logger && logger.logVerbose("\"" + packageJsonFilePath + "\" file exists. Comparing package names..."); packageJson = packageJson_1.readPackageJsonFileSync(packageJsonFilePath); if (packageJson.name) { if (packageJson.name === packageName) { result = { path: folderPath }; return [3 /*break*/, 15]; } } } if (!!result) return [3 /*break*/, 14]; parentFolderPath = path_1.getParentFolderPath(folderPath); if (!parentFolderPath) return [3 /*break*/, 14]; addFolderToVisit(parentFolderPath); _d.label = 7; case 7: _d.trys.push([7, 12, 13, 14]); e_2 = void 0; return [4 /*yield*/, fileSystem2_1.getChildFolderPaths(parentFolderPath)]; case 8: _a = (tslib_1.__values.apply(void 0, [(_d.sent())])), _b = _a.next(); _d.label = 9; case 9: if (!!_b.done) return [3 /*break*/, 11]; childFolderPath = _b.value; addFolderToVisit(childFolderPath); _d.label = 10; case 10: _b = _a.next(); return [3 /*break*/, 9]; case 11: return [3 /*break*/, 14]; case 12: e_2_1 = _d.sent(); e_2 = { error: e_2_1 }; return [3 /*break*/, 14]; case 13: try { if (_b && !_b.done && (_c = _a.return)) _c.call(_a); } finally { if (e_2) throw e_2.error; } return [7 /*endfinally*/]; case 14: return [3 /*break*/, 5]; case 15: if (clonedPackages) { clonedPackages[packageName] = result; } _d.label = 16; case 16: return [2 /*return*/, result]; } }); }); } exports.findPackage = findPackage; function getDependencyTargetVersion(clonedPackage, dependencyName, dependencyType, clonedPackages, logger) { return tslib_1.__awaiter(this, void 0, void 0, function () { var result, dependencyClonedPackage, dependencyViewResult, distTags; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, findPackage(dependencyName, clonedPackage.path, clonedPackages, logger)]; case 1: dependencyClonedPackage = _a.sent(); if (!!dependencyClonedPackage) return [3 /*break*/, 2]; logger && logger.logVerbose(" No cloned package found named " + dependencyName + "."); return [3 /*break*/, 6]; case 2: if (!!dependencyClonedPackage.targetVersion) return [3 /*break*/, 5]; if (!(dependencyType === "local")) return [3 /*break*/, 3]; dependencyClonedPackage.targetVersion = "file:" + dependencyClonedPackage.path; return [3 /*break*/, 5]; case 3: if (!(dependencyType === "latest")) return [3 /*break*/, 5]; return [4 /*yield*/, npm_1.npmView({ packageName: dependencyName })]; case 4: dependencyViewResult = _a.sent(); distTags = dependencyViewResult["dist-tags"]; dependencyClonedPackage.targetVersion = distTags && distTags["latest"]; if (dependencyClonedPackage.targetVersion) { dependencyClonedPackage.targetVersion = "^" + dependencyClonedPackage.targetVersion; } else { dependencyClonedPackage.targetVersion = dependencyClonedPackage.defaultVersion; } _a.label = 5; case 5: result = dependencyClonedPackage.targetVersion; _a.label = 6; case 6: return [2 /*return*/, result]; } }); }); } /** * Change all of the cloned dependencies in the package found at the provided package path to the * provided dependency type. */ function changeClonedDependenciesTo(packagePath, dependencyType, options) { if (options === void 0) { options = {}; } return tslib_1.__awaiter(this, void 0, void 0, function () { var logger, recursive, forceInstall, includeAzureJsDevTools, exitCode, clonedPackages, packageFolderPathsToVisit, packageFolderPathsVisited, packagePathsToAdd, packageFolderPaths, _loop_1, packagePathsToAdd_1, packagePathsToAdd_1_1, packagePathToAdd, state_1, folderPathsToRunNPMInstallIn, packageFolderPath, packageJsonFilePath, packageJson, packageName, clonedPackage, dependenciesChanged, devDependenciesChanged, packageLockJsonFilePath, packageLockJson, allDependencyNames, allDependencyNames_1, allDependencyNames_1_1, dependencyName, clonedDependency, clonedDependencyFolderPath, folderPathsToRunNPMInstallIn_1, folderPathsToRunNPMInstallIn_1_1, folderPath, e_3_1, _a, _b, extraFileToUpdate, originalFileContents, updatedFileContents, _c, _d, clonedPackageName, clonedPackage, regularExpression, match, e_4_1; var e_5, _e, e_6, _f, e_3, _g, e_4, _h, e_7, _j; return tslib_1.__generator(this, function (_k) { switch (_k.label) { case 0: logger = options.logger || logger_1.getDefaultLogger(); recursive = commandLine_1.getBooleanArgument("recursive", { defaultValue: true }); forceInstall = commandLine_1.getBooleanArgument("force-install", { defaultValue: false }); includeAzureJsDevTools = commandLine_1.getBooleanArgument("include-azure-js-dev-tools", { defaultValue: false }); exitCode = 0; clonedPackages = {}; packageFolderPathsToVisit = []; packageFolderPathsVisited = []; packagePathsToAdd = []; if (!options.packageFolders) { packagePathsToAdd.push(packagePath); } else { packageFolderPaths = options.packageFolders.map(function (packageFolder) { return typeof packageFolder === "string" ? packageFolder : packageFolder.path; }); packagePathsToAdd.push.apply(packagePathsToAdd, tslib_1.__spread(packageFolderPaths)); } _loop_1 = function (packagePathToAdd) { // logger.logInfo(`Looking for package.json file at or above "${packagePathToAdd}"...`); var packageJsonFilePath = packageJson_1.findPackageJsonFileSync(packagePathToAdd); if (!packageJsonFilePath) { logger.logError("Could not find a package.json at or above the provided package path (" + packagePathToAdd + ")."); exitCode = 1; return "break"; } else { // logger.logInfo(`Found package.json file at "${packageJsonFilePath}".`); var packageFolderPath = path_1.getParentFolderPath(packageJsonFilePath); var packageJson = packageJson_1.readPackageJsonFileSync(packageJsonFilePath); var packageName = packageJson.name; packageFolderPathsToVisit.push(packageFolderPath); var clonedPackage = { path: packageFolderPath }; var packageFolder = arrays_1.first(options.packageFolders, function (packageFolder) { return (typeof packageFolder === "string" ? packageFolder : packageFolder.path) === packagePathToAdd; }); if (packageFolder && typeof packageFolder !== "string") { clonedPackage.defaultVersion = packageFolder.defaultVersion; clonedPackage.dependenciesToIgnore = packageFolder.dependenciesToIgnore; clonedPackage.runNPMInstall = packageFolder.runNPMInstall; } clonedPackages[packageName] = clonedPackage; } }; try { for (packagePathsToAdd_1 = tslib_1.__values(packagePathsToAdd), packagePathsToAdd_1_1 = packagePathsToAdd_1.next(); !packagePathsToAdd_1_1.done; packagePathsToAdd_1_1 = packagePathsToAdd_1.next()) { packagePathToAdd = packagePathsToAdd_1_1.value; state_1 = _loop_1(packagePathToAdd); if (state_1 === "break") break; } } catch (e_5_1) { e_5 = { error: e_5_1 }; } finally { try { if (packagePathsToAdd_1_1 && !packagePathsToAdd_1_1.done && (_e = packagePathsToAdd_1.return)) _e.call(packagePathsToAdd_1); } finally { if (e_5) throw e_5.error; } } folderPathsToRunNPMInstallIn = []; _k.label = 1; case 1: if (!(packageFolderPathsToVisit.length > 0 && exitCode === 0)) return [3 /*break*/, 7]; packageFolderPath = packageFolderPathsToVisit.shift(); packageFolderPathsVisited.push(packageFolderPath); logger.logSection("Updating package folder \"" + packageFolderPath + "\"..."); packageJsonFilePath = path_1.joinPath(packageFolderPath, "package.json"); packageJson = packageJson_1.readPackageJsonFileSync(packageJsonFilePath); packageName = packageJson.name; clonedPackage = clonedPackages[packageName]; clonedPackage.updated = true; if (!includeAzureJsDevTools) { if (!clonedPackage.dependenciesToIgnore) { clonedPackage.dependenciesToIgnore = []; } clonedPackage.dependenciesToIgnore.push("@ts-common/azure-js-dev-tools"); } return [4 /*yield*/, updateDependencies(clonedPackage, packageJson.dependencies, dependencyType, clonedPackages, logger)]; case 2: dependenciesChanged = _k.sent(); return [4 /*yield*/, updateDependencies(clonedPackage, packageJson.devDependencies, dependencyType, clonedPackages, logger)]; case 3: devDependenciesChanged = _k.sent(); if (!(!arrays_1.any(dependenciesChanged) && !arrays_1.any(devDependenciesChanged))) return [3 /*break*/, 4]; logger.logInfo(" No changes made."); if (clonedPackage.runNPMInstall !== false && forceInstall) { folderPathsToRunNPMInstallIn.push(packageFolderPath); } return [3 /*break*/, 6]; case 4: packageJson_1.writePackageJsonFileSync(packageJson, packageJsonFilePath); packageLockJsonFilePath = path_1.joinPath(packageFolderPath, "package-lock.json"); return [4 /*yield*/, fileSystem2_1.fileExists(packageLockJsonFilePath)]; case 5: if (_k.sent()) { packageLockJson = packageJson_1.readPackageLockJsonFileSync(packageLockJsonFilePath); packageJson_1.removePackageLockJsonDependencies.apply(void 0, tslib_1.__spread([packageLockJson], dependenciesChanged, devDependenciesChanged)); packageJson_1.writePackageLockJsonFileSync(packageLockJson, packageLockJsonFilePath); } if (clonedPackage.runNPMInstall !== false) { folderPathsToRunNPMInstallIn.push(packageFolderPath); } _k.label = 6; case 6: if (recursive) { allDependencyNames = []; if (packageJson.dependencies) { allDependencyNames.push.apply(allDependencyNames, tslib_1.__spread(Object.keys(packageJson.dependencies))); } if (packageJson.devDependencies) { allDependencyNames.push.apply(allDependencyNames, tslib_1.__spread(Object.keys(packageJson.devDependencies))); } try { for (allDependencyNames_1 = (e_6 = void 0, tslib_1.__values(allDependencyNames)), allDependencyNames_1_1 = allDependencyNames_1.next(); !allDependencyNames_1_1.done; allDependencyNames_1_1 = allDependencyNames_1.next()) { dependencyName = allDependencyNames_1_1.value; clonedDependency = clonedPackages[dependencyName]; if (clonedDependency) { clonedDependencyFolderPath = clonedDependency.path; if (!clonedDependency.updated && !arrays_1.contains(packageFolderPathsVisited, clonedDependencyFolderPath) && !arrays_1.contains(packageFolderPathsToVisit, clonedDependencyFolderPath)) { packageFolderPathsToVisit.push(clonedDependencyFolderPath); } } } } catch (e_6_1) { e_6 = { error: e_6_1 }; } finally { try { if (allDependencyNames_1_1 && !allDependencyNames_1_1.done && (_f = allDependencyNames_1.return)) _f.call(allDependencyNames_1); } finally { if (e_6) throw e_6.error; } } } return [3 /*break*/, 1]; case 7: _k.trys.push([7, 12, 13, 14]); folderPathsToRunNPMInstallIn_1 = tslib_1.__values(folderPathsToRunNPMInstallIn), folderPathsToRunNPMInstallIn_1_1 = folderPathsToRunNPMInstallIn_1.next(); _k.label = 8; case 8: if (!!folderPathsToRunNPMInstallIn_1_1.done) return [3 /*break*/, 11]; folderPath = folderPathsToRunNPMInstallIn_1_1.value; return [4 /*yield*/, npm_1.npmInstall({ executionFolderPath: folderPath, log: logger.logSection, showCommand: true })]; case 9: exitCode = (_k.sent()).exitCode; if (exitCode !== 0) { return [3 /*break*/, 11]; } _k.label = 10; case 10: folderPathsToRunNPMInstallIn_1_1 = folderPathsToRunNPMInstallIn_1.next(); return [3 /*break*/, 8]; case 11: return [3 /*break*/, 14]; case 12: e_3_1 = _k.sent(); e_3 = { error: e_3_1 }; return [3 /*break*/, 14]; case 13: try { if (folderPathsToRunNPMInstallIn_1_1 && !folderPathsToRunNPMInstallIn_1_1.done && (_g = folderPathsToRunNPMInstallIn_1.return)) _g.call(folderPathsToRunNPMInstallIn_1); } finally { if (e_3) throw e_3.error; } return [7 /*endfinally*/]; case 14: if (!(exitCode === 0 && options.extraFilesToUpdate)) return [3 /*break*/, 26]; _k.label = 15; case 15: _k.trys.push([15, 24, 25, 26]); _a = tslib_1.__values(options.extraFilesToUpdate), _b = _a.next(); _k.label = 16; case 16: if (!!_b.done) return [3 /*break*/, 23]; extraFileToUpdate = _b.value; return [4 /*yield*/, fileSystem2_1.fileExists(extraFileToUpdate)]; case 17: if (!!(_k.sent())) return [3 /*break*/, 18]; logger.logError("The extra file to update \"" + extraFileToUpdate + "\" doesn't exist."); exitCode = 2; return [3 /*break*/, 23]; case 18: logger.logSection("Updating extra file \"" + extraFileToUpdate + "\"..."); return [4 /*yield*/, fileSystem2_1.readFileContents(extraFileToUpdate)]; case 19: originalFileContents = (_k.sent()); updatedFileContents = originalFileContents; try { for (_c = (e_7 = void 0, tslib_1.__values(Object.keys(clonedPackages))), _d = _c.next(); !_d.done; _d = _c.next()) { clonedPackageName = _d.value; clonedPackage = clonedPackages[clonedPackageName]; if (clonedPackage && clonedPackage.targetVersion) { regularExpression = new RegExp("\\.StringProperty\\(\"" + clonedPackageName + "\", \"(.*)\"\\);"); match = updatedFileContents.match(regularExpression); if (match && match[1] !== clonedPackage.targetVersion) { logger.logInfo(" Changing \"" + clonedPackageName + "\" version from \"" + match[1] + "\" to \"" + clonedPackage.targetVersion + "\"..."); updatedFileContents = updatedFileContents.replace(regularExpression, ".StringProperty(\"" + clonedPackageName + "\", \"" + clonedPackage.targetVersion + "\");"); } } } } catch (e_7_1) { e_7 = { error: e_7_1 }; } finally { try { if (_d && !_d.done && (_j = _c.return)) _j.call(_c); } finally { if (e_7) throw e_7.error; } } if (!(originalFileContents === updatedFileContents)) return [3 /*break*/, 20]; logger.logInfo(" No changes made."); return [3 /*break*/, 22]; case 20: logger.logInfo(" Writing changes back to file..."); return [4 /*yield*/, fileSystem2_1.writeFileContents(extraFileToUpdate, updatedFileContents)]; case 21: _k.sent(); _k.label = 22; case 22: _b = _a.next(); return [3 /*break*/, 16]; case 23: return [3 /*break*/, 26]; case 24: e_4_1 = _k.sent(); e_4 = { error: e_4_1 }; return [3 /*break*/, 26]; case 25: try { if (_b && !_b.done && (_h = _a.return)) _h.call(_a); } finally { if (e_4) throw e_4.error; } return [7 /*endfinally*/]; case 26: if (exitCode == undefined) { exitCode = 1; } if (options.setProcessExitCode !== false) { process.exitCode = exitCode; } return [2 /*return*/, exitCode]; } }); }); } exports.changeClonedDependenciesTo = changeClonedDependenciesTo; //# sourceMappingURL=dependencies.js.map