Unverified Commit 05dadb01 authored by Anurag Roy's avatar Anurag Roy Committed by GitHub

[flutter_tools] Make flutter upgrade --verify-only display framework version...

[flutter_tools] Make flutter upgrade --verify-only display framework version differences instead of commit hashes (#69420)
parent f4a0511e
......@@ -106,16 +106,15 @@ class UpgradeCommandRunner {
@required bool testFlow,
@required bool verifyOnly,
}) async {
final String upstreamRevision = await fetchRemoteRevision();
if (flutterVersion.frameworkRevision == upstreamRevision) {
final FlutterVersion upstreamVersion = await fetchLatestVersion();
if (flutterVersion.frameworkRevision == upstreamVersion.frameworkRevision) {
globals.printStatus('Flutter is already up to date on channel ${flutterVersion.channel}');
globals.printStatus('$flutterVersion');
return;
} else if (verifyOnly) {
globals.printStatus('A new version of Flutter is available on channel ${flutterVersion.channel}\n');
// TODO(fujino): use a [FlutterVersion] once that class supports arbitrary revisions.
globals.printStatus('The latest revision: $upstreamRevision', emphasis: true);
globals.printStatus('Your current version: ${flutterVersion.frameworkRevision}\n');
globals.printStatus('The latest version: ${upstreamVersion.frameworkVersion} (revision ${upstreamVersion.frameworkRevisionShort})', emphasis: true);
globals.printStatus('Your current version: ${flutterVersion.frameworkVersion} (revision ${flutterVersion.frameworkRevisionShort})\n');
globals.printStatus('To upgrade now, run "flutter upgrade".');
if (flutterVersion.channel == 'stable') {
globals.printStatus('\nSee the announcement and release notes:');
......@@ -153,7 +152,7 @@ class UpgradeCommandRunner {
);
}
recordState(flutterVersion);
await attemptReset(upstreamRevision);
await attemptReset(upstreamVersion.frameworkRevision);
if (!testFlow) {
await flutterUpgradeContinue();
}
......@@ -216,10 +215,10 @@ class UpgradeCommandRunner {
return false;
}
/// Returns the remote HEAD revision.
/// Returns the remote HEAD flutter version.
///
/// Exits tool if there is no upstream.
Future<String> fetchRemoteRevision() async {
Future<FlutterVersion> fetchLatestVersion() async {
String revision;
try {
// Fetch upstream branch's commits and tags
......@@ -253,7 +252,7 @@ class UpgradeCommandRunner {
throwToolExit(errorString);
}
}
return revision;
return FlutterVersion(workingDirectory: workingDirectory, frameworkRevision: revision);
}
/// Attempts a hard reset to the given revision.
......
......@@ -59,14 +59,15 @@ class FlutterVersion {
FlutterVersion({
SystemClock clock = const SystemClock(),
String workingDirectory,
String frameworkRevision,
}) : _clock = clock,
_workingDirectory = workingDirectory {
_frameworkRevision = _runGit(
_workingDirectory = workingDirectory {
_frameworkRevision = frameworkRevision ?? _runGit(
gitLog(<String>['-n', '1', '--pretty=format:%H']).join(' '),
globals.processUtils,
_workingDirectory,
);
_gitTagVersion = GitTagVersion.determine(globals.processUtils, workingDirectory: _workingDirectory, fetchTags: false);
_gitTagVersion = GitTagVersion.determine(globals.processUtils, workingDirectory: _workingDirectory, fetchTags: false, gitRef: _frameworkRevision);
_frameworkVersion = gitTagVersion.frameworkVersionFor(_frameworkRevision);
}
......@@ -733,7 +734,7 @@ class GitTagVersion {
/// The git tag that is this version's closest ancestor.
final String gitTag;
static GitTagVersion determine(ProcessUtils processUtils, {String workingDirectory, bool fetchTags = false}) {
static GitTagVersion determine(ProcessUtils processUtils, {String workingDirectory, bool fetchTags = false, String gitRef = 'HEAD'}) {
if (fetchTags) {
final String channel = _runGit('git rev-parse --abbrev-ref HEAD', processUtils, workingDirectory);
if (channel == 'dev' || channel == 'beta' || channel == 'stable') {
......@@ -743,7 +744,7 @@ class GitTagVersion {
}
}
final List<String> tags = _runGit(
'git tag --points-at HEAD', processUtils, workingDirectory).trim().split('\n');
'git tag --points-at $gitRef', processUtils, workingDirectory).trim().split('\n');
// Check first for a stable tag
final RegExp stableTagPattern = RegExp(r'^\d+\.\d+\.\d+$');
......@@ -764,7 +765,7 @@ class GitTagVersion {
// recent tag and number of commits past.
return parse(
_runGit(
'git describe --match *.*.* --long --tags',
'git describe --match *.*.* --long --tags $gitRef',
processUtils,
workingDirectory,
)
......
......@@ -48,6 +48,11 @@ void main() {
});
testUsingContext('throws on unknown tag, official branch, noforce', () async {
const String upstreamRevision = '';
final MockFlutterVersion latestVersion = MockFlutterVersion();
when(latestVersion.frameworkRevision).thenReturn(upstreamRevision);
fakeCommandRunner.remoteVersion = latestVersion;
final Future<FlutterCommandResult> result = fakeCommandRunner.runCommand(
force: false,
continueFlow: false,
......@@ -63,7 +68,12 @@ void main() {
});
testUsingContext('throws tool exit with uncommitted changes', () async {
const String upstreamRevision = '';
final MockFlutterVersion latestVersion = MockFlutterVersion();
when(latestVersion.frameworkRevision).thenReturn(upstreamRevision);
fakeCommandRunner.remoteVersion = latestVersion;
fakeCommandRunner.willHaveUncommittedChanges = true;
final Future<FlutterCommandResult> result = fakeCommandRunner.runCommand(
force: false,
continueFlow: false,
......@@ -80,9 +90,12 @@ void main() {
testUsingContext("Doesn't continue on known tag, dev branch, no force, already up-to-date", () async {
const String revision = 'abc123';
final MockFlutterVersion latestVersion = MockFlutterVersion();
when(flutterVersion.frameworkRevision).thenReturn(revision);
when(latestVersion.frameworkRevision).thenReturn(revision);
fakeCommandRunner.alreadyUpToDate = true;
fakeCommandRunner.remoteRevision = revision;
fakeCommandRunner.remoteVersion = latestVersion;
final Future<FlutterCommandResult> result = fakeCommandRunner.runCommand(
force: false,
continueFlow: false,
......@@ -99,10 +112,25 @@ void main() {
Platform: () => fakePlatform,
});
testUsingContext('Correctly provides upgrade version on verify only', () async {
testUsingContext('correctly provides upgrade version on verify only', () async {
const String revision = 'abc123';
const String upstreamRevision = 'def456';
const String version = '1.2.3';
const String upstreamVersion = '4.5.6';
when(flutterVersion.frameworkRevision).thenReturn(revision);
when(flutterVersion.frameworkRevisionShort).thenReturn(revision);
when(flutterVersion.frameworkVersion).thenReturn(version);
final MockFlutterVersion latestVersion = MockFlutterVersion();
when(latestVersion.frameworkRevision).thenReturn(upstreamRevision);
when(latestVersion.frameworkRevisionShort).thenReturn(upstreamRevision);
when(latestVersion.frameworkVersion).thenReturn(upstreamVersion);
fakeCommandRunner.alreadyUpToDate = false;
fakeCommandRunner.remoteVersion = latestVersion;
final Future<FlutterCommandResult> result = fakeCommandRunner.runCommand(
force: false,
continueFlow: false,
......@@ -113,16 +141,17 @@ void main() {
);
expect(await result, FlutterCommandResult.success());
expect(testLogger.statusText, contains('A new version of Flutter is available'));
expect(testLogger.statusText, contains(fakeCommandRunner.remoteRevision));
expect(testLogger.statusText, contains(revision));
expect(testLogger.statusText, contains('The latest version: 4.5.6 (revision def456)'));
expect(testLogger.statusText, contains('Your current version: 1.2.3 (revision abc123)'));
expect(processManager.hasRemainingExpectations, isFalse);
}, overrides: <Type, Generator>{
ProcessManager: () => processManager,
Platform: () => fakePlatform,
});
testUsingContext('fetchRemoteRevision returns revision if git succeeds', () async {
testUsingContext('fetchLatestVersion returns version if git succeeds', () async {
const String revision = 'abc123';
const String version = '1.2.3';
processManager.addCommands(<FakeCommand>[
const FakeCommand(command: <String>[
......@@ -132,16 +161,27 @@ void main() {
'git', 'rev-parse', '--verify', '@{u}',
],
stdout: revision),
const FakeCommand(command: <String>[
'git', 'tag', '--points-at', revision,
],
stdout: ''),
const FakeCommand(command: <String>[
'git', 'describe', '--match', '*.*.*', '--long', '--tags', revision,
],
stdout: version),
]);
expect(await realCommandRunner.fetchRemoteRevision(), revision);
final FlutterVersion updateVersion = await realCommandRunner.fetchLatestVersion();
expect(updateVersion.frameworkVersion, version);
expect(updateVersion.frameworkRevision, revision);
expect(processManager.hasRemainingExpectations, isFalse);
}, overrides: <Type, Generator>{
ProcessManager: () => processManager,
Platform: () => fakePlatform,
});
testUsingContext('fetchRemoteRevision throws toolExit if HEAD is detached', () async {
testUsingContext('fetchLatestVersion throws toolExit if HEAD is detached', () async {
processManager.addCommands(<FakeCommand>[
const FakeCommand(command: <String>[
'git', 'fetch', '--tags'
......@@ -159,7 +199,7 @@ void main() {
]);
await expectLater(
() async => await realCommandRunner.fetchRemoteRevision(),
() async => await realCommandRunner.fetchLatestVersion(),
throwsToolExit(message: 'You are not currently on a release branch.'),
);
expect(processManager.hasRemainingExpectations, isFalse);
......@@ -186,7 +226,7 @@ void main() {
]);
await expectLater(
() async => await realCommandRunner.fetchRemoteRevision(),
() async => await realCommandRunner.fetchLatestVersion(),
throwsToolExit(
message: 'Unable to upgrade Flutter: no origin repository configured.',
),
......@@ -274,6 +314,9 @@ void main() {
});
testUsingContext('does not throw on unknown tag, official branch, force', () async {
final MockFlutterVersion latestVersion = MockFlutterVersion();
fakeCommandRunner.remoteVersion = latestVersion;
final Future<FlutterCommandResult> result = fakeCommandRunner.runCommand(
force: true,
continueFlow: false,
......@@ -290,6 +333,8 @@ void main() {
});
testUsingContext('does not throw tool exit with uncommitted changes and force', () async {
final MockFlutterVersion latestVersion = MockFlutterVersion();
fakeCommandRunner.remoteVersion = latestVersion;
fakeCommandRunner.willHaveUncommittedChanges = true;
final Future<FlutterCommandResult> result = fakeCommandRunner.runCommand(
......@@ -308,6 +353,9 @@ void main() {
});
testUsingContext("Doesn't throw on known tag, dev branch, no force", () async {
final MockFlutterVersion latestVersion = MockFlutterVersion();
fakeCommandRunner.remoteVersion = latestVersion;
final Future<FlutterCommandResult> result = fakeCommandRunner.runCommand(
force: false,
continueFlow: false,
......@@ -341,7 +389,7 @@ void main() {
),
const FakeCommand(
command: <String>[
'git', 'describe', '--match', '*.*.*', '--long', '--tags',
'git', 'describe', '--match', '*.*.*', '--long', '--tags', 'HEAD',
],
stdout: 'v1.12.16-19-gb45b676af',
),
......@@ -386,13 +434,12 @@ void main() {
class FakeUpgradeCommandRunner extends UpgradeCommandRunner {
bool willHaveUncommittedChanges = false;
bool alreadyUpToDate = false;
String remoteRevision = '';
FlutterVersion remoteVersion;
@override
Future<String> fetchRemoteRevision() async => remoteRevision;
Future<FlutterVersion> fetchLatestVersion() async => remoteVersion;
@override
Future<bool> hasUncommittedChanges() async => willHaveUncommittedChanges;
......
......@@ -126,9 +126,9 @@ void main() {
workingDirectory: Cache.flutterRoot)).thenReturn(result);
when(processManager.runSync('git fetch https://github.com/flutter/flutter.git --tags'.split(' '),
workingDirectory: Cache.flutterRoot)).thenReturn(result);
when(processManager.runSync('git tag --points-at HEAD'.split(' '),
when(processManager.runSync('git tag --points-at random'.split(' '),
workingDirectory: Cache.flutterRoot)).thenReturn(result);
when(processManager.runSync('git describe --match *.*.* --long --tags'.split(' '),
when(processManager.runSync('git describe --match *.*.* --long --tags random'.split(' '),
workingDirectory: Cache.flutterRoot)).thenReturn(result);
when(processManager.runSync(FlutterVersion.gitLog('-n 1 --pretty=format:%ad --date=iso'.split(' ')),
workingDirectory: Cache.flutterRoot)).thenReturn(result);
......
......@@ -77,11 +77,11 @@ void main() {
));
processManager.addCommand(const FakeCommand(
command: <String>['git', 'tag', '--points-at', 'HEAD'],
command: <String>['git', 'tag', '--points-at', '1234abcd'],
));
processManager.addCommand(const FakeCommand(
command: <String>['git', 'describe', '--match', '*.*.*', '--long', '--tags'],
command: <String>['git', 'describe', '--match', '*.*.*', '--long', '--tags', '1234abcd'],
stdout: '0.1.2-3-1234abcd',
));
......@@ -563,7 +563,7 @@ void main() {
stdout: '', // no tag
),
const FakeCommand(
command: <String>['git', 'describe', '--match', '*.*.*', '--long', '--tags'],
command: <String>['git', 'describe', '--match', '*.*.*', '--long', '--tags', 'HEAD'],
stdout: '$devTag-$commitsAhead-g$headRevision',
),
],
......@@ -585,7 +585,7 @@ void main() {
environment: anyNamed('environment'),
)).thenReturn(RunResult(ProcessResult(105, 0, '', ''), <String>['git', 'fetch']));
when(processUtils.runSync(
<String>['git', 'describe', '--match', '*.*.*', '--long', '--tags'],
<String>['git', 'describe', '--match', '*.*.*', '--long', '--tags', 'HEAD'],
workingDirectory: anyNamed('workingDirectory'),
environment: anyNamed('environment'),
)).thenReturn(RunResult(ProcessResult(106, 0, 'v0.1.2-3-1234abcd', ''), <String>['git', 'describe']));
......@@ -611,7 +611,7 @@ void main() {
environment: anyNamed('environment'),
));
verify(processUtils.runSync(
<String>['git', 'describe', '--match', '*.*.*', '--long', '--tags'],
<String>['git', 'describe', '--match', '*.*.*', '--long', '--tags', 'HEAD'],
workingDirectory: anyNamed('workingDirectory'),
environment: anyNamed('environment'),
)).called(1);
......@@ -630,7 +630,7 @@ void main() {
environment: anyNamed('environment'),
)).thenReturn(RunResult(ProcessResult(106, 0, '', ''), <String>['git', 'fetch']));
when(processUtils.runSync(
<String>['git', 'describe', '--match', '*.*.*', '--long', '--tags'],
<String>['git', 'describe', '--match', '*.*.*', '--long', '--tags', 'HEAD'],
workingDirectory: anyNamed('workingDirectory'),
environment: anyNamed('environment'),
)).thenReturn(RunResult(ProcessResult(107, 0, 'v0.1.2-3-1234abcd', ''), <String>['git', 'describe']));
......@@ -656,7 +656,7 @@ void main() {
environment: anyNamed('environment'),
));
verify(processUtils.runSync(
<String>['git', 'describe', '--match', '*.*.*', '--long', '--tags'],
<String>['git', 'describe', '--match', '*.*.*', '--long', '--tags', 'HEAD'],
workingDirectory: anyNamed('workingDirectory'),
environment: anyNamed('environment'),
)).called(1);
......@@ -683,7 +683,7 @@ void main() {
<String>['git', 'tag', '--points-at', 'HEAD'],
));
when(processUtils.runSync(
<String>['git', 'describe', '--match', '*.*.*', '--long', '--tags'],
<String>['git', 'describe', '--match', '*.*.*', '--long', '--tags', 'HEAD'],
workingDirectory: anyNamed('workingDirectory'),
environment: anyNamed('environment'),
)).thenReturn(RunResult(ProcessResult(111, 0, 'v0.1.2-3-1234abcd', ''), <String>['git', 'describe']));
......@@ -701,7 +701,7 @@ void main() {
environment: anyNamed('environment'),
)).called(1);
verify(processUtils.runSync(
<String>['git', 'describe', '--match', '*.*.*', '--long', '--tags'],
<String>['git', 'describe', '--match', '*.*.*', '--long', '--tags', 'HEAD'],
workingDirectory: anyNamed('workingDirectory'),
environment: anyNamed('environment'),
)).called(1);
......@@ -728,7 +728,7 @@ void main() {
<String>['git', 'tag', '--points-at', 'HEAD'],
));
when(processUtils.runSync(
<String>['git', 'describe', '--match', '*.*.*', '--long', '--tags'],
<String>['git', 'describe', '--match', '*.*.*', '--long', '--tags', 'HEAD'],
workingDirectory: anyNamed('workingDirectory'),
environment: anyNamed('environment'),
)).thenReturn(RunResult(ProcessResult(111, 0, 'v0.1.2-3-1234abcd', ''), <String>['git', 'describe']));
......@@ -861,12 +861,12 @@ void fakeData(
environment: anyNamed('environment'),
)).thenReturn(ProcessResult(105, 0, '', ''));
when(pm.runSync(
<String>['git', 'tag', '--points-at', 'HEAD'],
<String>['git', 'tag', '--points-at', '1234abcd'],
workingDirectory: anyNamed('workingDirectory'),
environment: anyNamed('environment'),
)).thenReturn(ProcessResult(106, 0, '', ''));
when(pm.runSync(
<String>['git', 'describe', '--match', '*.*.*', '--long', '--tags'],
<String>['git', 'describe', '--match', '*.*.*', '--long', '--tags', '1234abcd'],
workingDirectory: anyNamed('workingDirectory'),
environment: anyNamed('environment'),
)).thenReturn(ProcessResult(107, 0, 'v0.1.2-3-1234abcd', ''));
......
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