-
Notifications
You must be signed in to change notification settings - Fork 0
/
cli.js
executable file
·128 lines (106 loc) · 3.07 KB
/
cli.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#!/usr/bin/env node
import * as path from 'node:path';
import find from 'find';
import { promises as fs } from 'node:fs';
import isGitClean from 'is-git-clean';
import meow from 'meow';
import { exec as nativeExec } from 'node:child_process';
import { promisify } from 'node:util';
import semver from 'semver';
const exec = promisify(nativeExec);
const cli = meow(
`
Usage
$ react-native-update-version <patch|minor|major>
Options
--branch, git branch name
--silent, do not show any output
`,
{
importMeta: import.meta,
flags: {
silent: {
type: 'boolean',
},
branch: {
type: 'string',
default: 'main',
},
},
}
);
const semverLevel = cli.input[0] || 'patch';
const branchName = cli.flags.branch;
function log(...args) {
if (cli.flags.silent) {
return;
}
console.log(...args);
}
async function updateAndroidVersionName(nextVersion, buildNumber) {
const filename = 'android/app/build.gradle';
const content = await fs.readFile(filename, 'utf8');
const newContent = content
.replace(/(versionName) "([0-9].+)"/, `$1 "${nextVersion}"`)
.replace(/(versionCode) ([0-9]+)/, `$1 ${buildNumber}`);
try {
return await fs.writeFile(filename, newContent);
} catch (error) {
throw new Error(`Set versionName ${nextVersion} in ${filename}`);
}
}
async function countGitCommits() {
return parseInt((await exec(`git rev-list ${branchName} --count`)).stdout);
}
function findPlistFiles() {
return new Promise((resolve) => {
find.file(
/ios\/(\w+)\/Info.plist$/,
path.resolve(process.cwd(), 'ios'),
(files) => {
resolve(files.filter((file) => !file.includes('Tests/Info.plist')));
}
);
});
}
async function updatePlistAtKey(plist, key, value) {
return exec(`/usr/libexec/PlistBuddy -c "Set :${key} ${value}" ${plist}`);
}
async function main() {
const isRepoClean = await isGitClean();
if (!isRepoClean) {
console.error(
'This command requires a clean git repo. Please stash or commit any changes before re-running this command.'
);
return;
}
const packageJson = JSON.parse(await fs.readFile('package.json'));
const currentVersion = packageJson.version;
const nextVersion = semver.inc(currentVersion, semverLevel);
const buildNumber = await countGitCommits();
for (const plistFile of await findPlistFiles()) {
await updatePlistAtKey(
plistFile,
'CFBundleShortVersionString',
nextVersion
);
await updatePlistAtKey(plistFile, 'CFBundleVersion', buildNumber);
}
await updateAndroidVersionName(nextVersion, buildNumber);
packageJson.version = nextVersion;
await fs.writeFile(
'package.json',
JSON.stringify(packageJson, null, 2) + '\n'
);
await exec('git add .');
await exec(`git commit -m ${nextVersion}`);
await exec(`git tag -a '${nextVersion}' -m '${nextVersion}'`);
log(
`Version numbers successfully updated to ${nextVersion} (${buildNumber}).`
);
log();
log('ios: cd ios && bundle exec fastlane beta');
log('android: cd android && ./gradlew assembleRelease');
log();
}
main();