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

Revert "[flutter_tools] Make `flutter upgrade` only work with standard remotes (#79372)" (#83423)

This reverts commit c835ad43.
parent 971f7015
...@@ -17,12 +17,6 @@ import '../globals_null_migrated.dart' as globals; ...@@ -17,12 +17,6 @@ import '../globals_null_migrated.dart' as globals;
import '../runner/flutter_command.dart'; import '../runner/flutter_command.dart';
import '../version.dart'; import '../version.dart';
/// The flutter GitHub repository.
String get _flutterGit => globals.platform.environment['FLUTTER_GIT_URL'] ?? 'https://github.com/flutter/flutter.git';
/// The official docs to install Flutter.
String get _flutterInstallDocs => 'https://flutter.dev/docs/get-started/install';
class UpgradeCommand extends FlutterCommand { class UpgradeCommand extends FlutterCommand {
UpgradeCommand({ UpgradeCommand({
@required bool verboseHelp, @required bool verboseHelp,
...@@ -119,7 +113,7 @@ class UpgradeCommandRunner { ...@@ -119,7 +113,7 @@ class UpgradeCommandRunner {
@required bool testFlow, @required bool testFlow,
@required bool verifyOnly, @required bool verifyOnly,
}) async { }) async {
final FlutterVersion upstreamVersion = await fetchLatestVersion(localVersion: flutterVersion); final FlutterVersion upstreamVersion = await fetchLatestVersion();
if (flutterVersion.frameworkRevision == upstreamVersion.frameworkRevision) { if (flutterVersion.frameworkRevision == upstreamVersion.frameworkRevision) {
globals.printStatus('Flutter is already up to date on channel ${flutterVersion.channel}'); globals.printStatus('Flutter is already up to date on channel ${flutterVersion.channel}');
globals.printStatus('$flutterVersion'); globals.printStatus('$flutterVersion');
...@@ -228,80 +222,10 @@ class UpgradeCommandRunner { ...@@ -228,80 +222,10 @@ class UpgradeCommandRunner {
} }
} }
/// Checks if the Flutter git repository is tracking a "standard remote".
///
/// Using `flutter upgrade` is not supported from a non-standard remote. A git
/// remote should have the same url as [_flutterGit] to be considered as a
/// "standard" remote.
///
/// Exits tool if the tracking remote is not standard.
void verifyStandardRemote(FlutterVersion localVersion) {
// If localVersion.repositoryUrl is null, exit
if (localVersion.repositoryUrl == null) {
throwToolExit(
'Unable to upgrade Flutter: The tool could not determine the url of '
'the remote upstream which is currently being tracked by the SDK.\n'
'Re-install Flutter by going to $_flutterInstallDocs.'
);
}
// Strip `.git` suffix from repository url and _flutterGit
final String trackingUrl = _stripDotGit(localVersion.repositoryUrl);
final String flutterGitUrl = _stripDotGit(_flutterGit);
// Exempt the flutter GitHub git SSH remote from this check
if (trackingUrl == 'git@github.com:flutter/flutter') {
return;
}
if (trackingUrl != flutterGitUrl) {
if (globals.platform.environment.containsKey('FLUTTER_GIT_URL')) {
// If `FLUTTER_GIT_URL` is set, inform the user to either remove the
// `FLUTTER_GIT_URL` environment variable or set it to the current
// tracking remote to continue.
throwToolExit(
'Unable to upgrade Flutter: The Flutter SDK is tracking '
'"${localVersion.repositoryUrl}" but "FLUTTER_GIT_URL" is set to '
'"$_flutterGit".\n'
'Either remove "FLUTTER_GIT_URL" from the environment or set '
'"FLUTTER_GIT_URL" to "${localVersion.repositoryUrl}", and retry. '
'Alternatively, re-install Flutter by going to $_flutterInstallDocs.\n'
'If this is intentional, it is recommended to use "git" directly to '
'keep Flutter SDK up-to date.'
);
}
// If `FLUTTER_GIT_URL` is unset, inform that the user has to set the
// environment variable to continue.
throwToolExit(
'Unable to upgrade Flutter: The Flutter SDK is tracking a non-standard '
'remote "${localVersion.repositoryUrl}".\n'
'Set the environment variable "FLUTTER_GIT_URL" to '
'"${localVersion.repositoryUrl}", and retry. '
'Alternatively, re-install Flutter by going to $_flutterInstallDocs.\n'
'If this is intentional, it is recommended to use "git" directly to '
'keep Flutter SDK up-to date.'
);
}
}
// Strips ".git" suffix from a given string, preferably an url.
// For example, changes 'https://github.com/flutter/flutter.git' to 'https://github.com/flutter/flutter'.
// URLs without ".git" suffix will be unaffected.
String _stripDotGit(String url) {
final RegExp pattern = RegExp(r'(.*)(\.git)$');
final RegExpMatch match = pattern.firstMatch(url);
if (match == null) {
return url;
}
return match.group(1);
}
/// Returns the remote HEAD flutter version. /// Returns the remote HEAD flutter version.
/// ///
/// Exits tool if HEAD isn't pointing to a branch, or there is no upstream. /// Exits tool if there is no upstream.
Future<FlutterVersion> fetchLatestVersion({ Future<FlutterVersion> fetchLatestVersion() async {
@required FlutterVersion localVersion,
}) async {
String revision; String revision;
try { try {
// Fetch upstream branch's commits and tags // Fetch upstream branch's commits and tags
...@@ -321,22 +245,20 @@ class UpgradeCommandRunner { ...@@ -321,22 +245,20 @@ class UpgradeCommandRunner {
final String errorString = e.toString(); final String errorString = e.toString();
if (errorString.contains('fatal: HEAD does not point to a branch')) { if (errorString.contains('fatal: HEAD does not point to a branch')) {
throwToolExit( throwToolExit(
'Unable to upgrade Flutter: HEAD does not point to a branch (Are you ' 'You are not currently on a release branch. Use git to '
'in a detached HEAD state?).\n' "check out an official branch ('stable', 'beta', 'dev', or 'master') "
'Use "flutter channel" to switch to an official channel, and retry. ' 'and retry, for example:\n'
'Alternatively, re-install Flutter by going to $_flutterInstallDocs.' ' git checkout stable'
); );
} else if (errorString.contains('fatal: no upstream configured for branch')) { } else if (errorString.contains('fatal: no upstream configured for branch')) {
throwToolExit( throwToolExit(
'Unable to upgrade Flutter: No upstream repository configured for ' 'Unable to upgrade Flutter: no origin repository configured. '
'current branch.\n' "Run 'git remote add origin "
'Re-install Flutter by going to $_flutterInstallDocs.' "https://github.com/flutter/flutter' in $workingDirectory");
);
} else { } else {
throwToolExit(errorString); throwToolExit(errorString);
} }
} }
verifyStandardRemote(localVersion);
return FlutterVersion(workingDirectory: workingDirectory, frameworkRevision: revision); return FlutterVersion(workingDirectory: workingDirectory, frameworkRevision: revision);
} }
......
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,6 @@
// @dart = 2.8 // @dart = 2.8
import 'package:flutter_tools/src/base/common.dart' show ToolExit;
import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/io.dart'; import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/platform.dart'; import 'package:flutter_tools/src/base/platform.dart';
...@@ -174,7 +173,7 @@ void main() { ...@@ -174,7 +173,7 @@ void main() {
stdout: version), stdout: version),
]); ]);
final FlutterVersion updateVersion = await realCommandRunner.fetchLatestVersion(localVersion: FakeFlutterVersion()); final FlutterVersion updateVersion = await realCommandRunner.fetchLatestVersion();
expect(updateVersion.frameworkVersion, version); expect(updateVersion.frameworkVersion, version);
expect(updateVersion.frameworkRevision, revision); expect(updateVersion.frameworkRevision, revision);
...@@ -199,23 +198,17 @@ void main() { ...@@ -199,23 +198,17 @@ void main() {
), ),
]); ]);
ToolExit err; await expectLater(
try { () async => realCommandRunner.fetchLatestVersion(),
await realCommandRunner.fetchLatestVersion(localVersion: FakeFlutterVersion()); throwsToolExit(message: 'You are not currently on a release branch.'),
} on ToolExit catch (e) { );
err = e;
}
expect(err, isNotNull);
expect(err.toString(), contains('Unable to upgrade Flutter: HEAD does not point to a branch'));
expect(err.toString(), contains('Use "flutter channel" to switch to an official channel, and retry'));
expect(err.toString(), contains('re-install Flutter by going to https://flutter.dev/docs/get-started/install'));
expect(processManager, hasNoRemainingExpectations); expect(processManager, hasNoRemainingExpectations);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
ProcessManager: () => processManager, ProcessManager: () => processManager,
Platform: () => fakePlatform, Platform: () => fakePlatform,
}); });
testUsingContext('fetchLatestVersion throws toolExit if no upstream configured', () async { testUsingContext('fetchRemoteRevision throws toolExit if no upstream configured', () async {
processManager.addCommands(const <FakeCommand>[ processManager.addCommands(const <FakeCommand>[
FakeCommand(command: <String>[ FakeCommand(command: <String>[
'git', 'fetch', '--tags' 'git', 'fetch', '--tags'
...@@ -230,152 +223,18 @@ void main() { ...@@ -230,152 +223,18 @@ void main() {
), ),
]); ]);
ToolExit err; await expectLater(
try { () async => realCommandRunner.fetchLatestVersion(),
await realCommandRunner.fetchLatestVersion(localVersion: FakeFlutterVersion()); throwsToolExit(
} on ToolExit catch (e) { message: 'Unable to upgrade Flutter: no origin repository configured.',
err = e; ),
} );
expect(err, isNotNull);
expect(err.toString(), contains('Unable to upgrade Flutter: No upstream repository configured for current branch.'));
expect(err.toString(), contains('Re-install Flutter by going to https://flutter.dev/docs/get-started/install'));
expect(processManager, hasNoRemainingExpectations); expect(processManager, hasNoRemainingExpectations);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
ProcessManager: () => processManager, ProcessManager: () => processManager,
Platform: () => fakePlatform, Platform: () => fakePlatform,
}); });
group('verifyStandardRemote', () {
const String flutterStandardUrlDotGit = 'https://github.com/flutter/flutter.git';
const String flutterNonStandardUrlDotGit = 'https://githubmirror.com/flutter/flutter.git';
const String flutterStandardUrl = 'https://github.com/flutter/flutter';
const String flutterStandardSshUrlDotGit = 'git@github.com:flutter/flutter.git';
testUsingContext('throws toolExit if repository url is null', () async {
final FakeFlutterVersion flutterVersion = FakeFlutterVersion(
channel: 'dev',
repositoryUrl: null,
);
ToolExit err;
try {
realCommandRunner.verifyStandardRemote(flutterVersion);
} on ToolExit catch (e) {
err = e;
}
expect(err, isNotNull);
expect(err.toString(), contains('could not determine the url of the remote upstream which is currently being tracked by the SDK'));
expect(err.toString(), contains('Re-install Flutter by going to https://flutter.dev/docs/get-started/install'));
expect(processManager, hasNoRemainingExpectations);
}, overrides: <Type, Generator> {
ProcessManager: () => processManager,
Platform: () => fakePlatform,
});
testUsingContext('does not throw toolExit at standard remote url with .git suffix and FLUTTER_GIT_URL unset', () async {
final FakeFlutterVersion flutterVersion = FakeFlutterVersion(
channel: 'dev',
repositoryUrl: flutterStandardUrlDotGit,
);
expect(() => realCommandRunner.verifyStandardRemote(flutterVersion), returnsNormally);
expect(processManager, hasNoRemainingExpectations);
}, overrides: <Type, Generator> {
ProcessManager: () => processManager,
Platform: () => fakePlatform,
});
testUsingContext('does not throw toolExit at standard remote url without .git suffix and FLUTTER_GIT_URL unset', () async {
final FakeFlutterVersion flutterVersion = FakeFlutterVersion(
channel: 'dev',
repositoryUrl: flutterStandardUrl,
);
expect(() => realCommandRunner.verifyStandardRemote(flutterVersion), returnsNormally);
expect(processManager, hasNoRemainingExpectations);
}, overrides: <Type, Generator> {
ProcessManager: () => processManager,
Platform: () => fakePlatform,
});
testUsingContext('throws toolExit at non-standard remote url with FLUTTER_GIT_URL unset', () async {
final FakeFlutterVersion flutterVersion = FakeFlutterVersion(
channel: 'dev',
repositoryUrl: flutterNonStandardUrlDotGit,
);
ToolExit err;
try {
realCommandRunner.verifyStandardRemote(flutterVersion);
} on ToolExit catch (e) {
err = e;
}
expect(err, isNotNull);
expect(err.toString(), contains('The Flutter SDK is tracking a non-standard remote "$flutterNonStandardUrlDotGit"'));
expect(err.toString(), contains('Set the environment variable "FLUTTER_GIT_URL" to "$flutterNonStandardUrlDotGit", and retry.'));
expect(err.toString(), contains('re-install Flutter by going to https://flutter.dev/docs/get-started/install'));
expect(err.toString(), contains('it is recommended to use "git" directly to keep Flutter SDK up-to date.'));
expect(processManager, hasNoRemainingExpectations);
}, overrides: <Type, Generator> {
ProcessManager: () => processManager,
Platform: () => fakePlatform,
});
testUsingContext('does not throw toolExit at non-standard remote url with FLUTTER_GIT_URL set', () async {
final FakeFlutterVersion flutterVersion = FakeFlutterVersion(
channel: 'dev',
repositoryUrl: flutterNonStandardUrlDotGit,
);
expect(() => realCommandRunner.verifyStandardRemote(flutterVersion), returnsNormally);
expect(processManager, hasNoRemainingExpectations);
}, overrides: <Type, Generator> {
ProcessManager: () => processManager,
Platform: () => fakePlatform..environment = Map<String, String>.unmodifiable(<String, String> {
'FLUTTER_GIT_URL': flutterNonStandardUrlDotGit,
}),
});
testUsingContext('throws toolExit at remote url and FLUTTER_GIT_URL set to different urls', () async {
final FakeFlutterVersion flutterVersion = FakeFlutterVersion(
channel: 'dev',
repositoryUrl: flutterNonStandardUrlDotGit,
);
ToolExit err;
try {
realCommandRunner.verifyStandardRemote(flutterVersion);
} on ToolExit catch (e) {
err = e;
}
expect(err, isNotNull);
expect(err.toString(), contains('The Flutter SDK is tracking "$flutterNonStandardUrlDotGit"'));
expect(err.toString(), contains('but "FLUTTER_GIT_URL" is set to "$flutterStandardUrl"'));
expect(err.toString(), contains('remove "FLUTTER_GIT_URL" from the environment or set "FLUTTER_GIT_URL" to "$flutterNonStandardUrlDotGit"'));
expect(err.toString(), contains('re-install Flutter by going to https://flutter.dev/docs/get-started/install'));
expect(err.toString(), contains('it is recommended to use "git" directly to keep Flutter SDK up-to date.'));
expect(processManager, hasNoRemainingExpectations);
}, overrides: <Type, Generator> {
ProcessManager: () => processManager,
Platform: () => fakePlatform..environment = Map<String, String>.unmodifiable(<String, String> {
'FLUTTER_GIT_URL': flutterStandardUrl,
}),
});
testUsingContext('exempts standard ssh url from check with FLUTTER_GIT_URL unset', () async {
final FakeFlutterVersion flutterVersion = FakeFlutterVersion(
channel: 'dev',
repositoryUrl: flutterStandardSshUrlDotGit,
);
expect(() => realCommandRunner.verifyStandardRemote(flutterVersion), returnsNormally);
expect(processManager, hasNoRemainingExpectations);
}, overrides: <Type, Generator> {
ProcessManager: () => processManager,
Platform: () => fakePlatform,
});
});
testUsingContext('git exception during attemptReset throwsToolExit', () async { testUsingContext('git exception during attemptReset throwsToolExit', () async {
const String revision = 'abc123'; const String revision = 'abc123';
const String errorMessage = 'fatal: Could not parse object ´$revision´'; const String errorMessage = 'fatal: Could not parse object ´$revision´';
...@@ -611,7 +470,7 @@ class FakeUpgradeCommandRunner extends UpgradeCommandRunner { ...@@ -611,7 +470,7 @@ class FakeUpgradeCommandRunner extends UpgradeCommandRunner {
FlutterVersion remoteVersion; FlutterVersion remoteVersion;
@override @override
Future<FlutterVersion> fetchLatestVersion({FlutterVersion localVersion}) async => remoteVersion; Future<FlutterVersion> fetchLatestVersion() async => remoteVersion;
@override @override
Future<bool> hasUncommittedChanges() async => willHaveUncommittedChanges; Future<bool> hasUncommittedChanges() async => willHaveUncommittedChanges;
......
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