blob: 2d8fdcede731713925755b666ce4c471cab9e164 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import '../base/common.dart';
import '../base/file_system.dart';
import '../base/io.dart';
import '../base/os.dart';
import '../base/process.dart';
import '../base/version.dart';
import '../cache.dart';
import '../dart/pub.dart';
import '../globals.dart';
import '../runner/flutter_command.dart';
import '../version.dart';
class VersionCommand extends FlutterCommand {
VersionCommand() : super() {
argParser.addFlag('force',
abbr: 'f',
help: 'Force switch to older Flutter versions that do not include a version command',
);
}
@override
final String name = 'version';
@override
final String description = 'List or switch flutter versions.';
// The first version of Flutter which includes the flutter version command. Switching to older
// versions will require the user to manually upgrade.
Version minSupportedVersion = Version.parse('1.2.1');
Future<List<String>> getTags() async {
RunResult runResult;
try {
runResult = await processUtils.run(
<String>['git', 'tag', '-l', 'v*', '--sort=-creatordate'],
throwOnError: true,
workingDirectory: Cache.flutterRoot,
);
} on ProcessException catch (error) {
throwToolExit(
'Unable to get the tags. '
'This might be due to git not being installed or an internal error'
'\nError: $error.'
);
}
return runResult.toString().split('\n');
}
@override
Future<FlutterCommandResult> runCommand() async {
final List<String> tags = await getTags();
if (argResults.rest.isEmpty) {
tags.forEach(printStatus);
return const FlutterCommandResult(ExitStatus.success);
}
final String version = argResults.rest[0].replaceFirst('v', '');
if (!tags.contains('v$version')) {
printError('There is no version: $version');
}
// check min supported version
final Version targetVersion = Version.parse(version);
if (targetVersion == null) {
throwToolExit('Failed to parse version "$version"');
}
bool withForce = false;
if (targetVersion < minSupportedVersion) {
if (!argResults['force']) {
printError(
'Version command is not supported in $targetVersion and it is supported since version $minSupportedVersion'
'which means if you switch to version $minSupportedVersion then you can not use version command.'
'If you really want to switch to version $targetVersion, please use `--force` flag: `flutter version --force $targetVersion`.'
);
return const FlutterCommandResult(ExitStatus.success);
}
withForce = true;
}
try {
await processUtils.run(
<String>['git', 'checkout', 'v$version'],
throwOnError: true,
workingDirectory: Cache.flutterRoot,
);
} catch (e) {
throwToolExit('Unable to checkout version branch for version $version.');
}
final FlutterVersion flutterVersion = FlutterVersion();
printStatus('Switching Flutter to version ${flutterVersion.frameworkVersion}${withForce ? ' with force' : ''}');
// Check for and download any engine and pkg/ updates.
// We run the 'flutter' shell script re-entrantly here
// so that it will download the updated Dart and so forth
// if necessary.
printStatus('');
printStatus('Downloading engine...');
int code = await processUtils.stream(<String>[
fs.path.join('bin', 'flutter'),
'--no-color',
'precache',
], workingDirectory: Cache.flutterRoot, allowReentrantFlutter: true);
if (code != 0) {
throwToolExit(null, exitCode: code);
}
printStatus('');
printStatus(flutterVersion.toString());
final String projectRoot = findProjectRoot();
if (projectRoot != null) {
printStatus('');
await pubGet(
context: PubContext.pubUpgrade,
directory: projectRoot,
upgrade: true,
checkLastModified: false,
);
}
// Run a doctor check in case system requirements have changed.
printStatus('');
printStatus('Running flutter doctor...');
code = await processUtils.stream(
<String>[
fs.path.join('bin', 'flutter'),
'doctor',
],
workingDirectory: Cache.flutterRoot,
allowReentrantFlutter: true,
);
if (code != 0) {
throwToolExit(null, exitCode: code);
}
return const FlutterCommandResult(ExitStatus.success);
}
}