diff --git a/README.md b/README.md index 358f6d15afae..da50c1f5337a 100644 --- a/README.md +++ b/README.md @@ -52,21 +52,21 @@ These are the packages hosted in this repository: | [go\_router\_builder](./packages/go_router_builder/) | [![pub package](https://img.shields.io/pub/v/go_router_builder.svg)](https://pub.dev/packages/go_router_builder) | [![pub points](https://img.shields.io/pub/points/go_router_builder)](https://pub.dev/packages/go_router_builder/score) | [![downloads](https://img.shields.io/pub/dm/go_router_builder)](https://pub.dev/packages/go_router_builder/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20go_router_builder?label=)](https://github.com/flutter/flutter/labels/p%3A%20go_router_builder) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20go_router_builder?label=)](https://github.com/flutter/packages/labels/p%3A%20go_router_builder) | | [google\_adsense](./packages/google_adsense/)| [![pub package](https://img.shields.io/pub/v/google_adsense.svg)](https://pub.dev/packages/google_adsense) | [![pub points](https://img.shields.io/pub/points/google_adsense)](https://pub.dev/packages/google_adsense/score) | [![downloads](https://img.shields.io/pub/dm/google_adsense)](https://pub.dev/packages/google_adsense/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20google_adsense?label=)](https://github.com/flutter/flutter/labels/p%3A%20google_adsense) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20google_adsense?label=)](https://github.com/flutter/packages/labels/p%3A%20google_adsense) | | [google\_fonts](./packages/google_fonts/) | [![pub package](https://img.shields.io/pub/v/google_fonts.svg)](https://pub.dev/packages/google_fonts) | [![pub points](https://img.shields.io/pub/points/google_fonts)](https://pub.dev/packages/google_fonts/score) | [![downloads](https://img.shields.io/pub/dm/google_fonts)](https://pub.dev/packages/google_fonts/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20google_fonts?label=)](https://github.com/flutter/flutter/labels/p%3A%20google_fonts) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20google_fonts?label=)](https://github.com/flutter/packages/labels/p%3A%20google_fonts) | +| [google\_identity\_services\_web](./packages/google_identity_services_web/) | [![pub package](https://img.shields.io/pub/v/google_identity_services_web.svg)](https://pub.dev/packages/google_identity_services_web) | [![pub points](https://img.shields.io/pub/points/google_identity_services_web)](https://pub.dev/packages/google_identity_services_web/score) | [![downloads](https://img.shields.io/pub/dm/google_identity_services_web)](https://pub.dev/packages/google_identity_services_web/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20google_identity_services_web?label=)](https://github.com/flutter/flutter/labels/p%3A%20google_identity_services_web) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20google_identity_services_web?label=)](https://github.com/flutter/packages/labels/p%3A%20google_identity_services_web) | | [google\_maps\_flutter](./packages/google_maps_flutter/) | [![pub package](https://img.shields.io/pub/v/google_maps_flutter.svg)](https://pub.dev/packages/google_maps_flutter) | [![pub points](https://img.shields.io/pub/points/google_maps_flutter)](https://pub.dev/packages/google_maps_flutter/score) | [![downloads](https://img.shields.io/pub/dm/google_maps_flutter)](https://pub.dev/packages/google_maps_flutter/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20maps?label=)](https://github.com/flutter/flutter/labels/p%3A%20maps) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20google_maps_flutter?label=)](https://github.com/flutter/packages/labels/p%3A%20google_maps_flutter) | | [google\_sign\_in](./packages/google_sign_in/) | [![pub package](https://img.shields.io/pub/v/google_sign_in.svg)](https://pub.dev/packages/google_sign_in) | [![pub points](https://img.shields.io/pub/points/google_sign_in)](https://pub.dev/packages/google_sign_in/score) | [![downloads](https://img.shields.io/pub/dm/google_sign_in)](https://pub.dev/packages/google_sign_in/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20google_sign_in?label=)](https://github.com/flutter/flutter/labels/p%3A%20google_sign_in) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20google_sign_in?label=)](https://github.com/flutter/packages/labels/p%3A%20google_sign_in) | | [image\_picker](./packages/image_picker/) | [![pub package](https://img.shields.io/pub/v/image_picker.svg)](https://pub.dev/packages/image_picker) | [![pub points](https://img.shields.io/pub/points/image_picker)](https://pub.dev/packages/image_picker/score) | [![downloads](https://img.shields.io/pub/dm/image_picker)](https://pub.dev/packages/image_picker/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20image_picker?label=)](https://github.com/flutter/flutter/labels/p%3A%20image_picker) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20image_picker?label=)](https://github.com/flutter/packages/labels/p%3A%20image_picker) | -| [interactive\_media\_ads](./packages/interactive_media_ads/) | [![pub package](https://img.shields.io/pub/v/interactive_media_ads.svg)](https://pub.dev/packages/interactive_media_ads) | [![pub points](https://img.shields.io/pub/points/interactive_media_ads)](https://pub.dev/packages/interactive_media_ads/score) | [![downloads](https://img.shields.io/pub/dm/interactive_media_ads)](https://pub.dev/packages/interactive_media_ads/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20interactive_media_ads?label=)](https://github.com/flutter/flutter/labels/p%3A%20interactive_media_ads) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20interactive_media_ads?label=)](https://github.com/flutter/packages/labels/p%3A%20interactive_media_ads) | | [in\_app\_purchase](./packages/in_app_purchase/) | [![pub package](https://img.shields.io/pub/v/in_app_purchase.svg)](https://pub.dev/packages/in_app_purchase) | [![pub points](https://img.shields.io/pub/points/in_app_purchase)](https://pub.dev/packages/in_app_purchase/score) | [![downloads](https://img.shields.io/pub/dm/in_app_purchase)](https://pub.dev/packages/in_app_purchase/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20in_app_purchase?label=)](https://github.com/flutter/flutter/labels/p%3A%20in_app_purchase) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20in_app_purchase?label=)](https://github.com/flutter/packages/labels/p%3A%20in_app_purchase) | +| [interactive\_media\_ads](./packages/interactive_media_ads/) | [![pub package](https://img.shields.io/pub/v/interactive_media_ads.svg)](https://pub.dev/packages/interactive_media_ads) | [![pub points](https://img.shields.io/pub/points/interactive_media_ads)](https://pub.dev/packages/interactive_media_ads/score) | [![downloads](https://img.shields.io/pub/dm/interactive_media_ads)](https://pub.dev/packages/interactive_media_ads/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20interactive_media_ads?label=)](https://github.com/flutter/flutter/labels/p%3A%20interactive_media_ads) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20interactive_media_ads?label=)](https://github.com/flutter/packages/labels/p%3A%20interactive_media_ads) | | [local\_auth](./packages/local_auth/) | [![pub package](https://img.shields.io/pub/v/local_auth.svg)](https://pub.dev/packages/local_auth) | [![pub points](https://img.shields.io/pub/points/local_auth)](https://pub.dev/packages/local_auth/score) | [![downloads](https://img.shields.io/pub/dm/local_auth)](https://pub.dev/packages/local_auth/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20local_auth?label=)](https://github.com/flutter/flutter/labels/p%3A%20local_auth) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20local_auth?label=)](https://github.com/flutter/packages/labels/p%3A%20local_auth) | | [material\_ui](./packages/material_ui/) | [![pub package](https://img.shields.io/pub/v/material_ui.svg)](https://pub.dev/packages/material_ui) | [![pub points](https://img.shields.io/pub/points/material_ui)](https://pub.dev/packages/material_ui/score) | [![downloads](https://img.shields.io/pub/dm/material_ui)](https://pub.dev/packages/material_ui/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20material_ui?label=)](https://github.com/flutter/flutter/labels/p%3A%20material_ui) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20material_ui?label=)](https://github.com/flutter/packages/labels/p%3A%20material_ui) | | [metrics\_center](./packages/metrics_center/) | [![pub package](https://img.shields.io/pub/v/metrics_center.svg)](https://pub.dev/packages/metrics_center) | [![pub points](https://img.shields.io/pub/points/metrics_center)](https://pub.dev/packages/metrics_center/score) | [![downloads](https://img.shields.io/pub/dm/metrics_center)](https://pub.dev/packages/metrics_center/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20metrics_center?label=)](https://github.com/flutter/flutter/labels/p%3A%20metrics_center) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20metrics_center?label=)](https://github.com/flutter/packages/labels/p%3A%20metrics_center) | | [path\_parsing](./third_party/packages/path_parsing/) | [![pub package](https://img.shields.io/pub/v/path_parsing.svg)](https://pub.dev/packages/path_parsing) | [![pub points](https://img.shields.io/pub/points/path_parsing)](https://pub.dev/packages/path_parsing/score) | [![downloads](https://img.shields.io/pub/dm/path_parsing)](https://pub.dev/packages/path_parsing/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20path_parsing?label=)](https://github.com/flutter/flutter/labels/p%3A%20path_parsing) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20path_parsing?label=)](https://github.com/flutter/packages/labels/p%3A%20path_parsing) | | [path\_provider](./packages/path_provider/) | [![pub package](https://img.shields.io/pub/v/path_provider.svg)](https://pub.dev/packages/path_provider) | [![pub points](https://img.shields.io/pub/points/path_provider)](https://pub.dev/packages/path_provider/score) | [![downloads](https://img.shields.io/pub/dm/path_provider)](https://pub.dev/packages/path_provider/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20path_provider?label=)](https://github.com/flutter/flutter/labels/p%3A%20path_provider) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20path_provider?label=)](https://github.com/flutter/packages/labels/p%3A%20path_provider) | | [pigeon](./packages/pigeon/) | [![pub package](https://img.shields.io/pub/v/pigeon.svg)](https://pub.dev/packages/pigeon) | [![pub points](https://img.shields.io/pub/points/pigeon)](https://pub.dev/packages/pigeon/score) | [![downloads](https://img.shields.io/pub/dm/pigeon)](https://pub.dev/packages/pigeon/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20pigeon?label=)](https://github.com/flutter/flutter/labels/p%3A%20pigeon) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20pigeon?label=)](https://github.com/flutter/packages/labels/p%3A%20pigeon) | -| [pointer\_interceptor](./packages/pointer_interceptor/) | [![pub package](https://img.shields.io/pub/v/pointer_interceptor.svg)](https://pub.dev/packages/pointer_interceptor) | [![pub points](https://img.shields.io/pub/points/pointer_interceptor)](https://pub.dev/packages/pointer_interceptor/score) | [![downloads](https://img.shields.io/pub/dm/pointer_interceptor)](https://pub.dev/packages/pointer_interceptor/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20pointer_interceptor?label=)](https://github.com/flutter/flutter/labels/p%3A%20pointer_interceptor) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20pointer_interceptor?label=)](https://github.com/flutter/packages/labels/p%3A%20pointer_interceptor) | | [plugin\_platform\_interface](./packages/plugin_platform_interface/) | [![pub package](https://img.shields.io/pub/v/plugin_platform_interface.svg)](https://pub.dev/packages/plugin_platform_interface) | [![pub points](https://img.shields.io/pub/points/plugin_platform_interface)](https://pub.dev/packages/plugin_platform_interface/score) | [![downloads](https://img.shields.io/pub/dm/plugin_platform_interface)](https://pub.dev/packages/plugin_platform_interface/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20plugin_platform_interface?label=)](https://github.com/flutter/flutter/labels/p%3A%20plugin_platform_interface) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20plugin_platform_interface?label=)](https://github.com/flutter/packages/labels/p%3A%20plugin_platform_interface) | +| [pointer\_interceptor](./packages/pointer_interceptor/) | [![pub package](https://img.shields.io/pub/v/pointer_interceptor.svg)](https://pub.dev/packages/pointer_interceptor) | [![pub points](https://img.shields.io/pub/points/pointer_interceptor)](https://pub.dev/packages/pointer_interceptor/score) | [![downloads](https://img.shields.io/pub/dm/pointer_interceptor)](https://pub.dev/packages/pointer_interceptor/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20pointer_interceptor?label=)](https://github.com/flutter/flutter/labels/p%3A%20pointer_interceptor) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20pointer_interceptor?label=)](https://github.com/flutter/packages/labels/p%3A%20pointer_interceptor) | | [quick\_actions](./packages/quick_actions/) | [![pub package](https://img.shields.io/pub/v/quick_actions.svg)](https://pub.dev/packages/quick_actions) | [![pub points](https://img.shields.io/pub/points/quick_actions)](https://pub.dev/packages/quick_actions/score) | [![downloads](https://img.shields.io/pub/dm/quick_actions)](https://pub.dev/packages/quick_actions/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20quick_actions?label=)](https://github.com/flutter/flutter/labels/p%3A%20quick_actions) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20quick_actions?label=)](https://github.com/flutter/packages/labels/p%3A%20quick_actions) | -| [google\_identity\_services\_web](./packages/google_identity_services_web/) | [![pub package](https://img.shields.io/pub/v/google_identity_services_web.svg)](https://pub.dev/packages/google_identity_services_web) | [![pub points](https://img.shields.io/pub/points/google_identity_services_web)](https://pub.dev/packages/google_identity_services_web/score) | [![downloads](https://img.shields.io/pub/dm/google_identity_services_web)](https://pub.dev/packages/google_identity_services_web/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20google_identity_services_web?label=)](https://github.com/flutter/flutter/labels/p%3A%20google_identity_services_web) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20google_identity_services_web?label=)](https://github.com/flutter/packages/labels/p%3A%20google_identity_services_web) | | [rfw](./packages/rfw/) | [![pub package](https://img.shields.io/pub/v/rfw.svg)](https://pub.dev/packages/rfw) | [![pub points](https://img.shields.io/pub/points/rfw)](https://pub.dev/packages/rfw/score) | [![downloads](https://img.shields.io/pub/dm/rfw)](https://pub.dev/packages/rfw/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20rfw?label=)](https://github.com/flutter/flutter/labels/p%3A%20rfw) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20rfw?label=)](https://github.com/flutter/packages/labels/p%3A%20rfw) | | [shared\_preferences](./packages/shared_preferences/) | [![pub package](https://img.shields.io/pub/v/shared_preferences.svg)](https://pub.dev/packages/shared_preferences) | [![pub points](https://img.shields.io/pub/points/shared_preferences)](https://pub.dev/packages/shared_preferences/score) | [![downloads](https://img.shields.io/pub/dm/shared_preferences)](https://pub.dev/packages/shared_preferences/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20shared_preferences?label=)](https://github.com/flutter/flutter/labels/p%3A%20shared_preferences) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20shared_preferences?label=)](https://github.com/flutter/packages/labels/p%3A%20shared_preferences) | | [two\_dimensional\_scrollables](./packages/two_dimensional_scrollables/) | [![pub package](https://img.shields.io/pub/v/two_dimensional_scrollables.svg)](https://pub.dev/packages/two_dimensional_scrollables) | [![pub points](https://img.shields.io/pub/points/two_dimensional_scrollables)](https://pub.dev/packages/two_dimensional_scrollables/score) | [![downloads](https://img.shields.io/pub/dm/two_dimensional_scrollables)](https://pub.dev/packages/two_dimensional_scrollables/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20two_dimensional_scrollables?label=)](https://github.com/flutter/flutter/labels/p%3A%20two_dimensional_scrollables) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20two_dimensional_scrollables?label=)](https://github.com/flutter/packages/labels/p%3A%20two_dimensional_scrollables) | diff --git a/script/tool/CHANGELOG.md b/script/tool/CHANGELOG.md index 82ddb260f8fe..2697ab3b0071 100644 --- a/script/tool/CHANGELOG.md +++ b/script/tool/CHANGELOG.md @@ -1,5 +1,6 @@ ## NEXT +* Adds validation that the root README package table is sorted alphabetically. * Adds support for batch release of pre-1.0 packages. ## 0.14.4 diff --git a/script/tool/lib/src/validators/repo_info_validator.dart b/script/tool/lib/src/validators/repo_info_validator.dart index b31f54d54170..09906476ac4a 100644 --- a/script/tool/lib/src/validators/repo_info_validator.dart +++ b/script/tool/lib/src/validators/repo_info_validator.dart @@ -13,6 +13,7 @@ import '../common/tool_config.dart'; const int _exitBadTableEntry = 3; const int _exitUnknownPackageEntry = 4; +const int _exitUnsortedTable = 5; /// Validates that a package has all of the expected repository-level entries. class RepoInfoValidator { @@ -45,6 +46,7 @@ class RepoInfoValidator { }) { final entries = >{}; final namePattern = RegExp(r'\[(.*?)\]\('); + String? previousName; for (final String line in repoRoot.childFile('README.md').readAsLinesSync()) { // Find all the table entries, skipping the header. if (line.startsWith('|') && !line.startsWith('| Package') && !line.startsWith('|-')) { @@ -59,13 +61,20 @@ class RepoInfoValidator { printError('Unexpected README table line:\n $line'); throw ToolExit(_exitBadTableEntry); } - entries[name] = cells; - if (!(packagesDir.childDirectory(name).existsSync() || thirdPartyPackagesDir.childDirectory(name).existsSync())) { printError('Unknown package "$name" in root README.md table.'); throw ToolExit(_exitUnknownPackageEntry); } + if (previousName != null && name.compareTo(previousName) < 0) { + printError( + 'README package table is not sorted alphabetically: ' + '"$name" must appear before "$previousName".', + ); + throw ToolExit(_exitUnsortedTable); + } + previousName = name; + entries[name] = cells; } } return entries; diff --git a/script/tool/test/validate_command_repo_info_test.dart b/script/tool/test/validate_command_repo_info_test.dart index bcb59f03b94c..780ac5d1ae8e 100644 --- a/script/tool/test/validate_command_repo_info_test.dart +++ b/script/tool/test/validate_command_repo_info_test.dart @@ -94,6 +94,38 @@ ${readmeTableEntry('a_package')} expect(output, containsAllInOrder([contains('Running for a_package')])); }); + test('fails when README table entries are not sorted', () async { + final packages = [ + createFakePackage('a_package', packagesDir), + createFakePackage('b_package', packagesDir), + ]; + + root.childFile('README.md').writeAsStringSync(''' +${readmeTableHeader()} +${readmeTableEntry('b_package')} +${readmeTableEntry('a_package')} +'''); + writeAutoLabelerYaml(packages); + + Error? commandError; + final List output = await runCapturingPrint( + runner, + ['validate'], + errorHandler: (Error e) { + commandError = e; + }, + ); + + expect(commandError, isA()); + expect( + output, + contains( + 'README package table is not sorted alphabetically: ' + '"a_package" must appear before "b_package".', + ), + ); + }); + test('passes for correct coverage with a different repo name', () async { final packages = [createFakePackage('a_package', packagesDir)];