From 885837911fb90e20370e975c6e77c1a3145ab65f Mon Sep 17 00:00:00 2001 From: Pierre-Louis <6655696+guidezpl@users.noreply.github.com> Date: Thu, 9 Dec 2021 09:43:08 +0100 Subject: [PATCH 1/9] Run verifications on all platforms --- .github/workflows/test.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b37d619e38..192ae87e50 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -35,14 +35,8 @@ jobs: # Run custom scripts defined in `tool/grind.dart`. - name: Verify that localizations are up to date run: flutter pub run grinder verify-l10n - # TODO: Enable verify-l10n for Windows when it behaves the same as on macOS/Ubuntu: - # https://github.com/material-components/material-components-flutter-gallery/issues/565 - if: startsWith(matrix.os, 'macOS') || startsWith(matrix.os, 'ubuntu') - name: Verify that code segments are up to date run: flutter pub run grinder verify-code-segments - # TODO: Enable verify-code-segments for Unix and Windows when it behaves the same as on macOS: - # https://github.com/material-components/material-components-flutter-gallery/issues/565 - if: startsWith(matrix.os, 'macOS') benchmark-test: From 2566ec09b43afbc8256e86ce92c7eb7f73244393 Mon Sep 17 00:00:00 2001 From: guidezpl <6655696+guidezpl@users.noreply.github.com> Date: Thu, 9 Dec 2021 13:41:27 +0100 Subject: [PATCH 2/9] xx --- .github/workflows/test.yml | 104 +++++++++++++++++------------------- lib/l10n/intl_en.arb | 16 +++--- lib/l10n/intl_en_US.xml | 16 +++--- test/l10n.dart | 21 ++++++++ tool/grind.dart | 23 -------- tool/l10n_cli/l10n_cli.dart | 47 ++++++++-------- tool/l10n_cli/main.dart | 2 +- 7 files changed, 111 insertions(+), 118 deletions(-) create mode 100644 test/l10n.dart diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 192ae87e50..bd156b36b2 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -2,7 +2,7 @@ name: Tests on: push: branches: - - master + - master pull_request: jobs: @@ -13,73 +13,69 @@ jobs: matrix: os: [ubuntu-18.04, windows-2019, macos-10.15] steps: - # Set up Flutter. - - name: Clone Flutter repository with master channel - uses: subosito/flutter-action@4389e6cbc6cb8a4b18c628ff96ff90be0e926aa8 - with: - channel: master - - run: flutter doctor -v + # Set up Flutter. + - name: Clone Flutter repository with master channel + uses: subosito/flutter-action@4389e6cbc6cb8a4b18c628ff96ff90be0e926aa8 + with: + channel: master + - run: flutter doctor -v - # Checkout gallery code and get packages. - - name: Checkout gallery code - uses: actions/checkout@v2 - - run: flutter pub get + # Checkout gallery code and get packages. + - name: Checkout gallery code + uses: actions/checkout@v2 + - run: flutter pub get - # Analyze, check formatting, and run unit tests. - - run: flutter analyze - - name: Ensure the Dart code is formatted correctly - run: flutter format --set-exit-if-changed --dry-run . - - name: Run Flutter unit tests - run: flutter test - - # Run custom scripts defined in `tool/grind.dart`. - - name: Verify that localizations are up to date - run: flutter pub run grinder verify-l10n - - name: Verify that code segments are up to date - run: flutter pub run grinder verify-code-segments + # Analyze, check formatting, and run unit tests. + - run: flutter analyze + - name: Ensure the Dart code is formatted correctly + run: flutter format --set-exit-if-changed --dry-run . + - name: Run Flutter unit tests + run: flutter test + # Run custom scripts defined in `tool/grind.dart`. + - name: Verify that code segments are up to date + run: flutter pub run grinder verify-code-segments benchmark-test: name: Benchmark tests runs-on: ubuntu-18.04 steps: - # Set up Flutter. - - name: Clone Flutter repository with master channel - uses: subosito/flutter-action@4389e6cbc6cb8a4b18c628ff96ff90be0e926aa8 - with: - channel: master - - run: flutter doctor -v - - run: flutter config --enable-web - - # Checkout gallery code and get packages. - - name: Checkout gallery code - uses: actions/checkout@v2 - - run: flutter pub get + # Set up Flutter. + - name: Clone Flutter repository with master channel + uses: subosito/flutter-action@4389e6cbc6cb8a4b18c628ff96ff90be0e926aa8 + with: + channel: master + - run: flutter doctor -v + - run: flutter config --enable-web - - run: flutter test test_benchmarks + # Checkout gallery code and get packages. + - name: Checkout gallery code + uses: actions/checkout@v2 + - run: flutter pub get + - run: flutter test test_benchmarks golden-test: name: Golden tests runs-on: macos-10.15 steps: - # Set up Flutter. - - name: Clone Flutter repository with master channel - uses: subosito/flutter-action@4389e6cbc6cb8a4b18c628ff96ff90be0e926aa8 - with: - channel: master - - run: flutter doctor -v + # Set up Flutter. + - name: Clone Flutter repository with master channel + uses: subosito/flutter-action@4389e6cbc6cb8a4b18c628ff96ff90be0e926aa8 + with: + channel: master + - run: flutter doctor -v - # Checkout gallery code and get packages. - - name: Checkout gallery code - uses: actions/checkout@v2 - - run: flutter pub get + # Checkout gallery code and get packages. + - name: Checkout gallery code + uses: actions/checkout@v2 + - run: flutter pub get - # Run the golden tests and upload failed test artifacts. - - run: flutter test test_goldens - - name: Upload goldens if tests fail - uses: actions/upload-artifact@v1 - if: failure() - with: - name: goldens - path: test_goldens/failures/ + # Run the golden tests and upload failed test artifacts. + - run: flutter test test_goldens + - name: Upload goldens if tests fail + uses: actions/upload-artifact@v1 + if: failure() + with: + name: goldens + path: test_goldens/failures/ diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index 57b3e8af0c..ebbafb11f2 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -343,7 +343,7 @@ "@rallyLoginButtonLogin": { "description": "Text for login button." }, - "rallyAlertsMessageHeadsUpShopping": "Heads up, you’ve used up {percent} of your Shopping budget for this month.", + "rallyAlertsMessageHeadsUpShopping": "Heads up, you've used up {percent} of your Shopping budget for this month.", "@rallyAlertsMessageHeadsUpShopping": { "description": "Alert message shown when for example, user has used more than 90% of their shopping budget.", "placeholders": { @@ -352,7 +352,7 @@ } } }, - "rallyAlertsMessageSpentOnRestaurants": "You’ve spent {amount} on Restaurants this week.", + "rallyAlertsMessageSpentOnRestaurants": "You've spent {amount} on Restaurants this week.", "@rallyAlertsMessageSpentOnRestaurants": { "description": "Alert message shown when for example, user has spent $120 on Restaurants this week.", "placeholders": { @@ -361,7 +361,7 @@ } } }, - "rallyAlertsMessageATMFees": "You’ve spent {amount} in ATM fees this month", + "rallyAlertsMessageATMFees": "You've spent {amount} in ATM fees this month", "@rallyAlertsMessageATMFees": { "description": "Alert message shown when for example, the user has spent $24 in ATM fees this month.", "placeholders": { @@ -601,7 +601,7 @@ "@demoAppBarSubtitle": { "description": "Subtitle for the material App bar component demo." }, - "demoAppBarDescription": "The App bar provides content and actions related to the current screen. It’s used for branding, screen titles, navigation, and actions", + "demoAppBarDescription": "The App bar provides content and actions related to the current screen. It's used for branding, screen titles, navigation, and actions", "@demoAppBarDescription": { "description": "Description for the material App bar component demo." }, @@ -781,7 +781,7 @@ "@demoDataTableSubtitle": { "description": "Subtitle for the material data table component demo." }, - "demoDataTableDescription": "Data tables display information in a grid-like format of rows and columns. They organize information in a way that’s easy to scan, so that users can look for patterns and insights.", + "demoDataTableDescription": "Data tables display information in a grid-like format of rows and columns. They organize information in a way that's easy to scan, so that users can look for patterns and insights.", "@demoDataTableDescription": { "description": "Description for the material data table component demo." }, @@ -1916,7 +1916,7 @@ "@demoSnackbarsSubtitle": { "description": "Subtitle for snackbars demo." }, - "demoSnackbarsDescription": "Snackbars inform users of a process that an app has performed or will perform. They appear temporarily, towards the bottom of the screen. They shouldn’t interrupt the user experience, and they don’t require user input to disappear.", + "demoSnackbarsDescription": "Snackbars inform users of a process that an app has performed or will perform. They appear temporarily, towards the bottom of the screen. They shouldn't interrupt the user experience, and they don't require user input to disappear.", "@demoSnackbarsDescription": { "description": "Description for snackbars demo." }, @@ -1934,7 +1934,7 @@ }, "demoSnackbarsAction": "You pressed the snackbar action.", "@demoSnackbarsAction": { - "description": "Text that appears when you press on a snackbars’ action." + "description": "Text that appears when you press on a snackbars' action." }, "demoSelectionControlsTitle": "Selection controls", "@demoSelectionControlsTitle": { @@ -1964,7 +1964,7 @@ "@demoSelectionControlsSwitchTitle": { "description": "Title for the switches (selection controls) demo." }, - "demoSelectionControlsSwitchDescription": "On/off switches toggle the state of a single settings option. The option that the switch controls, as well as the state it’s in, should be made clear from the corresponding inline label.", + "demoSelectionControlsSwitchDescription": "On/off switches toggle the state of a single settings option. The option that the switch controls, as well as the state it's in, should be made clear from the corresponding inline label.", "@demoSelectionControlsSwitchDescription": { "description": "Description for the switches (selection controls) demo." }, diff --git a/lib/l10n/intl_en_US.xml b/lib/l10n/intl_en_US.xml index dba74b68dc..c47605d4df 100644 --- a/lib/l10n/intl_en_US.xml +++ b/lib/l10n/intl_en_US.xml @@ -332,15 +332,15 @@ Heads up, you’ve used up {percent} of your Shopping budget for this month. + >Heads up, you've used up {percent} of your Shopping budget for this month. You’ve spent {amount} on Restaurants this week. + >You've spent {amount} on Restaurants this week. You’ve spent {amount} in ATM fees this month + >You've spent {amount} in ATM fees this month The App bar provides content and actions related to the current screen. It’s used for branding, screen titles, navigation, and actions + >The App bar provides content and actions related to the current screen. It's used for branding, screen titles, navigation, and actions Data tables display information in a grid-like format of rows and columns. They organize information in a way that’s easy to scan, so that users can look for patterns and insights. + >Data tables display information in a grid-like format of rows and columns. They organize information in a way that's easy to scan, so that users can look for patterns and insights. Snackbars inform users of a process that an app has performed or will perform. They appear temporarily, towards the bottom of the screen. They shouldn’t interrupt the user experience, and they don’t require user input to disappear. + >Snackbars inform users of a process that an app has performed or will perform. They appear temporarily, towards the bottom of the screen. They shouldn't interrupt the user experience, and they don't require user input to disappear. ACTION You pressed the snackbar action. On/off switches toggle the state of a single settings option. The option that the switch controls, as well as the state it’s in, should be made clear from the corresponding inline label. + >On/off switches toggle the state of a single settings option. The option that the switch controls, as well as the state it's in, should be made clear from the corresponding inline label. str.replaceAll('\r\n', '\n'); + +void main() { + /// Verifies that intl_en_US.xml is updated. + test('verify intl_en_US.xml is up to date', () async { + final currentXml = getDefaultXml().replaceAll('\r\n', '\n'); + final newXml = (await generateXmlFromArb()).replaceAll('\r\n', '\n'); + + expect(_standardizeLineEndings(currentXml), _standardizeLineEndings(newXml), + reason: 'intl_en_US.xml is not up to date. ' + 'Did you forget to run `flutter pub run grinder l10n`?'); + }); +} diff --git a/tool/grind.dart b/tool/grind.dart index cb2992d5c2..ff1f8a3d57 100644 --- a/tool/grind.dart +++ b/tool/grind.dart @@ -31,29 +31,6 @@ Future l10n() async { Dart.run(l10nPath); } -@Task('Verify xml localizations') -Future verifyL10n() async { - final l10nPath = - path.join(Directory.current.path, 'tool', 'l10n_cli', 'main.dart'); - - // Run the tool to transform arb to xml, and write the output to stdout. - final xmlOutput = Dart.run(l10nPath, arguments: ['--dry-run'], quiet: true); - - // Read the original xml file. - final xmlPath = - path.join(Directory.current.path, 'lib', 'l10n', 'intl_en_US.xml'); - final expectedXmlOutput = await File(xmlPath).readAsString(); - - if (xmlOutput.trim() != expectedXmlOutput.trim()) { - stderr.writeln( - 'The contents of $xmlPath are different from that produced by ' - 'l10n_cli. Did you forget to run `flutter pub run grinder ' - 'l10n` after updating an .arb file?', - ); - exit(1); - } -} - @Task('Update code segments') Future updateCodeSegments() async { final codeviewerPath = diff --git a/tool/l10n_cli/l10n_cli.dart b/tool/l10n_cli/l10n_cli.dart index 1eb02754ae..de3ec77247 100644 --- a/tool/l10n_cli/l10n_cli.dart +++ b/tool/l10n_cli/l10n_cli.dart @@ -5,10 +5,16 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; -import 'package:meta/meta.dart'; const _l10nDir = 'lib/l10n'; -const _intlHeader = ''' +// Note that the filename for `intl_en_US.xml` is used by the internal +// translation console and changing the filename may require manually updating +// already translated messages to point to the new file. Therefore, avoid doing so +// unless necessary. +const _englishXmlPath = '$_l10nDir/intl_en_US.xml'; +const _englishArbPath = '$_l10nDir/intl_en.arb'; + +const _xmlHeader = '''