version.dart 4.51 KB
Newer Older
1 2 3 4 5 6 7 8
// 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';
9
import '../base/io.dart';
10 11 12 13 14 15 16 17 18 19
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 {
20
  VersionCommand() : super() {
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
    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 {
38 39
    RunResult runResult;
    try {
40
      runResult = await processUtils.run(
41
        <String>['git', 'tag', '-l', 'v*', '--sort=-creatordate'],
42
        throwOnError: true,
43 44 45 46 47 48 49 50 51
        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.'
      );
    }
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
    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);
69 70 71 72
    if (targetVersion == null) {
      throwToolExit('Failed to parse version "$version"');
    }

73 74
    bool withForce = false;
    if (targetVersion < minSupportedVersion) {
75
      if (!boolArg('force')) {
76 77 78 79 80 81 82 83 84 85 86
        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 {
87
      await processUtils.run(
88
        <String>['git', 'checkout', 'v$version'],
89
        throwOnError: true,
90
        workingDirectory: Cache.flutterRoot,
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
      );
    } 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...');
106
    int code = await processUtils.stream(<String>[
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
      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('');
122
      await pub.get(
123 124 125
        context: PubContext.pubUpgrade,
        directory: projectRoot,
        upgrade: true,
126
        checkLastModified: false,
127 128 129 130 131 132
      );
    }

    // Run a doctor check in case system requirements have changed.
    printStatus('');
    printStatus('Running flutter doctor...');
133
    code = await processUtils.stream(
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
      <String>[
        fs.path.join('bin', 'flutter'),
        'doctor',
      ],
      workingDirectory: Cache.flutterRoot,
      allowReentrantFlutter: true,
    );

    if (code != 0) {
      throwToolExit(null, exitCode: code);
    }

    return const FlutterCommandResult(ExitStatus.success);
  }
}