Migrate flutter_command to null safety (#92871)
This commit is contained in:
parent
1980492997
commit
a4e7b5994c
@ -2,8 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'package:args/args.dart';
|
||||
import 'package:args/command_runner.dart';
|
||||
import 'package:file/file.dart';
|
||||
@ -70,7 +68,7 @@ class FlutterCommandResult {
|
||||
/// Optional data that can be appended to the timing event.
|
||||
/// https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#timingLabel
|
||||
/// Do not add PII.
|
||||
final List<String> timingLabelParts;
|
||||
final List<String>? timingLabelParts;
|
||||
|
||||
/// Optional epoch time when the command's non-interactive wait time is
|
||||
/// complete during the command's execution. Use to measure user perceivable
|
||||
@ -78,7 +76,7 @@ class FlutterCommandResult {
|
||||
///
|
||||
/// [FlutterCommand] will automatically measure and report the command's
|
||||
/// complete time if not overridden.
|
||||
final DateTime endTimeOverride;
|
||||
final DateTime? endTimeOverride;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
@ -92,7 +90,6 @@ class FlutterCommandResult {
|
||||
case ExitStatus.killed:
|
||||
return 'killed';
|
||||
}
|
||||
return null; // dead code, remove with null safety migration
|
||||
}
|
||||
}
|
||||
|
||||
@ -131,7 +128,7 @@ abstract class FlutterCommand extends Command<void> {
|
||||
/// The currently executing command (or sub-command).
|
||||
///
|
||||
/// Will be `null` until the top-most command has begun execution.
|
||||
static FlutterCommand get current => context.get<FlutterCommand>();
|
||||
static FlutterCommand? get current => context.get<FlutterCommand>();
|
||||
|
||||
/// The option name for a custom observatory port.
|
||||
static const String observatoryPortOption = 'observatory-port';
|
||||
@ -168,7 +165,7 @@ abstract class FlutterCommand extends Command<void> {
|
||||
);
|
||||
|
||||
@override
|
||||
FlutterCommandRunner get runner => super.runner as FlutterCommandRunner;
|
||||
FlutterCommandRunner? get runner => super.runner as FlutterCommandRunner?;
|
||||
|
||||
bool _requiresPubspecYaml = false;
|
||||
|
||||
@ -197,7 +194,7 @@ abstract class FlutterCommand extends Command<void> {
|
||||
_requiresPubspecYaml = true;
|
||||
}
|
||||
|
||||
void usesWebOptions({ @required bool verboseHelp }) {
|
||||
void usesWebOptions({ required bool verboseHelp }) {
|
||||
argParser.addOption('web-hostname',
|
||||
defaultsTo: 'localhost',
|
||||
help:
|
||||
@ -208,7 +205,6 @@ abstract class FlutterCommand extends Command<void> {
|
||||
hide: !verboseHelp,
|
||||
);
|
||||
argParser.addOption('web-port',
|
||||
defaultsTo: null,
|
||||
help: 'The host port to serve the web application from. If not provided, the tool '
|
||||
'will select a random open port on the host.',
|
||||
hide: !verboseHelp,
|
||||
@ -241,13 +237,11 @@ abstract class FlutterCommand extends Command<void> {
|
||||
hide: !verboseHelp,
|
||||
);
|
||||
argParser.addFlag('web-allow-expose-url',
|
||||
defaultsTo: false,
|
||||
help: 'Enables daemon-to-editor requests (app.exposeUrl) for exposing URLs '
|
||||
'when running on remote machines.',
|
||||
hide: !verboseHelp,
|
||||
);
|
||||
argParser.addFlag('web-run-headless',
|
||||
defaultsTo: false,
|
||||
help: 'Launches the browser in headless mode. Currently only Chrome '
|
||||
'supports this option.',
|
||||
hide: !verboseHelp,
|
||||
@ -278,11 +272,12 @@ abstract class FlutterCommand extends Command<void> {
|
||||
}
|
||||
|
||||
String get targetFile {
|
||||
if (argResults.wasParsed('target')) {
|
||||
return stringArg('target');
|
||||
if (argResults?.wasParsed('target') == true) {
|
||||
return stringArg('target')!;
|
||||
}
|
||||
if (argResults.rest.isNotEmpty) {
|
||||
return argResults.rest.first;
|
||||
final List<String>? rest = argResults?.rest;
|
||||
if (rest != null && rest.isNotEmpty) {
|
||||
return rest.first;
|
||||
}
|
||||
return bundle.defaultMainPath;
|
||||
}
|
||||
@ -290,12 +285,12 @@ abstract class FlutterCommand extends Command<void> {
|
||||
/// Path to the Dart's package config file.
|
||||
///
|
||||
/// This can be overridden by some of its subclasses.
|
||||
String get packagesPath => globalResults['packages'] as String;
|
||||
String? get packagesPath => globalResults?['packages'] as String?;
|
||||
|
||||
/// The value of the `--filesystem-scheme` argument.
|
||||
///
|
||||
/// This can be overridden by some of its subclasses.
|
||||
String get fileSystemScheme =>
|
||||
String? get fileSystemScheme =>
|
||||
argParser.options.containsKey(FlutterOptions.kFileSystemScheme)
|
||||
? stringArg(FlutterOptions.kFileSystemScheme)
|
||||
: null;
|
||||
@ -303,7 +298,7 @@ abstract class FlutterCommand extends Command<void> {
|
||||
/// The values of the `--filesystem-root` argument.
|
||||
///
|
||||
/// This can be overridden by some of its subclasses.
|
||||
List<String> get fileSystemRoots =>
|
||||
List<String>? get fileSystemRoots =>
|
||||
argParser.options.containsKey(FlutterOptions.kFileSystemRoot)
|
||||
? stringsArg(FlutterOptions.kFileSystemRoot)
|
||||
: null;
|
||||
@ -320,7 +315,7 @@ abstract class FlutterCommand extends Command<void> {
|
||||
///
|
||||
/// The `hide` argument indicates whether or not to hide these options when
|
||||
/// the user asks for help.
|
||||
void usesFilesystemOptions({ @required bool hide }) {
|
||||
void usesFilesystemOptions({ required bool hide }) {
|
||||
argParser
|
||||
..addOption('output-dill',
|
||||
hide: hide,
|
||||
@ -342,7 +337,7 @@ abstract class FlutterCommand extends Command<void> {
|
||||
}
|
||||
|
||||
/// Adds options for connecting to the Dart VM observatory port.
|
||||
void usesPortOptions({ @required bool verboseHelp }) {
|
||||
void usesPortOptions({ required bool verboseHelp }) {
|
||||
argParser.addOption(observatoryPortOption,
|
||||
help: '(deprecated; use host-vmservice-port instead) '
|
||||
'Listen to the given port for an observatory debugger connection.\n'
|
||||
@ -364,7 +359,7 @@ abstract class FlutterCommand extends Command<void> {
|
||||
_usesPortOption = true;
|
||||
}
|
||||
|
||||
void addDevToolsOptions({@required bool verboseHelp}) {
|
||||
void addDevToolsOptions({required bool verboseHelp}) {
|
||||
argParser.addFlag(
|
||||
kEnableDevTools,
|
||||
hide: !verboseHelp,
|
||||
@ -382,7 +377,7 @@ abstract class FlutterCommand extends Command<void> {
|
||||
);
|
||||
}
|
||||
|
||||
void addDdsOptions({@required bool verboseHelp}) {
|
||||
void addDdsOptions({required bool verboseHelp}) {
|
||||
argParser.addOption('dds-port',
|
||||
help: 'When this value is provided, the Dart Development Service (DDS) will be '
|
||||
'bound to the provided port.\n'
|
||||
@ -407,55 +402,61 @@ abstract class FlutterCommand extends Command<void> {
|
||||
);
|
||||
}
|
||||
|
||||
bool _ddsEnabled;
|
||||
bool get enableDds {
|
||||
if (_ddsEnabled == null) {
|
||||
if (argResults.wasParsed('disable-dds')) {
|
||||
if (argResults.wasParsed('dds')) {
|
||||
throwToolExit('The "--[no-]dds" and "--[no-]disable-dds" arguments are mutually exclusive. Only specify "--[no-]dds".');
|
||||
}
|
||||
_ddsEnabled = !boolArg('disable-dds');
|
||||
// TODO(ianh): enable the following code once google3 is migrated away from --disable-dds (and add test to flutter_command_test.dart)
|
||||
if (false) { // ignore: dead_code
|
||||
if (_ddsEnabled) {
|
||||
globals.printError('${globals.logger.terminal.warningMark} The "--no-disable-dds" argument is deprecated and redundant, and should be omitted.');
|
||||
} else {
|
||||
globals.printError('${globals.logger.terminal.warningMark} The "--disable-dds" argument is deprecated. Use "--no-dds" instead.');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
_ddsEnabled = boolArg('dds');
|
||||
late final bool enableDds = () {
|
||||
bool ddsEnabled = false;
|
||||
if (argResults?.wasParsed('disable-dds') == true) {
|
||||
if (argResults?.wasParsed('dds') == true) {
|
||||
throwToolExit(
|
||||
'The "--[no-]dds" and "--[no-]disable-dds" arguments are mutually exclusive. Only specify "--[no-]dds".');
|
||||
}
|
||||
ddsEnabled = !boolArg('disable-dds');
|
||||
// TODO(ianh): enable the following code once google3 is migrated away from --disable-dds (and add test to flutter_command_test.dart)
|
||||
if (false) { // ignore: dead_code
|
||||
if (ddsEnabled) {
|
||||
globals.printError('${globals.logger.terminal
|
||||
.warningMark} The "--no-disable-dds" argument is deprecated and redundant, and should be omitted.');
|
||||
} else {
|
||||
globals.printError('${globals.logger.terminal
|
||||
.warningMark} The "--disable-dds" argument is deprecated. Use "--no-dds" instead.');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ddsEnabled = boolArg('dds');
|
||||
}
|
||||
return _ddsEnabled;
|
||||
}
|
||||
return ddsEnabled;
|
||||
}();
|
||||
|
||||
bool get _hostVmServicePortProvided => argResults.wasParsed('observatory-port') ||
|
||||
argResults.wasParsed('host-vmservice-port');
|
||||
bool get _hostVmServicePortProvided => argResults?.wasParsed('observatory-port') == true ||
|
||||
argResults?.wasParsed('host-vmservice-port') == true;
|
||||
|
||||
int _tryParseHostVmservicePort() {
|
||||
final String? observatoryPort = stringArg('observatory-port');
|
||||
final String? hostPort = stringArg('host-vmservice-port');
|
||||
if (observatoryPort == null && hostPort == null) {
|
||||
throwToolExit('Invalid port for `--observatory-port/--host-vmservice-port`');
|
||||
}
|
||||
try {
|
||||
return int.parse(stringArg('observatory-port') ?? stringArg('host-vmservice-port'));
|
||||
return int.parse((observatoryPort ?? hostPort)!);
|
||||
} on FormatException catch (error) {
|
||||
throwToolExit('Invalid port for `--observatory-port/--host-vmservice-port`: $error');
|
||||
}
|
||||
}
|
||||
|
||||
int get ddsPort {
|
||||
if (!argResults.wasParsed('dds-port') && _hostVmServicePortProvided) {
|
||||
if (argResults?.wasParsed('dds-port') != true && _hostVmServicePortProvided) {
|
||||
// If an explicit DDS port is _not_ provided, use the host-vmservice-port for DDS.
|
||||
return _tryParseHostVmservicePort();
|
||||
} else if (argResults.wasParsed('dds-port')) {
|
||||
} else if (argResults?.wasParsed('dds-port') == true) {
|
||||
// If an explicit DDS port is provided, use dds-port for DDS.
|
||||
return int.tryParse(stringArg('dds-port')) ?? 0;
|
||||
return int.tryParse(stringArg('dds-port')!) ?? 0;
|
||||
}
|
||||
// Otherwise, DDS can bind to a random port.
|
||||
return 0;
|
||||
}
|
||||
|
||||
Uri get devToolsServerAddress {
|
||||
if (argResults.wasParsed(kDevToolsServerAddress)) {
|
||||
final Uri uri = Uri.tryParse(stringArg(kDevToolsServerAddress));
|
||||
Uri? get devToolsServerAddress {
|
||||
if (argResults?.wasParsed(kDevToolsServerAddress) == true) {
|
||||
final Uri? uri = Uri.tryParse(stringArg(kDevToolsServerAddress)!);
|
||||
if (uri != null && uri.host.isNotEmpty && uri.port != 0) {
|
||||
return uri;
|
||||
}
|
||||
@ -470,19 +471,19 @@ abstract class FlutterCommand extends Command<void> {
|
||||
/// specified.
|
||||
///
|
||||
/// If no port is set, returns null.
|
||||
int get hostVmservicePort {
|
||||
int? get hostVmservicePort {
|
||||
if (!_usesPortOption || !_hostVmServicePortProvided) {
|
||||
return null;
|
||||
}
|
||||
if (argResults.wasParsed('observatory-port') &&
|
||||
argResults.wasParsed('host-vmservice-port')) {
|
||||
if (argResults?.wasParsed('observatory-port') == true &&
|
||||
argResults?.wasParsed('host-vmservice-port') == true) {
|
||||
throwToolExit('Only one of "--observatory-port" and '
|
||||
'"--host-vmservice-port" may be specified.');
|
||||
}
|
||||
// If DDS is enabled and no explicit DDS port is provided, use the
|
||||
// host-vmservice-port for DDS instead and bind the VM service to a random
|
||||
// port.
|
||||
if (enableDds && !argResults.wasParsed('dds-port')) {
|
||||
if (enableDds && argResults?.wasParsed('dds-port') != true) {
|
||||
return null;
|
||||
}
|
||||
return _tryParseHostVmservicePort();
|
||||
@ -491,12 +492,13 @@ abstract class FlutterCommand extends Command<void> {
|
||||
/// Gets the vmservice port provided to in the 'device-vmservice-port' option.
|
||||
///
|
||||
/// If no port is set, returns null.
|
||||
int get deviceVmservicePort {
|
||||
if (!_usesPortOption || argResults['device-vmservice-port'] == null) {
|
||||
int? get deviceVmservicePort {
|
||||
final String? devicePort = stringArg('device-vmservice-port');
|
||||
if (!_usesPortOption || devicePort == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return int.parse(stringArg('device-vmservice-port'));
|
||||
return int.parse(devicePort);
|
||||
} on FormatException catch (error) {
|
||||
throwToolExit('Invalid port for `--device-vmservice-port`: $error');
|
||||
}
|
||||
@ -504,7 +506,6 @@ abstract class FlutterCommand extends Command<void> {
|
||||
|
||||
void addPublishPort({ bool enabledByDefault = true, bool verboseHelp = false }) {
|
||||
argParser.addFlag('publish-port',
|
||||
negatable: true,
|
||||
hide: !verboseHelp,
|
||||
help: 'Publish the VM service port over mDNS. Disable to prevent the '
|
||||
'local network permission app dialog in debug and profile build modes (iOS devices only).',
|
||||
@ -514,7 +515,7 @@ abstract class FlutterCommand extends Command<void> {
|
||||
|
||||
bool get disablePortPublication => !boolArg('publish-port');
|
||||
|
||||
void usesIpv6Flag({@required bool verboseHelp}) {
|
||||
void usesIpv6Flag({required bool verboseHelp}) {
|
||||
argParser.addFlag(ipv6Flag,
|
||||
negatable: false,
|
||||
help: 'Binds to IPv6 localhost instead of IPv4 when the flutter tool '
|
||||
@ -525,7 +526,7 @@ abstract class FlutterCommand extends Command<void> {
|
||||
_usesIpv6Flag = true;
|
||||
}
|
||||
|
||||
bool get ipv6 => _usesIpv6Flag ? boolArg('ipv6') : null;
|
||||
bool? get ipv6 => _usesIpv6Flag ? boolArg('ipv6') : null;
|
||||
|
||||
void usesBuildNumberOption() {
|
||||
argParser.addOption('build-number',
|
||||
@ -592,22 +593,20 @@ abstract class FlutterCommand extends Command<void> {
|
||||
/// Whether this command should report null safety analytics.
|
||||
bool get reportNullSafety => false;
|
||||
|
||||
Duration get deviceDiscoveryTimeout {
|
||||
if (_deviceDiscoveryTimeout == null
|
||||
&& argResults.options.contains(FlutterOptions.kDeviceTimeout)
|
||||
&& argResults.wasParsed(FlutterOptions.kDeviceTimeout)) {
|
||||
final int timeoutSeconds = int.tryParse(stringArg(FlutterOptions.kDeviceTimeout));
|
||||
late final Duration? deviceDiscoveryTimeout = () {
|
||||
if (argResults?.options.contains(FlutterOptions.kDeviceTimeout) == true
|
||||
&& argResults?.wasParsed(FlutterOptions.kDeviceTimeout) == true) {
|
||||
final int? timeoutSeconds = int.tryParse(stringArg(FlutterOptions.kDeviceTimeout)!);
|
||||
if (timeoutSeconds == null) {
|
||||
throwToolExit( 'Could not parse "--${FlutterOptions.kDeviceTimeout}" argument. It must be an integer.');
|
||||
}
|
||||
_deviceDiscoveryTimeout = Duration(seconds: timeoutSeconds);
|
||||
return Duration(seconds: timeoutSeconds);
|
||||
}
|
||||
return _deviceDiscoveryTimeout;
|
||||
}
|
||||
Duration _deviceDiscoveryTimeout;
|
||||
return null;
|
||||
}();
|
||||
|
||||
void addBuildModeFlags({
|
||||
@required bool verboseHelp,
|
||||
required bool verboseHelp,
|
||||
bool defaultToRelease = true,
|
||||
bool excludeDebug = false,
|
||||
bool excludeRelease = false,
|
||||
@ -669,7 +668,7 @@ abstract class FlutterCommand extends Command<void> {
|
||||
);
|
||||
}
|
||||
|
||||
void addBundleSkSLPathOption({ @required bool hide }) {
|
||||
void addBundleSkSLPathOption({ required bool hide }) {
|
||||
argParser.addOption(FlutterOptions.kBundleSkSLPathOption,
|
||||
help: 'A path to a file containing precompiled SkSL shaders generated '
|
||||
'during "flutter run". These can be included in an application to '
|
||||
@ -680,26 +679,24 @@ abstract class FlutterCommand extends Command<void> {
|
||||
}
|
||||
|
||||
void addTreeShakeIconsFlag({
|
||||
bool enabledByDefault
|
||||
bool? enabledByDefault
|
||||
}) {
|
||||
argParser.addFlag('tree-shake-icons',
|
||||
negatable: true,
|
||||
defaultsTo: enabledByDefault
|
||||
?? kIconTreeShakerEnabledDefault,
|
||||
help: 'Tree shake icon fonts so that only glyphs used by the application remain.',
|
||||
);
|
||||
}
|
||||
|
||||
void addShrinkingFlag({ @required bool verboseHelp }) {
|
||||
void addShrinkingFlag({ required bool verboseHelp }) {
|
||||
argParser.addFlag('shrink',
|
||||
negatable: true,
|
||||
hide: !verboseHelp,
|
||||
help: 'This flag has no effect. Code shrinking is always enabled in release builds. '
|
||||
'To learn more, see: https://developer.android.com/studio/build/shrink-code'
|
||||
);
|
||||
}
|
||||
|
||||
void addNullSafetyModeOptions({ @required bool hide }) {
|
||||
void addNullSafetyModeOptions({ required bool hide }) {
|
||||
argParser.addFlag(FlutterOptions.kNullSafety,
|
||||
help:
|
||||
'Whether to override the inferred null safety mode. This allows null-safe '
|
||||
@ -720,13 +717,12 @@ abstract class FlutterCommand extends Command<void> {
|
||||
|
||||
/// Enables support for the hidden options --extra-front-end-options and
|
||||
/// --extra-gen-snapshot-options.
|
||||
void usesExtraDartFlagOptions({ @required bool verboseHelp }) {
|
||||
void usesExtraDartFlagOptions({ required bool verboseHelp }) {
|
||||
argParser.addMultiOption(FlutterOptions.kExtraFrontEndOptions,
|
||||
aliases: <String>[ kExtraFrontEndOptions ], // supported for historical reasons
|
||||
help: 'A comma-separated list of additional command line arguments that will be passed directly to the Dart front end. '
|
||||
'For example, "--${FlutterOptions.kExtraFrontEndOptions}=--enable-experiment=nonfunction-type-aliases".',
|
||||
valueHelp: '--foo,--bar',
|
||||
splitCommas: true,
|
||||
hide: !verboseHelp,
|
||||
);
|
||||
argParser.addMultiOption(FlutterOptions.kExtraGenSnapshotOptions,
|
||||
@ -735,7 +731,6 @@ abstract class FlutterCommand extends Command<void> {
|
||||
'(Only used in "--profile" or "--release" builds.) '
|
||||
'For example, "--${FlutterOptions.kExtraGenSnapshotOptions}=--no-strip".',
|
||||
valueHelp: '--foo,--bar',
|
||||
splitCommas: true,
|
||||
hide: !verboseHelp,
|
||||
);
|
||||
}
|
||||
@ -757,7 +752,7 @@ abstract class FlutterCommand extends Command<void> {
|
||||
);
|
||||
}
|
||||
|
||||
void addEnableExperimentation({ @required bool hide }) {
|
||||
void addEnableExperimentation({ required bool hide }) {
|
||||
argParser.addMultiOption(
|
||||
FlutterOptions.kEnableExperiment,
|
||||
help:
|
||||
@ -810,7 +805,7 @@ abstract class FlutterCommand extends Command<void> {
|
||||
);
|
||||
}
|
||||
|
||||
void usesInitializeFromDillOption({ @required bool hide }) {
|
||||
void usesInitializeFromDillOption({ required bool hide }) {
|
||||
argParser.addOption(FlutterOptions.kInitializeFromDill,
|
||||
help: 'Initializes the resident compiler with a specific kernel file instead of '
|
||||
'the default cached location.',
|
||||
@ -820,7 +815,6 @@ abstract class FlutterCommand extends Command<void> {
|
||||
|
||||
void addMultidexOption({ bool hide = false }) {
|
||||
argParser.addFlag('multidex',
|
||||
negatable: true,
|
||||
defaultsTo: true,
|
||||
help: 'When enabled, indicates that the app should be built with multidex support. This '
|
||||
'flag adds the dependencies for multidex when the minimum android sdk is 20 or '
|
||||
@ -829,7 +823,7 @@ abstract class FlutterCommand extends Command<void> {
|
||||
}
|
||||
|
||||
/// Adds build options common to all of the desktop build commands.
|
||||
void addCommonDesktopBuildOptions({ @required bool verboseHelp }) {
|
||||
void addCommonDesktopBuildOptions({ required bool verboseHelp }) {
|
||||
addBuildModeFlags(verboseHelp: verboseHelp);
|
||||
addBuildPerformanceFile(hide: !verboseHelp);
|
||||
addBundleSkSLPathOption(hide: !verboseHelp);
|
||||
@ -850,7 +844,7 @@ abstract class FlutterCommand extends Command<void> {
|
||||
/// explicitly specified.
|
||||
///
|
||||
/// Use [getBuildMode] to obtain the actual effective build mode.
|
||||
BuildMode defaultBuildMode;
|
||||
BuildMode defaultBuildMode = BuildMode.debug;
|
||||
|
||||
BuildMode getBuildMode() {
|
||||
// No debug when _excludeDebug is true.
|
||||
@ -866,7 +860,7 @@ abstract class FlutterCommand extends Command<void> {
|
||||
];
|
||||
if (modeFlags.where((bool flag) => flag).length > 1) {
|
||||
throw UsageException('Only one of "--debug", "--profile", "--jit-release", '
|
||||
'or "--release" can be specified.', null);
|
||||
'or "--release" can be specified.', '');
|
||||
}
|
||||
if (debugResult) {
|
||||
return BuildMode.debug;
|
||||
@ -892,7 +886,7 @@ abstract class FlutterCommand extends Command<void> {
|
||||
);
|
||||
}
|
||||
|
||||
void usesTrackWidgetCreation({ bool hasEffect = true, @required bool verboseHelp }) {
|
||||
void usesTrackWidgetCreation({ bool hasEffect = true, required bool verboseHelp }) {
|
||||
argParser.addFlag(
|
||||
'track-widget-creation',
|
||||
hide: !hasEffect && !verboseHelp,
|
||||
@ -905,7 +899,6 @@ abstract class FlutterCommand extends Command<void> {
|
||||
void usesAnalyzeSizeFlag() {
|
||||
argParser.addFlag(
|
||||
FlutterOptions.kAnalyzeSize,
|
||||
defaultsTo: false,
|
||||
help: 'Whether to produce additional profile information for artifact output size. '
|
||||
'This flag is only supported on "--release" builds. When building for Android, a single '
|
||||
'ABI must be specified at a time with the "--target-platform" flag. When building for iOS, '
|
||||
@ -928,11 +921,11 @@ abstract class FlutterCommand extends Command<void> {
|
||||
///
|
||||
/// Throws a [ToolExit] if the current set of options is not compatible with
|
||||
/// each other.
|
||||
Future<BuildInfo> getBuildInfo({ BuildMode forcedBuildMode, File forcedTargetFile }) async {
|
||||
Future<BuildInfo> getBuildInfo({ BuildMode? forcedBuildMode, File? forcedTargetFile }) async {
|
||||
final bool trackWidgetCreation = argParser.options.containsKey('track-widget-creation') &&
|
||||
boolArg('track-widget-creation');
|
||||
|
||||
final String buildNumber = argParser.options.containsKey('build-number')
|
||||
final String? buildNumber = argParser.options.containsKey('build-number')
|
||||
? stringArg('build-number')
|
||||
: null;
|
||||
|
||||
@ -962,7 +955,7 @@ abstract class FlutterCommand extends Command<void> {
|
||||
}
|
||||
}
|
||||
|
||||
String codeSizeDirectory;
|
||||
String? codeSizeDirectory;
|
||||
if (argParser.options.containsKey(FlutterOptions.kAnalyzeSize) && boolArg(FlutterOptions.kAnalyzeSize)) {
|
||||
Directory directory = globals.fsUtils.getUniqueDirectory(
|
||||
globals.fs.directory(getBuildDirectory()),
|
||||
@ -980,13 +973,13 @@ abstract class FlutterCommand extends Command<void> {
|
||||
// Explicitly check for `true` and `false` so that `null` results in not
|
||||
// passing a flag. Examine the entrypoint file to determine if it
|
||||
// is opted in or out.
|
||||
final bool wasNullSafetyFlagParsed = argResults.wasParsed(FlutterOptions.kNullSafety);
|
||||
final bool wasNullSafetyFlagParsed = argResults?.wasParsed(FlutterOptions.kNullSafety) == true;
|
||||
if (!wasNullSafetyFlagParsed && (argParser.options.containsKey('target') || forcedTargetFile != null)) {
|
||||
final File entrypointFile = forcedTargetFile ?? globals.fs.file(targetFile);
|
||||
final LanguageVersion languageVersion = determineLanguageVersion(
|
||||
entrypointFile,
|
||||
packageConfig.packageOf(entrypointFile.absolute.uri),
|
||||
Cache.flutterRoot,
|
||||
Cache.flutterRoot!,
|
||||
);
|
||||
// Extra frontend options are only provided if explicitly
|
||||
// requested.
|
||||
@ -1011,7 +1004,7 @@ abstract class FlutterCommand extends Command<void> {
|
||||
final bool dartObfuscation = argParser.options.containsKey(FlutterOptions.kDartObfuscationOption)
|
||||
&& boolArg(FlutterOptions.kDartObfuscationOption);
|
||||
|
||||
final String splitDebugInfoPath = argParser.options.containsKey(FlutterOptions.kSplitDebugInfoOption)
|
||||
final String? splitDebugInfoPath = argParser.options.containsKey(FlutterOptions.kSplitDebugInfoOption)
|
||||
? stringArg(FlutterOptions.kSplitDebugInfoOption)
|
||||
: null;
|
||||
|
||||
@ -1037,10 +1030,10 @@ abstract class FlutterCommand extends Command<void> {
|
||||
}
|
||||
|
||||
final bool treeShakeIcons = argParser.options.containsKey('tree-shake-icons')
|
||||
&& buildMode.isPrecompiled
|
||||
&& buildMode.isPrecompiled == true
|
||||
&& boolArg('tree-shake-icons');
|
||||
|
||||
final String bundleSkSLPath = argParser.options.containsKey(FlutterOptions.kBundleSkSLPathOption)
|
||||
final String? bundleSkSLPath = argParser.options.containsKey(FlutterOptions.kBundleSkSLPathOption)
|
||||
? stringArg(FlutterOptions.kBundleSkSLPathOption)
|
||||
: null;
|
||||
|
||||
@ -1048,7 +1041,7 @@ abstract class FlutterCommand extends Command<void> {
|
||||
throwToolExit('No SkSL shader bundle found at $bundleSkSLPath.');
|
||||
}
|
||||
|
||||
final String performanceMeasurementFile = argParser.options.containsKey(FlutterOptions.kPerformanceMeasurementFile)
|
||||
final String? performanceMeasurementFile = argParser.options.containsKey(FlutterOptions.kPerformanceMeasurementFile)
|
||||
? stringArg(FlutterOptions.kPerformanceMeasurementFile)
|
||||
: null;
|
||||
|
||||
@ -1057,7 +1050,7 @@ abstract class FlutterCommand extends Command<void> {
|
||||
: <String>[];
|
||||
|
||||
if (argParser.options.containsKey('web-renderer')) {
|
||||
dartDefines = updateDartDefines(dartDefines, stringArg('web-renderer'));
|
||||
dartDefines = updateDartDefines(dartDefines, stringArg('web-renderer')!);
|
||||
}
|
||||
|
||||
return BuildInfo(buildMode,
|
||||
@ -1065,10 +1058,10 @@ abstract class FlutterCommand extends Command<void> {
|
||||
? stringArg('flavor')
|
||||
: null,
|
||||
trackWidgetCreation: trackWidgetCreation,
|
||||
extraFrontEndOptions: extraFrontEndOptions?.isNotEmpty ?? false
|
||||
extraFrontEndOptions: extraFrontEndOptions.isNotEmpty
|
||||
? extraFrontEndOptions
|
||||
: null,
|
||||
extraGenSnapshotOptions: extraGenSnapshotOptions?.isNotEmpty ?? false
|
||||
extraGenSnapshotOptions: extraGenSnapshotOptions.isNotEmpty
|
||||
? extraGenSnapshotOptions
|
||||
: null,
|
||||
fileSystemRoots: fileSystemRoots,
|
||||
@ -1102,10 +1095,10 @@ abstract class FlutterCommand extends Command<void> {
|
||||
|
||||
/// The path to send to Google Analytics. Return null here to disable
|
||||
/// tracking of the command.
|
||||
Future<String> get usagePath async {
|
||||
Future<String?> get usagePath async {
|
||||
if (parent is FlutterCommand) {
|
||||
final FlutterCommand commandParent = parent as FlutterCommand;
|
||||
final String path = await commandParent.usagePath;
|
||||
final FlutterCommand? commandParent = parent as FlutterCommand?;
|
||||
final String? path = await commandParent?.usagePath;
|
||||
// Don't report for parents that return null for usagePath.
|
||||
return path == null ? null : '$path/$name';
|
||||
} else {
|
||||
@ -1133,15 +1126,19 @@ abstract class FlutterCommand extends Command<void> {
|
||||
// Prints the welcome message if needed.
|
||||
globals.flutterUsage.printWelcome();
|
||||
_printDeprecationWarning();
|
||||
final String commandPath = await usagePath;
|
||||
_registerSignalHandlers(commandPath, startTime);
|
||||
final String? commandPath = await usagePath;
|
||||
if (commandPath != null) {
|
||||
_registerSignalHandlers(commandPath, startTime);
|
||||
}
|
||||
FlutterCommandResult commandResult = FlutterCommandResult.fail();
|
||||
try {
|
||||
commandResult = await verifyThenRunCommand(commandPath);
|
||||
} finally {
|
||||
final DateTime endTime = globals.systemClock.now();
|
||||
globals.printTrace(userMessages.flutterElapsedTime(name, getElapsedAsMilliseconds(endTime.difference(startTime))));
|
||||
_sendPostUsage(commandPath, commandResult, startTime, endTime);
|
||||
if (commandPath != null) {
|
||||
_sendPostUsage(commandPath, commandResult, startTime, endTime);
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
@ -1167,7 +1164,10 @@ abstract class FlutterCommand extends Command<void> {
|
||||
&& dartDefines.any((String d) => d.startsWith('FLUTTER_WEB_USE_SKIA='))) {
|
||||
dartDefinesSet.removeWhere((String d) => d.startsWith('FLUTTER_WEB_USE_SKIA='));
|
||||
}
|
||||
dartDefinesSet.addAll(_webRendererDartDefines[webRenderer]);
|
||||
final Iterable<String>? webRendererDefine = _webRendererDartDefines[webRenderer];
|
||||
if (webRendererDefine != null) {
|
||||
dartDefinesSet.addAll(webRendererDefine);
|
||||
}
|
||||
return dartDefinesSet.toList();
|
||||
}
|
||||
|
||||
@ -1207,7 +1207,7 @@ abstract class FlutterCommand extends Command<void> {
|
||||
if (commandResult.exitStatus != null)
|
||||
getEnumName(commandResult.exitStatus),
|
||||
if (commandResult.timingLabelParts?.isNotEmpty ?? false)
|
||||
...commandResult.timingLabelParts,
|
||||
...?commandResult.timingLabelParts,
|
||||
];
|
||||
|
||||
final String label = labels
|
||||
@ -1233,7 +1233,7 @@ abstract class FlutterCommand extends Command<void> {
|
||||
/// then call this method to execute the command
|
||||
/// rather than calling [runCommand] directly.
|
||||
@mustCallSuper
|
||||
Future<FlutterCommandResult> verifyThenRunCommand(String commandPath) async {
|
||||
Future<FlutterCommandResult> verifyThenRunCommand(String? commandPath) async {
|
||||
// Populate the cache. We call this before pub get below so that the
|
||||
// sky_engine package is available in the flutter cache for pub to find.
|
||||
if (shouldUpdateCache) {
|
||||
@ -1249,7 +1249,7 @@ abstract class FlutterCommand extends Command<void> {
|
||||
if (shouldRunPub) {
|
||||
final FlutterProject project = FlutterProject.current();
|
||||
final Environment environment = Environment(
|
||||
artifacts: globals.artifacts,
|
||||
artifacts: globals.artifacts!,
|
||||
logger: globals.logger,
|
||||
cacheDir: globals.cache.getRoot(),
|
||||
engineVersion: globals.flutterVersion.engineRevision,
|
||||
@ -1264,7 +1264,7 @@ abstract class FlutterCommand extends Command<void> {
|
||||
|
||||
await generateLocalizationsSyntheticPackage(
|
||||
environment: environment,
|
||||
buildSystem: globals.buildSystem,
|
||||
buildSystem: globals.buildSystem!,
|
||||
);
|
||||
|
||||
await pub.get(
|
||||
@ -1314,21 +1314,21 @@ abstract class FlutterCommand extends Command<void> {
|
||||
/// devices and criteria entered by the user on the command line.
|
||||
/// If no device can be found that meets specified criteria,
|
||||
/// then print an error message and return null.
|
||||
Future<List<Device>> findAllTargetDevices({
|
||||
Future<List<Device>?> findAllTargetDevices({
|
||||
bool includeUnsupportedDevices = false,
|
||||
}) async {
|
||||
if (!globals.doctor.canLaunchAnything) {
|
||||
if (!globals.doctor!.canLaunchAnything) {
|
||||
globals.printError(userMessages.flutterNoDevelopmentDevice);
|
||||
return null;
|
||||
}
|
||||
final DeviceManager deviceManager = globals.deviceManager;
|
||||
final DeviceManager deviceManager = globals.deviceManager!;
|
||||
List<Device> devices = await deviceManager.findTargetDevices(
|
||||
includeUnsupportedDevices ? null : FlutterProject.current(),
|
||||
timeout: deviceDiscoveryTimeout,
|
||||
);
|
||||
|
||||
if (devices.isEmpty && deviceManager.hasSpecifiedDeviceId) {
|
||||
globals.printStatus(userMessages.flutterNoMatchingDevice(deviceManager.specifiedDeviceId));
|
||||
globals.printStatus(userMessages.flutterNoMatchingDevice(deviceManager.specifiedDeviceId!));
|
||||
return null;
|
||||
} else if (devices.isEmpty) {
|
||||
if (deviceManager.hasSpecifiedAllDevices) {
|
||||
@ -1346,7 +1346,7 @@ abstract class FlutterCommand extends Command<void> {
|
||||
.toList(),
|
||||
'\n',
|
||||
);
|
||||
result.writeln('');
|
||||
result.writeln();
|
||||
result.writeln(userMessages.flutterMissPlatformProjects(
|
||||
Device.devicesPlatformTypes(unsupportedDevices),
|
||||
));
|
||||
@ -1355,7 +1355,7 @@ abstract class FlutterCommand extends Command<void> {
|
||||
return null;
|
||||
} else if (devices.length > 1 && !deviceManager.hasSpecifiedAllDevices) {
|
||||
if (deviceManager.hasSpecifiedDeviceId) {
|
||||
globals.printStatus(userMessages.flutterFoundSpecifiedDevices(devices.length, deviceManager.specifiedDeviceId));
|
||||
globals.printStatus(userMessages.flutterFoundSpecifiedDevices(devices.length, deviceManager.specifiedDeviceId!));
|
||||
} else {
|
||||
globals.printStatus(userMessages.flutterSpecifyDeviceWithAllOption);
|
||||
devices = await deviceManager.getAllConnectedDevices();
|
||||
@ -1374,16 +1374,16 @@ abstract class FlutterCommand extends Command<void> {
|
||||
///
|
||||
/// If [includeUnsupportedDevices] is true, the tool does not filter
|
||||
/// the list by the current project support list.
|
||||
Future<Device> findTargetDevice({
|
||||
Future<Device?> findTargetDevice({
|
||||
bool includeUnsupportedDevices = false,
|
||||
}) async {
|
||||
List<Device> deviceList = await findAllTargetDevices(includeUnsupportedDevices: includeUnsupportedDevices);
|
||||
List<Device>? deviceList = await findAllTargetDevices(includeUnsupportedDevices: includeUnsupportedDevices);
|
||||
if (deviceList == null) {
|
||||
return null;
|
||||
}
|
||||
if (deviceList.length > 1) {
|
||||
globals.printStatus(userMessages.flutterSpecifyDevice);
|
||||
deviceList = await globals.deviceManager.getAllConnectedDevices();
|
||||
deviceList = await globals.deviceManager!.getAllConnectedDevices();
|
||||
globals.printStatus('');
|
||||
await Device.printDevices(deviceList, globals.logger);
|
||||
return null;
|
||||
@ -1394,7 +1394,7 @@ abstract class FlutterCommand extends Command<void> {
|
||||
@protected
|
||||
@mustCallSuper
|
||||
Future<void> validateCommand() async {
|
||||
if (_requiresPubspecYaml && !globalResults.wasParsed('packages')) {
|
||||
if (_requiresPubspecYaml && globalResults?.wasParsed('packages') != true) {
|
||||
// Don't expect a pubspec.yaml file if the user passed in an explicit .packages file path.
|
||||
|
||||
// If there is no pubspec in the current directory, look in the parent
|
||||
@ -1433,23 +1433,23 @@ abstract class FlutterCommand extends Command<void> {
|
||||
description,
|
||||
'',
|
||||
'Global options:',
|
||||
runner.argParser.usage,
|
||||
'${runner?.argParser.usage}',
|
||||
'',
|
||||
usageWithoutDescription,
|
||||
].join('\n');
|
||||
return help;
|
||||
}
|
||||
|
||||
ApplicationPackageFactory applicationPackages;
|
||||
ApplicationPackageFactory? applicationPackages;
|
||||
|
||||
/// Gets the parsed command-line option named [name] as `bool`.
|
||||
bool boolArg(String name) => argResults[name] as bool;
|
||||
bool boolArg(String name) => argResults?[name] as bool? ?? false;
|
||||
|
||||
/// Gets the parsed command-line option named [name] as `String`.
|
||||
String stringArg(String name) => argResults[name] as String;
|
||||
String? stringArg(String name) => argResults?[name] as String?;
|
||||
|
||||
/// Gets the parsed command-line option named [name] as `List<String>`.
|
||||
List<String> stringsArg(String name) => argResults[name] as List<String>;
|
||||
List<String> stringsArg(String name) => argResults?[name] as List<String>? ?? <String>[];
|
||||
}
|
||||
|
||||
/// A mixin which applies an implementation of [requiredArtifacts] that only
|
||||
@ -1460,7 +1460,7 @@ mixin DeviceBasedDevelopmentArtifacts on FlutterCommand {
|
||||
// If there are no attached devices, use the default configuration.
|
||||
// Otherwise, only add development artifacts which correspond to a
|
||||
// connected device.
|
||||
final List<Device> devices = await globals.deviceManager.getDevices();
|
||||
final List<Device> devices = await globals.deviceManager!.getDevices();
|
||||
if (devices.isEmpty) {
|
||||
return super.requiredArtifacts;
|
||||
}
|
||||
@ -1469,7 +1469,7 @@ mixin DeviceBasedDevelopmentArtifacts on FlutterCommand {
|
||||
};
|
||||
for (final Device device in devices) {
|
||||
final TargetPlatform targetPlatform = await device.targetPlatform;
|
||||
final DevelopmentArtifact developmentArtifact = artifactFromTargetPlatform(targetPlatform);
|
||||
final DevelopmentArtifact? developmentArtifact = artifactFromTargetPlatform(targetPlatform);
|
||||
if (developmentArtifact != null) {
|
||||
artifacts.add(developmentArtifact);
|
||||
}
|
||||
@ -1481,7 +1481,7 @@ mixin DeviceBasedDevelopmentArtifacts on FlutterCommand {
|
||||
// Returns the development artifact for the target platform, or null
|
||||
// if none is supported
|
||||
@protected
|
||||
DevelopmentArtifact artifactFromTargetPlatform(TargetPlatform targetPlatform) {
|
||||
DevelopmentArtifact? artifactFromTargetPlatform(TargetPlatform targetPlatform) {
|
||||
switch (targetPlatform) {
|
||||
case TargetPlatform.android:
|
||||
case TargetPlatform.android_arm:
|
||||
@ -1518,7 +1518,6 @@ DevelopmentArtifact artifactFromTargetPlatform(TargetPlatform targetPlatform) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Returns true if s is either null, empty or is solely made of whitespace characters (as defined by String.trim).
|
||||
|
@ -2,8 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'package:args/args.dart';
|
||||
import 'package:args/command_runner.dart';
|
||||
import 'package:completion/completion.dart';
|
||||
@ -45,14 +43,12 @@ class FlutterCommandRunner extends CommandRunner<void> {
|
||||
argParser.addFlag('prefixed-errors',
|
||||
negatable: false,
|
||||
help: 'Causes lines sent to stderr to be prefixed with "ERROR:".',
|
||||
hide: !verboseHelp,
|
||||
defaultsTo: false);
|
||||
hide: !verboseHelp);
|
||||
argParser.addFlag('quiet',
|
||||
negatable: false,
|
||||
hide: !verboseHelp,
|
||||
help: 'Reduce the amount of output from some commands.');
|
||||
argParser.addFlag('wrap',
|
||||
negatable: true,
|
||||
hide: !verboseHelp,
|
||||
help: 'Toggles output word wrapping, regardless of whether or not the output is a terminal.',
|
||||
defaultsTo: true);
|
||||
@ -60,8 +56,7 @@ class FlutterCommandRunner extends CommandRunner<void> {
|
||||
hide: !verboseHelp,
|
||||
help: 'Sets the output wrap column. If not set, uses the width of the terminal. No '
|
||||
'wrapping occurs if not writing to a terminal. Use "--no-wrap" to turn off wrapping '
|
||||
'when connected to a terminal.',
|
||||
defaultsTo: null);
|
||||
'when connected to a terminal.');
|
||||
argParser.addOption('device-id',
|
||||
abbr: 'd',
|
||||
help: 'Target device id or name (prefixes allowed).');
|
||||
@ -73,12 +68,10 @@ class FlutterCommandRunner extends CommandRunner<void> {
|
||||
hide: !verboseHelp,
|
||||
help: 'When used with the "--version" flag, outputs the information using JSON.');
|
||||
argParser.addFlag('color',
|
||||
negatable: true,
|
||||
hide: !verboseHelp,
|
||||
help: 'Whether to use terminal colors (requires support for ANSI escape sequences).',
|
||||
defaultsTo: true);
|
||||
argParser.addFlag('version-check',
|
||||
negatable: true,
|
||||
defaultsTo: true,
|
||||
hide: !verboseHelp,
|
||||
help: 'Allow Flutter to check for updates when this command runs.');
|
||||
@ -158,12 +151,12 @@ class FlutterCommandRunner extends CommandRunner<void> {
|
||||
usageException(error.message);
|
||||
}
|
||||
|
||||
Command<void> command = commands[error.commands.first];
|
||||
Command<void>? command = commands[error.commands.first];
|
||||
for (final String commandName in error.commands.skip(1)) {
|
||||
command = command.subcommands[commandName];
|
||||
command = command?.subcommands[commandName];
|
||||
}
|
||||
|
||||
command.usageException(error.message);
|
||||
command!.usageException(error.message);
|
||||
}
|
||||
}
|
||||
|
||||
@ -184,12 +177,12 @@ class FlutterCommandRunner extends CommandRunner<void> {
|
||||
|
||||
@override
|
||||
Future<void> runCommand(ArgResults topLevelResults) async {
|
||||
final Map<Type, dynamic> contextOverrides = <Type, dynamic>{};
|
||||
final Map<Type, Object?> contextOverrides = <Type, Object?>{};
|
||||
|
||||
// Don't set wrapColumns unless the user said to: if it's set, then all
|
||||
// wrapping will occur at this width explicitly, and won't adapt if the
|
||||
// terminal size changes during a run.
|
||||
int wrapColumn;
|
||||
int? wrapColumn;
|
||||
if (topLevelResults.wasParsed('wrap-column')) {
|
||||
try {
|
||||
wrapColumn = int.parse(topLevelResults['wrap-column'] as String);
|
||||
@ -208,53 +201,53 @@ class FlutterCommandRunner extends CommandRunner<void> {
|
||||
: globals.stdio.terminalColumns != null && topLevelResults['wrap'] as bool;
|
||||
contextOverrides[OutputPreferences] = OutputPreferences(
|
||||
wrapText: useWrapping,
|
||||
showColor: topLevelResults['color'] as bool,
|
||||
showColor: topLevelResults['color'] as bool?,
|
||||
wrapColumn: wrapColumn,
|
||||
);
|
||||
|
||||
if (topLevelResults['show-test-device'] as bool ||
|
||||
if ((topLevelResults['show-test-device'] as bool?) == true ||
|
||||
topLevelResults['device-id'] == FlutterTesterDevices.kTesterDeviceId) {
|
||||
FlutterTesterDevices.showFlutterTesterDevice = true;
|
||||
}
|
||||
if (topLevelResults['show-web-server-device'] as bool ||
|
||||
if ((topLevelResults['show-web-server-device'] as bool?) == true ||
|
||||
topLevelResults['device-id'] == WebServerDevice.kWebServerDeviceId) {
|
||||
WebServerDevice.showWebServerDevice = true;
|
||||
}
|
||||
|
||||
// Set up the tooling configuration.
|
||||
final EngineBuildPaths engineBuildPaths = await globals.localEngineLocator.findEnginePath(
|
||||
topLevelResults['local-engine-src-path'] as String,
|
||||
topLevelResults['local-engine'] as String,
|
||||
topLevelResults['packages'] as String,
|
||||
final EngineBuildPaths? engineBuildPaths = await globals.localEngineLocator?.findEnginePath(
|
||||
topLevelResults['local-engine-src-path'] as String?,
|
||||
topLevelResults['local-engine'] as String?,
|
||||
topLevelResults['packages'] as String?,
|
||||
);
|
||||
if (engineBuildPaths != null) {
|
||||
contextOverrides.addAll(<Type, dynamic>{
|
||||
contextOverrides.addAll(<Type, Object?>{
|
||||
Artifacts: Artifacts.getLocalEngine(engineBuildPaths),
|
||||
});
|
||||
}
|
||||
|
||||
await context.run<void>(
|
||||
overrides: contextOverrides.map<Type, Generator>((Type type, dynamic value) {
|
||||
overrides: contextOverrides.map<Type, Generator>((Type type, Object? value) {
|
||||
return MapEntry<Type, Generator>(type, () => value);
|
||||
}),
|
||||
body: () async {
|
||||
globals.logger.quiet = topLevelResults['quiet'] as bool;
|
||||
globals.logger.quiet = (topLevelResults['quiet'] as bool?) == true;
|
||||
|
||||
if (globals.platform.environment['FLUTTER_ALREADY_LOCKED'] != 'true') {
|
||||
await globals.cache.lock();
|
||||
}
|
||||
|
||||
if (topLevelResults['suppress-analytics'] as bool) {
|
||||
if ((topLevelResults['suppress-analytics'] as bool?) == true) {
|
||||
globals.flutterUsage.suppressAnalytics = true;
|
||||
}
|
||||
|
||||
globals.flutterVersion.ensureVersionFile();
|
||||
final bool machineFlag = topLevelResults['machine'] as bool;
|
||||
final bool machineFlag = topLevelResults['machine'] as bool? ?? false;
|
||||
final bool ci = await globals.botDetector.isRunningOnBot;
|
||||
final bool redirectedCompletion = !globals.stdio.hasTerminal &&
|
||||
(topLevelResults.command?.name ?? '').endsWith('-completion');
|
||||
final bool isMachine = machineFlag || ci || redirectedCompletion;
|
||||
final bool versionCheckFlag = topLevelResults['version-check'] as bool;
|
||||
final bool versionCheckFlag = topLevelResults['version-check'] as bool? ?? false;
|
||||
final bool explicitVersionCheckPassed = topLevelResults.wasParsed('version-check') && versionCheckFlag;
|
||||
|
||||
if (topLevelResults.command?.name != 'upgrade' &&
|
||||
@ -263,16 +256,16 @@ class FlutterCommandRunner extends CommandRunner<void> {
|
||||
}
|
||||
|
||||
// See if the user specified a specific device.
|
||||
globals.deviceManager.specifiedDeviceId = topLevelResults['device-id'] as String;
|
||||
globals.deviceManager?.specifiedDeviceId = topLevelResults['device-id'] as String?;
|
||||
|
||||
if (topLevelResults['version'] as bool) {
|
||||
if ((topLevelResults['version'] as bool?) == true) {
|
||||
globals.flutterUsage.sendCommand('version');
|
||||
globals.flutterVersion.fetchTagsAndUpdate();
|
||||
String status;
|
||||
if (machineFlag) {
|
||||
final Map<String, Object> jsonOut = globals.flutterVersion.toJson();
|
||||
if (jsonOut != null) {
|
||||
jsonOut['flutterRoot'] = Cache.flutterRoot;
|
||||
jsonOut['flutterRoot'] = Cache.flutterRoot!;
|
||||
}
|
||||
status = const JsonEncoder.withIndent(' ').convert(jsonOut);
|
||||
} else {
|
||||
@ -292,7 +285,7 @@ class FlutterCommandRunner extends CommandRunner<void> {
|
||||
|
||||
/// Get the root directories of the repo - the directories containing Dart packages.
|
||||
List<String> getRepoRoots() {
|
||||
final String root = globals.fs.path.absolute(Cache.flutterRoot);
|
||||
final String root = globals.fs.path.absolute(Cache.flutterRoot!);
|
||||
// not bin, and not the root
|
||||
return <String>['dev', 'examples', 'packages'].map<String>((String item) {
|
||||
return globals.fs.path.join(root, item);
|
||||
|
Loading…
x
Reference in New Issue
Block a user