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 10'use strict'; 11 12/** 13 * This script updates relevant React Native files with supplied version: 14 * * Prepares a package.json suitable for package consumption 15 * * Updates package.json for template project 16 * * Updates the version in gradle files and makes sure they are consistent between each other 17 * * Creates a gemfile 18 */ 19const fs = require('fs'); 20const os = require('os'); 21const path = require('path'); 22const {cat, echo, exec, exit, sed} = require('shelljs'); 23const yargs = require('yargs'); 24const {parseVersion, validateBuildType} = require('./version-utils'); 25const {saveFiles} = require('./scm-utils'); 26 27let argv = yargs 28 .option('v', { 29 alias: 'to-version', 30 type: 'string', 31 required: true, 32 }) 33 .option('b', { 34 alias: 'build-type', 35 type: 'string', 36 required: true, 37 }).argv; 38 39const buildType = argv.buildType; 40const version = argv.toVersion; 41 42try { 43 validateBuildType(buildType); 44} catch (e) { 45 throw e; 46} 47 48let major, 49 minor, 50 patch, 51 prerelease = -1; 52try { 53 ({major, minor, patch, prerelease} = parseVersion(version, buildType)); 54} catch (e) { 55 throw e; 56} 57 58const tmpVersioningFolder = fs.mkdtempSync( 59 path.join(os.tmpdir(), 'rn-set-version'), 60); 61echo(`The temp versioning folder is ${tmpVersioningFolder}`); 62 63saveFiles(['package.json', 'template/package.json'], tmpVersioningFolder); 64 65fs.writeFileSync( 66 'ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.java', 67 cat('scripts/versiontemplates/ReactNativeVersion.java.template') 68 .replace('${major}', major) 69 .replace('${minor}', minor) 70 .replace('${patch}', patch) 71 .replace( 72 '${prerelease}', 73 prerelease !== undefined ? `"${prerelease}"` : 'null', 74 ), 75 'utf-8', 76); 77 78fs.writeFileSync( 79 'React/Base/RCTVersion.m', 80 cat('scripts/versiontemplates/RCTVersion.m.template') 81 .replace('${major}', `@(${major})`) 82 .replace('${minor}', `@(${minor})`) 83 .replace('${patch}', `@(${patch})`) 84 .replace( 85 '${prerelease}', 86 prerelease !== undefined ? `@"${prerelease}"` : '[NSNull null]', 87 ), 88 'utf-8', 89); 90 91fs.writeFileSync( 92 'ReactCommon/cxxreact/ReactNativeVersion.h', 93 cat('scripts/versiontemplates/ReactNativeVersion.h.template') 94 .replace('${major}', major) 95 .replace('${minor}', minor) 96 .replace('${patch}', patch) 97 .replace( 98 '${prerelease}', 99 prerelease !== undefined ? `"${prerelease}"` : '""', 100 ), 101 'utf-8', 102); 103 104fs.writeFileSync( 105 'Libraries/Core/ReactNativeVersion.js', 106 cat('scripts/versiontemplates/ReactNativeVersion.js.template') 107 .replace('${major}', major) 108 .replace('${minor}', minor) 109 .replace('${patch}', patch) 110 .replace( 111 '${prerelease}', 112 prerelease !== undefined ? `'${prerelease}'` : 'null', 113 ), 114 'utf-8', 115); 116 117let packageJson = JSON.parse(cat('package.json')); 118packageJson.version = version; 119delete packageJson.workspaces; 120delete packageJson.private; 121 122// Copy repo-config/package.json dependencies as devDependencies 123const repoConfigJson = JSON.parse(cat('repo-config/package.json')); 124packageJson.devDependencies = { 125 ...packageJson.devDependencies, 126 ...repoConfigJson.dependencies, 127}; 128// Make react-native-codegen a direct dependency of react-native 129delete packageJson.devDependencies['react-native-codegen']; 130packageJson.dependencies = { 131 ...packageJson.dependencies, 132 'react-native-codegen': repoConfigJson.dependencies['react-native-codegen'], 133}; 134fs.writeFileSync('package.json', JSON.stringify(packageJson, null, 2), 'utf-8'); 135 136// Change ReactAndroid/gradle.properties 137saveFiles(['ReactAndroid/gradle.properties'], tmpVersioningFolder); 138if ( 139 sed( 140 '-i', 141 /^VERSION_NAME=.*/, 142 `VERSION_NAME=${version}`, 143 'ReactAndroid/gradle.properties', 144 ).code 145) { 146 echo("Couldn't update version for Gradle"); 147 exit(1); 148} 149 150// Change react-native version in the template's package.json 151exec(`node scripts/set-rn-template-version.js ${version}`); 152 153// Make sure to update ruby version 154if (exec('scripts/update-ruby.sh').code) { 155 echo('Failed to update Ruby version'); 156 exit(1); 157} 158 159// Verify that files changed, we just do a git diff and check how many times version is added across files 160const filesToValidate = [ 161 'package.json', 162 'ReactAndroid/gradle.properties', 163 'template/package.json', 164]; 165 166const numberOfChangedLinesWithNewVersion = exec( 167 `diff -r ${tmpVersioningFolder} . | grep '^[>]' | grep -c ${version} `, 168 {silent: true}, 169).stdout.trim(); 170 171if (+numberOfChangedLinesWithNewVersion !== filesToValidate.length) { 172 // TODO: the logic that checks whether all the changes have been applied 173 // is missing several files. For example, it is not checking Ruby version nor that 174 // the Objecive-C files, the codegen and other files are properly updated. 175 // We are going to work on this in another PR. 176 echo('WARNING:'); 177 echo( 178 `Failed to update all the files: [${filesToValidate.join( 179 ', ', 180 )}] must have versions in them`, 181 ); 182 echo(`These files already had version ${version} set.`); 183} 184 185exit(0); 186