Unverified Commit e593a863 authored by Christopher Fujino's avatar Christopher Fujino Committed by GitHub

[flutter_conductor] validate git parsed version and release branch match (#92064)

parent 8f574c29
......@@ -54,7 +54,8 @@ Directory get localFlutterRoot {
final String checkoutsDirname = fileSystem.path.normalize(
fileSystem.path.join(
fileSystem.path.dirname(filePath),
'..', // flutter/dev/tools
'..', // flutter/dev/conductor/core
'..', // flutter/dev/conductor
'..', // flutter/dev
'..', // flutter
),
......
......@@ -382,7 +382,8 @@ class StartContext {
// Get framework version
final Version lastVersion = Version.fromString(await framework.getFullTag(
framework.upstreamRemote.name, candidateBranch,
exact: false));
exact: false,
))..ensureValid(candidateBranch, incrementLetter);
Version nextVersion;
if (incrementLetter == 'm') {
nextVersion = Version.fromCandidateBranch(candidateBranch);
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import './globals.dart' show ConductorException;
import './globals.dart' show releaseCandidateBranchRegex, ConductorException;
/// Possible string formats that `flutter --version` can return.
enum VersionType {
......@@ -251,6 +251,51 @@ class Version {
final VersionType type;
/// Validate that the parsed version is valid.
///
/// Will throw a [ConductorException] if the version is not possible given the
/// [candidateBranch] and [incrementLetter].
void ensureValid(String candidateBranch, String incrementLetter) {
if (!const <String>{'y', 'z', 'm', 'n'}.contains(incrementLetter)) {
throw ConductorException('Invalid incrementLetter: $incrementLetter');
}
final RegExpMatch? branchMatch = releaseCandidateBranchRegex.firstMatch(candidateBranch);
if (branchMatch == null) {
throw ConductorException(
'Candidate branch $candidateBranch does not match the pattern '
'${releaseCandidateBranchRegex.pattern}',
);
}
// These groups are required in the pattern, so these match groups should
// not be null
final String branchX = branchMatch.group(1)!;
if (x != int.tryParse(branchX)) {
throw ConductorException(
'Parsed version ${toString()} has a different x value than candidate '
'branch $candidateBranch',
);
}
final String branchY = branchMatch.group(2)!;
if (y != int.tryParse(branchY)) {
throw ConductorException(
'Parsed version ${toString()} has a different y value than candidate '
'branch $candidateBranch',
);
}
// stable type versions don't have an m field set
if (type != VersionType.stable && incrementLetter != 'm') {
final String branchM = branchMatch.group(3)!;
if (m != int.tryParse(branchM)) {
throw ConductorException(
'Parsed version ${toString()} has a different m value than candidate '
'branch $candidateBranch',
);
}
}
}
@override
String toString() {
switch (type) {
......
......@@ -310,7 +310,7 @@ void main() {
const String revision3 = '123abc';
const String previousDartRevision = '171876a4e6cf56ee6da1f97d203926bd7afda7ef';
const String nextDartRevision = 'f6c91128be6b77aef8351e1e3a9d07c85bc2e46e';
const String previousVersion = '1.2.0-1.0.pre';
const String previousVersion = '1.2.0-3.0.pre';
const String nextVersion = '1.2.0';
const String incrementLevel = 'z';
......
......@@ -81,4 +81,77 @@ void main() {
}, onPlatform: <String, dynamic>{
'windows': const Skip('Flutter Conductor only supported on macos/linux'),
});
group('.ensureValid()', () {
test('throws when x does not match', () {
const String versionString = '1.2.3-4.5.pre';
const String candidateBranch = 'flutter-3.2-candidate.4';
final Version version = Version.fromString(versionString);
expect(
() => version.ensureValid(candidateBranch, 'n'),
throwsExceptionWith(
'Parsed version $versionString has a different x value than '
'candidate branch $candidateBranch',
),
);
});
test('throws when y does not match', () {
const String versionString = '1.2.3';
const String candidateBranch = 'flutter-1.15-candidate.4';
final Version version = Version.fromString(versionString);
expect(
() => version.ensureValid(candidateBranch, 'm'),
throwsExceptionWith(
'Parsed version $versionString has a different y value than '
'candidate branch $candidateBranch',
),
);
});
test('throws when m does not match', () {
const String versionString = '1.2.3-4.5.pre';
const String candidateBranch = 'flutter-1.2-candidate.0';
final Version version = Version.fromString(versionString);
expect(
() => version.ensureValid(candidateBranch, 'n'),
throwsExceptionWith(
'Parsed version $versionString has a different m value than '
'candidate branch $candidateBranch',
),
);
});
test('does not validate m if version type is stable', () {
const String versionString = '1.2.0';
const String candidateBranch = 'flutter-1.2-candidate.98';
final Version version = Version.fromString(versionString);
expect(
() => version.ensureValid(candidateBranch, 'n'),
isNot(throwsException),
);
});
test('throws on malformed candidate branch', () {
const String versionString = '1.2.0';
const String candidateBranch = 'stable';
final Version version = Version.fromString(versionString);
expect(
() => version.ensureValid(candidateBranch, 'z'),
throwsExceptionWith(
'Candidate branch $candidateBranch does not match the pattern',
),
);
});
test('does not validate m if incrementLetter is m', () {
const String versionString = '1.2.0-0.0.pre';
const String candidateBranch = 'flutter-1.2-candidate.42';
final Version version = Version.fromString(versionString);
expect(
() => version.ensureValid(candidateBranch, 'm'),
isNot(throwsException),
);
});
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment