1/** 2 * Copyright (c) Meta Platforms, Inc. and affiliates. 3 * 4 * This source code is licensed under the MIT license found in the 5 * LICENSE file in the root directory of this source tree. 6 * 7 * @format 8 */ 9 10const {spawnSync} = require('child_process'); 11const {writeFileSync, readFileSync} = require('fs'); 12const path = require('path'); 13 14const checkForGitChanges = require('./check-for-git-changes'); 15const forEachPackage = require('./for-each-package'); 16 17const ROOT_LOCATION = path.join(__dirname, '..', '..'); 18const TEMPLATE_LOCATION = path.join(ROOT_LOCATION, 'template'); 19const REPO_CONFIG_LOCATION = path.join(ROOT_LOCATION, 'repo-config'); 20 21const readJSONFile = pathToFile => JSON.parse(readFileSync(pathToFile)); 22 23const checkIfShouldUpdateDependencyPackageVersion = ( 24 consumerPackageAbsolutePath, 25 updatedPackageName, 26 updatedPackageVersion, 27) => { 28 const consumerPackageManifestPath = path.join( 29 consumerPackageAbsolutePath, 30 'package.json', 31 ); 32 const consumerPackageManifest = readJSONFile(consumerPackageManifestPath); 33 34 const dependencyVersion = 35 consumerPackageManifest.dependencies?.[updatedPackageName]; 36 37 if (dependencyVersion && dependencyVersion !== '*') { 38 const updatedDependencyVersion = dependencyVersion.startsWith('^') 39 ? `^${updatedPackageVersion}` 40 : updatedPackageVersion; 41 42 if (updatedDependencyVersion !== dependencyVersion) { 43 console.log( 44 `\uD83D\uDCA1 ${consumerPackageManifest.name} was updated: now using version ${updatedPackageVersion} of ${updatedPackageName}`, 45 ); 46 47 const updatedPackageManifest = { 48 ...consumerPackageManifest, 49 dependencies: { 50 ...consumerPackageManifest.dependencies, 51 [updatedPackageName]: updatedDependencyVersion, 52 }, 53 }; 54 55 writeFileSync( 56 consumerPackageManifestPath, 57 JSON.stringify(updatedPackageManifest, null, 2) + '\n', 58 'utf-8', 59 ); 60 } 61 } 62 63 const devDependencyVersion = 64 consumerPackageManifest.devDependencies?.[updatedPackageName]; 65 66 if (devDependencyVersion && devDependencyVersion !== '*') { 67 const updatedDependencyVersion = devDependencyVersion.startsWith('^') 68 ? `^${updatedPackageVersion}` 69 : updatedPackageVersion; 70 71 if (updatedDependencyVersion !== devDependencyVersion) { 72 console.log( 73 `\uD83D\uDCA1 ${consumerPackageManifest.name} was updated: now using version ${updatedPackageVersion} of ${updatedPackageName}`, 74 ); 75 76 const updatedPackageManifest = { 77 ...consumerPackageManifest, 78 devDependencies: { 79 ...consumerPackageManifest.devDependencies, 80 [updatedPackageName]: updatedDependencyVersion, 81 }, 82 }; 83 84 writeFileSync( 85 consumerPackageManifestPath, 86 JSON.stringify(updatedPackageManifest, null, 2) + '\n', 87 'utf-8', 88 ); 89 } 90 } 91}; 92 93const alignPackageVersions = () => { 94 if (checkForGitChanges()) { 95 console.log( 96 '\u274c Found uncommitted changes. Please commit or stash them before running this script', 97 ); 98 99 process.exit(1); 100 } 101 102 forEachPackage((packageAbsolutePath, _, packageManifest) => { 103 checkIfShouldUpdateDependencyPackageVersion( 104 ROOT_LOCATION, 105 packageManifest.name, 106 packageManifest.version, 107 ); 108 109 checkIfShouldUpdateDependencyPackageVersion( 110 TEMPLATE_LOCATION, 111 packageManifest.name, 112 packageManifest.version, 113 ); 114 115 checkIfShouldUpdateDependencyPackageVersion( 116 REPO_CONFIG_LOCATION, 117 packageManifest.name, 118 packageManifest.version, 119 ); 120 121 forEachPackage(pathToPackage => 122 checkIfShouldUpdateDependencyPackageVersion( 123 pathToPackage, 124 packageManifest.name, 125 packageManifest.version, 126 ), 127 ); 128 }); 129 130 if (!checkForGitChanges()) { 131 console.log( 132 '\u2705 There were no changes. Every consumer package uses the actual version of dependency package.', 133 ); 134 return; 135 } 136 137 console.log('Running yarn to update lock file...'); 138 spawnSync('yarn', ['install'], { 139 cwd: ROOT_LOCATION, 140 shell: true, 141 stdio: 'inherit', 142 encoding: 'utf-8', 143 }); 144}; 145 146alignPackageVersions(); 147