mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
214 lines
5.5 KiB
Dart
214 lines
5.5 KiB
Dart
// Copyright 2014 The Flutter Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
/// Possible string formats that `flutter --version` can return.
|
|
enum VersionType {
|
|
/// A stable flutter release.
|
|
///
|
|
/// Example: '1.2.3'
|
|
stable,
|
|
|
|
/// A pre-stable flutter release.
|
|
///
|
|
/// Example: '1.2.3-4.5.pre'
|
|
development,
|
|
|
|
/// A master channel flutter version.
|
|
///
|
|
/// Example: '1.2.3-4.0.pre.10'
|
|
///
|
|
/// The last number is the number of commits past the last tagged version.
|
|
latest,
|
|
}
|
|
|
|
final Map<VersionType, RegExp> versionPatterns = <VersionType, RegExp>{
|
|
VersionType.stable: RegExp(r'^(\d+)\.(\d+)\.(\d+)$'),
|
|
VersionType.development: RegExp(r'^(\d+)\.(\d+)\.(\d+)-(\d+)\.(\d+)\.pre$'),
|
|
VersionType.latest: RegExp(r'^(\d+)\.(\d+)\.(\d+)-(\d+)\.(\d+)\.pre\.(\d+)$'),
|
|
};
|
|
|
|
class Version {
|
|
Version({
|
|
required this.x,
|
|
required this.y,
|
|
required this.z,
|
|
this.m,
|
|
this.n,
|
|
this.commits,
|
|
required this.type,
|
|
}) {
|
|
switch (type) {
|
|
case VersionType.stable:
|
|
assert(m == null);
|
|
assert(n == null);
|
|
assert(commits == null);
|
|
break;
|
|
case VersionType.development:
|
|
assert(m != null);
|
|
assert(n != null);
|
|
assert(commits == null);
|
|
break;
|
|
case VersionType.latest:
|
|
assert(m != null);
|
|
assert(n != null);
|
|
assert(commits != null);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/// Create a new [Version] from a version string.
|
|
///
|
|
/// It is expected that [versionString] will be generated by
|
|
/// `flutter --version` and match one of `stablePattern`, `developmentPattern`
|
|
/// and `latestPattern`.
|
|
factory Version.fromString(String versionString) {
|
|
assert(versionString != null);
|
|
|
|
versionString = versionString.trim();
|
|
// stable tag
|
|
Match? match = versionPatterns[VersionType.stable]!.firstMatch(versionString);
|
|
if (match != null) {
|
|
// parse stable
|
|
final List<int> parts = match
|
|
.groups(<int>[1, 2, 3])
|
|
.map((String? s) => int.parse(s!))
|
|
.toList();
|
|
return Version(
|
|
x: parts[0],
|
|
y: parts[1],
|
|
z: parts[2],
|
|
type: VersionType.stable,
|
|
);
|
|
}
|
|
// development tag
|
|
match = versionPatterns[VersionType.development]!.firstMatch(versionString);
|
|
if (match != null) {
|
|
// parse development
|
|
final List<int> parts =
|
|
match.groups(<int>[1, 2, 3, 4, 5]).map((String? s) => int.parse(s!)).toList();
|
|
return Version(
|
|
x: parts[0],
|
|
y: parts[1],
|
|
z: parts[2],
|
|
m: parts[3],
|
|
n: parts[4],
|
|
type: VersionType.development,
|
|
);
|
|
}
|
|
// latest tag
|
|
match = versionPatterns[VersionType.latest]!.firstMatch(versionString);
|
|
if (match != null) {
|
|
// parse latest
|
|
final List<int> parts = match.groups(
|
|
<int>[1, 2, 3, 4, 5, 6],
|
|
).map(
|
|
(String? s) => int.parse(s!),
|
|
).toList();
|
|
return Version(
|
|
x: parts[0],
|
|
y: parts[1],
|
|
z: parts[2],
|
|
m: parts[3],
|
|
n: parts[4],
|
|
commits: parts[5],
|
|
type: VersionType.latest,
|
|
);
|
|
}
|
|
throw Exception('${versionString.trim()} cannot be parsed');
|
|
}
|
|
|
|
// Returns a new version with the given [increment] part incremented.
|
|
// NOTE new version must be of same type as previousVersion.
|
|
factory Version.increment(
|
|
Version previousVersion,
|
|
String increment, {
|
|
VersionType? nextVersionType,
|
|
}) {
|
|
final int nextX = previousVersion.x;
|
|
int nextY = previousVersion.y;
|
|
int nextZ = previousVersion.z;
|
|
int? nextM = previousVersion.m;
|
|
int? nextN = previousVersion.n;
|
|
if (nextVersionType == null) {
|
|
if (previousVersion.type == VersionType.latest) {
|
|
nextVersionType = VersionType.development;
|
|
} else {
|
|
nextVersionType = previousVersion.type;
|
|
}
|
|
}
|
|
|
|
switch (increment) {
|
|
case 'x':
|
|
// This was probably a mistake.
|
|
throw Exception('Incrementing x is not supported by this tool.');
|
|
case 'y':
|
|
// Dev release following a beta release.
|
|
nextY += 1;
|
|
nextZ = 0;
|
|
if (previousVersion.type != VersionType.stable) {
|
|
nextM = 0;
|
|
nextN = 0;
|
|
}
|
|
break;
|
|
case 'z':
|
|
// Hotfix to stable release.
|
|
assert(previousVersion.type == VersionType.stable);
|
|
nextZ += 1;
|
|
break;
|
|
case 'm':
|
|
// Regular dev release.
|
|
assert(previousVersion.type == VersionType.development);
|
|
nextM = nextM! + 1;
|
|
nextN = 0;
|
|
break;
|
|
case 'n':
|
|
// Hotfix to internal roll.
|
|
nextN = nextN! + 1;
|
|
break;
|
|
default:
|
|
throw Exception('Unknown increment level $increment.');
|
|
}
|
|
return Version(
|
|
x: nextX,
|
|
y: nextY,
|
|
z: nextZ,
|
|
m: nextM,
|
|
n: nextN,
|
|
type: nextVersionType,
|
|
);
|
|
}
|
|
|
|
/// Major version.
|
|
final int x;
|
|
|
|
/// Zero-indexed count of beta releases after a major release.
|
|
final int y;
|
|
|
|
/// Number of hotfix releases after a stable release.
|
|
final int z;
|
|
|
|
/// Zero-indexed count of dev releases after a beta release.
|
|
final int? m;
|
|
|
|
/// Number of hotfixes required to make a dev release.
|
|
final int? n;
|
|
|
|
/// Number of commits past last tagged dev release.
|
|
final int? commits;
|
|
|
|
final VersionType type;
|
|
|
|
@override
|
|
String toString() {
|
|
switch (type) {
|
|
case VersionType.stable:
|
|
return '$x.$y.$z';
|
|
case VersionType.development:
|
|
return '$x.$y.$z-$m.$n.pre';
|
|
case VersionType.latest:
|
|
return '$x.$y.$z-$m.$n.pre.$commits';
|
|
}
|
|
}
|
|
}
|