Use "aliases" in args to fix some technical debt (#81073)
This commit is contained in:
parent
858123dced
commit
a7eb2c8a1a
@ -85,11 +85,6 @@ List<Target> _kDefaultTargets = <Target>[
|
||||
const ReleaseBundleWindowsAssetsUwp(),
|
||||
];
|
||||
|
||||
// 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
|
||||
/// system.
|
||||
class AssembleCommand extends FlutterCommand {
|
||||
@ -128,8 +123,8 @@ class AssembleCommand extends FlutterCommand {
|
||||
'files will be written. Must be either absolute or relative from the '
|
||||
'root of the current Flutter project.',
|
||||
);
|
||||
usesExtraDartFlagOptions(verboseHelp: verboseHelp, useLegacyNames: useLegacyNames);
|
||||
usesDartDefineOption(useLegacyNames: useLegacyNames);
|
||||
usesExtraDartFlagOptions(verboseHelp: verboseHelp);
|
||||
usesDartDefineOption();
|
||||
argParser.addOption(
|
||||
'resource-pool-size',
|
||||
help: 'The maximum number of concurrent tasks the build system will run.',
|
||||
@ -263,18 +258,18 @@ class AssembleCommand extends FlutterCommand {
|
||||
final String value = chunk.substring(indexEquals + 1);
|
||||
results[key] = value;
|
||||
}
|
||||
if (argResults.wasParsed(useLegacyNames ? kExtraGenSnapshotOptions : FlutterOptions.kExtraGenSnapshotOptions)) {
|
||||
results[kExtraGenSnapshotOptions] = (argResults[useLegacyNames ? kExtraGenSnapshotOptions : FlutterOptions.kExtraGenSnapshotOptions] as List<String>).join(',');
|
||||
if (argResults.wasParsed(FlutterOptions.kExtraGenSnapshotOptions)) {
|
||||
results[kExtraGenSnapshotOptions] = (argResults[FlutterOptions.kExtraGenSnapshotOptions] as List<String>).join(',');
|
||||
}
|
||||
if (argResults.wasParsed(useLegacyNames ? kDartDefines : FlutterOptions.kDartDefinesOption)) {
|
||||
results[kDartDefines] = (argResults[useLegacyNames ? kDartDefines : FlutterOptions.kDartDefinesOption] as List<String>).join(',');
|
||||
if (argResults.wasParsed(FlutterOptions.kDartDefinesOption)) {
|
||||
results[kDartDefines] = (argResults[FlutterOptions.kDartDefinesOption] as List<String>).join(',');
|
||||
}
|
||||
results[kDeferredComponents] = 'false';
|
||||
if (FlutterProject.current().manifest.deferredComponents != null && isDeferredComponentsTargets() && !isDebug()) {
|
||||
results[kDeferredComponents] = 'true';
|
||||
}
|
||||
if (argResults.wasParsed(useLegacyNames ? kExtraFrontEndOptions : FlutterOptions.kExtraFrontEndOptions)) {
|
||||
results[kExtraFrontEndOptions] = (argResults[useLegacyNames ? kExtraFrontEndOptions : FlutterOptions.kExtraFrontEndOptions] as List<String>).join(',');
|
||||
if (argResults.wasParsed(FlutterOptions.kExtraFrontEndOptions)) {
|
||||
results[kExtraFrontEndOptions] = (argResults[FlutterOptions.kExtraFrontEndOptions] as List<String>).join(',');
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ import '../vmservice.dart';
|
||||
/// With an application already running, a HotRunner can be attached to it
|
||||
/// with:
|
||||
/// ```
|
||||
/// $ flutter attach --debug-uri http://127.0.0.1:12345/QqL7EFEDNG0=/
|
||||
/// $ flutter attach --debug-url http://127.0.0.1:12345/QqL7EFEDNG0=/
|
||||
/// ```
|
||||
///
|
||||
/// If `--disable-service-auth-codes` was provided to the application at startup
|
||||
@ -77,9 +77,10 @@ class AttachCommand extends FlutterCommand {
|
||||
help: '(deprecated) Device port where the observatory is listening. Requires '
|
||||
'"--disable-service-auth-codes" to also be provided to the Flutter '
|
||||
'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-url" should be used instead.',
|
||||
)..addOption(
|
||||
'debug-uri', // TODO(ianh): we should support --debug-url as well (leaving this as an alias).
|
||||
'debug-url',
|
||||
aliases: <String>[ 'debug-uri' ], // supported for historical reasons
|
||||
help: 'The URL at which the observatory is listening.',
|
||||
)..addOption(
|
||||
'app-id',
|
||||
@ -153,15 +154,15 @@ known, it can be explicitly provided to attach via the command-line, e.g.
|
||||
}
|
||||
|
||||
Uri get debugUri {
|
||||
if (argResults['debug-uri'] == null) {
|
||||
if (argResults['debug-url'] == null) {
|
||||
return null;
|
||||
}
|
||||
final Uri uri = Uri.tryParse(stringArg('debug-uri'));
|
||||
final Uri uri = Uri.tryParse(stringArg('debug-url'));
|
||||
if (uri == null) {
|
||||
throwToolExit('Invalid `--debug-uri`: ${stringArg('debug-uri')}');
|
||||
throwToolExit('Invalid `--debug-url`: ${stringArg('debug-url')}');
|
||||
}
|
||||
if (!uri.hasPort) {
|
||||
throwToolExit('Port not specified for `--debug-uri`: $uri');
|
||||
throwToolExit('Port not specified for `--debug-url`: $uri');
|
||||
}
|
||||
return uri;
|
||||
}
|
||||
@ -181,13 +182,13 @@ known, it can be explicitly provided to attach via the command-line, e.g.
|
||||
debugPort;
|
||||
if (debugPort == null && debugUri == null && argResults.wasParsed(FlutterCommand.ipv6Flag)) {
|
||||
throwToolExit(
|
||||
'When the --debug-port or --debug-uri is unknown, this command determines '
|
||||
'When the --debug-port or --debug-url is unknown, this command determines '
|
||||
'the value of --ipv6 on its own.',
|
||||
);
|
||||
}
|
||||
if (debugPort == null && debugUri == null && argResults.wasParsed(FlutterCommand.observatoryPortOption)) {
|
||||
throwToolExit(
|
||||
'When the --debug-port or --debug-uri is unknown, this command does not use '
|
||||
'When the --debug-port or --debug-url is unknown, this command does not use '
|
||||
'the value of --observatory-port.',
|
||||
);
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ import '../vmservice.dart';
|
||||
|
||||
const String _kOut = 'out';
|
||||
const String _kType = 'type';
|
||||
const String _kObservatoryUri = 'observatory-uri'; // TODO(ianh): change this to "observatory-url" (but support -uri as an alias)
|
||||
const String _kObservatoryUrl = 'observatory-url';
|
||||
const String _kDeviceType = 'device';
|
||||
const String _kSkiaType = 'skia';
|
||||
const String _kRasterizerType = 'rasterizer';
|
||||
@ -30,7 +30,8 @@ class ScreenshotCommand extends FlutterCommand {
|
||||
help: 'Location to write the screenshot.',
|
||||
);
|
||||
argParser.addOption(
|
||||
_kObservatoryUri,
|
||||
_kObservatoryUrl,
|
||||
aliases: <String>[ 'observatory-url' ], // for historical reasons
|
||||
valueHelp: 'URI',
|
||||
help: 'The Observatory URL to which to connect.\n'
|
||||
'This is required when "--$_kType" is "$_kSkiaType" or "$_kRasterizerType".\n'
|
||||
@ -46,8 +47,8 @@ class ScreenshotCommand extends FlutterCommand {
|
||||
_kDeviceType: 'Delegate to the device\'s native screenshot capabilities. This '
|
||||
'screenshots the entire screen currently being displayed (including content '
|
||||
'not rendered by Flutter, like the device status bar).',
|
||||
_kSkiaType: 'Render the Flutter app as a Skia picture. Requires "--$_kObservatoryUri".',
|
||||
_kRasterizerType: 'Render the Flutter app using the rasterizer. Requires "--$_kObservatoryUri."',
|
||||
_kSkiaType: 'Render the Flutter app as a Skia picture. Requires "--$_kObservatoryUrl".',
|
||||
_kRasterizerType: 'Render the Flutter app using the rasterizer. Requires "--$_kObservatoryUrl."',
|
||||
},
|
||||
defaultsTo: _kDeviceType,
|
||||
);
|
||||
@ -65,10 +66,10 @@ class ScreenshotCommand extends FlutterCommand {
|
||||
|
||||
Device device;
|
||||
|
||||
Future<void> _validateOptions(String screenshotType, String observatoryUri) async {
|
||||
Future<void> _validateOptions(String screenshotType, String observatoryUrl) async {
|
||||
switch (screenshotType) {
|
||||
case _kDeviceType:
|
||||
if (observatoryUri != null) {
|
||||
if (observatoryUrl != null) {
|
||||
throwToolExit('Observatory URI cannot be provided for screenshot type $screenshotType');
|
||||
}
|
||||
device = await findTargetDevice();
|
||||
@ -80,18 +81,18 @@ class ScreenshotCommand extends FlutterCommand {
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (observatoryUri == null) {
|
||||
if (observatoryUrl == null) {
|
||||
throwToolExit('Observatory URI must be specified for screenshot type $screenshotType');
|
||||
}
|
||||
if (observatoryUri.isEmpty || Uri.tryParse(observatoryUri) == null) {
|
||||
throwToolExit('Observatory URI "$observatoryUri" is invalid');
|
||||
if (observatoryUrl.isEmpty || Uri.tryParse(observatoryUrl) == null) {
|
||||
throwToolExit('Observatory URI "$observatoryUrl" is invalid');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<FlutterCommandResult> verifyThenRunCommand(String commandPath) async {
|
||||
await _validateOptions(stringArg(_kType), stringArg(_kObservatoryUri));
|
||||
await _validateOptions(stringArg(_kType), stringArg(_kObservatoryUrl));
|
||||
return super.verifyThenRunCommand(commandPath);
|
||||
}
|
||||
|
||||
@ -134,8 +135,8 @@ class ScreenshotCommand extends FlutterCommand {
|
||||
}
|
||||
|
||||
Future<bool> runSkia(File outputFile) async {
|
||||
final Uri observatoryUri = Uri.parse(stringArg(_kObservatoryUri));
|
||||
final FlutterVmService vmService = await connectToVmService(observatoryUri, logger: globals.logger);
|
||||
final Uri observatoryUrl = Uri.parse(stringArg(_kObservatoryUrl));
|
||||
final FlutterVmService vmService = await connectToVmService(observatoryUrl, logger: globals.logger);
|
||||
final vm_service.Response skp = await vmService.screenshotSkp();
|
||||
if (skp == null) {
|
||||
globals.printError(
|
||||
@ -158,8 +159,8 @@ class ScreenshotCommand extends FlutterCommand {
|
||||
}
|
||||
|
||||
Future<bool> runRasterizer(File outputFile) async {
|
||||
final Uri observatoryUri = Uri.parse(stringArg(_kObservatoryUri));
|
||||
final FlutterVmService vmService = await connectToVmService(observatoryUri, logger: globals.logger);
|
||||
final Uri observatoryUrl = Uri.parse(stringArg(_kObservatoryUrl));
|
||||
final FlutterVmService vmService = await connectToVmService(observatoryUrl, logger: globals.logger);
|
||||
final vm_service.Response response = await vmService.screenshot();
|
||||
if (response == null) {
|
||||
globals.printError(
|
||||
|
@ -18,7 +18,7 @@ import '../base/user_messages.dart';
|
||||
import '../base/utils.dart';
|
||||
import '../build_info.dart';
|
||||
import '../build_system/build_system.dart';
|
||||
import '../build_system/targets/common.dart' show kExtraFrontEndOptions, kExtraGenSnapshotOptions; // for "useLegacyNames" only
|
||||
import '../build_system/targets/common.dart' show kExtraFrontEndOptions, kExtraGenSnapshotOptions; // for deprecated option name aliases only
|
||||
import '../bundle.dart' as bundle;
|
||||
import '../cache.dart';
|
||||
import '../dart/generate_synthetic_packages.dart';
|
||||
@ -527,9 +527,10 @@ abstract class FlutterCommand extends Command<void> {
|
||||
valueHelp: 'x.y.z');
|
||||
}
|
||||
|
||||
void usesDartDefineOption({ bool useLegacyNames = false }) {
|
||||
void usesDartDefineOption() {
|
||||
argParser.addMultiOption(
|
||||
useLegacyNames ? kDartDefines : FlutterOptions.kDartDefinesOption,
|
||||
FlutterOptions.kDartDefinesOption,
|
||||
aliases: <String>[ kDartDefines ], // supported for historical reasons
|
||||
help: 'Additional key-value pairs that will be available as constants '
|
||||
'from the String.fromEnvironment, bool.fromEnvironment, int.fromEnvironment, '
|
||||
'and double.fromEnvironment constructors.\n'
|
||||
@ -700,15 +701,17 @@ 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, bool useLegacyNames = false }) {
|
||||
argParser.addMultiOption(useLegacyNames ? kExtraFrontEndOptions : FlutterOptions.kExtraFrontEndOptions,
|
||||
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(useLegacyNames ? kExtraGenSnapshotOptions : FlutterOptions.kExtraGenSnapshotOptions,
|
||||
argParser.addMultiOption(FlutterOptions.kExtraGenSnapshotOptions,
|
||||
aliases: <String>[ kExtraGenSnapshotOptions ], // supported for historical reasons
|
||||
help: 'A comma-separated list of additional command line arguments that will be passed directly to the Dart native compiler. '
|
||||
'(Only used in "--profile" or "--release" builds.) '
|
||||
'For example, "--${FlutterOptions.kExtraGenSnapshotOptions}=--no-strip".',
|
||||
|
@ -254,7 +254,7 @@ void main() {
|
||||
await expectLater(
|
||||
createTestCommandRunner(command).run(<String>['attach', '--ipv6']),
|
||||
throwsToolExit(
|
||||
message: 'When the --debug-port or --debug-uri is unknown, this command determines '
|
||||
message: 'When the --debug-port or --debug-url is unknown, this command determines '
|
||||
'the value of --ipv6 on its own.',
|
||||
),
|
||||
);
|
||||
@ -277,7 +277,7 @@ void main() {
|
||||
await expectLater(
|
||||
createTestCommandRunner(command).run(<String>['attach', '--observatory-port', '100']),
|
||||
throwsToolExit(
|
||||
message: 'When the --debug-port or --debug-uri is unknown, this command does not use '
|
||||
message: 'When the --debug-port or --debug-url is unknown, this command does not use '
|
||||
'the value of --observatory-port.',
|
||||
),
|
||||
);
|
||||
|
@ -29,12 +29,12 @@ void main() {
|
||||
};
|
||||
|
||||
await expectLater(() => createTestCommandRunner(ScreenshotCommand())
|
||||
.run(<String>['screenshot', '--type=skia', '--observatory-uri=http://localhost:8181']),
|
||||
.run(<String>['screenshot', '--type=skia', '--observatory-url=http://localhost:8181']),
|
||||
throwsA(isA<Exception>().having((dynamic exception) => exception.toString(), 'message', contains('dummy'))),
|
||||
);
|
||||
|
||||
await expectLater(() => createTestCommandRunner(ScreenshotCommand())
|
||||
.run(<String>['screenshot', '--type=rasterizer', '--observatory-uri=http://localhost:8181']),
|
||||
.run(<String>['screenshot', '--type=rasterizer', '--observatory-url=http://localhost:8181']),
|
||||
throwsA(isA<Exception>().having((dynamic exception) => exception.toString(), 'message', contains('dummy'))),
|
||||
);
|
||||
});
|
||||
@ -61,7 +61,7 @@ void main() {
|
||||
|
||||
testUsingContext('device screenshots cannot provided Observatory', () async {
|
||||
await expectLater(() => createTestCommandRunner(ScreenshotCommand())
|
||||
.run(<String>['screenshot', '--observatory-uri=http://localhost:8181']),
|
||||
.run(<String>['screenshot', '--observatory-url=http://localhost:8181']),
|
||||
throwsToolExit(message: 'Observatory URI cannot be provided for screenshot type device'),
|
||||
);
|
||||
});
|
||||
|
@ -27,22 +27,20 @@ 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);
|
||||
verifyOptions(null, 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);
|
||||
verifyOptions(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)$');
|
||||
final RegExp _allowedArgumentNamePattern = RegExp(r'^([-a-z0-9]+)$');
|
||||
final RegExp _allowedArgumentNamePatternForPrecache = RegExp(r'^([-a-z0-9_]+)$');
|
||||
final RegExp _bannedArgumentNamePattern = RegExp(r'-uri$');
|
||||
|
||||
// Patterns for help messages.
|
||||
final RegExp _bannedLeadingPatterns = RegExp(r'^[-a-z]', multiLine: true);
|
||||
@ -50,6 +48,7 @@ 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]');
|
||||
final RegExp _bannedUri = RegExp(r'\b[Uu][Rr][Ii]\b');
|
||||
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 '
|
||||
@ -59,34 +58,45 @@ const String _needHelp = 'Every option must have help explaining what it does, e
|
||||
const String _header = ' Comment: ';
|
||||
|
||||
void verifyOptions(String command, Iterable<Option> options) {
|
||||
assert(command.contains('"'));
|
||||
String target;
|
||||
if (command == null) {
|
||||
target = 'the global argument "';
|
||||
} else {
|
||||
target = '"flutter $command ';
|
||||
}
|
||||
assert(target.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).');
|
||||
if (command == 'precache') {
|
||||
expect(option.name, matches(_allowedArgumentNamePatternForPrecache), reason: '$_header$target--${option.name}" is not a valid name for a command line argument. (Is it all lowercase?)');
|
||||
} else {
|
||||
expect(option.name, matches(_allowedArgumentNamePattern), reason: '$_header$target--${option.name}" is not a valid name for a command line argument. (Is it all lowercase? Does it use hyphens rather than underscores?)');
|
||||
}
|
||||
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".');
|
||||
expect(option.name, isNot(matches(_bannedArgumentNamePattern)), reason: '$_header$target--${option.name}" is not a valid name for a command line argument. (We use "--foo-url", not "--foo-uri", for example.)');
|
||||
expect(option.hide, isFalse, reason: '${_header}Help for $target--${option.name}" is always hidden. $_needHelp');
|
||||
expect(option.help, isNotNull, reason: '${_header}Help for $target--${option.name}" has null help. $_needHelp');
|
||||
expect(option.help, isNotEmpty, reason: '${_header}Help for $target--${option.name}" has empty help. $_needHelp');
|
||||
expect(option.help, isNot(matches(_bannedLeadingPatterns)), reason: '${_header}A line in the help for $target--${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 $target--${option.name}" should start with lowercase "(deprecated)" for consistency with other deprecated commands.');
|
||||
expect(option.help, isNot(startsWith('(Required')), reason: '${_header}Help for $target--${option.name}" should start with lowercase "(required)" for consistency with other deprecated commands.');
|
||||
expect(option.help, isNot(contains('?')), reason: '${_header}Help for $target--${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 $target--${option.name}" uses "Note:". See our style guide entry about "empty prose".');
|
||||
expect(option.help, isNot(contains('Note that')), reason: '${_header}Help for $target--${option.name}" uses "Note that". See our style guide entry about "empty prose".');
|
||||
expect(option.help, isNot(matches(_bannedQuotePatterns)), reason: '${_header}Help for $target--${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 $target--${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 $target--${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 $target--${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(line, isNot(contains(' ')), reason: '${_header}Help for $target--${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 $target--${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.');
|
||||
expect(option.help, isNot(endsWith(':')), reason: '${_header}Help for $target--${option.name}" ends with a colon, which seems unlikely to be correct.');
|
||||
expect(option.help, isNot(contains(_bannedUri)), reason: '${_header}Help for $target--${option.name}" uses the term "URI" rather than "URL".');
|
||||
// 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".
|
||||
}
|
||||
}
|
||||
|
@ -152,7 +152,8 @@ void main() {
|
||||
expect(versionInfo, containsPair('flutterRoot', isNotNull));
|
||||
});
|
||||
|
||||
testWithoutContext('A tool exit is thrown for an invalid debug-uri in flutter attach', () async {
|
||||
testWithoutContext('A tool exit is thrown for an invalid debug-url in flutter attach', () async {
|
||||
// This test is almost exactly like the next one; update them together please.
|
||||
final String flutterBin = fileSystem.path.join(getFlutterRoot(), 'bin', 'flutter');
|
||||
final String helloWorld = fileSystem.path.join(getFlutterRoot(), 'examples', 'hello_world');
|
||||
final ProcessResult result = await processManager.run(<String>[
|
||||
@ -162,11 +163,29 @@ void main() {
|
||||
'attach',
|
||||
'-d',
|
||||
'flutter-tester',
|
||||
'--debug-uri=http://127.0.0.1:3333*/',
|
||||
'--debug-url=http://127.0.0.1:3333*/',
|
||||
], workingDirectory: helloWorld);
|
||||
|
||||
expect(result.exitCode, 1);
|
||||
expect(result.stderr, contains('Invalid `--debug-uri`: http://127.0.0.1:3333*/'));
|
||||
expect(result.stderr, contains('Invalid `--debug-url`: http://127.0.0.1:3333*/'));
|
||||
});
|
||||
|
||||
testWithoutContext('--debug-uri is an alias for --debug-url', () async {
|
||||
// This text is exactly the same as the previous one but with a "l" turned to an "i".
|
||||
final String flutterBin = fileSystem.path.join(getFlutterRoot(), 'bin', 'flutter');
|
||||
final String helloWorld = fileSystem.path.join(getFlutterRoot(), 'examples', 'hello_world');
|
||||
final ProcessResult result = await processManager.run(<String>[
|
||||
flutterBin,
|
||||
...getLocalEngineArguments(),
|
||||
'--show-test-device',
|
||||
'attach',
|
||||
'-d',
|
||||
'flutter-tester',
|
||||
'--debug-uri=http://127.0.0.1:3333*/', // "uri" not "url"
|
||||
], workingDirectory: helloWorld);
|
||||
|
||||
expect(result.exitCode, 1);
|
||||
expect(result.stderr, contains('Invalid `--debug-url`: http://127.0.0.1:3333*/')); // _"url"_ not "uri"!
|
||||
});
|
||||
|
||||
testWithoutContext('will load bootstrap script before starting', () async {
|
||||
|
Loading…
x
Reference in New Issue
Block a user