-
-
Notifications
You must be signed in to change notification settings - Fork 283
Expand file tree
/
Copy pathbump_version.dart
More file actions
137 lines (125 loc) · 4.38 KB
/
bump_version.dart
File metadata and controls
137 lines (125 loc) · 4.38 KB
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
129
130
131
132
133
134
135
136
137
// ignore_for_file: avoid_print
import 'dart:convert';
import 'dart:io';
/// - `-r` to bump release version
/// - `-y` to force bump same version
/// - `-b` to build apk
/// - `-v` to print build details
/// - `--skip-git` to skip adding changes to git
void main(List<String> argsFixed) async {
final args = List<String>.from(argsFixed);
final pubspec = File('pubspec.yaml');
final pubspecLines = pubspec.readAsLinesSync();
const versionLinePrefix = 'version: ';
bool didBump = false;
bool didAddToGit = false;
final skipGit = args.remove('--skip-git');
final isRelease = args.remove('-r');
final forceBump = args.remove('-y');
final buildApk = args.remove('-b');
final buildApkV = args.remove('-v');
for (int i = 0; i < pubspecLines.length; i++) {
final line = pubspecLines[i];
if (line.startsWith(versionLinePrefix)) {
final currentName = line.split(versionLinePrefix).last.split('+').first;
final currentVersion = currentName.split('-').first; // stripping `-beta`
String? versionName = args.isEmpty ? null : args[0];
if (versionName == null) {
print('please provide version name, current is: $currentVersion');
break;
}
if (currentVersion == versionName) {
if (!forceBump) {
print('you entered the same version name: $currentVersion, enter `y` to force bump');
final input = stdin.readLineSync();
if (input?.toLowerCase() != 'y') break;
}
}
final suffix = isRelease ? '' : '-beta';
final newVersionName = "$versionName$suffix";
String newBuildNumber;
if (args.length > 1) {
newBuildNumber = args[1];
} else {
final date = DateTime.now().toUtc();
final year = date.year.toString();
String padLeft(int number) => number.toString().padLeft(2, '0');
final minutesPercentage = (date.minute / 60).toString().substring(2, 3);
newBuildNumber = "${year.substring(2)}${padLeft(date.month)}${padLeft(date.day)}${padLeft(date.hour)}$minutesPercentage";
}
final newLine = '$versionLinePrefix$newVersionName+$newBuildNumber';
print("old $line");
pubspecLines[i] = newLine;
print("new $newLine");
didBump = true;
pubspec.writeAsStringSync("""${pubspecLines.join('\n')}
""");
if (!skipGit) {
print('git: adding changed files');
didAddToGit = await _runGitAdd(oldLine: line, newLine: newLine, args: []);
}
break;
}
}
if (!didAddToGit) print('couldn\'t add to git stage');
if (!didBump) {
print('couldn\'t bump version');
return;
}
print('version bumped');
if (buildApk) {
print('building...');
final didBuild = await _buildAPK(verbose: buildApkV);
print(didBuild ? 'build success' : 'build error');
}
}
Future<bool> _buildAPK({required bool verbose}) async {
final v = verbose ? ' -v' : '';
final buildCommand = 'build apk --target-platform android-arm,android-arm64 --release --split-per-abi$v';
final success = await _runProcess(
program: 'flutter',
command: buildCommand,
onOutput: verbose ? (data, _) => print(data) : null,
);
return success;
}
Future<bool> _runGitAdd({required String oldLine, required String newLine, required List<String> args}) async {
bool added = false;
bool executedFirstCommand = false;
final success = await _runProcess(
program: 'git',
command: 'add pubspec.yaml -p',
onOutput: (data, stdinStream) {
if (executedFirstCommand) return;
executedFirstCommand = true;
stdinStream.writeln('s');
stdinStream.writeln('/');
stdinStream.writeln('^version: ');
stdinStream.writeln('y');
stdinStream.writeln('q');
added = true;
},
);
return success && added;
}
Future<bool> _runProcess({
required String program,
required String command,
void Function(String data, IOSink stdinStream)? onOutput,
}) async {
final process = await Process.start(program, command.split(' '), runInShell: true);
final stdinStream = process.stdin;
if (onOutput != null) {
final stdoutStream = process.stdout;
stdoutStream.transform(utf8.decoder).listen((data) => onOutput(data, stdinStream));
}
final stderrStream = process.stderr;
stderrStream
.transform(utf8.decoder)
.listen(
(data) => print('$program error: $data'),
);
final exitCode = await process.exitCode;
stdinStream.close();
return exitCode == 0;
}