Unverified Commit ce318b7b authored by Ian Hickson's avatar Ian Hickson Committed by GitHub

All arguments must be documented. (#75888)

parent 696e4f70
...@@ -80,7 +80,7 @@ add_custom_command( ...@@ -80,7 +80,7 @@ add_custom_command(
COMMAND ${CMAKE_COMMAND} -E env COMMAND ${CMAKE_COMMAND} -E env
${FLUTTER_TOOL_ENVIRONMENT} ${FLUTTER_TOOL_ENVIRONMENT}
"${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh" "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh"
linux-x64 ${CMAKE_BUILD_TYPE} ${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE}
VERBATIM VERBATIM
) )
add_custom_target(flutter_assemble DEPENDS add_custom_target(flutter_assemble DEPENDS
......
...@@ -89,7 +89,52 @@ Future<void> main(List<String> args) async { ...@@ -89,7 +89,52 @@ Future<void> main(List<String> args) async {
userMessages: UserMessages(), userMessages: UserMessages(),
); );
await runner.run(args, () => <FlutterCommand>[ await runner.run(
args,
() => generateCommands(
verboseHelp: verboseHelp,
verbose: verbose,
),
verbose: verbose,
muteCommandLogging: muteCommandLogging,
verboseHelp: verboseHelp,
overrides: <Type, Generator>{
// The web runner is not supported in google3 because it depends
// on dwds.
WebRunnerFactory: () => DwdsWebRunnerFactory(),
// The mustache dependency is different in google3
TemplateRenderer: () => const MustacheTemplateRenderer(),
// The devtools launcher is not supported in google3 because it depends on
// devtools source code.
DevtoolsLauncher: () => DevtoolsServerLauncher(
processManager: globals.processManager,
pubExecutable: globals.artifacts.getArtifactPath(Artifact.pubExecutable),
logger: globals.logger,
platform: globals.platform,
persistentToolState: globals.persistentToolState,
),
Logger: () {
final LoggerFactory loggerFactory = LoggerFactory(
outputPreferences: globals.outputPreferences,
terminal: globals.terminal,
stdio: globals.stdio,
);
return loggerFactory.createLogger(
daemon: daemon,
machine: runMachine,
verbose: verbose && !muteCommandLogging,
prefixedErrors: prefixedErrors,
windows: globals.platform.isWindows,
);
},
},
);
}
List<FlutterCommand> generateCommands({
@required bool verboseHelp,
@required bool verbose,
}) => <FlutterCommand>[
AnalyzeCommand( AnalyzeCommand(
verboseHelp: verboseHelp, verboseHelp: verboseHelp,
fileSystem: globals.fs, fileSystem: globals.fs,
...@@ -99,17 +144,17 @@ Future<void> main(List<String> args) async { ...@@ -99,17 +144,17 @@ Future<void> main(List<String> args) async {
terminal: globals.terminal, terminal: globals.terminal,
artifacts: globals.artifacts, artifacts: globals.artifacts,
), ),
AssembleCommand(), AssembleCommand(verboseHelp: verboseHelp),
AttachCommand(verboseHelp: verboseHelp), AttachCommand(verboseHelp: verboseHelp),
BuildCommand(verboseHelp: verboseHelp), BuildCommand(verboseHelp: verboseHelp),
ChannelCommand(verboseHelp: verboseHelp), ChannelCommand(verboseHelp: verboseHelp),
CleanCommand(verbose: verbose), CleanCommand(verbose: verbose),
ConfigCommand(verboseHelp: verboseHelp), ConfigCommand(verboseHelp: verboseHelp),
CreateCommand(), CreateCommand(verboseHelp: verboseHelp),
DaemonCommand(hidden: !verboseHelp), DaemonCommand(hidden: !verboseHelp),
DevicesCommand(), DevicesCommand(verboseHelp: verboseHelp),
DoctorCommand(verbose: verbose), DoctorCommand(verbose: verbose),
DowngradeCommand(), DowngradeCommand(verboseHelp: verboseHelp),
DriveCommand(verboseHelp: verboseHelp, DriveCommand(verboseHelp: verboseHelp,
fileSystem: globals.fs, fileSystem: globals.fs,
logger: globals.logger, logger: globals.logger,
...@@ -136,7 +181,7 @@ Future<void> main(List<String> args) async { ...@@ -136,7 +181,7 @@ Future<void> main(List<String> args) async {
ScreenshotCommand(), ScreenshotCommand(),
ShellCompletionCommand(), ShellCompletionCommand(),
TestCommand(verboseHelp: verboseHelp), TestCommand(verboseHelp: verboseHelp),
UpgradeCommand(), UpgradeCommand(verboseHelp: verboseHelp),
SymbolizeCommand( SymbolizeCommand(
stdio: globals.stdio, stdio: globals.stdio,
fileSystem: globals.fs, fileSystem: globals.fs,
...@@ -144,40 +189,7 @@ Future<void> main(List<String> args) async { ...@@ -144,40 +189,7 @@ Future<void> main(List<String> args) async {
// Development-only commands. These are always hidden, // Development-only commands. These are always hidden,
IdeConfigCommand(), IdeConfigCommand(),
UpdatePackagesCommand(), UpdatePackagesCommand(),
], verbose: verbose, ];
muteCommandLogging: muteCommandLogging,
verboseHelp: verboseHelp,
overrides: <Type, Generator>{
// The web runner is not supported in google3 because it depends
// on dwds.
WebRunnerFactory: () => DwdsWebRunnerFactory(),
// The mustache dependency is different in google3
TemplateRenderer: () => const MustacheTemplateRenderer(),
// The devtools launcher is not supported in google3 because it depends on
// devtools source code.
DevtoolsLauncher: () => DevtoolsServerLauncher(
processManager: globals.processManager,
pubExecutable: globals.artifacts.getArtifactPath(Artifact.pubExecutable),
logger: globals.logger,
platform: globals.platform,
persistentToolState: globals.persistentToolState,
),
Logger: () {
final LoggerFactory loggerFactory = LoggerFactory(
outputPreferences: globals.outputPreferences,
terminal: globals.terminal,
stdio: globals.stdio,
);
return loggerFactory.createLogger(
daemon: daemon,
machine: runMachine,
verbose: verbose && !muteCommandLogging,
prefixedErrors: prefixedErrors,
windows: globals.platform.isWindows,
);
}
});
}
/// An abstraction for instantiation of the correct logger type. /// An abstraction for instantiation of the correct logger type.
/// ///
......
...@@ -25,9 +25,6 @@ import 'src/runner/flutter_command.dart'; ...@@ -25,9 +25,6 @@ import 'src/runner/flutter_command.dart';
import 'src/runner/flutter_command_runner.dart'; import 'src/runner/flutter_command_runner.dart';
/// Runs the Flutter tool with support for the specified list of [commands]. /// Runs the Flutter tool with support for the specified list of [commands].
///
/// [commands] must be either `List<FlutterCommand>` or `List<FlutterCommand> Function()`.
// TODO(jonahwilliams): update command type once g3 has rolled.
Future<int> run( Future<int> run(
List<String> args, List<String> args,
List<FlutterCommand> Function() commands, { List<FlutterCommand> Function() commands, {
......
...@@ -42,14 +42,14 @@ class AnalyzeCommand extends FlutterCommand { ...@@ -42,14 +42,14 @@ class AnalyzeCommand extends FlutterCommand {
argParser.addFlag('dartdocs', argParser.addFlag('dartdocs',
negatable: false, negatable: false,
help: 'List every public member that is lacking documentation. ' help: 'List every public member that is lacking documentation. '
'(The public_member_api_docs lint must be enabled in analysis_options.yaml)', '(The "public_member_api_docs" lint must be enabled in "analysis_options.yaml".)',
hide: !verboseHelp); hide: !verboseHelp);
argParser.addFlag('watch', argParser.addFlag('watch',
help: 'Run analysis continuously, watching the filesystem for changes.', help: 'Run analysis continuously, watching the filesystem for changes.',
negatable: false); negatable: false);
argParser.addOption('write', argParser.addOption('write',
valueHelp: 'file', valueHelp: 'file',
help: 'Also output the results to a file. This is useful with --watch ' help: 'Also output the results to a file. This is useful with "--watch" '
'if you want a file to always contain the latest results.'); 'if you want a file to always contain the latest results.');
argParser.addOption('dart-sdk', argParser.addOption('dart-sdk',
valueHelp: 'path-to-sdk', valueHelp: 'path-to-sdk',
...@@ -67,13 +67,13 @@ class AnalyzeCommand extends FlutterCommand { ...@@ -67,13 +67,13 @@ class AnalyzeCommand extends FlutterCommand {
// Not used by analyze --watch // Not used by analyze --watch
argParser.addFlag('congratulate', argParser.addFlag('congratulate',
help: 'Show output even when there are no errors, warnings, hints, or lints. ' help: 'Show output even when there are no errors, warnings, hints, or lints. '
'Ignored if --watch is specified.', 'Ignored if "--watch" is specified.',
defaultsTo: true); defaultsTo: true);
argParser.addFlag('preamble', argParser.addFlag('preamble',
defaultsTo: true, defaultsTo: true,
help: 'When analyzing the flutter repository, display the number of ' help: 'When analyzing the flutter repository, display the number of '
'files that will be analyzed.\n' 'files that will be analyzed.\n'
'Ignored if --watch is specified.'); 'Ignored if "--watch" is specified.');
argParser.addFlag('fatal-infos', argParser.addFlag('fatal-infos',
negatable: true, negatable: true,
help: 'Treat info level issues as fatal.', help: 'Treat info level issues as fatal.',
......
...@@ -73,14 +73,20 @@ const List<Target> _kDefaultTargets = <Target>[ ...@@ -73,14 +73,20 @@ const List<Target> _kDefaultTargets = <Target>[
ReleaseBundleWindowsAssets(), ReleaseBundleWindowsAssets(),
]; ];
// TODO(ianh): https://github.com/dart-lang/args/issues/181 will allow us to remove useLegacyNames
// and just switch to arguments that use the regular style, which still supporting the old names.
// When fixing this, remove the hack in test/general.shard/args_test.dart that ignores these names.
const bool useLegacyNames = true;
/// Assemble provides a low level API to interact with the flutter tool build /// Assemble provides a low level API to interact with the flutter tool build
/// system. /// system.
class AssembleCommand extends FlutterCommand { class AssembleCommand extends FlutterCommand {
AssembleCommand() { AssembleCommand({ bool verboseHelp = false }) {
argParser.addMultiOption( argParser.addMultiOption(
'define', 'define',
abbr: 'd', abbr: 'd',
help: 'Allows passing configuration to a target with --define=target=key=value.', valueHelp: 'target=key=value',
help: 'Allows passing configuration to a target, as in "--define=target=key=value".',
); );
argParser.addOption( argParser.addOption(
'performance-measurement-file', 'performance-measurement-file',
...@@ -89,28 +95,28 @@ class AssembleCommand extends FlutterCommand { ...@@ -89,28 +95,28 @@ class AssembleCommand extends FlutterCommand {
argParser.addMultiOption( argParser.addMultiOption(
'input', 'input',
abbr: 'i', abbr: 'i',
help: 'Allows passing additional inputs with --input=key=value. Unlike ' help: 'Allows passing additional inputs with "--input=key=value". Unlike '
'defines, additional inputs do not generate a new configuration, instead ' 'defines, additional inputs do not generate a new configuration; instead '
'they are treated as dependencies of the targets that use them.' 'they are treated as dependencies of the targets that use them.'
); );
argParser.addOption('depfile', help: 'A file path where a depfile will be written. ' argParser.addOption('depfile',
'This contains all build inputs and outputs in a make style syntax' help: 'A file path where a depfile will be written. '
'This contains all build inputs and outputs in a Make-style syntax.'
); );
argParser.addOption('build-inputs', help: 'A file path where a newline ' argParser.addOption('build-inputs', help: 'A file path where a newline-separated '
'separated file containing all inputs used will be written after a build.' 'file containing all inputs used will be written after a build. '
' This file is not included as a build input or output. This file is not' 'This file is not included as a build input or output. This file is not '
' written if the build fails for any reason.'); 'written if the build fails for any reason.');
argParser.addOption('build-outputs', help: 'A file path where a newline ' argParser.addOption('build-outputs', help: 'A file path where a newline-separated '
'separated file containing all outputs used will be written after a build.' 'file containing all outputs created will be written after a build. '
' This file is not included as a build input or output. This file is not' 'This file is not included as a build input or output. This file is not '
' written if the build fails for any reason.'); 'written if the build fails for any reason.');
argParser.addOption('output', abbr: 'o', help: 'A directory where output ' argParser.addOption('output', abbr: 'o', help: 'A directory where output '
'files will be written. Must be either absolute or relative from the ' 'files will be written. Must be either absolute or relative from the '
'root of the current Flutter project.', 'root of the current Flutter project.',
); );
argParser.addOption(kExtraGenSnapshotOptions); usesExtraDartFlagOptions(verboseHelp: verboseHelp, useLegacyNames: useLegacyNames);
argParser.addOption(kExtraFrontEndOptions); usesDartDefineOption(useLegacyNames: useLegacyNames);
argParser.addOption(kDartDefines);
argParser.addOption( argParser.addOption(
'resource-pool-size', 'resource-pool-size',
help: 'The maximum number of concurrent tasks the build system will run.', help: 'The maximum number of concurrent tasks the build system will run.',
...@@ -205,15 +211,14 @@ class AssembleCommand extends FlutterCommand { ...@@ -205,15 +211,14 @@ class AssembleCommand extends FlutterCommand {
final String value = chunk.substring(indexEquals + 1); final String value = chunk.substring(indexEquals + 1);
results[key] = value; results[key] = value;
} }
// Workaround for extraGenSnapshot formatting. if (argResults.wasParsed(useLegacyNames ? kExtraGenSnapshotOptions : FlutterOptions.kExtraGenSnapshotOptions)) {
if (argResults.wasParsed(kExtraGenSnapshotOptions)) { results[kExtraGenSnapshotOptions] = (argResults[useLegacyNames ? kExtraGenSnapshotOptions : FlutterOptions.kExtraGenSnapshotOptions] as List<String>).join(',');
results[kExtraGenSnapshotOptions] = argResults[kExtraGenSnapshotOptions] as String;
} }
if (argResults.wasParsed(kDartDefines)) { if (argResults.wasParsed(useLegacyNames ? kDartDefines : FlutterOptions.kDartDefinesOption)) {
results[kDartDefines] = argResults[kDartDefines] as String; results[kDartDefines] = (argResults[useLegacyNames ? kDartDefines : FlutterOptions.kDartDefinesOption] as List<String>).join(',');
} }
if (argResults.wasParsed(kExtraFrontEndOptions)) { if (argResults.wasParsed(useLegacyNames ? kExtraFrontEndOptions : FlutterOptions.kExtraFrontEndOptions)) {
results[kExtraFrontEndOptions] = argResults[kExtraFrontEndOptions] as String; results[kExtraFrontEndOptions] = (argResults[useLegacyNames ? kExtraFrontEndOptions : FlutterOptions.kExtraFrontEndOptions] as List<String>).join(',');
} }
return results; return results;
} }
......
...@@ -59,10 +59,10 @@ import '../vmservice.dart'; ...@@ -59,10 +59,10 @@ import '../vmservice.dart';
/// also be provided. /// also be provided.
class AttachCommand extends FlutterCommand { class AttachCommand extends FlutterCommand {
AttachCommand({bool verboseHelp = false, this.hotRunnerFactory}) { AttachCommand({bool verboseHelp = false, this.hotRunnerFactory}) {
addBuildModeFlags(defaultToRelease: false, excludeRelease: true); addBuildModeFlags(verboseHelp: verboseHelp, defaultToRelease: false, excludeRelease: true);
usesTargetOption(); usesTargetOption();
usesPortOptions(); usesPortOptions(verboseHelp: verboseHelp);
usesIpv6Flag(); usesIpv6Flag(verboseHelp: verboseHelp);
usesFilesystemOptions(hide: !verboseHelp); usesFilesystemOptions(hide: !verboseHelp);
usesFuchsiaOptions(hide: !verboseHelp); usesFuchsiaOptions(hide: !verboseHelp);
usesDartDefineOption(); usesDartDefineOption();
...@@ -73,13 +73,13 @@ class AttachCommand extends FlutterCommand { ...@@ -73,13 +73,13 @@ class AttachCommand extends FlutterCommand {
..addOption( ..addOption(
'debug-port', 'debug-port',
hide: !verboseHelp, hide: !verboseHelp,
help: 'Device port where the observatory is listening. Requires ' help: '(deprecated) Device port where the observatory is listening. Requires '
'--disable-service-auth-codes to also be provided to the Flutter ' '"--disable-service-auth-codes" to also be provided to the Flutter '
'application at launch, otherwise this command will fail to connect to ' 'application at launch, otherwise this command will fail to connect to '
'the application. In general, --debug-uri should be used instead.', 'the application. In general, "--debug-uri" should be used instead.',
)..addOption( )..addOption(
'debug-uri', 'debug-uri', // TODO(ianh): we should support --debug-url as well (leaving this as an alias).
help: 'The URI at which the observatory is listening.', help: 'The URL at which the observatory is listening.',
)..addOption( )..addOption(
'app-id', 'app-id',
help: 'The package name (Android) or bundle identifier (iOS) for the app. ' help: 'The package name (Android) or bundle identifier (iOS) for the app. '
...@@ -99,7 +99,7 @@ class AttachCommand extends FlutterCommand { ...@@ -99,7 +99,7 @@ class AttachCommand extends FlutterCommand {
'report-ready', 'report-ready',
help: 'Print "ready" to the console after handling a keyboard command.\n' help: 'Print "ready" to the console after handling a keyboard command.\n'
'This is primarily useful for tests and other automation, but consider ' 'This is primarily useful for tests and other automation, but consider '
'using --machine instead.', 'using "--machine" instead.',
hide: !verboseHelp, hide: !verboseHelp,
)..addOption( )..addOption(
'project-root', 'project-root',
...@@ -417,8 +417,8 @@ known, it can be explicitly provided to attach via the command-line, e.g. ...@@ -417,8 +417,8 @@ known, it can be explicitly provided to attach via the command-line, e.g.
final FlutterDevice flutterDevice = await FlutterDevice.create( final FlutterDevice flutterDevice = await FlutterDevice.create(
device, device,
fileSystemRoots: stringsArg('filesystem-root'), fileSystemRoots: stringsArg(FlutterOptions.kFileSystemRoot),
fileSystemScheme: stringArg('filesystem-scheme'), fileSystemScheme: stringArg(FlutterOptions.kFileSystemScheme),
target: targetFile, target: targetFile,
targetModel: TargetModel(stringArg('target-model')), targetModel: TargetModel(stringArg('target-model')),
buildInfo: buildInfo, buildInfo: buildInfo,
......
...@@ -58,7 +58,7 @@ class BuildAarCommand extends BuildSubCommand { ...@@ -58,7 +58,7 @@ class BuildAarCommand extends BuildSubCommand {
..addOption( ..addOption(
'output-dir', 'output-dir',
help: 'The absolute path to the directory where the repository is generated. ' help: 'The absolute path to the directory where the repository is generated. '
"By default, this is '<current-directory>android/build'. ", 'By default, this is "<current-directory>android/build".',
); );
} }
......
...@@ -24,11 +24,11 @@ class BuildApkCommand extends BuildSubCommand { ...@@ -24,11 +24,11 @@ class BuildApkCommand extends BuildSubCommand {
usesPubOption(); usesPubOption();
usesBuildNumberOption(); usesBuildNumberOption();
usesBuildNameOption(); usesBuildNameOption();
addShrinkingFlag(); addShrinkingFlag(verboseHelp: verboseHelp);
addSplitDebugInfoOption(); addSplitDebugInfoOption();
addDartObfuscationOption(); addDartObfuscationOption();
usesDartDefineOption(); usesDartDefineOption();
usesExtraDartFlagOptions(); usesExtraDartFlagOptions(verboseHelp: verboseHelp);
addBundleSkSLPathOption(hide: !verboseHelp); addBundleSkSLPathOption(hide: !verboseHelp);
addEnableExperimentation(hide: !verboseHelp); addEnableExperimentation(hide: !verboseHelp);
addBuildPerformanceFile(hide: !verboseHelp); addBuildPerformanceFile(hide: !verboseHelp);
......
...@@ -19,16 +19,16 @@ class BuildAppBundleCommand extends BuildSubCommand { ...@@ -19,16 +19,16 @@ class BuildAppBundleCommand extends BuildSubCommand {
BuildAppBundleCommand({bool verboseHelp = false}) { BuildAppBundleCommand({bool verboseHelp = false}) {
addTreeShakeIconsFlag(); addTreeShakeIconsFlag();
usesTargetOption(); usesTargetOption();
addBuildModeFlags(); addBuildModeFlags(verboseHelp: verboseHelp);
usesFlavorOption(); usesFlavorOption();
usesPubOption(); usesPubOption();
usesBuildNumberOption(); usesBuildNumberOption();
usesBuildNameOption(); usesBuildNameOption();
addShrinkingFlag(); addShrinkingFlag(verboseHelp: verboseHelp);
addSplitDebugInfoOption(); addSplitDebugInfoOption();
addDartObfuscationOption(); addDartObfuscationOption();
usesDartDefineOption(); usesDartDefineOption();
usesExtraDartFlagOptions(); usesExtraDartFlagOptions(verboseHelp: verboseHelp);
addBundleSkSLPathOption(hide: !verboseHelp); addBundleSkSLPathOption(hide: !verboseHelp);
addBuildPerformanceFile(hide: !verboseHelp); addBuildPerformanceFile(hide: !verboseHelp);
usesTrackWidgetCreation(verboseHelp: verboseHelp); usesTrackWidgetCreation(verboseHelp: verboseHelp);
......
...@@ -11,7 +11,7 @@ import '../features.dart'; ...@@ -11,7 +11,7 @@ import '../features.dart';
import '../globals.dart' as globals; import '../globals.dart' as globals;
import '../project.dart'; import '../project.dart';
import '../reporting/reporting.dart'; import '../reporting/reporting.dart';
import '../runner/flutter_command.dart' show FlutterCommandResult; import '../runner/flutter_command.dart';
import 'build.dart'; import 'build.dart';
class BuildBundleCommand extends BuildSubCommand { class BuildBundleCommand extends BuildSubCommand {
...@@ -21,9 +21,13 @@ class BuildBundleCommand extends BuildSubCommand { ...@@ -21,9 +21,13 @@ class BuildBundleCommand extends BuildSubCommand {
usesFilesystemOptions(hide: !verboseHelp); usesFilesystemOptions(hide: !verboseHelp);
usesBuildNumberOption(); usesBuildNumberOption();
addBuildModeFlags(verboseHelp: verboseHelp, defaultToRelease: false); addBuildModeFlags(verboseHelp: verboseHelp, defaultToRelease: false);
usesExtraDartFlagOptions(); usesExtraDartFlagOptions(verboseHelp: verboseHelp);
argParser argParser
..addOption('depfile', defaultsTo: defaultDepfilePath) ..addOption('depfile',
defaultsTo: defaultDepfilePath,
help: 'A file path where a depfile will be written. '
'This contains all build inputs and outputs in a Make-style syntax.'
)
..addOption('target-platform', ..addOption('target-platform',
defaultsTo: 'android-arm', defaultsTo: 'android-arm',
allowed: const <String>[ allowed: const <String>[
...@@ -37,8 +41,13 @@ class BuildBundleCommand extends BuildSubCommand { ...@@ -37,8 +41,13 @@ class BuildBundleCommand extends BuildSubCommand {
'linux-arm64', 'linux-arm64',
'windows-x64', 'windows-x64',
], ],
help: 'The architecture for which to build the application.',
) )
..addOption('asset-dir', defaultsTo: getAssetBuildDirectory()); ..addOption('asset-dir',
defaultsTo: getAssetBuildDirectory(),
help: 'The output directory for the kernel_blob.bin file, the native snapshet, the assets, etc. '
'Can be used to redirect the output when driving the Flutter toolchain from another build system.',
);
usesPubOption(); usesPubOption();
usesTrackWidgetCreation(verboseHelp: verboseHelp); usesTrackWidgetCreation(verboseHelp: verboseHelp);
...@@ -112,8 +121,8 @@ class BuildBundleCommand extends BuildSubCommand { ...@@ -112,8 +121,8 @@ class BuildBundleCommand extends BuildSubCommand {
trackWidgetCreation: boolArg('track-widget-creation'), trackWidgetCreation: boolArg('track-widget-creation'),
extraFrontEndOptions: buildInfo.extraFrontEndOptions, extraFrontEndOptions: buildInfo.extraFrontEndOptions,
extraGenSnapshotOptions: buildInfo.extraGenSnapshotOptions, extraGenSnapshotOptions: buildInfo.extraGenSnapshotOptions,
fileSystemScheme: stringArg('filesystem-scheme'), fileSystemRoots: stringsArg(FlutterOptions.kFileSystemRoot),
fileSystemRoots: stringsArg('filesystem-root'), fileSystemScheme: stringArg(FlutterOptions.kFileSystemScheme),
treeShakeIcons: buildInfo.treeShakeIcons, treeShakeIcons: buildInfo.treeShakeIcons,
); );
return FlutterCommandResult.success(); return FlutterCommandResult.success();
......
...@@ -173,7 +173,7 @@ abstract class _BuildIOSSubCommand extends BuildSubCommand { ...@@ -173,7 +173,7 @@ abstract class _BuildIOSSubCommand extends BuildSubCommand {
_BuildIOSSubCommand({ @required bool verboseHelp }) { _BuildIOSSubCommand({ @required bool verboseHelp }) {
addTreeShakeIconsFlag(); addTreeShakeIconsFlag();
addSplitDebugInfoOption(); addSplitDebugInfoOption();
addBuildModeFlags(defaultToRelease: true); addBuildModeFlags(verboseHelp: verboseHelp, defaultToRelease: true);
usesTargetOption(); usesTargetOption();
usesFlavorOption(); usesFlavorOption();
usesPubOption(); usesPubOption();
...@@ -181,7 +181,7 @@ abstract class _BuildIOSSubCommand extends BuildSubCommand { ...@@ -181,7 +181,7 @@ abstract class _BuildIOSSubCommand extends BuildSubCommand {
usesBuildNameOption(); usesBuildNameOption();
addDartObfuscationOption(); addDartObfuscationOption();
usesDartDefineOption(); usesDartDefineOption();
usesExtraDartFlagOptions(); usesExtraDartFlagOptions(verboseHelp: verboseHelp);
addEnableExperimentation(hide: !verboseHelp); addEnableExperimentation(hide: !verboseHelp);
addBuildPerformanceFile(hide: !verboseHelp); addBuildPerformanceFile(hide: !verboseHelp);
addBundleSkSLPathOption(hide: !verboseHelp); addBundleSkSLPathOption(hide: !verboseHelp);
......
...@@ -50,7 +50,7 @@ class BuildIOSFrameworkCommand extends BuildSubCommand { ...@@ -50,7 +50,7 @@ class BuildIOSFrameworkCommand extends BuildSubCommand {
usesDartDefineOption(); usesDartDefineOption();
addSplitDebugInfoOption(); addSplitDebugInfoOption();
addDartObfuscationOption(); addDartObfuscationOption();
usesExtraDartFlagOptions(); usesExtraDartFlagOptions(verboseHelp: verboseHelp);
addNullSafetyModeOptions(hide: !verboseHelp); addNullSafetyModeOptions(hide: !verboseHelp);
addEnableExperimentation(hide: !verboseHelp); addEnableExperimentation(hide: !verboseHelp);
...@@ -74,15 +74,15 @@ class BuildIOSFrameworkCommand extends BuildSubCommand { ...@@ -74,15 +74,15 @@ class BuildIOSFrameworkCommand extends BuildSubCommand {
'By default, all build configurations are built.' 'By default, all build configurations are built.'
) )
..addFlag('universal', ..addFlag('universal',
help: '(Deprecated) Produce universal frameworks that include all valid architectures.', help: '(deprecated) Produce universal frameworks that include all valid architectures.',
negatable: true, negatable: true,
hide: true, hide: !verboseHelp,
) )
..addFlag('xcframework', ..addFlag('xcframework',
help: 'Produce xcframeworks that include all valid architectures.', help: 'Produce xcframeworks that include all valid architectures.',
negatable: false, negatable: false,
defaultsTo: true, defaultsTo: true,
hide: true, hide: !verboseHelp,
) )
..addFlag('cocoapods', ..addFlag('cocoapods',
help: 'Produce a Flutter.podspec instead of an engine Flutter.xcframework (recommended if host app uses CocoaPods).', help: 'Produce a Flutter.podspec instead of an engine Flutter.xcframework (recommended if host app uses CocoaPods).',
...@@ -94,8 +94,8 @@ class BuildIOSFrameworkCommand extends BuildSubCommand { ...@@ -94,8 +94,8 @@ class BuildIOSFrameworkCommand extends BuildSubCommand {
) )
..addFlag('force', ..addFlag('force',
abbr: 'f', abbr: 'f',
help: 'Force Flutter.podspec creation on the master channel. For testing only.', help: 'Force Flutter.podspec creation on the master channel. This is only intended for testing the tool itself.',
hide: true hide: !verboseHelp,
); );
} }
......
...@@ -23,7 +23,7 @@ class BuildWebCommand extends BuildSubCommand { ...@@ -23,7 +23,7 @@ class BuildWebCommand extends BuildSubCommand {
addTreeShakeIconsFlag(enabledByDefault: false); addTreeShakeIconsFlag(enabledByDefault: false);
usesTargetOption(); usesTargetOption();
usesPubOption(); usesPubOption();
addBuildModeFlags(excludeDebug: true); addBuildModeFlags(verboseHelp: verboseHelp, excludeDebug: true);
usesDartDefineOption(); usesDartDefineOption();
usesWebRendererOption(); usesWebRendererOption();
addEnableExperimentation(hide: !verboseHelp); addEnableExperimentation(hide: !verboseHelp);
...@@ -38,25 +38,26 @@ class BuildWebCommand extends BuildSubCommand { ...@@ -38,25 +38,26 @@ class BuildWebCommand extends BuildSubCommand {
argParser.addFlag( argParser.addFlag(
'source-maps', 'source-maps',
defaultsTo: false, defaultsTo: false,
help: 'Whether to generate a sourcemap file. These can be used by browsers ' help: 'Generate a sourcemap file. These can be used by browsers '
'To view and debug the original source code of a compiled and minified Dart ' 'to view and debug the original source code of a compiled and minified Dart '
'application. Defaults to false (i.e. no sourcemaps produced).' 'application.'
); );
argParser.addOption('pwa-strategy', argParser.addOption('pwa-strategy',
defaultsTo: kOfflineFirst, defaultsTo: kOfflineFirst,
help: help: 'The caching strategy to be used by the PWA service worker.',
'The caching strategy to be used by the PWA service worker.\n' allowed: <String>[
'offline-first will attempt to cache the app shell eagerly and ' kOfflineFirst,
kNoneWorker,
],
allowedHelp: <String, String>{
kOfflineFirst: 'Attempt to cache the application shell eagerly and '
'then lazily cache all subsequent assets as they are loaded. When ' 'then lazily cache all subsequent assets as they are loaded. When '
'making a network request for an asset, the offline cache will be ' 'making a network request for an asset, the offline cache will be '
'preferred.\n' 'preferred.',
'none will generate a service worker with no body. This is useful for ' kNoneWorker: 'Generate a service worker with no body. This is useful for '
'local testing or in cases where the service worker caching functionality ' 'local testing or in cases where the service worker caching functionality '
'is not desirable', 'is not desirable',
allowed: <String>[ },
kOfflineFirst,
kNoneWorker,
]
); );
} }
......
...@@ -22,7 +22,7 @@ class ConfigCommand extends FlutterCommand { ...@@ -22,7 +22,7 @@ class ConfigCommand extends FlutterCommand {
help: 'Clear the saved development certificate choice used to sign apps for iOS device deployment.'); help: 'Clear the saved development certificate choice used to sign apps for iOS device deployment.');
argParser.addOption('android-sdk', help: 'The Android SDK directory.'); argParser.addOption('android-sdk', help: 'The Android SDK directory.');
argParser.addOption('android-studio-dir', help: 'The Android Studio install directory.'); argParser.addOption('android-studio-dir', help: 'The Android Studio install directory.');
argParser.addOption('build-dir', help: 'The relative path to override a projects build directory', argParser.addOption('build-dir', help: 'The relative path to override a projects build directory.',
valueHelp: 'out/'); valueHelp: 'out/');
argParser.addFlag('machine', argParser.addFlag('machine',
negatable: false, negatable: false,
......
...@@ -23,10 +23,12 @@ import '../runner/flutter_command.dart'; ...@@ -23,10 +23,12 @@ import '../runner/flutter_command.dart';
import 'create_base.dart'; import 'create_base.dart';
class CreateCommand extends CreateBase { class CreateCommand extends CreateBase {
CreateCommand() { CreateCommand({
bool verboseHelp = false,
}) : super(verboseHelp: verboseHelp) {
addPlatformsOptions(customHelp: 'The platforms supported by this project. ' addPlatformsOptions(customHelp: 'The platforms supported by this project. '
'This argument only works when the --template is set to app or plugin. '
'Platform folders (e.g. android/) will be generated in the target project. ' 'Platform folders (e.g. android/) will be generated in the target project. '
'This argument only works when "--template" is set to app or plugin. '
'When adding platforms to a plugin project, the pubspec.yaml will be updated with the requested platform. ' 'When adding platforms to a plugin project, the pubspec.yaml will be updated with the requested platform. '
'Adding desktop platforms requires the corresponding desktop config setting to be enabled.'); 'Adding desktop platforms requires the corresponding desktop config setting to be enabled.');
argParser.addOption( argParser.addOption(
...@@ -50,17 +52,17 @@ class CreateCommand extends CreateBase { ...@@ -50,17 +52,17 @@ class CreateCommand extends CreateBase {
argParser.addOption( argParser.addOption(
'sample', 'sample',
abbr: 's', abbr: 's',
help: 'Specifies the Flutter code sample to use as the main.dart for an application. Implies ' help: 'Specifies the Flutter code sample to use as the "main.dart" for an application. Implies '
'--template=app. The value should be the sample ID of the desired sample from the API ' '"--template=app". The value should be the sample ID of the desired sample from the API '
'documentation website (http://docs.flutter.dev). An example can be found at ' 'documentation website (http://docs.flutter.dev/). An example can be found at: '
'https://master-api.flutter.dev/flutter/widgets/SingleChildScrollView-class.html', 'https://api.flutter.dev/flutter/widgets/SingleChildScrollView-class.html',
defaultsTo: null, defaultsTo: null,
valueHelp: 'id', valueHelp: 'id',
); );
argParser.addOption( argParser.addOption(
'list-samples', 'list-samples',
help: 'Specifies a JSON output file for a listing of Flutter code samples ' help: 'Specifies a JSON output file for a listing of Flutter code samples '
'that can be created with --sample.', 'that can be created with "--sample".',
valueHelp: 'path', valueHelp: 'path',
); );
} }
...@@ -218,7 +220,7 @@ class CreateCommand extends CreateBase { ...@@ -218,7 +220,7 @@ class CreateCommand extends CreateBase {
if (boolArg('with-driver-test')) { if (boolArg('with-driver-test')) {
globals.printError( globals.printError(
'--with-driver-test has been deprecated and will no longer add a flutter ' 'The "--with-driver-test" argument has been deprecated and will no longer add a flutter '
'driver template. Instead, learn how to use package:integration_test by ' 'driver template. Instead, learn how to use package:integration_test by '
'visiting https://pub.dev/packages/integration_test .' 'visiting https://pub.dev/packages/integration_test .'
); );
......
...@@ -32,13 +32,15 @@ const List<String> _kAvailablePlatforms = <String>[ ...@@ -32,13 +32,15 @@ const List<String> _kAvailablePlatforms = <String>[
]; ];
const String _kDefaultPlatformArgumentHelp = const String _kDefaultPlatformArgumentHelp =
'Required: The platforms supported by this project. ' '(required) The platforms supported by this project. '
'Platform folders (e.g. android/) will be generated in the target project. ' 'Platform folders (e.g. android/) will be generated in the target project. '
'Adding desktop platforms requires the corresponding desktop config setting to be enabled.'; 'Adding desktop platforms requires the corresponding desktop config setting to be enabled.';
/// Common behavior for `flutter create` commands. /// Common behavior for `flutter create` commands.
abstract class CreateBase extends FlutterCommand { abstract class CreateBase extends FlutterCommand {
CreateBase() { CreateBase({
@required bool verboseHelp,
}) {
argParser.addFlag( argParser.addFlag(
'pub', 'pub',
defaultsTo: true, defaultsTo: true,
...@@ -57,9 +59,10 @@ abstract class CreateBase extends FlutterCommand { ...@@ -57,9 +59,10 @@ abstract class CreateBase extends FlutterCommand {
'with-driver-test', 'with-driver-test',
negatable: true, negatable: true,
defaultsTo: false, defaultsTo: false,
help: '(Deprecated) Also add a flutter_driver dependency and generate a ' help: '(deprecated) Historically, this added a flutter_driver dependency and generated a '
"sample 'flutter drive' test. This flag has been deprecated, instead see " 'sample "flutter drive" test. Now it does nothing. Consider using the '
'package:integration_test at https://pub.dev/packages/integration_test .', '"integration_test" package: https://pub.dev/packages/integration_test',
hide: !verboseHelp,
); );
argParser.addFlag( argParser.addFlag(
'overwrite', 'overwrite',
...@@ -91,19 +94,21 @@ abstract class CreateBase extends FlutterCommand { ...@@ -91,19 +94,21 @@ abstract class CreateBase extends FlutterCommand {
abbr: 'i', abbr: 'i',
defaultsTo: 'swift', defaultsTo: 'swift',
allowed: <String>['objc', 'swift'], allowed: <String>['objc', 'swift'],
help: 'The language to use for iOS-specific code, either ObjectiveC (legacy) or Swift (recommended).'
); );
argParser.addOption( argParser.addOption(
'android-language', 'android-language',
abbr: 'a', abbr: 'a',
defaultsTo: 'kotlin', defaultsTo: 'kotlin',
allowed: <String>['java', 'kotlin'], allowed: <String>['java', 'kotlin'],
help: 'The language to use for Android-specific code, either Java (legacy) or Kotlin (recommended).',
); );
argParser.addFlag( argParser.addFlag(
'skip-name-checks', 'skip-name-checks',
help: help:
'integration test only parameter to allow creating applications/plugins with ' 'Allow the creation of applications and plugins with invalid names. '
'invalid names.', 'This is only intended to enable testing of the tool itself.',
hide: true, hide: !verboseHelp,
); );
} }
......
...@@ -12,17 +12,17 @@ import '../globals.dart' as globals; ...@@ -12,17 +12,17 @@ import '../globals.dart' as globals;
import '../runner/flutter_command.dart'; import '../runner/flutter_command.dart';
class DevicesCommand extends FlutterCommand { class DevicesCommand extends FlutterCommand {
DevicesCommand({ bool verboseHelp = false }) {
DevicesCommand() {
argParser.addFlag('machine', argParser.addFlag('machine',
negatable: false, negatable: false,
help: 'Output device information in machine readable structured JSON format', help: 'Output device information in machine readable structured JSON format.',
); );
argParser.addOption( argParser.addOption(
'timeout', 'timeout',
abbr: 't', abbr: 't',
defaultsTo: null, defaultsTo: null,
help: '(deprecated) Use --device-timeout instead', help: '(deprecated) This option has been replaced by "--${FlutterOptions.kDeviceTimeout}".',
hide: !verboseHelp,
); );
usesDeviceTimeoutOption(); usesDeviceTimeoutOption();
} }
...@@ -38,7 +38,7 @@ class DevicesCommand extends FlutterCommand { ...@@ -38,7 +38,7 @@ class DevicesCommand extends FlutterCommand {
if (argResults['timeout'] != null) { if (argResults['timeout'] != null) {
final int timeoutSeconds = int.tryParse(stringArg('timeout')); final int timeoutSeconds = int.tryParse(stringArg('timeout'));
if (timeoutSeconds == null) { if (timeoutSeconds == null) {
throwToolExit( 'Could not parse -t/--timeout argument. It must be an integer.'); throwToolExit('Could not parse -t/--timeout argument. It must be an integer.');
} }
return Duration(seconds: timeoutSeconds); return Duration(seconds: timeoutSeconds);
} }
...@@ -48,7 +48,7 @@ class DevicesCommand extends FlutterCommand { ...@@ -48,7 +48,7 @@ class DevicesCommand extends FlutterCommand {
@override @override
Future<void> validateCommand() { Future<void> validateCommand() {
if (argResults['timeout'] != null) { if (argResults['timeout'] != null) {
globals.printError('--timeout has been deprecated, use --${FlutterOptions.kDeviceTimeout} instead'); globals.printError('"--timeout" argument is deprecated, use "--${FlutterOptions.kDeviceTimeout}" instead');
} }
return super.validateCommand(); return super.validateCommand();
} }
......
...@@ -30,6 +30,7 @@ import '../version.dart'; ...@@ -30,6 +30,7 @@ import '../version.dart';
/// the command would fail since there was no previously recorded stable version. /// the command would fail since there was no previously recorded stable version.
class DowngradeCommand extends FlutterCommand { class DowngradeCommand extends FlutterCommand {
DowngradeCommand({ DowngradeCommand({
bool verboseHelp = false,
PersistentToolState persistentToolState, PersistentToolState persistentToolState,
Logger logger, Logger logger,
ProcessManager processManager, ProcessManager processManager,
...@@ -46,14 +47,17 @@ class DowngradeCommand extends FlutterCommand { ...@@ -46,14 +47,17 @@ class DowngradeCommand extends FlutterCommand {
_fileSystem = fileSystem { _fileSystem = fileSystem {
argParser.addOption( argParser.addOption(
'working-directory', 'working-directory',
hide: true, hide: !verboseHelp,
help: 'Override the downgrade working directory for integration testing.' help: 'Override the downgrade working directory. '
'This is only intended to enable integration testing of the tool itself.'
); );
argParser.addFlag( argParser.addFlag(
'prompt', 'prompt',
defaultsTo: true, defaultsTo: true,
hide: true, hide: !verboseHelp,
help: 'Disable the downgrade prompt for integration testing.' help: 'Show the downgrade prompt. '
'The ability to disable this using "--no-prompt" is only provided for '
'integration testing of the tool itself.'
); );
} }
...@@ -74,7 +78,7 @@ class DowngradeCommand extends FlutterCommand { ...@@ -74,7 +78,7 @@ class DowngradeCommand extends FlutterCommand {
@override @override
Future<FlutterCommandResult> runCommand() async { Future<FlutterCommandResult> runCommand() async {
// Note: commands do not necessarily have access to the correct zone injected // Commands do not necessarily have access to the correct zone injected
// values when being created. Fields must be lazily instantiated in runCommand, // values when being created. Fields must be lazily instantiated in runCommand,
// at least until the zone injection is refactored. // at least until the zone injection is refactored.
_terminal ??= globals.terminal; _terminal ??= globals.terminal;
......
...@@ -52,7 +52,8 @@ class DriveCommand extends RunCommandBase { ...@@ -52,7 +52,8 @@ class DriveCommand extends RunCommandBase {
@required Logger logger, @required Logger logger,
}) : _flutterDriverFactory = flutterDriverFactory, }) : _flutterDriverFactory = flutterDriverFactory,
_fileSystem = fileSystem, _fileSystem = fileSystem,
_logger = logger { _logger = logger,
super(verboseHelp: verboseHelp) {
requiresPubspecYaml(); requiresPubspecYaml();
addEnableExperimentation(hide: !verboseHelp); addEnableExperimentation(hide: !verboseHelp);
...@@ -65,14 +66,14 @@ class DriveCommand extends RunCommandBase { ...@@ -65,14 +66,14 @@ class DriveCommand extends RunCommandBase {
defaultsTo: null, defaultsTo: null,
help: 'Will keep the Flutter application running when done testing.\n' help: 'Will keep the Flutter application running when done testing.\n'
'By default, "flutter drive" stops the application after tests are finished, ' 'By default, "flutter drive" stops the application after tests are finished, '
'and --keep-app-running overrides this. On the other hand, if --use-existing-app ' 'and "--keep-app-running" overrides this. On the other hand, if "--use-existing-app" '
'is specified, then "flutter drive" instead defaults to leaving the application ' 'is specified, then "flutter drive" instead defaults to leaving the application '
'running, and --no-keep-app-running overrides it.', 'running, and "--no-keep-app-running" overrides it.',
) )
..addOption('use-existing-app', ..addOption('use-existing-app',
help: 'Connect to an already running instance via the given observatory URL. ' help: 'Connect to an already running instance via the given observatory URL. '
'If this option is given, the application will not be automatically started, ' 'If this option is given, the application will not be automatically started, '
'and it will only be stopped if --no-keep-app-running is explicitly set.', 'and it will only be stopped if "--no-keep-app-running" is explicitly set.',
valueHelp: 'url', valueHelp: 'url',
) )
..addOption('driver', ..addOption('driver',
...@@ -86,23 +87,21 @@ class DriveCommand extends RunCommandBase { ...@@ -86,23 +87,21 @@ class DriveCommand extends RunCommandBase {
) )
..addFlag('build', ..addFlag('build',
defaultsTo: true, defaultsTo: true,
help: '(Deprecated) Build the app before running. To use an existing app, pass the --use-application-binary ' help: '(deprecated) Build the app before running. To use an existing app, pass the "--use-application-binary" '
'flag with an existing APK', 'flag with an existing APK.',
) )
..addOption('driver-port', ..addOption('driver-port',
defaultsTo: '4444', defaultsTo: '4444',
help: 'The port where Webdriver server is launched at. Defaults to 4444.', help: 'The port where Webdriver server is launched at.',
valueHelp: '4444' valueHelp: '4444'
) )
..addFlag('headless', ..addFlag('headless',
defaultsTo: true, defaultsTo: true,
help: 'Whether the driver browser is going to be launched in headless mode. Defaults to true.', help: 'Whether the driver browser is going to be launched in headless mode.',
) )
..addOption('browser-name', ..addOption('browser-name',
defaultsTo: 'chrome', defaultsTo: 'chrome',
help: 'Name of browser where tests will be executed. \n' help: 'Name of the browser where tests will be executed.',
'Following browsers are supported: \n'
'Chrome, Firefox, Safari (macOS and iOS) and Edge. Defaults to Chrome.',
allowed: <String>[ allowed: <String>[
'android-chrome', 'android-chrome',
'chrome', 'chrome',
...@@ -111,23 +110,30 @@ class DriveCommand extends RunCommandBase { ...@@ -111,23 +110,30 @@ class DriveCommand extends RunCommandBase {
'ios-safari', 'ios-safari',
'safari', 'safari',
], ],
allowedHelp: <String, String>{
'android-chrome': 'Chrome on Android (see also "--android-emulator").',
'chrome': 'Google Chrome on this computer (see also "--chrome-binary").',
'edge': 'Microsoft Edge on this computer (Windows only).',
'firefox': 'Mozilla Firefox on this computer.',
'ios-safari': 'Apple Safari on an iOS device.',
'safari': 'Apple Safari on this computer (macOS only).',
},
) )
..addOption('browser-dimension', ..addOption('browser-dimension',
defaultsTo: '1600,1024', defaultsTo: '1600,1024',
help: 'The dimension of browser when running Flutter Web test. \n' help: 'The dimension of the browser when running a Flutter Web test. '
'This will affect screenshot and all offset-related actions. \n' 'This will affect screenshot and all offset-related actions.',
'By default. it is set to 1600,1024 (1600 by 1024).', valueHelp: 'width,height',
) )
..addFlag('android-emulator', ..addFlag('android-emulator',
defaultsTo: true, defaultsTo: true,
help: 'Whether to perform Flutter Driver testing on Android Emulator.' help: 'Whether to perform Flutter Driver testing using an Android Emulator. '
'Works only if \'browser-name\' is set to \'android-chrome\'') 'Works only if "browser-name" is set to "android-chrome".')
..addOption('chrome-binary', ..addOption('chrome-binary',
help: 'Location of Chrome binary. ' help: 'Location of the Chrome binary. '
'Works only if \'browser-name\' is set to \'chrome\'') 'Works only if "browser-name" is set to "chrome".')
..addOption('write-sksl-on-exit', ..addOption('write-sksl-on-exit',
help: help: 'Attempts to write an SkSL file when the drive process is finished '
'Attempts to write an SkSL file when the drive process is finished '
'to the provided file, overwriting it if necessary.') 'to the provided file, overwriting it if necessary.')
..addMultiOption('test-arguments', help: 'Additional arguments to pass to the ' ..addMultiOption('test-arguments', help: 'Additional arguments to pass to the '
'Dart VM running The test script.'); 'Dart VM running The test script.');
......
...@@ -19,7 +19,7 @@ class EmulatorsCommand extends FlutterCommand { ...@@ -19,7 +19,7 @@ class EmulatorsCommand extends FlutterCommand {
help: 'Creates a new Android emulator based on a Pixel device.', help: 'Creates a new Android emulator based on a Pixel device.',
negatable: false); negatable: false);
argParser.addOption('name', argParser.addOption('name',
help: 'Used with flag --create. Specifies a name for the emulator being created.'); help: 'Used with the "--create" flag. Specifies a name for the emulator being created.');
} }
@override @override
......
...@@ -30,7 +30,8 @@ class FormatCommand extends FlutterCommand { ...@@ -30,7 +30,8 @@ class FormatCommand extends FlutterCommand {
); );
argParser.addOption('line-length', argParser.addOption('line-length',
abbr: 'l', abbr: 'l',
help: 'Wrap lines longer than this length. Defaults to 80 characters.', help: 'Wrap lines longer than this length.',
valueHelp: 'characters',
defaultsTo: '80', defaultsTo: '80',
); );
} }
......
...@@ -34,14 +34,14 @@ class GenerateLocalizationsCommand extends FlutterCommand { ...@@ -34,14 +34,14 @@ class GenerateLocalizationsCommand extends FlutterCommand {
argParser.addOption( argParser.addOption(
'output-dir', 'output-dir',
help: 'The directory where the generated localization classes will be written ' help: 'The directory where the generated localization classes will be written '
'if the synthetic-package flag is set to false.' 'if the synthetic-package flag is set to false.\n'
'\n\n' '\n'
'If output-dir is specified and the synthetic-package flag is enabled, ' 'If output-dir is specified and the synthetic-package flag is enabled, '
'this option will be ignored by the tool.' 'this option will be ignored by the tool.\n'
'\n\n' '\n'
'The app must import the file specified in the \'output-localization-file\' ' 'The app must import the file specified in the "--output-localization-file" '
'option from this directory. If unspecified, this defaults to the same ' 'option from this directory. If unspecified, this defaults to the same '
'directory as the input directory specified in \'arb-dir\'.', 'directory as the input directory specified in "--arb-dir".',
); );
argParser.addOption( argParser.addOption(
'template-arb-file', 'template-arb-file',
...@@ -57,12 +57,14 @@ class GenerateLocalizationsCommand extends FlutterCommand { ...@@ -57,12 +57,14 @@ class GenerateLocalizationsCommand extends FlutterCommand {
); );
argParser.addOption( argParser.addOption(
'untranslated-messages-file', 'untranslated-messages-file',
help: 'The location of a file that describes the localization\n' help: 'The location of a file that describes the localization '
'messages have not been translated yet. Using this option will create\n' 'messages have not been translated yet. Using this option will create '
'a JSON file at the target location, in the following format:\n\n' 'a JSON file at the target location, in the following format:\n'
'"locale": ["message_1", "message_2" ... "message_n"]\n\n' '\n'
'If this option is not specified, a summary of the messages that\n' ' "locale": ["message_1", "message_2" ... "message_n"]\n'
'have not been translated will be printed on the command line.' '\n'
'If this option is not specified, a summary of the messages that '
'have not been translated will be printed on the command line.',
); );
argParser.addOption( argParser.addOption(
'output-class', 'output-class',
...@@ -76,18 +78,20 @@ class GenerateLocalizationsCommand extends FlutterCommand { ...@@ -76,18 +78,20 @@ class GenerateLocalizationsCommand extends FlutterCommand {
help: 'The list of preferred supported locales for the application. ' help: 'The list of preferred supported locales for the application. '
'By default, the tool will generate the supported locales list in ' 'By default, the tool will generate the supported locales list in '
'alphabetical order. Use this flag if you would like to default to ' 'alphabetical order. Use this flag if you would like to default to '
'a different locale. \n\n' 'a different locale. '
'For example, pass in `en_US` if you would like your app to ' 'For example, pass in "en_US" if you would like your app to '
'default to American English if a device supports it.' 'default to American English on devices that support it. '
'(Pass this option multiple times for defining multiple items', 'Pass this option multiple times to define multiple items.',
); );
argParser.addOption( argParser.addOption(
'header', 'header',
help: 'The header to prepend to the generated Dart localizations ' help: 'The header to prepend to the generated Dart localizations '
'files. This option takes in a string. \n\n' 'files. This option takes in a string.\n'
'\n'
'For example, pass in "/// All localized files." if you would ' 'For example, pass in "/// All localized files." if you would '
'like this string prepended to the generated Dart file. \n\n' 'like this string prepended to the generated Dart file.\n'
'Alternatively, see the `header-file` option to pass in a text ' '\n'
'Alternatively, see the "--header-file" option to pass in a text '
'file for longer headers.' 'file for longer headers.'
); );
argParser.addOption( argParser.addOption(
...@@ -95,16 +99,18 @@ class GenerateLocalizationsCommand extends FlutterCommand { ...@@ -95,16 +99,18 @@ class GenerateLocalizationsCommand extends FlutterCommand {
help: 'The header to prepend to the generated Dart localizations ' help: 'The header to prepend to the generated Dart localizations '
'files. The value of this option is the name of the file that ' 'files. The value of this option is the name of the file that '
'contains the header text which will be inserted at the top ' 'contains the header text which will be inserted at the top '
'of each generated Dart file. \n\n' 'of each generated Dart file.\n'
'Alternatively, see the `header` option to pass in a string ' '\n'
'for a simpler header. \n\n' 'Alternatively, see the "--header" option to pass in a string '
'This file should be placed in the directory specified in \'arb-dir\'.' 'for a simpler header.\n'
'\n'
'This file should be placed in the directory specified in "--arb-dir".'
); );
argParser.addFlag( argParser.addFlag(
'use-deferred-loading', 'use-deferred-loading',
defaultsTo: false, defaultsTo: false,
help: 'Whether to generate the Dart localization file with locales imported' help: 'Whether to generate the Dart localization file with locales imported '
' as deferred, allowing for lazy loading of each locale in Flutter web.\n' 'as deferred, allowing for lazy loading of each locale in Flutter web.\n'
'\n' '\n'
'This can reduce a web app’s initial startup time by decreasing the ' 'This can reduce a web app’s initial startup time by decreasing the '
'size of the JavaScript bundle. When this flag is set to true, the ' 'size of the JavaScript bundle. When this flag is set to true, the '
...@@ -114,23 +120,24 @@ class GenerateLocalizationsCommand extends FlutterCommand { ...@@ -114,23 +120,24 @@ class GenerateLocalizationsCommand extends FlutterCommand {
'improvement to have deferred loading. For projects with a small number ' 'improvement to have deferred loading. For projects with a small number '
'of locales, the difference is negligible, and might slow down the start ' 'of locales, the difference is negligible, and might slow down the start '
'up compared to bundling the localizations with the rest of the ' 'up compared to bundling the localizations with the rest of the '
'application.\n\n' 'application.\n'
'Note that this flag does not affect other platforms such as mobile or ' '\n'
'desktop.', 'This flag does not affect other platforms such as mobile or desktop.',
); );
argParser.addOption( argParser.addOption(
'gen-inputs-and-outputs-list', 'gen-inputs-and-outputs-list',
valueHelp: 'path-to-output-directory', valueHelp: 'path-to-output-directory',
help: 'When specified, the tool generates a JSON file containing the ' help: 'When specified, the tool generates a JSON file containing the '
'tool\'s inputs and outputs named gen_l10n_inputs_and_outputs.json.' 'tool\'s inputs and outputs named gen_l10n_inputs_and_outputs.json.\n'
'\n\n' '\n'
'This can be useful for keeping track of which files of the Flutter ' 'This can be useful for keeping track of which files of the Flutter '
'project were used when generating the latest set of localizations. ' 'project were used when generating the latest set of localizations. '
'For example, the Flutter tool\'s build system uses this file to ' 'For example, the Flutter tool\'s build system uses this file to '
'keep track of when to call gen_l10n during hot reload.\n\n' 'keep track of when to call gen_l10n during hot reload.\n'
'\n'
'The value of this option is the directory where the JSON file will be ' 'The value of this option is the directory where the JSON file will be '
'generated.' 'generated.\n'
'\n\n' '\n'
'When null, the JSON file will not be generated.' 'When null, the JSON file will not be generated.'
); );
argParser.addFlag( argParser.addFlag(
...@@ -138,29 +145,31 @@ class GenerateLocalizationsCommand extends FlutterCommand { ...@@ -138,29 +145,31 @@ class GenerateLocalizationsCommand extends FlutterCommand {
defaultsTo: true, defaultsTo: true,
help: 'Determines whether or not the generated output files will be ' help: 'Determines whether or not the generated output files will be '
'generated as a synthetic package or at a specified directory in ' 'generated as a synthetic package or at a specified directory in '
'the Flutter project.' 'the Flutter project.\n'
'\n\n' '\n'
'This flag is set to true by default.' 'This flag is set to true by default.\n'
'\n\n' '\n'
'When synthetic-package is set to false, it will generate the ' 'When synthetic-package is set to false, it will generate the '
'localizations files in the directory specified by arb-dir by default. ' 'localizations files in the directory specified by arb-dir by default.\n'
'\n\n' '\n'
'If output-dir is specified, files will be generated there.', 'If output-dir is specified, files will be generated there.',
); );
argParser.addOption( argParser.addOption(
'project-dir', 'project-dir',
valueHelp: 'absolute/path/to/flutter/project', valueHelp: 'absolute/path/to/flutter/project',
help: 'When specified, the tool uses the path passed into this option ' help: 'When specified, the tool uses the path passed into this option '
'as the directory of the root Flutter project.' 'as the directory of the root Flutter project.\n'
'\n\n' '\n'
'When null, the relative path to the present working directory will be used.' 'When null, the relative path to the present working directory will be used.'
); );
argParser.addFlag( argParser.addFlag(
'required-resource-attributes', 'required-resource-attributes',
help: 'Requires all resource ids to contain a corresponding resource attribute.\n\n' help: 'Requires all resource ids to contain a corresponding resource attribute.\n'
'\n'
'By default, simple messages will not require metadata, but it is highly ' 'By default, simple messages will not require metadata, but it is highly '
'recommended as this provides context for the meaning of a message to ' 'recommended as this provides context for the meaning of a message to '
'readers.\n\n' 'readers.\n'
'\n'
'Resource attributes are still required for plural messages.' 'Resource attributes are still required for plural messages.'
); );
} }
......
...@@ -24,8 +24,8 @@ class IdeConfigCommand extends FlutterCommand { ...@@ -24,8 +24,8 @@ class IdeConfigCommand extends FlutterCommand {
negatable: false, negatable: false,
help: 'Update the templates in the template directory from the current ' help: 'Update the templates in the template directory from the current '
'configuration files. This is the opposite of what $name usually does. ' 'configuration files. This is the opposite of what $name usually does. '
'Will search the flutter tree for .iml files and copy any missing ones ' 'Will search the flutter tree for *.iml files and copy any missing ones '
'into the template directory. If --overwrite is also specified, it will ' 'into the template directory. If "--overwrite" is also specified, it will '
'update any out-of-date files, and remove any deleted files from the ' 'update any out-of-date files, and remove any deleted files from the '
'template directory.', 'template directory.',
); );
......
...@@ -32,7 +32,7 @@ class PrecacheCommand extends FlutterCommand { ...@@ -32,7 +32,7 @@ class PrecacheCommand extends FlutterCommand {
help: 'Force re-downloading of artifacts.'); help: 'Force re-downloading of artifacts.');
argParser.addFlag('android', negatable: true, defaultsTo: false, argParser.addFlag('android', negatable: true, defaultsTo: false,
help: 'Precache artifacts for Android development.', help: 'Precache artifacts for Android development.',
hide: verboseHelp); hide: !verboseHelp);
argParser.addFlag('android_gen_snapshot', negatable: true, defaultsTo: false, argParser.addFlag('android_gen_snapshot', negatable: true, defaultsTo: false,
help: 'Precache gen_snapshot for Android development.', help: 'Precache gen_snapshot for Android development.',
hide: !verboseHelp); hide: !verboseHelp);
...@@ -57,9 +57,9 @@ class PrecacheCommand extends FlutterCommand { ...@@ -57,9 +57,9 @@ class PrecacheCommand extends FlutterCommand {
argParser.addFlag('universal', negatable: true, defaultsTo: true, argParser.addFlag('universal', negatable: true, defaultsTo: true,
help: 'Precache artifacts required for any development platform.'); help: 'Precache artifacts required for any development platform.');
argParser.addFlag('flutter_runner', negatable: true, defaultsTo: false, argParser.addFlag('flutter_runner', negatable: true, defaultsTo: false,
help: 'Precache the flutter runner artifacts.', hide: true); help: 'Precache the flutter runner artifacts.', hide: !verboseHelp);
argParser.addFlag('use-unsigned-mac-binaries', negatable: true, defaultsTo: false, argParser.addFlag('use-unsigned-mac-binaries', negatable: true, defaultsTo: false,
help: 'Precache the unsigned mac binaries when available.', hide: true); help: 'Precache the unsigned macOS binaries when available.', hide: !verboseHelp);
} }
final Cache _cache; final Cache _cache;
......
...@@ -16,7 +16,7 @@ import '../vmservice.dart'; ...@@ -16,7 +16,7 @@ import '../vmservice.dart';
const String _kOut = 'out'; const String _kOut = 'out';
const String _kType = 'type'; const String _kType = 'type';
const String _kObservatoryUri = 'observatory-uri'; const String _kObservatoryUri = 'observatory-uri'; // TODO(ianh): change this to "observatory-url" (but support -uri as an alias)
const String _kDeviceType = 'device'; const String _kDeviceType = 'device';
const String _kSkiaType = 'skia'; const String _kSkiaType = 'skia';
const String _kRasterizerType = 'rasterizer'; const String _kRasterizerType = 'rasterizer';
...@@ -32,9 +32,9 @@ class ScreenshotCommand extends FlutterCommand { ...@@ -32,9 +32,9 @@ class ScreenshotCommand extends FlutterCommand {
argParser.addOption( argParser.addOption(
_kObservatoryUri, _kObservatoryUri,
valueHelp: 'URI', valueHelp: 'URI',
help: 'The observatory URI to connect to.\n' help: 'The Observatory URL to which to connect.\n'
'This is required when --$_kType is "$_kSkiaType" or "$_kRasterizerType".\n' 'This is required when "--$_kType" is "$_kSkiaType" or "$_kRasterizerType".\n'
'To find the observatory URI, use "flutter run" and look for ' 'To find the Observatory URL, use "flutter run" and look for '
'"An Observatory ... is available at" in the output.', '"An Observatory ... is available at" in the output.',
); );
argParser.addOption( argParser.addOption(
...@@ -43,11 +43,11 @@ class ScreenshotCommand extends FlutterCommand { ...@@ -43,11 +43,11 @@ class ScreenshotCommand extends FlutterCommand {
help: 'The type of screenshot to retrieve.', help: 'The type of screenshot to retrieve.',
allowed: const <String>[_kDeviceType, _kSkiaType, _kRasterizerType], allowed: const <String>[_kDeviceType, _kSkiaType, _kRasterizerType],
allowedHelp: const <String, String>{ allowedHelp: const <String, String>{
_kDeviceType: "Delegate to the device's native screenshot capabilities. This " _kDeviceType: 'Delegate to the device\'s native screenshot capabilities. This '
'screenshots the entire screen currently being displayed (including content ' 'screenshots the entire screen currently being displayed (including content '
'not rendered by Flutter, like the device status bar).', 'not rendered by Flutter, like the device status bar).',
_kSkiaType: 'Render the Flutter app as a Skia picture. Requires --$_kObservatoryUri', _kSkiaType: 'Render the Flutter app as a Skia picture. Requires "--$_kObservatoryUri".',
_kRasterizerType: 'Render the Flutter app using the rasterizer. Requires --$_kObservatoryUri', _kRasterizerType: 'Render the Flutter app using the rasterizer. Requires "--$_kObservatoryUri."',
}, },
defaultsTo: _kDeviceType, defaultsTo: _kDeviceType,
); );
......
...@@ -45,7 +45,7 @@ class SymbolizeCommand extends FlutterCommand { ...@@ -45,7 +45,7 @@ class SymbolizeCommand extends FlutterCommand {
argParser.addOption( argParser.addOption(
'output', 'output',
abbr: 'o', abbr: 'o',
valueHelp: 'A file path for a symbolized stack trace to be written to.' help: 'A file path for a symbolized stack trace to be written to.'
); );
} }
......
...@@ -49,11 +49,11 @@ class TestCommand extends FlutterCommand { ...@@ -49,11 +49,11 @@ class TestCommand extends FlutterCommand {
) )
..addOption('tags', ..addOption('tags',
abbr: 't', abbr: 't',
help: 'Run only tests associated with tags', help: 'Run only tests associated with the specified tags. See: https://pub.dev/packages/test#tagging-tests',
) )
..addOption('exclude-tags', ..addOption('exclude-tags',
abbr: 'x', abbr: 'x',
help: 'Run only tests WITHOUT given tags', help: 'Run only tests that do not have the specified tags. See: https://pub.dev/packages/test#tagging-tests',
) )
..addFlag('start-paused', ..addFlag('start-paused',
defaultsTo: false, defaultsTo: false,
...@@ -64,11 +64,11 @@ class TestCommand extends FlutterCommand { ...@@ -64,11 +64,11 @@ class TestCommand extends FlutterCommand {
'console once the test has started.', 'console once the test has started.',
) )
..addFlag('disable-service-auth-codes', ..addFlag('disable-service-auth-codes',
hide: !verboseHelp,
defaultsTo: false, defaultsTo: false,
negatable: false, negatable: false,
help: 'No longer require an authentication code to connect to the VM ' hide: !verboseHelp,
'service (not recommended).', help: '(deprecated) Allow connections to the VM service without using authentication codes. '
'(Not recommended! This can open your device to remote code execution attacks!)'
) )
..addFlag('coverage', ..addFlag('coverage',
defaultsTo: false, defaultsTo: false,
...@@ -79,11 +79,11 @@ class TestCommand extends FlutterCommand { ...@@ -79,11 +79,11 @@ class TestCommand extends FlutterCommand {
defaultsTo: false, defaultsTo: false,
negatable: false, negatable: false,
help: 'Whether to merge coverage data with "coverage/lcov.base.info".\n' help: 'Whether to merge coverage data with "coverage/lcov.base.info".\n'
'Implies collecting coverage data. (Requires lcov)', 'Implies collecting coverage data. (Requires lcov.)',
) )
..addFlag('ipv6', ..addFlag('ipv6',
negatable: false, negatable: false,
hide: true, hide: !verboseHelp,
help: 'Whether to use IPv6 for the test harness server socket.', help: 'Whether to use IPv6 for the test harness server socket.',
) )
..addOption('coverage-path', ..addOption('coverage-path',
...@@ -93,12 +93,12 @@ class TestCommand extends FlutterCommand { ...@@ -93,12 +93,12 @@ class TestCommand extends FlutterCommand {
..addFlag('machine', ..addFlag('machine',
hide: !verboseHelp, hide: !verboseHelp,
negatable: false, negatable: false,
help: 'Handle machine structured JSON command input\n' help: 'Handle machine structured JSON command input '
'and provide output and progress in machine friendly format.', 'and provide output and progress in machine friendly format.',
) )
..addFlag('update-goldens', ..addFlag('update-goldens',
negatable: false, negatable: false,
help: 'Whether matchesGoldenFile() calls within your test methods should ' help: 'Whether "matchesGoldenFile()" calls within your test methods should '
'update the golden files rather than test for an existing match.', 'update the golden files rather than test for an existing match.',
) )
..addOption('concurrency', ..addOption('concurrency',
...@@ -110,8 +110,9 @@ class TestCommand extends FlutterCommand { ...@@ -110,8 +110,9 @@ class TestCommand extends FlutterCommand {
..addFlag('test-assets', ..addFlag('test-assets',
defaultsTo: true, defaultsTo: true,
negatable: true, negatable: true,
help: 'Whether to build the assets bundle for testing.\n' help: 'Whether to build the assets bundle for testing. '
'Consider using --no-test-assets if assets are not required.', 'This takes additional time before running the tests. '
'Consider using "--no-test-assets" if assets are not required.',
) )
// --platform is not supported to be used by Flutter developers. It only // --platform is not supported to be used by Flutter developers. It only
// exists to test the Flutter framework itself and may be removed entirely // exists to test the Flutter framework itself and may be removed entirely
...@@ -119,33 +120,47 @@ class TestCommand extends FlutterCommand { ...@@ -119,33 +120,47 @@ class TestCommand extends FlutterCommand {
// `package:integration_test` instead. // `package:integration_test` instead.
..addOption('platform', ..addOption('platform',
allowed: const <String>['tester', 'chrome'], allowed: const <String>['tester', 'chrome'],
hide: true, hide: !verboseHelp,
defaultsTo: 'tester', defaultsTo: 'tester',
help: 'Selects the test backend.',
allowedHelp: <String, String>{
'tester': 'Run tests using the default VM-based test environment.',
'chrome': '(deprecated) Run tests using the Google Chrome web browser. '
'This value is intended for testing the Flutter framework '
'itself and may be removed at any time.',
},
) )
..addOption('test-randomize-ordering-seed', ..addOption('test-randomize-ordering-seed',
help: 'The seed to randomize the execution order of test cases.\n' help: 'The seed to randomize the execution order of test cases within test files. '
'Must be a 32bit unsigned integer or "random".\n' 'Must be a 32bit unsigned integer or the string "random", '
'If "random", pick a random seed to use.\n' 'which indicates that a seed should be selected randomly. '
'If not passed, do not randomize test case execution order.', 'By default, tests run in the order they are declared.',
) )
..addFlag('enable-vmservice', ..addFlag('enable-vmservice',
defaultsTo: false, defaultsTo: false,
hide: !verboseHelp, hide: !verboseHelp,
help: 'Enables the vmservice without --start-paused. This flag is ' help: 'Enables the VM service without "--start-paused". This flag is '
'intended for use with tests that will use dart:developer to ' 'intended for use with tests that will use "dart:developer" to '
'interact with the vmservice at runtime.\n' 'interact with the VM service at runtime.\n'
'This flag is ignored if --start-paused or coverage are requested. ' 'This flag is ignored if "--start-paused" or coverage are requested, as '
'The vmservice will be enabled no matter what in those cases.' 'the VM service will be enabled in those cases regardless.'
) )
..addOption('reporter', ..addOption('reporter',
abbr: 'r', abbr: 'r',
defaultsTo: 'compact', defaultsTo: 'compact',
help: 'Set how to print test results.\n' help: 'Set how to print test results.',
'[compact] (default) A single line, updated continuously.\n' allowed: <String>['compact', 'expanded', 'json'],
'[expanded] A separate line for each update.\n' allowedHelp: <String, String>{
'[json] A machine-readable format (see https://dart.dev/go/test-docs/json_reporter.md).\n') 'compact': 'A single line that updates dynamically.',
'expanded': 'A separate line for each update. May be preferred when logging to a file or in continuous integration.',
'json': 'A machine-readable format. See: https://dart.dev/go/test-docs/json_reporter.md',
},
)
..addOption('timeout', ..addOption('timeout',
help: 'The default test timeout. For example: 15s, 2x, none. Defaults to "30s"', help: 'The default test timeout, specified either '
'in seconds (e.g. "60s"), '
'as a multiplier of the default timeout (e.g. "2x"), '
'or as the string "none" to disable the timeout entirely.',
defaultsTo: '30s', defaultsTo: '30s',
); );
addDdsOptions(verboseHelp: verboseHelp); addDdsOptions(verboseHelp: verboseHelp);
......
...@@ -86,19 +86,19 @@ class UpdatePackagesCommand extends FlutterCommand { ...@@ -86,19 +86,19 @@ class UpdatePackagesCommand extends FlutterCommand {
..addFlag( ..addFlag(
'paths', 'paths',
help: 'Finds paths in the dependency chain leading from package specified ' help: 'Finds paths in the dependency chain leading from package specified '
'in --from to package specified in --to.', 'in "--from" to package specified in "--to".',
defaultsTo: false, defaultsTo: false,
negatable: false, negatable: false,
) )
..addOption( ..addOption(
'from', 'from',
help: 'Used with flag --dependency-path. Specifies the package to begin ' help: 'Used with "--dependency-path". Specifies the package to begin '
'searching dependency path from.', 'searching dependency path from.',
) )
..addOption( ..addOption(
'to', 'to',
help: 'Used with flag --dependency-path. Specifies the package that the ' help: 'Used with "--dependency-path". Specifies the package that the '
'sought after dependency path leads to.', 'sought-after dependency path leads to.',
) )
..addFlag( ..addFlag(
'transitive-closure', 'transitive-closure',
...@@ -110,20 +110,20 @@ class UpdatePackagesCommand extends FlutterCommand { ...@@ -110,20 +110,20 @@ class UpdatePackagesCommand extends FlutterCommand {
..addFlag( ..addFlag(
'consumer-only', 'consumer-only',
help: 'Only prints the dependency graph that is the transitive closure ' help: 'Only prints the dependency graph that is the transitive closure '
'that a consumer of the Flutter SDK will observe (When combined ' 'that a consumer of the Flutter SDK will observe (when combined '
'with transitive-closure)', 'with transitive-closure).',
defaultsTo: false, defaultsTo: false,
negatable: false, negatable: false,
) )
..addFlag( ..addFlag(
'verify-only', 'verify-only',
help: 'verifies the package checksum without changing or updating deps', help: 'Verifies the package checksum without changing or updating deps.',
defaultsTo: false, defaultsTo: false,
negatable: false, negatable: false,
) )
..addFlag( ..addFlag(
'offline', 'offline',
help: 'Use cached packages instead of accessing the network', help: 'Use cached packages instead of accessing the network.',
defaultsTo: false, defaultsTo: false,
negatable: false, negatable: false,
); );
......
...@@ -18,7 +18,10 @@ import '../runner/flutter_command.dart'; ...@@ -18,7 +18,10 @@ import '../runner/flutter_command.dart';
import '../version.dart'; import '../version.dart';
class UpgradeCommand extends FlutterCommand { class UpgradeCommand extends FlutterCommand {
UpgradeCommand([UpgradeCommandRunner commandRunner]) UpgradeCommand({
@required bool verboseHelp,
UpgradeCommandRunner commandRunner,
})
: _commandRunner = commandRunner ?? UpgradeCommandRunner() { : _commandRunner = commandRunner ?? UpgradeCommandRunner() {
argParser argParser
..addFlag( ..addFlag(
...@@ -29,20 +32,22 @@ class UpgradeCommand extends FlutterCommand { ...@@ -29,20 +32,22 @@ class UpgradeCommand extends FlutterCommand {
) )
..addFlag( ..addFlag(
'continue', 'continue',
hide: true, hide: !verboseHelp,
negatable: false, negatable: false,
help: 'For the second half of the upgrade flow requiring the new ' help: 'Trigger the second half of the upgrade flow. This should not be invoked '
'version of Flutter. Should not be invoked manually, but ' 'manually. It is used re-entrantly by the standard upgrade command after '
're-entrantly by the standard upgrade command.', 'the new version of Flutter is available, to hand off the upgrade process '
'from the old version to the new version.',
) )
..addOption( ..addOption(
'working-directory', 'working-directory',
hide: true, hide: !verboseHelp,
help: 'Override the upgrade working directory for integration testing.' help: 'Override the upgrade working directory. '
'This is only intended to enable integration testing of the tool itself.'
) )
..addFlag( ..addFlag(
'verify-only', 'verify-only',
help: 'Verifies for any new flutter update, without fetching the update.', help: 'Checks for any new flutter updates, without actually fetching them.',
negatable: false, negatable: false,
); );
} }
...@@ -138,7 +143,7 @@ class UpgradeCommandRunner { ...@@ -138,7 +143,7 @@ class UpgradeCommandRunner {
throwToolExit( throwToolExit(
'Unknown flutter tag. Abandoning upgrade to avoid destroying local ' 'Unknown flutter tag. Abandoning upgrade to avoid destroying local '
'changes. If it is okay to remove local changes, then re-run this ' 'changes. If it is okay to remove local changes, then re-run this '
'command with --force.' 'command with "--force".'
); );
} }
} }
...@@ -150,7 +155,7 @@ class UpgradeCommandRunner { ...@@ -150,7 +155,7 @@ class UpgradeCommandRunner {
'upgrading. If you want to keep these changes, it is recommended that ' 'upgrading. If you want to keep these changes, it is recommended that '
'you stash them via "git stash" or else commit the changes to a local ' 'you stash them via "git stash" or else commit the changes to a local '
'branch. If it is okay to remove local changes, then re-run this ' 'branch. If it is okay to remove local changes, then re-run this '
'command with --force.' 'command with "--force".'
); );
} }
recordState(flutterVersion); recordState(flutterVersion);
...@@ -211,8 +216,8 @@ class UpgradeCommandRunner { ...@@ -211,8 +216,8 @@ class UpgradeCommandRunner {
'The tool could not verify the status of the current flutter checkout. ' 'The tool could not verify the status of the current flutter checkout. '
'This might be due to git not being installed or an internal error. ' 'This might be due to git not being installed or an internal error. '
'If it is okay to ignore potential local changes, then re-run this ' 'If it is okay to ignore potential local changes, then re-run this '
'command with --force.' 'command with "--force".\n'
'\nError: $error.' 'Error: $error.'
); );
} }
return false; return false;
......
...@@ -45,10 +45,13 @@ class FlutterCommandRunner extends CommandRunner<void> { ...@@ -45,10 +45,13 @@ class FlutterCommandRunner extends CommandRunner<void> {
abbr: 'v', abbr: 'v',
negatable: false, negatable: false,
help: 'Noisy logging, including all shell commands executed.\n' help: 'Noisy logging, including all shell commands executed.\n'
'If used with --help, shows hidden options.'); 'If used with "--help", shows hidden options. '
'If used with "flutter doctor", shows additional diagnostic information. '
'(Use "-vv" to force verbose logging in those cases.)');
argParser.addFlag('prefixed-errors', argParser.addFlag('prefixed-errors',
negatable: false, negatable: false,
hide: true, help: 'Causes lines sent to stderr to be prefixed with "ERROR:".',
hide: !verboseHelp,
defaultsTo: false); defaultsTo: false);
argParser.addFlag('quiet', argParser.addFlag('quiet',
negatable: false, negatable: false,
...@@ -62,7 +65,7 @@ class FlutterCommandRunner extends CommandRunner<void> { ...@@ -62,7 +65,7 @@ class FlutterCommandRunner extends CommandRunner<void> {
argParser.addOption('wrap-column', argParser.addOption('wrap-column',
hide: !verboseHelp, hide: !verboseHelp,
help: 'Sets the output wrap column. If not set, uses the width of the terminal. No ' 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 ' 'wrapping occurs if not writing to a terminal. Use "--no-wrap" to turn off wrapping '
'when connected to a terminal.', 'when connected to a terminal.',
defaultsTo: null); defaultsTo: null);
argParser.addOption('device-id', argParser.addOption('device-id',
...@@ -74,7 +77,7 @@ class FlutterCommandRunner extends CommandRunner<void> { ...@@ -74,7 +77,7 @@ class FlutterCommandRunner extends CommandRunner<void> {
argParser.addFlag('machine', argParser.addFlag('machine',
negatable: false, negatable: false,
hide: !verboseHelp, hide: !verboseHelp,
help: 'When used with the --version flag, outputs the information using JSON.'); help: 'When used with the "--version" flag, outputs the information using JSON.');
argParser.addFlag('color', argParser.addFlag('color',
negatable: true, negatable: true,
hide: !verboseHelp, hide: !verboseHelp,
...@@ -106,7 +109,7 @@ class FlutterCommandRunner extends CommandRunner<void> { ...@@ -106,7 +109,7 @@ class FlutterCommandRunner extends CommandRunner<void> {
hide: !verboseHelp, hide: !verboseHelp,
help: 'Name of a build output within the engine out directory, if you are building Flutter locally.\n' help: 'Name of a build output within the engine out directory, if you are building Flutter locally.\n'
'Use this to select a specific version of the engine if you have built multiple engine targets.\n' 'Use this to select a specific version of the engine if you have built multiple engine targets.\n'
'This path is relative to --local-engine-src-path/out.'); 'This path is relative to "--local-engine-src-path" or "--local-engine-src-out" (q.v.).');
if (verboseHelp) { if (verboseHelp) {
argParser.addSeparator('Options for testing the "flutter" tool itself:'); argParser.addSeparator('Options for testing the "flutter" tool itself:');
...@@ -114,12 +117,12 @@ class FlutterCommandRunner extends CommandRunner<void> { ...@@ -114,12 +117,12 @@ class FlutterCommandRunner extends CommandRunner<void> {
argParser.addFlag('show-test-device', argParser.addFlag('show-test-device',
negatable: false, negatable: false,
hide: !verboseHelp, hide: !verboseHelp,
help: "List the special 'flutter-tester' device in device listings. " help: 'List the special "flutter-tester" device in device listings. '
'This headless device is used to\ntest Flutter tooling.'); 'This headless device is used to test Flutter tooling.');
argParser.addFlag('show-web-server-device', argParser.addFlag('show-web-server-device',
negatable: false, negatable: false,
hide: !verboseHelp, hide: !verboseHelp,
help: "List the special 'web-server' device in device listings. " help: 'List the special "web-server" device in device listings.',
); );
} }
...@@ -275,7 +278,7 @@ class FlutterCommandRunner extends CommandRunner<void> { ...@@ -275,7 +278,7 @@ class FlutterCommandRunner extends CommandRunner<void> {
} }
if (machineFlag) { if (machineFlag) {
throwToolExit('The --machine flag is only valid with the --version flag.', exitCode: 2); throwToolExit('The "--machine" flag is only valid with the "--version" flag.', exitCode: 2);
} }
await super.runCommand(topLevelResults); await super.runCommand(topLevelResults);
}, },
......
...@@ -434,7 +434,10 @@ void main() { ...@@ -434,7 +434,10 @@ void main() {
}); });
testUsingContext('upgrade continue prints welcome message', () async { testUsingContext('upgrade continue prints welcome message', () async {
final UpgradeCommand upgradeCommand = UpgradeCommand(fakeCommandRunner); final UpgradeCommand upgradeCommand = UpgradeCommand(
verboseHelp: false,
commandRunner: fakeCommandRunner,
);
await createTestCommandRunner(upgradeCommand).run( await createTestCommandRunner(upgradeCommand).run(
<String>[ <String>[
......
// Copyright 2014 The Flutter Authors. All rights reserved.
// 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:flutter_tools/executable.dart' as executable;
import 'package:flutter_tools/src/runner/flutter_command_runner.dart';
import '../src/common.dart';
import '../src/testbed.dart';
void main() {
test('Help for command line arguments is consistently styled and complete', () => Testbed().run(() {
final FlutterCommandRunner runner = FlutterCommandRunner(verboseHelp: true);
executable.generateCommands(
verboseHelp: true,
verbose: true,
).forEach(runner.addCommand);
verifyCommandRunner(runner);
}));
}
void verifyCommandRunner(CommandRunner<Object> runner) {
expect(runner.argParser, isNotNull, reason: '${runner.runtimeType} has no argParser');
expect(runner.argParser.allowsAnything, isFalse, reason: '${runner.runtimeType} allows anything');
expect(runner.argParser.allowTrailingOptions, isFalse, reason: '${runner.runtimeType} allows trailing options');
verifyOptions('the global argument "', runner.argParser.options.values);
runner.commands.values.forEach(verifyCommand);
}
void verifyCommand(Command<Object> runner) {
expect(runner.argParser, isNotNull, reason: 'command ${runner.name} has no argParser');
verifyOptions('"flutter ${runner.name} ', runner.argParser.options.values);
runner.subcommands.values.forEach(verifyCommand);
}
// Patterns for arguments names.
// The "ExtraFrontEndOptions", "ExtraGenSnapshotOptions", and "DartDefines" cases are special cases
// that we should remove; search for "useLegacyNames" in commands/assemble.dart and other files.
// TODO(ianh): consider changing all underscores to hyphens in argument names when we can do aliases.
// That depends on being able to have argument aliases: https://github.com/dart-lang/args/issues/181
final RegExp _allowedArgumentNamePattern = RegExp(r'^([-a-z0-9_]+|ExtraFrontEndOptions|ExtraGenSnapshotOptions|DartDefines)$');
// Patterns for help messages.
final RegExp _bannedLeadingPatterns = RegExp(r'^[-a-z]', multiLine: true);
final RegExp _allowedTrailingPatterns = RegExp(r'([^ ][.!:]\)?|: https?://[^ ]+[^.]|^)$');
final RegExp _bannedQuotePatterns = RegExp(r" '|' |'\.|\('|'\)|`");
final RegExp _bannedArgumentReferencePatterns = RegExp(r'[^"=]--[^ ]');
final RegExp _questionablePatterns = RegExp(r'[a-z]\.[A-Z]');
const String _needHelp = 'Every option must have help explaining what it does, even if it\'s '
'for testing purposes, because this is the bare minimum of '
'documentation we can add just for ourselves. If it is not intended '
'for developers, then use "hide: !verboseHelp" to only show the '
'help when people run with "--help --verbose".';
const String _header = ' Comment: ';
void verifyOptions(String command, Iterable<Option> options) {
assert(command.contains('"'));
for (final Option option in options) {
// If you think you need to add an exception here, please ask Hixie (but he'll say no).
expect(option.name, matches(_allowedArgumentNamePattern), reason: '$_header$command--${option.name}" is not a valid name for a command line argument. (Is it all lowercase?)');
expect(option.hide, isFalse, reason: '${_header}Help for $command--${option.name}" is always hidden. $_needHelp');
expect(option.help, isNotNull, reason: '${_header}Help for $command--${option.name}" has null help. $_needHelp');
expect(option.help, isNotEmpty, reason: '${_header}Help for $command--${option.name}" has empty help. $_needHelp');
expect(option.help, isNot(matches(_bannedLeadingPatterns)), reason: '${_header}A line in the help for $command--${option.name}" starts with a lowercase letter. For stylistic consistency, all help messages must start with a capital letter.');
expect(option.help, isNot(startsWith('(Deprecated')), reason: '${_header}Help for $command--${option.name}" should start with lowercase "(deprecated)" for consistency with other deprecated commands.');
expect(option.help, isNot(startsWith('(Required')), reason: '${_header}Help for $command--${option.name}" should start with lowercase "(required)" for consistency with other deprecated commands.');
expect(option.help, isNot(contains('?')), reason: '${_header}Help for $command--${option.name}" has a question mark. Generally we prefer the passive voice for help messages.');
expect(option.help, isNot(contains('Note:')), reason: '${_header}Help for $command--${option.name}" uses "Note:". See our style guide entry about "empty prose".');
expect(option.help, isNot(contains('Note that')), reason: '${_header}Help for $command--${option.name}" uses "Note that". See our style guide entry about "empty prose".');
expect(option.help, isNot(matches(_bannedQuotePatterns)), reason: '${_header}Help for $command--${option.name}" uses single quotes or backticks instead of double quotes in the help message. For consistency we use double quotes throughout.');
expect(option.help, isNot(matches(_questionablePatterns)), reason: '${_header}Help for $command--${option.name}" may have a typo. (If it does not you may have to update args_test.dart, sorry. Search for "_questionablePatterns")');
if (option.defaultsTo != null) {
expect(option.help, isNot(contains('Default')), reason: '${_header}Help for $command--${option.name}" mentions the default value but that is redundant with the defaultsTo option which is also specified (and preferred).');
}
expect(option.help, isNot(matches(_bannedArgumentReferencePatterns)), reason: '${_header}Help for $command--${option.name}" contains the string "--" in an unexpected way. If it\'s trying to mention another argument, it should be quoted, as in "--foo".');
for (final String line in option.help.split('\n')) {
if (!line.startsWith(' ')) {
expect(line, isNot(contains(' ')), reason: '${_header}Help for $command--${option.name}" has excessive whitespace (check e.g. for double spaces after periods or round line breaks in the source).');
expect(line, matches(_allowedTrailingPatterns), reason: '${_header}A line in the help for $command--${option.name}" does not end with the expected period that a full sentence should end with. (If the help ends with a URL, place it after a colon, don\'t leave a trailing period; if it\'s sample code, prefix the line with four spaces.)');
}
}
expect(option.help, isNot(endsWith(':')), reason: '${_header}Help for $command--${option.name}" ends with a colon, which seems unlikely to be correct.');
// TODO(ianh): add some checking for embedded URLs to make sure we're consistent on how we format those.
// TODO(ianh): arguably we should ban help text that starts with "Whether to..." since by definition a flag is to enable a feature, so the "whether to" is redundant.
// TODO(ianh): consider looking for strings that use the term "URI" instead of "URL".
}
}
...@@ -96,7 +96,7 @@ void main() { ...@@ -96,7 +96,7 @@ void main() {
print(result.stdout); print(result.stdout);
print(result.stderr); print(result.stderr);
expect(result.stderr.toString(), contains('--analyze-size can only be used on release builds')); expect(result.stderr.toString(), contains('"--analyze-size" can only be used on release builds'));
expect(result.exitCode, 1); expect(result.exitCode, 1);
}); });
...@@ -113,7 +113,7 @@ void main() { ...@@ -113,7 +113,7 @@ void main() {
'--split-debug-info=infos' '--split-debug-info=infos'
], workingDirectory: fileSystem.path.join(getFlutterRoot(), 'examples', 'hello_world')); ], workingDirectory: fileSystem.path.join(getFlutterRoot(), 'examples', 'hello_world'));
expect(result.stderr.toString(), contains('--analyze-size cannot be combined with --split-debug-info')); expect(result.stderr.toString(), contains('"--analyze-size" cannot be combined with "--split-debug-info"'));
expect(result.exitCode, 1); expect(result.exitCode, 1);
}); });
......
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