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 {cat, echo, exec, exit, sed} = require('shelljs');
21const yargs = require('yargs');
22const {parseVersion} = require('./version-utils');
23
24let argv = yargs.option('v', {
25  alias: 'to-version',
26  type: 'string',
27}).argv;
28
29const version = argv.toVersion;
30
31if (!version) {
32  echo('You must specify a version using -v');
33  exit(1);
34}
35
36let major,
37  minor,
38  patch,
39  prerelease = -1;
40try {
41  ({major, minor, patch, prerelease} = parseVersion(version));
42} catch (e) {
43  echo(e.message);
44  exit(1);
45}
46
47fs.writeFileSync(
48  'ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.java',
49  cat('scripts/versiontemplates/ReactNativeVersion.java.template')
50    .replace('${major}', major)
51    .replace('${minor}', minor)
52    .replace('${patch}', patch)
53    .replace(
54      '${prerelease}',
55      prerelease !== undefined ? `"${prerelease}"` : 'null',
56    ),
57  'utf-8',
58);
59
60fs.writeFileSync(
61  'React/Base/RCTVersion.m',
62  cat('scripts/versiontemplates/RCTVersion.m.template')
63    .replace('${major}', `@(${major})`)
64    .replace('${minor}', `@(${minor})`)
65    .replace('${patch}', `@(${patch})`)
66    .replace(
67      '${prerelease}',
68      prerelease !== undefined ? `@"${prerelease}"` : '[NSNull null]',
69    ),
70  'utf-8',
71);
72
73fs.writeFileSync(
74  'ReactCommon/cxxreact/ReactNativeVersion.h',
75  cat('scripts/versiontemplates/ReactNativeVersion.h.template')
76    .replace('${major}', major)
77    .replace('${minor}', minor)
78    .replace('${patch}', patch)
79    .replace(
80      '${prerelease}',
81      prerelease !== undefined ? `"${prerelease}"` : '""',
82    ),
83  'utf-8',
84);
85
86fs.writeFileSync(
87  'Libraries/Core/ReactNativeVersion.js',
88  cat('scripts/versiontemplates/ReactNativeVersion.js.template')
89    .replace('${major}', major)
90    .replace('${minor}', minor)
91    .replace('${patch}', patch)
92    .replace(
93      '${prerelease}',
94      prerelease !== undefined ? `'${prerelease}'` : 'null',
95    ),
96  'utf-8',
97);
98
99let packageJson = JSON.parse(cat('package.json'));
100packageJson.version = version;
101delete packageJson.workspaces;
102delete packageJson.private;
103
104// Copy repo-config/package.json dependencies as devDependencies
105const repoConfigJson = JSON.parse(cat('repo-config/package.json'));
106packageJson.devDependencies = {
107  ...packageJson.devDependencies,
108  ...repoConfigJson.dependencies,
109};
110// Make react-native-codegen a direct dependency of react-native
111delete packageJson.devDependencies['react-native-codegen'];
112packageJson.dependencies = {
113  ...packageJson.dependencies,
114  'react-native-codegen': repoConfigJson.dependencies['react-native-codegen'],
115};
116fs.writeFileSync('package.json', JSON.stringify(packageJson, null, 2), 'utf-8');
117
118// Change ReactAndroid/gradle.properties
119if (
120  sed(
121    '-i',
122    /^VERSION_NAME=.*/,
123    `VERSION_NAME=${version}`,
124    'ReactAndroid/gradle.properties',
125  ).code
126) {
127  echo("Couldn't update version for Gradle");
128  exit(1);
129}
130
131// Change react-native version in the template's package.json
132exec(`node scripts/set-rn-template-version.js ${version}`);
133
134// Make sure to update ruby version
135if (exec('scripts/update-ruby.sh').code) {
136  echo('Failed to update Ruby version');
137  exit(1);
138}
139
140// Verify that files changed, we just do a git diff and check how many times version is added across files
141const filesToValidate = [
142  'package.json',
143  'ReactAndroid/gradle.properties',
144  'template/package.json',
145];
146const numberOfChangedLinesWithNewVersion = exec(
147  `git diff -U0 ${filesToValidate.join(
148    ' ',
149  )}| grep '^[+]' | grep -c ${version} `,
150  {silent: true},
151).stdout.trim();
152
153if (+numberOfChangedLinesWithNewVersion !== filesToValidate.length) {
154  echo(
155    `Failed to update all the files: [${filesToValidate.join(
156      ', ',
157    )}] must have versions in them`,
158  );
159  echo('Fix the issue and try again');
160  exit(1);
161}
162
163exit(0);
164