mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Use an alternative to git describe for master version resolution (#174088)
Closes https://github.com/flutter/flutter/issues/173904. It's not clear to me how `git describe --tags HEAD` ever ... worked to determine a fallback. From what I can tell, the _intent_ was to use the latest (newest? closest?) tag as the base version, and then append `-{commitCount}-{shortHash}` as the fallback version number when on `master` (or any non-published branch). So, I rewrote the implementation, unfortunately with 4 separate calls out to `git ...` instead of a single one. There are 20+ tests that fail as a result of this change, mostly because they make specific expectations around `git describe` being invoked, and of course that is no longer the case - putting those aside, I'd like to double check that: 1. I understand what the original command was _intending_ to do 2. We like the _output_ of the updated command 3. ... we either are okay with the implementation, or have an alternative in mind (I'm no `git` master) Wdyt? At this commit: ```sh $ flutter-dev --version Flutter 3.36.0-1.0.pre-170 • channel [user-branch] • https://github.com/matanlurey/flutter Framework • revision 250381a185 (5 minutes ago) • 2025-08-19 18:57:36 -0700 Engine • hash f278b0aa3b8c6732ab636563eb8e896c35fc9c79 (revision 9ac4facf7e) (2 hours ago) • 2025-08-19 23:42:28.000Z Tools • Dart 3.10.0 (build 3.10.0-115.0.dev) • DevTools 2.49.0 ``` /cc @zanderso @jmagman for historics.
This commit is contained in:
parent
4d4a69f14f
commit
e45fd36aac
@ -1049,23 +1049,47 @@ class GitTagVersion {
|
||||
}
|
||||
}
|
||||
|
||||
// If we're not currently on a tag, use git describe to find the most
|
||||
// recent tag and number of commits past.
|
||||
return parse(
|
||||
git
|
||||
.runSync([
|
||||
'describe',
|
||||
'--match',
|
||||
'*.*.*',
|
||||
'--long',
|
||||
'--tags',
|
||||
gitRef,
|
||||
], workingDirectory: workingDirectory)
|
||||
.stdout
|
||||
.trim(),
|
||||
// If we don't exist in a tag, use git to find the latest tag.
|
||||
return _useNewestTagAndCommitsPastFallback(
|
||||
git: git,
|
||||
workingDirectory: workingDirectory,
|
||||
gitRef: gitRef,
|
||||
);
|
||||
}
|
||||
|
||||
static GitTagVersion _useNewestTagAndCommitsPastFallback({
|
||||
required Git git,
|
||||
required String? workingDirectory,
|
||||
required String gitRef,
|
||||
}) {
|
||||
final String latestTag = git
|
||||
.runSync([
|
||||
'for-each-ref',
|
||||
'--sort=-v:refname',
|
||||
'--count=1',
|
||||
'--format=%(refname:short)',
|
||||
'refs/tags/[0-9]*.*.*',
|
||||
], workingDirectory: workingDirectory)
|
||||
.stdout
|
||||
.trim();
|
||||
|
||||
final String ancestorRef = git
|
||||
.runSync(['merge-base', gitRef, latestTag], workingDirectory: workingDirectory)
|
||||
.stdout
|
||||
.trim();
|
||||
|
||||
final String commitCount = git
|
||||
.runSync([
|
||||
'rev-list',
|
||||
'--count',
|
||||
'$ancestorRef..$gitRef',
|
||||
], workingDirectory: workingDirectory)
|
||||
.stdout
|
||||
.trim();
|
||||
|
||||
return parse('$latestTag-$commitCount');
|
||||
}
|
||||
|
||||
/// Parse a version string.
|
||||
///
|
||||
/// The version string can either be an exact release tag (e.g. '1.2.3' for
|
||||
@ -1109,6 +1133,7 @@ class GitTagVersion {
|
||||
);
|
||||
}
|
||||
|
||||
@visibleForTesting
|
||||
static GitTagVersion parse(String version) {
|
||||
GitTagVersion gitTagVersion;
|
||||
|
||||
|
||||
@ -291,9 +291,8 @@ void main() {
|
||||
command: <String>['git', 'rev-parse', '--verify', '@{upstream}'],
|
||||
stdout: revision,
|
||||
),
|
||||
const FakeCommand(command: <String>['git', 'tag', '--points-at', revision]),
|
||||
const FakeCommand(
|
||||
command: <String>['git', 'describe', '--match', '*.*.*', '--long', '--tags', revision],
|
||||
command: <String>['git', 'tag', '--points-at', revision],
|
||||
stdout: version,
|
||||
),
|
||||
]);
|
||||
|
||||
@ -16,6 +16,7 @@ import 'package:flutter_tools/src/features.dart';
|
||||
import 'package:flutter_tools/src/git.dart';
|
||||
import 'package:flutter_tools/src/globals.dart' as globals;
|
||||
import 'package:flutter_tools/src/version.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:test/fake.dart';
|
||||
|
||||
import '../src/common.dart';
|
||||
@ -57,6 +58,34 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
/// Mocks the series of commands used to determine the Flutter version for `master`.
|
||||
@useResult
|
||||
List<FakeCommand> mockGitTagHistory({
|
||||
required String latestTag,
|
||||
required String headRef,
|
||||
required String ancestorRef,
|
||||
required int commitsBetweenRefs,
|
||||
}) {
|
||||
return [
|
||||
FakeCommand(
|
||||
command: const [
|
||||
'git',
|
||||
'for-each-ref',
|
||||
'--sort=-v:refname',
|
||||
'--count=1',
|
||||
'--format=%(refname:short)',
|
||||
'refs/tags/[0-9]*.*.*',
|
||||
],
|
||||
stdout: latestTag,
|
||||
),
|
||||
FakeCommand(command: ['git', 'merge-base', headRef, latestTag], stdout: ancestorRef),
|
||||
FakeCommand(
|
||||
command: ['git', 'rev-list', '--count', '$ancestorRef..$headRef'],
|
||||
stdout: '$commitsBetweenRefs',
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
for (final String channel in kOfficialChannels) {
|
||||
DateTime getChannelUpToDateVersion() {
|
||||
return _testClock.ago(VersionFreshnessValidator.versionAgeConsideredUpToDate(channel) ~/ 2);
|
||||
@ -100,17 +129,11 @@ void main() {
|
||||
stdout: '1234abcd',
|
||||
),
|
||||
const FakeCommand(command: <String>['git', 'tag', '--points-at', '1234abcd']),
|
||||
const FakeCommand(
|
||||
command: <String>[
|
||||
'git',
|
||||
'describe',
|
||||
'--match',
|
||||
'*.*.*',
|
||||
'--long',
|
||||
'--tags',
|
||||
'1234abcd',
|
||||
],
|
||||
stdout: '0.1.2-3-1234abcd',
|
||||
...mockGitTagHistory(
|
||||
latestTag: '',
|
||||
headRef: '1234abcd',
|
||||
ancestorRef: '',
|
||||
commitsBetweenRefs: 0,
|
||||
),
|
||||
FakeCommand(
|
||||
command: const <String>['git', 'symbolic-ref', '--short', 'HEAD'],
|
||||
@ -278,17 +301,11 @@ void main() {
|
||||
],
|
||||
),
|
||||
const FakeCommand(command: <String>['git', 'tag', '--points-at', '1234abcd']),
|
||||
const FakeCommand(
|
||||
command: <String>[
|
||||
'git',
|
||||
'describe',
|
||||
'--match',
|
||||
'*.*.*',
|
||||
'--long',
|
||||
'--tags',
|
||||
'1234abcd',
|
||||
],
|
||||
stdout: '0.1.2-3-1234abcd',
|
||||
...mockGitTagHistory(
|
||||
latestTag: '0.1.2-3',
|
||||
headRef: '1234abcd',
|
||||
ancestorRef: 'abcd1234',
|
||||
commitsBetweenRefs: 170,
|
||||
),
|
||||
FakeCommand(
|
||||
command: const <String>['git', 'symbolic-ref', '--short', 'HEAD'],
|
||||
@ -467,17 +484,11 @@ void main() {
|
||||
stdout: '1234abcd',
|
||||
),
|
||||
const FakeCommand(command: <String>['git', 'tag', '--points-at', '1234abcd']),
|
||||
const FakeCommand(
|
||||
command: <String>[
|
||||
'git',
|
||||
'describe',
|
||||
'--match',
|
||||
'*.*.*',
|
||||
'--long',
|
||||
'--tags',
|
||||
'1234abcd',
|
||||
],
|
||||
stdout: '0.1.2-3-1234abcd',
|
||||
...mockGitTagHistory(
|
||||
latestTag: '0.1.2-3',
|
||||
headRef: '1234abcd',
|
||||
ancestorRef: 'abcd1234',
|
||||
commitsBetweenRefs: 170,
|
||||
),
|
||||
FakeCommand(
|
||||
command: const <String>['git', 'symbolic-ref', '--short', 'HEAD'],
|
||||
@ -859,9 +870,11 @@ void main() {
|
||||
stdout: '1234abcd',
|
||||
),
|
||||
const FakeCommand(command: <String>['git', 'tag', '--points-at', '1234abcd']),
|
||||
const FakeCommand(
|
||||
command: <String>['git', 'describe', '--match', '*.*.*', '--long', '--tags', '1234abcd'],
|
||||
stdout: '0.1.2-3-1234abcd',
|
||||
...mockGitTagHistory(
|
||||
latestTag: '0.1.2-3',
|
||||
headRef: '1234abcd',
|
||||
ancestorRef: 'abcd1234',
|
||||
commitsBetweenRefs: 170,
|
||||
),
|
||||
const FakeCommand(
|
||||
command: <String>['git', 'symbolic-ref', '--short', 'HEAD'],
|
||||
@ -907,9 +920,11 @@ void main() {
|
||||
stdout: '1234abcd',
|
||||
),
|
||||
const FakeCommand(command: <String>['git', 'tag', '--points-at', '1234abcd']),
|
||||
const FakeCommand(
|
||||
command: <String>['git', 'describe', '--match', '*.*.*', '--long', '--tags', '1234abcd'],
|
||||
stdout: '0.1.2-3-1234abcd',
|
||||
...mockGitTagHistory(
|
||||
latestTag: '0.1.2-3',
|
||||
headRef: '1234abcd',
|
||||
ancestorRef: 'abcd1234',
|
||||
commitsBetweenRefs: 170,
|
||||
),
|
||||
const FakeCommand(
|
||||
command: <String>['git', 'symbolic-ref', '--short', 'HEAD'],
|
||||
@ -1148,9 +1163,11 @@ void main() {
|
||||
stdout: '1234abcd',
|
||||
),
|
||||
const FakeCommand(command: <String>['git', 'tag', '--points-at', '1234abcd']),
|
||||
const FakeCommand(
|
||||
command: <String>['git', 'describe', '--match', '*.*.*', '--long', '--tags', '1234abcd'],
|
||||
stdout: '0.1.2-3-1234abcd',
|
||||
...mockGitTagHistory(
|
||||
latestTag: '0.1.2-3',
|
||||
headRef: '1234abcd',
|
||||
ancestorRef: 'abcd1234',
|
||||
commitsBetweenRefs: 170,
|
||||
),
|
||||
const FakeCommand(
|
||||
command: <String>['git', 'symbolic-ref', '--short', 'HEAD'],
|
||||
@ -1400,15 +1417,16 @@ void main() {
|
||||
testUsingContext('determine reports correct git describe version if HEAD is not at a tag', () {
|
||||
const devTag = '1.2.0-2.0.pre';
|
||||
const headRevision = 'abcd1234';
|
||||
const commitsAhead = '12';
|
||||
processManager.addCommands(<FakeCommand>[
|
||||
const FakeCommand(
|
||||
command: <String>['git', 'tag', '--points-at', 'HEAD'],
|
||||
// no output, since there's no tag
|
||||
),
|
||||
const FakeCommand(
|
||||
command: <String>['git', 'describe', '--match', '*.*.*', '--long', '--tags', 'HEAD'],
|
||||
stdout: '$devTag-$commitsAhead-g$headRevision',
|
||||
...mockGitTagHistory(
|
||||
latestTag: devTag,
|
||||
headRef: 'HEAD',
|
||||
ancestorRef: 'abcd1234',
|
||||
commitsBetweenRefs: 12,
|
||||
),
|
||||
]);
|
||||
final platform = FakePlatform();
|
||||
@ -1425,9 +1443,11 @@ void main() {
|
||||
testUsingContext('determine does not call fetch --tags', () {
|
||||
processManager.addCommands(<FakeCommand>[
|
||||
const FakeCommand(command: <String>['git', 'tag', '--points-at', 'HEAD']),
|
||||
const FakeCommand(
|
||||
command: <String>['git', 'describe', '--match', '*.*.*', '--long', '--tags', 'HEAD'],
|
||||
stdout: 'v0.1.2-3-1234abcd',
|
||||
...mockGitTagHistory(
|
||||
latestTag: 'v0.1.2-3',
|
||||
headRef: 'HEAD',
|
||||
ancestorRef: 'abcd1234',
|
||||
commitsBetweenRefs: 12,
|
||||
),
|
||||
]);
|
||||
final platform = FakePlatform();
|
||||
@ -1443,9 +1463,11 @@ void main() {
|
||||
stdout: 'beta',
|
||||
),
|
||||
const FakeCommand(command: <String>['git', 'tag', '--points-at', 'HEAD']),
|
||||
const FakeCommand(
|
||||
command: <String>['git', 'describe', '--match', '*.*.*', '--long', '--tags', 'HEAD'],
|
||||
stdout: 'v0.1.2-3-1234abcd',
|
||||
...mockGitTagHistory(
|
||||
latestTag: 'v0.1.2-3',
|
||||
headRef: 'HEAD',
|
||||
ancestorRef: 'abcd1234',
|
||||
commitsBetweenRefs: 12,
|
||||
),
|
||||
]);
|
||||
final platform = FakePlatform();
|
||||
@ -1464,9 +1486,11 @@ void main() {
|
||||
command: <String>['git', 'fetch', 'https://github.com/flutter/flutter.git', '--tags', '-f'],
|
||||
),
|
||||
const FakeCommand(command: <String>['git', 'tag', '--points-at', 'HEAD']),
|
||||
const FakeCommand(
|
||||
command: <String>['git', 'describe', '--match', '*.*.*', '--long', '--tags', 'HEAD'],
|
||||
stdout: 'v0.1.2-3-1234abcd',
|
||||
...mockGitTagHistory(
|
||||
latestTag: 'v0.1.2-3',
|
||||
headRef: 'HEAD',
|
||||
ancestorRef: 'abcd1234',
|
||||
commitsBetweenRefs: 12,
|
||||
),
|
||||
]);
|
||||
final platform = FakePlatform();
|
||||
@ -1485,9 +1509,11 @@ void main() {
|
||||
command: <String>['git', 'fetch', 'https://githubmirror.com/flutter.git', '--tags', '-f'],
|
||||
),
|
||||
const FakeCommand(command: <String>['git', 'tag', '--points-at', 'HEAD']),
|
||||
const FakeCommand(
|
||||
command: <String>['git', 'describe', '--match', '*.*.*', '--long', '--tags', 'HEAD'],
|
||||
stdout: 'v0.1.2-3-1234abcd',
|
||||
...mockGitTagHistory(
|
||||
latestTag: 'v0.1.2-3',
|
||||
headRef: 'HEAD',
|
||||
ancestorRef: 'abcd1234',
|
||||
commitsBetweenRefs: 12,
|
||||
),
|
||||
]);
|
||||
final platform = FakePlatform(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user