From 669a3d2b4718a318985b3b86a4adba42460351e9 Mon Sep 17 00:00:00 2001 From: engine-flutter-autoroll Date: Tue, 10 Jan 2023 12:08:11 -0500 Subject: [PATCH 01/17] Roll Plugins from 0a0e3d205ca3 to 9fdc899b72ca (8 revisions) (#118253) * d03de2fce [tool] Don't add Guava in the all-packages app (flutter/plugins#6747) * d485c7e83 [local_auth]: Bump espresso-core (flutter/plugins#6925) * a47e71988 [webview_flutter_platform_interface] Improves error message when `WebViewPlatform.instance` is null (flutter/plugins#6938) * 7132dac0e [google_maps]: Bump espresso-core from 3.4.0 to 3.5.1 in /packages/google_maps_flutter/google_maps_flutter_android/android (flutter/plugins#6937) * dc3287ccf [espresso]: Bump truth from 1.4.0 to 1.5.0 in /packages/espresso/android (flutter/plugins#6707) * 1de6477bd [camera]: Bump camerax_version from 1.3.0-alpha01 to 1.3.0-alpha02 in /packages/camera/camera_android_camerax/android (flutter/plugins#6828) * fb405819e [shared_preferences] Merge iOS and macOS implementations (flutter/plugins#6920) * 9fdc899b7 [various] Enable `avoid_dynamic_calls` (flutter/plugins#6834) --- bin/internal/flutter_plugins.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/internal/flutter_plugins.version b/bin/internal/flutter_plugins.version index 513c401bb6334..5328797297ae9 100644 --- a/bin/internal/flutter_plugins.version +++ b/bin/internal/flutter_plugins.version @@ -1 +1 @@ -0a0e3d205ca32fdeebe237262e6ac824b3f3d51f +9fdc899b72cac49a4ffade799563c4730c0279a8 From cb62cfdd1f6accf3684a47dde67a40dc9b80845b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Sharma?= <737941+loic-sharma@users.noreply.github.com> Date: Tue, 10 Jan 2023 10:03:15 -0800 Subject: [PATCH 02/17] Manually mark Windows run_debug_test_windows as unflaky (#118112) --- .ci.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.ci.yaml b/.ci.yaml index f1764a4e624c9..1877c0a99c008 100644 --- a/.ci.yaml +++ b/.ci.yaml @@ -4303,7 +4303,6 @@ targets: - name: Windows run_debug_test_windows recipe: devicelab/devicelab_drone - bringup: true presubmit: false timeout: 60 properties: From 0cd8d8451c3f7d298f595c452c2c7f8de95bbe0e Mon Sep 17 00:00:00 2001 From: Flutter GitHub Bot Date: Tue, 10 Jan 2023 10:07:07 -0800 Subject: [PATCH 03/17] Marks Mac_arm64_android run_debug_test_android to be unflaky (#117469) --- .ci.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.ci.yaml b/.ci.yaml index 1877c0a99c008..0d8f256af8073 100644 --- a/.ci.yaml +++ b/.ci.yaml @@ -3270,7 +3270,6 @@ targets: - name: Mac_arm64_android run_debug_test_android recipe: devicelab/devicelab_drone - bringup: true presubmit: false runIf: - dev/** From 3cee38e80f7d5d8b542a0fc6c80c1ce851924c86 Mon Sep 17 00:00:00 2001 From: Flutter GitHub Bot Date: Tue, 10 Jan 2023 10:07:09 -0800 Subject: [PATCH 04/17] Marks Mac_arm64_ios run_debug_test_macos to be unflaky (#117990) --- .ci.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.ci.yaml b/.ci.yaml index 0d8f256af8073..6f00385c4c4a6 100644 --- a/.ci.yaml +++ b/.ci.yaml @@ -3973,7 +3973,6 @@ targets: - name: Mac_arm64_ios run_debug_test_macos recipe: devicelab/devicelab_drone - bringup: true timeout: 60 properties: tags: > From 1d2e62b7644a4ad7e8d26e7e0784c9daa98c4b62 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Tue, 10 Jan 2023 11:03:27 -0800 Subject: [PATCH 05/17] remove unsound mode web test (#118256) --- dev/bots/test.dart | 1 - .../web/lib/null_assert_main.dart | 24 ------------------- 2 files changed, 25 deletions(-) delete mode 100644 dev/integration_tests/web/lib/null_assert_main.dart diff --git a/dev/bots/test.dart b/dev/bots/test.dart index e6919b72ab888..48ad19c23fc5b 100644 --- a/dev/bots/test.dart +++ b/dev/bots/test.dart @@ -1236,7 +1236,6 @@ Future _runWebLongRunningTests() async { () => _runWebDebugTest('lib/framework_stack_trace.dart'), () => _runWebDebugTest('lib/web_directory_loading.dart'), () => _runWebDebugTest('test/test.dart'), - () => _runWebDebugTest('lib/null_assert_main.dart', enableNullSafety: true), () => _runWebDebugTest('lib/null_safe_main.dart', enableNullSafety: true), () => _runWebDebugTest('lib/web_define_loading.dart', additionalArguments: [ diff --git a/dev/integration_tests/web/lib/null_assert_main.dart b/dev/integration_tests/web/lib/null_assert_main.dart deleted file mode 100644 index e9588628ccdf7..0000000000000 --- a/dev/integration_tests/web/lib/null_assert_main.dart +++ /dev/null @@ -1,24 +0,0 @@ -// 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. - -// ignore_for_file: enable_null_safety - -// @dart = 2.8 - -import 'null_enabled_api.dart'; - -void main() { - dynamic error; - try { - // Validate that a generated null assertion is thrown. - methodThatAcceptsNonNull(null); - } catch (err) { - error = err; - } - if (error is AssertionError) { - print('--- TEST SUCCEEDED ---'); - } else { - print('--- TEST FAILED ---'); - } -} From 3d3f8e85a608613bc46e59c31bd905921de33093 Mon Sep 17 00:00:00 2001 From: Taha Tesser Date: Tue, 10 Jan 2023 21:49:22 +0200 Subject: [PATCH 06/17] Update `CupertinoPicker` example (#118248) * Update `CupertinoPicker` example * format lines * Revert making variable public * revert variable change --- .../cupertino/picker/cupertino_picker.0.dart | 16 +++++++++------- .../picker/cupertino_picker.0_test.dart | 17 ++++++++++++++--- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/examples/api/lib/cupertino/picker/cupertino_picker.0.dart b/examples/api/lib/cupertino/picker/cupertino_picker.0.dart index ca626d29c8449..73d57cc11d103 100644 --- a/examples/api/lib/cupertino/picker/cupertino_picker.0.dart +++ b/examples/api/lib/cupertino/picker/cupertino_picker.0.dart @@ -29,6 +29,7 @@ class CupertinoPickerApp extends StatelessWidget { ); } } + class CupertinoPickerExample extends StatefulWidget { const CupertinoPickerExample({super.key}); @@ -57,7 +58,7 @@ class _CupertinoPickerExampleState extends State { top: false, child: child, ), - ) + ), ); } @@ -86,6 +87,10 @@ class _CupertinoPickerExampleState extends State { squeeze: 1.2, useMagnifier: true, itemExtent: _kItemExtent, + // This sets the initial item. + scrollController: FixedExtentScrollController( + initialItem: _selectedFruit, + ), // This is called when selected item is changed. onSelectedItemChanged: (int selectedItem) { setState(() { @@ -93,16 +98,13 @@ class _CupertinoPickerExampleState extends State { }); }, children: List.generate(_fruitNames.length, (int index) { - return Center( - child: Text( - _fruitNames[index], - ), - ); + return Center(child: Text(_fruitNames[index])); }), ), ), // This displays the selected fruit name. - child: Text(_fruitNames[_selectedFruit], + child: Text( + _fruitNames[_selectedFruit], style: const TextStyle( fontSize: 22.0, ), diff --git a/examples/api/test/cupertino/picker/cupertino_picker.0_test.dart b/examples/api/test/cupertino/picker/cupertino_picker.0_test.dart index f2e9a97fa6050..178764ae7c447 100644 --- a/examples/api/test/cupertino/picker/cupertino_picker.0_test.dart +++ b/examples/api/test/cupertino/picker/cupertino_picker.0_test.dart @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'package:flutter/cupertino.dart'; import 'package:flutter_api_samples/cupertino/picker/cupertino_picker.0.dart' as example; import 'package:flutter_test/flutter_test.dart'; @@ -14,12 +15,15 @@ void main() { ); // Open the Cupertino picker. - await tester.tap(find.text('Apple')); + await tester.tap(find.widgetWithText(CupertinoButton, 'Apple')); await tester.pumpAndSettle(); + // Test the initial item. + CupertinoPicker picker = tester.widget(find.byType(CupertinoPicker)); + expect(picker.scrollController!.initialItem, 0); + // Drag the wheel to change fruit selection. await tester.drag(find.text('Mango'), _kRowOffset, touchSlopY: 0, warnIfMissed: false); // see top of file - await tester.pump(); await tester.pump(const Duration(milliseconds: 500)); @@ -27,6 +31,13 @@ void main() { await tester.tapAt(const Offset(1.0, 1.0)); await tester.pumpAndSettle(); - expect(find.text('Banana'), findsOneWidget); + expect(find.widgetWithText(CupertinoButton, 'Banana'), findsOneWidget); + + // Test if the initial item has updated. + await tester.tap(find.widgetWithText(CupertinoButton, 'Banana')); + await tester.pumpAndSettle(); + + picker = tester.widget(find.byType(CupertinoPicker)); + expect(picker.scrollController!.initialItem, 2); }); } From 594333b3691e478ae3bd69f8601834f820de157b Mon Sep 17 00:00:00 2001 From: Flutter GitHub Bot Date: Tue, 10 Jan 2023 13:23:23 -0800 Subject: [PATCH 07/17] roll packages (#118117) --- packages/flutter_tools/pubspec.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/flutter_tools/pubspec.yaml b/packages/flutter_tools/pubspec.yaml index 0ee430397808f..1c92f0cc2060f 100644 --- a/packages/flutter_tools/pubspec.yaml +++ b/packages/flutter_tools/pubspec.yaml @@ -11,7 +11,7 @@ dependencies: args: 2.3.1 browser_launcher: 1.1.1 dds: 2.6.0 - dwds: 16.0.1 + dwds: 16.0.2 completion: 1.0.1 coverage: 1.6.1 crypto: 3.0.2 @@ -102,4 +102,4 @@ dartdoc: # Exclude this package from the hosted API docs. nodoc: true -# PUBSPEC CHECKSUM: 13f7 +# PUBSPEC CHECKSUM: 48f8 From a6f17e697c61e02ee868d0fb4d6d13301e056956 Mon Sep 17 00:00:00 2001 From: Youchen Du Date: Wed, 11 Jan 2023 05:31:17 +0800 Subject: [PATCH 08/17] Add option for opting out of enter route snapshotting. (#118086) * Add option for opting out of enter route snapshotting. * Fix typo. * Merge find layers logic. * Add justification comment on why web is skipped in test. * Update documentation as suggested. * Update documentation as suggested. --- .../src/material/page_transitions_theme.dart | 28 ++++++- packages/flutter/test/material/page_test.dart | 83 +++++++++++++++++++ 2 files changed, 108 insertions(+), 3 deletions(-) diff --git a/packages/flutter/lib/src/material/page_transitions_theme.dart b/packages/flutter/lib/src/material/page_transitions_theme.dart index ce9415079897e..168003077cdc5 100644 --- a/packages/flutter/lib/src/material/page_transitions_theme.dart +++ b/packages/flutter/lib/src/material/page_transitions_theme.dart @@ -157,6 +157,7 @@ class _ZoomPageTransition extends StatelessWidget { required this.animation, required this.secondaryAnimation, required this.allowSnapshotting, + required this.allowEnterRouteSnapshotting, this.child, }) : assert(animation != null), assert(secondaryAnimation != null); @@ -207,6 +208,15 @@ class _ZoomPageTransition extends StatelessWidget { /// [secondaryAnimation]. final Widget? child; + /// Whether to enable snapshotting on the entering route during the + /// transition animation. + /// + /// If not specified, defaults to true. + /// If false, the route snapshotting will not be applied to the route being + /// animating into, e.g. when transitioning from route A to route B, B will + /// not be snapshotted. + final bool allowEnterRouteSnapshotting; + @override Widget build(BuildContext context) { return DualTransitionBuilder( @@ -218,7 +228,7 @@ class _ZoomPageTransition extends StatelessWidget { ) { return _ZoomEnterTransition( animation: animation, - allowSnapshotting: allowSnapshotting, + allowSnapshotting: allowSnapshotting && allowEnterRouteSnapshotting, child: child, ); }, @@ -243,7 +253,7 @@ class _ZoomPageTransition extends StatelessWidget { ) { return _ZoomEnterTransition( animation: animation, - allowSnapshotting: allowSnapshotting, + allowSnapshotting: allowSnapshotting && allowEnterRouteSnapshotting , reverse: true, child: child, ); @@ -596,7 +606,18 @@ class OpenUpwardsPageTransitionsBuilder extends PageTransitionsBuilder { class ZoomPageTransitionsBuilder extends PageTransitionsBuilder { /// Constructs a page transition animation that matches the transition used on /// Android Q. - const ZoomPageTransitionsBuilder(); + const ZoomPageTransitionsBuilder({ + this.allowEnterRouteSnapshotting = true, + }); + + /// Whether to enable snapshotting on the entering route during the + /// transition animation. + /// + /// If not specified, defaults to true. + /// If false, the route snapshotting will not be applied to the route being + /// animating into, e.g. when transitioning from route A to route B, B will + /// not be snapshotted. + final bool allowEnterRouteSnapshotting; @override Widget buildTransitions( @@ -610,6 +631,7 @@ class ZoomPageTransitionsBuilder extends PageTransitionsBuilder { animation: animation, secondaryAnimation: secondaryAnimation, allowSnapshotting: route?.allowSnapshotting ?? true, + allowEnterRouteSnapshotting: allowEnterRouteSnapshotting, child: child, ); } diff --git a/packages/flutter/test/material/page_test.dart b/packages/flutter/test/material/page_test.dart index 0296c25bcddde..87d9d6211c625 100644 --- a/packages/flutter/test/material/page_test.dart +++ b/packages/flutter/test/material/page_test.dart @@ -287,6 +287,89 @@ void main() { } }, variant: TargetPlatformVariant.only(TargetPlatform.android), skip: kIsWeb); // [intended] rasterization is not used on the web. + + testWidgets( + 'test page transition (_ZoomPageTransition) with rasterization disables snapshotting for enter route', + (WidgetTester tester) async { + Iterable findLayers(Finder of) { + return tester.layerListOf( + find.ancestor(of: of, matching: find.byType(SnapshotWidget)).first, + ); + } + + bool isTransitioningWithoutSnapshotting(Finder of) { + // When snapshotting is off, the OpacityLayer and TransformLayer will be + // applied directly. + final Iterable layers = findLayers(of); + return layers.whereType().length == 1 && + layers.whereType().length == 1; + } + + bool isSnapshotted(Finder of) { + final Iterable layers = findLayers(of); + // The scrim and the snapshot image are the only two layers. + return layers.length == 2 && + layers.whereType().length == 1 && + layers.whereType().length == 1; + } + + await tester.pumpWidget( + MaterialApp( + routes: { + '/1': (_) => const Material(child: Text('Page 1')), + '/2': (_) => const Material(child: Text('Page 2')), + }, + initialRoute: '/1', + builder: (BuildContext context, Widget? child) { + final ThemeData themeData = Theme.of(context); + return Theme( + data: themeData.copyWith( + pageTransitionsTheme: PageTransitionsTheme( + builders: { + ...themeData.pageTransitionsTheme.builders, + TargetPlatform.android: const ZoomPageTransitionsBuilder( + allowEnterRouteSnapshotting: false, + ), + }, + ), + ), + child: Builder(builder: (_) => child!), + ); + }, + ), + ); + + final Finder page1Finder = find.text('Page 1'); + final Finder page2Finder = find.text('Page 2'); + + // Page 1 on top. + expect(isSnapshotted(page1Finder), isFalse); + + // Transitioning from page 1 to page 2. + tester.state(find.byType(Navigator)).pushNamed('/2'); + await tester.pump(); + await tester.pump(const Duration(milliseconds: 50)); + + expect(isSnapshotted(page1Finder), isTrue); + expect(isTransitioningWithoutSnapshotting(page2Finder), isTrue); + + // Page 2 on top. + await tester.pumpAndSettle(); + expect(isSnapshotted(page2Finder), isFalse); + + // Transitioning back from page 2 to page 1. + tester.state(find.byType(Navigator)).pop(); + await tester.pump(); + await tester.pump(const Duration(milliseconds: 50)); + + expect(isTransitioningWithoutSnapshotting(page1Finder), isTrue); + expect(isSnapshotted(page2Finder), isTrue); + + // Page 1 on top. + await tester.pumpAndSettle(); + expect(isSnapshotted(page1Finder), isFalse); + }, variant: TargetPlatformVariant.only(TargetPlatform.android), skip: kIsWeb); // [intended] rasterization is not used on the web. + testWidgets('test fullscreen dialog transition', (WidgetTester tester) async { await tester.pumpWidget( const MaterialApp( From 01583b7486b4914f42de899ea3c2cf05b0b9e78c Mon Sep 17 00:00:00 2001 From: Flutter GitHub Bot Date: Tue, 10 Jan 2023 15:03:04 -0800 Subject: [PATCH 09/17] roll packages (#118272) --- .../gradle_deprecated_settings/pubspec.yaml | 8 ++++---- packages/flutter_tools/pubspec.yaml | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dev/integration_tests/gradle_deprecated_settings/pubspec.yaml b/dev/integration_tests/gradle_deprecated_settings/pubspec.yaml index 269023793aa30..2f83c7024a859 100644 --- a/dev/integration_tests/gradle_deprecated_settings/pubspec.yaml +++ b/dev/integration_tests/gradle_deprecated_settings/pubspec.yaml @@ -9,9 +9,9 @@ dependencies: sdk: flutter camera: 0.10.1 - camera_android: 0.10.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - camera_avfoundation: 0.9.10 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - camera_platform_interface: 2.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + camera_android: 0.10.2+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + camera_avfoundation: 0.9.10+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + camera_platform_interface: 2.3.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" camera_web: 0.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" characters: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" collection: 1.17.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -31,4 +31,4 @@ dependencies: flutter: uses-material-design: true -# PUBSPEC CHECKSUM: eabf +# PUBSPEC CHECKSUM: 7d79 diff --git a/packages/flutter_tools/pubspec.yaml b/packages/flutter_tools/pubspec.yaml index 1c92f0cc2060f..724902683ceb8 100644 --- a/packages/flutter_tools/pubspec.yaml +++ b/packages/flutter_tools/pubspec.yaml @@ -10,7 +10,7 @@ dependencies: archive: 3.3.2 args: 2.3.1 browser_launcher: 1.1.1 - dds: 2.6.0 + dds: 2.7.0 dwds: 16.0.2 completion: 1.0.1 coverage: 1.6.1 @@ -102,4 +102,4 @@ dartdoc: # Exclude this package from the hosted API docs. nodoc: true -# PUBSPEC CHECKSUM: 48f8 +# PUBSPEC CHECKSUM: 02f9 From cf529ec57eb0cfb3a62467c9a53c678fadb1e1dd Mon Sep 17 00:00:00 2001 From: engine-flutter-autoroll Date: Tue, 10 Jan 2023 18:03:07 -0500 Subject: [PATCH 10/17] Roll Flutter Engine from 687e3cb0fbe2 to c1d61cf11da8 (6 revisions) (#118274) * ad9052a38 Roll Dart SDK from 8d7a6aabd3a3 to b90a008ddb29 (1 revision) (flutter/engine#38740) * c4c97023f Mark nodes as `kIsLineBreakingObject` by default, TODO further distinctions (flutter/engine#38721) * f40af3eb4 Roll Dart SDK from b90a008ddb29 to 5e344de60564 (1 revision) (flutter/engine#38744) * 41cfbdd7e Roll Fuchsia Mac SDK from zC90VpkAGMG1jJ-BK... to 6xysoRPCXJ3cJX12x... (flutter/engine#38746) * 95c7b1f8a Make operator == parameter non-nullable (flutter/engine#38663) * c1d61cf11 Move canvaskit artifacts to expected location in Web SDK Archive (flutter/engine#38168) --- bin/internal/engine.version | 2 +- bin/internal/fuchsia-mac.version | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/internal/engine.version b/bin/internal/engine.version index 8e43cc8e5f5dd..5bb9105ab93a3 100644 --- a/bin/internal/engine.version +++ b/bin/internal/engine.version @@ -1 +1 @@ -687e3cb0fbe2fd7006d8d0dcd642471c2d3363fe +c1d61cf11da89cfcf83e8df2c20aa0ebe4dd9995 diff --git a/bin/internal/fuchsia-mac.version b/bin/internal/fuchsia-mac.version index 391920b009eb4..394b1f208b385 100644 --- a/bin/internal/fuchsia-mac.version +++ b/bin/internal/fuchsia-mac.version @@ -1 +1 @@ -zC90VpkAGMG1jJ-BKmFqF8gWp4vYu6FGaFAwUXf9QWMC +6xysoRPCXJ3cJX12x2Z-uYCsDxak4cGAcywM84p3TSkC From b7881e5b64e28a84a66ab30b29d35484428ea062 Mon Sep 17 00:00:00 2001 From: Sigurd Meldgaard Date: Wed, 11 Jan 2023 00:29:09 +0100 Subject: [PATCH 11/17] Align `flutter pub get/upgrade/add/remove/downgrade` (#117896) * Align `flutter pub get/upgrade/add/remove/downgrade` * Add final . to command description * Remove trailing whitespace * Don't print message that command is being run * Update expectations * Use relative path * Remove duplicated line * Improve function dartdoc --- .../lib/src/commands/packages.dart | 323 +++++++++--------- packages/flutter_tools/lib/src/dart/pub.dart | 164 ++++----- .../hermetic/create_usage_test.dart | 1 - .../commands.shard/hermetic/drive_test.dart | 1 - .../commands.shard/hermetic/pub_get_test.dart | 38 +-- .../hermetic/update_packages_test.dart | 1 - .../permeable/packages_test.dart | 1 + .../test/general.shard/cache_test.dart | 1 - .../test/general.shard/dart/pub_get_test.dart | 9 +- .../runner/flutter_command_test.dart | 1 - .../test/src/fake_process_manager.dart | 11 +- .../flutter_tools/test/src/throwing_pub.dart | 8 +- 12 files changed, 255 insertions(+), 304 deletions(-) diff --git a/packages/flutter_tools/lib/src/commands/packages.dart b/packages/flutter_tools/lib/src/commands/packages.dart index 14503a03b2f52..b65e3177b1fb6 100644 --- a/packages/flutter_tools/lib/src/commands/packages.dart +++ b/packages/flutter_tools/lib/src/commands/packages.dart @@ -20,10 +20,10 @@ import '../runner/flutter_command.dart'; class PackagesCommand extends FlutterCommand { PackagesCommand() { - addSubcommand(PackagesGetCommand('get', false)); - addSubcommand(PackagesInteractiveGetCommand('upgrade', "Upgrade the current package's dependencies to latest versions.")); - addSubcommand(PackagesInteractiveGetCommand('add', 'Add a dependency to pubspec.yaml.')); - addSubcommand(PackagesInteractiveGetCommand('remove', 'Removes a dependency from the current package.')); + addSubcommand(PackagesGetCommand('get', "Get the current package's dependencies.", PubContext.pubGet)); + addSubcommand(PackagesGetCommand('upgrade', "Upgrade the current package's dependencies to latest versions.", PubContext.pubUpgrade)); + addSubcommand(PackagesGetCommand('add', 'Add a dependency to pubspec.yaml.', PubContext.pubAdd)); + addSubcommand(PackagesGetCommand('remove', 'Removes a dependency from the current package.', PubContext.pubRemove)); addSubcommand(PackagesTestCommand()); addSubcommand(PackagesForwardCommand('publish', 'Publish the current package to pub.dartlang.org.', requiresPubspec: true)); addSubcommand(PackagesForwardCommand('downgrade', 'Downgrade packages in a Flutter project.', requiresPubspec: true)); @@ -56,136 +56,6 @@ class PackagesCommand extends FlutterCommand { Future runCommand() async => FlutterCommandResult.fail(); } -class PackagesGetCommand extends FlutterCommand { - PackagesGetCommand(this.name, this.upgrade) { - argParser.addFlag('offline', - negatable: false, - help: 'Use cached packages instead of accessing the network.', - ); - } - - @override - final String name; - - final bool upgrade; - - @override - String get description { - return '${ upgrade ? "Upgrade" : "Get" } packages in a Flutter project.'; - } - - @override - String get invocation { - return '${runner!.executableName} pub $name []'; - } - - /// The pub packages usage values are incorrect since these are calculated/sent - /// before pub get completes. This needs to be performed after dependency resolution. - @override - Future get usageValues async { - final ArgResults argumentResults = argResults!; - final String? workingDirectory = argumentResults.rest.length == 1 ? argumentResults.rest[0] : null; - final String? target = findProjectRoot(globals.fs, workingDirectory); - if (target == null) { - return const CustomDimensions(); - } - - int numberPlugins; - - final FlutterProject rootProject = FlutterProject.fromDirectory(globals.fs.directory(target)); - // Do not send plugin analytics if pub has not run before. - final bool hasPlugins = rootProject.flutterPluginsDependenciesFile.existsSync() - && rootProject.packageConfigFile.existsSync(); - if (hasPlugins) { - // Do not fail pub get if package config files are invalid before pub has - // had a chance to run. - final List plugins = await findPlugins(rootProject, throwOnError: false); - numberPlugins = plugins.length; - } else { - numberPlugins = 0; - } - - return CustomDimensions( - commandPackagesNumberPlugins: numberPlugins, - commandPackagesProjectModule: rootProject.isModule, - commandPackagesAndroidEmbeddingVersion: rootProject.android.getEmbeddingVersion().toString().split('.').last, - ); - } - - Future _runPubGet(String directory, FlutterProject flutterProject) async { - if (flutterProject.manifest.generateSyntheticPackage) { - final Environment environment = Environment( - artifacts: globals.artifacts!, - logger: globals.logger, - cacheDir: globals.cache.getRoot(), - engineVersion: globals.flutterVersion.engineRevision, - fileSystem: globals.fs, - flutterRootDir: globals.fs.directory(Cache.flutterRoot), - outputDir: globals.fs.directory(getBuildDirectory()), - processManager: globals.processManager, - platform: globals.platform, - usage: globals.flutterUsage, - projectDir: flutterProject.directory, - generateDartPluginRegistry: true, - ); - - await generateLocalizationsSyntheticPackage( - environment: environment, - buildSystem: globals.buildSystem, - ); - } - - final Stopwatch pubGetTimer = Stopwatch()..start(); - try { - await pub.get( - context: PubContext.pubGet, - project: flutterProject, - upgrade: upgrade, - shouldSkipThirdPartyGenerator: false, - offline: boolArgDeprecated('offline'), - ); - pubGetTimer.stop(); - globals.flutterUsage.sendTiming('pub', 'get', pubGetTimer.elapsed, label: 'success'); - // Not limiting to catching Exception because the exception is rethrown. - } catch (_) { // ignore: avoid_catches_without_on_clauses - pubGetTimer.stop(); - globals.flutterUsage.sendTiming('pub', 'get', pubGetTimer.elapsed, label: 'failure'); - rethrow; - } - } - - @override - Future runCommand() async { - final ArgResults argumentResults = argResults!; - if (argumentResults.rest.length > 1) { - throwToolExit('Too many arguments.\n$usage'); - } - - final String? workingDirectory = argumentResults.rest.length == 1 ? argumentResults.rest[0] : null; - final String? target = findProjectRoot(globals.fs, workingDirectory); - if (target == null) { - throwToolExit( - 'Expected to find project root in ' - '${ workingDirectory ?? "current working directory" }.' - ); - } - final FlutterProject rootProject = FlutterProject.fromDirectory(globals.fs.directory(target)); - - // This will also resolve dependencies for the example folder, - await _runPubGet(target, rootProject); - - // We need to regenerate the platform specific tooling for both the project - // itself and example (if present). - await rootProject.regeneratePlatformSpecificTooling(); - if (rootProject.hasExampleApp && rootProject.example.pubspecFile.existsSync()) { - final FlutterProject exampleProject = rootProject.example; - await exampleProject.regeneratePlatformSpecificTooling(); - } - - return FlutterCommandResult.success(); - } -} - class PackagesTestCommand extends FlutterCommand { PackagesTestCommand() { requiresPubspecYaml(); @@ -223,6 +93,8 @@ class PackagesForwardCommand extends FlutterCommand { } } + PubContext context = PubContext.pubForward; + @override ArgParser argParser = ArgParser.allowAnything(); @@ -247,7 +119,11 @@ class PackagesForwardCommand extends FlutterCommand { Future runCommand() async { final List subArgs = argResults!.rest.toList() ..removeWhere((String arg) => arg == '--'); - await pub.interactively([_commandName, ...subArgs], stdio: globals.stdio); + await pub.interactively( + [ _commandName, ...subArgs], + context: context, + command: _commandName, + ); return FlutterCommandResult.success(); } } @@ -270,21 +146,31 @@ class PackagesPassthroughCommand extends FlutterCommand { return '${runner!.executableName} packages pub []'; } + static final PubContext _context = PubContext.pubPassThrough; + @override Future runCommand() async { - await pub.interactively(argResults!.rest, stdio: globals.stdio); + await pub.interactively( + command: 'pub', + argResults!.rest, + context: _context, + ); return FlutterCommandResult.success(); } } -class PackagesInteractiveGetCommand extends FlutterCommand { - PackagesInteractiveGetCommand(this._commandName, this._description); +/// Represents the pub sub-commands that makes package-resolutions. +class PackagesGetCommand extends FlutterCommand { + PackagesGetCommand(this._commandName, this._description, this._context); @override ArgParser argParser = ArgParser.allowAnything(); final String _commandName; final String _description; + final PubContext _context; + + FlutterProject? _rootProject; @override String get name => _commandName; @@ -300,29 +186,89 @@ class PackagesInteractiveGetCommand extends FlutterCommand { return '${runner!.executableName} pub $_commandName []'; } + /// An [ArgParser] that accepts all options and flags that the + /// + /// `pub get` + /// `pub upgrade` + /// `pub downgrade` + /// `pub add` + /// `pub remove` + /// + /// commands accept. + ArgParser get _permissiveArgParser { + final ArgParser argParser = ArgParser(); + argParser.addOption('directory', abbr: 'C'); + argParser.addFlag('offline'); + argParser.addFlag('dry-run', abbr: 'n'); + argParser.addFlag('help', abbr: 'h'); + argParser.addFlag('enforce-lockfile'); + argParser.addFlag('precompile'); + argParser.addFlag('major-versions'); + argParser.addFlag('null-safety'); + argParser.addFlag('example', defaultsTo: true); + argParser.addOption('sdk'); + argParser.addOption('path'); + argParser.addOption('hosted-url'); + argParser.addOption('git-url'); + argParser.addOption('git-ref'); + argParser.addOption('git-path'); + argParser.addFlag('dev'); + return argParser; + } + @override Future runCommand() async { List rest = argResults!.rest; - final bool isHelp = rest.contains('-h') || rest.contains('--help'); - String? target; - if (rest.length == 1 && (rest.single.contains('/') || rest.single.contains(r'\'))) { - // For historical reasons, if there is one argument to the command and it contains - // a multiple-component path (i.e. contains a slash) then we use that to determine - // to which project we're applying the command. - target = findProjectRoot(globals.fs, rest.single); - rest = []; - } else { - target = findProjectRoot(globals.fs); + bool isHelp = false; + bool example = true; + bool exampleWasParsed = false; + String? directoryOption; + bool dryRun = false; + try { + final ArgResults results = _permissiveArgParser.parse(rest); + isHelp = results['help'] as bool; + directoryOption = results['directory'] as String?; + example = results['example'] as bool; + exampleWasParsed = results.wasParsed('example'); + dryRun = results['dry-run'] as bool; + } on ArgParserException { + // Let pub give the error message. } + String? target; + FlutterProject? rootProject; - FlutterProject? flutterProject; if (!isHelp) { - if (target == null) { - throwToolExit('Expected to find project root in current working directory.'); + if (directoryOption == null && rest.length == 1 && + ((rest.single.contains('/') || rest.single.contains(r'\')) || + name == 'get')) { + // For historical reasons, if there is one argument to the command and it contains + // a multiple-component path (i.e. contains a slash) then we use that to determine + // to which project we're applying the command. + target = findProjectRoot(globals.fs, rest.single); + + globals.printWarning(''' + Using a naked argument for directory is deprecated and will stop working in a future Flutter release. + + Use --directory instead.'''); + if (target == null) { + throwToolExit('Expected to find project root in ${rest.single}.'); + } + rest = []; + } else { + target = findProjectRoot(globals.fs, directoryOption); + if (target == null) { + if (directoryOption == null) { + throwToolExit('Expected to find project root in current working directory.'); + } else { + throwToolExit('Expected to find project root in $directoryOption.'); + } + } } - flutterProject = FlutterProject.fromDirectory(globals.fs.directory(target)); - if (flutterProject.manifest.generateSyntheticPackage) { + rootProject = FlutterProject.fromDirectory(globals.fs.directory(target)); + _rootProject = rootProject; + + if (rootProject.manifest.generateSyntheticPackage) { final Environment environment = Environment( artifacts: globals.artifacts!, logger: globals.logger, @@ -334,7 +280,7 @@ class PackagesInteractiveGetCommand extends FlutterCommand { processManager: globals.processManager, platform: globals.platform, usage: globals.flutterUsage, - projectDir: flutterProject.directory, + projectDir: rootProject.directory, generateDartPluginRegistry: true, ); @@ -344,17 +290,70 @@ class PackagesInteractiveGetCommand extends FlutterCommand { ); } } + final String? relativeTarget = target == null ? null : globals.fs.path.relative(target); final List subArgs = rest.toList()..removeWhere((String arg) => arg == '--'); - await pub.interactively( - [name, ...subArgs], - directory: target, - stdio: globals.stdio, - touchesPackageConfig: !isHelp, - generateSyntheticPackage: flutterProject?.manifest.generateSyntheticPackage ?? false, - ); + final Stopwatch timer = Stopwatch()..start(); + try { + await pub.interactively( + [ + name, + ...subArgs, + // `dart pub get` and friends defaults to `--no-example`. + if(!exampleWasParsed && target != null) '--example', + if(directoryOption == null && relativeTarget != null) ...['--directory', relativeTarget], + ], + project: rootProject, + context: _context, + command: name, + touchesPackageConfig: !(isHelp || dryRun), + ); + globals.flutterUsage.sendTiming('pub', 'get', timer.elapsed, label: 'success'); + // Not limiting to catching Exception because the exception is rethrown. + } catch (_) { // ignore: avoid_catches_without_on_clauses + globals.flutterUsage.sendTiming('pub', 'get', timer.elapsed, label: 'failure'); + rethrow; + } + + if (rootProject != null) { + // We need to regenerate the platform specific tooling for both the project + // itself and example(if present). + await rootProject.regeneratePlatformSpecificTooling(); + if (example && rootProject.hasExampleApp && rootProject.example.pubspecFile.existsSync()) { + final FlutterProject exampleProject = rootProject.example; + await exampleProject.regeneratePlatformSpecificTooling(); + } + } - await flutterProject?.regeneratePlatformSpecificTooling(); return FlutterCommandResult.success(); } + + /// The pub packages usage values are incorrect since these are calculated/sent + /// before pub get completes. This needs to be performed after dependency resolution. + @override + Future get usageValues async { + final FlutterProject? rootProject = _rootProject; + if (rootProject == null) { + return const CustomDimensions(); + } + + int numberPlugins; + // Do not send plugin analytics if pub has not run before. + final bool hasPlugins = rootProject.flutterPluginsDependenciesFile.existsSync() + && rootProject.packageConfigFile.existsSync(); + if (hasPlugins) { + // Do not fail pub get if package config files are invalid before pub has + // had a chance to run. + final List plugins = await findPlugins(rootProject, throwOnError: false); + numberPlugins = plugins.length; + } else { + numberPlugins = 0; + } + + return CustomDimensions( + commandPackagesNumberPlugins: numberPlugins, + commandPackagesProjectModule: rootProject.isModule, + commandPackagesAndroidEmbeddingVersion: rootProject.android.getEmbeddingVersion().toString().split('.').last, + ); + } } diff --git a/packages/flutter_tools/lib/src/dart/pub.dart b/packages/flutter_tools/lib/src/dart/pub.dart index fdb97d6a19a29..94c07ea003149 100644 --- a/packages/flutter_tools/lib/src/dart/pub.dart +++ b/packages/flutter_tools/lib/src/dart/pub.dart @@ -120,7 +120,10 @@ class PubContext { static final PubContext interactive = PubContext._(['interactive']); static final PubContext pubGet = PubContext._(['get']); static final PubContext pubUpgrade = PubContext._(['upgrade']); + static final PubContext pubAdd = PubContext._(['add']); + static final PubContext pubRemove = PubContext._(['remove']); static final PubContext pubForward = PubContext._(['forward']); + static final PubContext pubPassThrough = PubContext._(['passthrough']); static final PubContext runTest = PubContext._(['run_test']); static final PubContext flutterTests = PubContext._(['flutter_tests']); static final PubContext updatePackages = PubContext._(['update_packages']); @@ -161,7 +164,7 @@ abstract class Pub { required Stdio stdio, }) = _DefaultPub.test; - /// Runs `pub get` or `pub upgrade` for [project]. + /// Runs `pub get` for [project]. /// /// [context] provides extra information to package server requests to /// understand usage. @@ -173,7 +176,6 @@ abstract class Pub { Future get({ required PubContext context, required FlutterProject project, - bool skipIfAbsent = false, bool upgrade = false, bool offline = false, String? flutterRootOverride, @@ -203,14 +205,23 @@ abstract class Pub { /// Runs pub in 'interactive' mode. /// - /// directly piping the stdin stream of this process to that of pub, and the - /// stdout/stderr stream of pub to the corresponding streams of this process. + /// This will run the pub process with StdioInherited (unless [_stdio] is set + /// for testing). + /// + /// The pub process will be run in current working directory, so `--directory` + /// should be passed appropriately in [arguments]. This ensures output from + /// pub will refer to relative paths correctly. + /// + /// [touchesPackageConfig] should be true if this is a command expexted to + /// create a new `.dart_tool/package_config.json` file. Future interactively( List arguments, { - String? directory, - required io.Stdio stdio, + FlutterProject? project, + required PubContext context, + required String command, bool touchesPackageConfig = false, bool generateSyntheticPackage = false, + bool printProgress = true, }); } @@ -268,7 +279,6 @@ class _DefaultPub implements Pub { Future get({ required PubContext context, required FlutterProject project, - bool skipIfAbsent = false, bool upgrade = false, bool offline = false, bool generateSyntheticPackage = false, @@ -280,8 +290,6 @@ class _DefaultPub implements Pub { }) async { final String directory = project.directory.path; final File packageConfigFile = project.packageConfigFile; - final Directory generatedDirectory = _fileSystem.directory( - _fileSystem.path.join(directory, '.dart_tool', 'flutter_gen')); final File lastVersion = _fileSystem.file( _fileSystem.path.join(directory, '.dart_tool', 'version')); final File currentVersion = _fileSystem.file( @@ -352,25 +360,7 @@ class _DefaultPub implements Pub { flutterRootOverride: flutterRootOverride, printProgress: printProgress ); - - if (!packageConfigFile.existsSync()) { - throwToolExit('$directory: pub did not create .dart_tools/package_config.json file.'); - } - lastVersion.writeAsStringSync(currentVersion.readAsStringSync()); - await _updatePackageConfig( - packageConfigFile, - generatedDirectory, - project.manifest.generateSyntheticPackage, - ); - if (project.hasExampleApp && project.example.pubspecFile.existsSync()) { - final Directory exampleGeneratedDirectory = _fileSystem.directory( - _fileSystem.path.join(project.example.directory.path, '.dart_tool', 'flutter_gen')); - await _updatePackageConfig( - project.example.packageConfigFile, - exampleGeneratedDirectory, - project.example.manifest.generateSyntheticPackage, - ); - } + await _updateVersionAndPackageConfig(project); } /// Runs pub with [arguments] and [ProcessStartMode.inheritStdio] mode. @@ -392,9 +382,6 @@ class _DefaultPub implements Pub { String? flutterRootOverride, }) async { int exitCode; - if (printProgress) { - _logger.printStatus('Running "flutter pub $command" in ${_fileSystem.path.basename(directory)}...'); - } final List pubCommand = _pubCommand(arguments); final Map pubEnvironment = await _createPubEnvironment(context, flutterRootOverride); @@ -567,64 +554,22 @@ class _DefaultPub implements Pub { @override Future interactively( List arguments, { - String? directory, - required io.Stdio stdio, + FlutterProject? project, + required PubContext context, + required String command, bool touchesPackageConfig = false, bool generateSyntheticPackage = false, + bool printProgress = true, }) async { - // Fully resolved pub or pub.bat is calculated based on current platform. - final io.Process process = await _processUtils.start( - _pubCommand([ - if (_logger.supportsColor) '--color', - ...arguments, - ]), - workingDirectory: directory, - environment: await _createPubEnvironment(PubContext.interactive), + await _runWithStdioInherited( + arguments, + command: command, + directory: _fileSystem.currentDirectory.path, + context: context, + printProgress: printProgress, ); - - // Pipe the Flutter tool stdin to the pub stdin. - unawaited(process.stdin.addStream(stdio.stdin) - // If pub exits unexpectedly with an error, that will be reported below - // by the tool exit after the exit code check. - .catchError((dynamic err, StackTrace stack) { - _logger.printTrace('Echoing stdin to the pub subprocess failed:'); - _logger.printTrace('$err\n$stack'); - } - )); - - // Pipe the pub stdout and stderr to the tool stdout and stderr. - try { - await Future.wait(>[ - stdio.addStdoutStream(process.stdout), - stdio.addStderrStream(process.stderr), - ]); - } on Exception catch (err, stack) { - _logger.printTrace('Echoing stdout or stderr from the pub subprocess failed:'); - _logger.printTrace('$err\n$stack'); - } - - // Wait for pub to exit. - final int code = await process.exitCode; - if (code != 0) { - throwToolExit('pub finished with exit code $code', exitCode: code); - } - - if (touchesPackageConfig) { - final String targetDirectory = directory ?? _fileSystem.currentDirectory.path; - final File packageConfigFile = _fileSystem.file( - _fileSystem.path.join(targetDirectory, '.dart_tool', 'package_config.json')); - final Directory generatedDirectory = _fileSystem.directory( - _fileSystem.path.join(targetDirectory, '.dart_tool', 'flutter_gen')); - final File lastVersion = _fileSystem.file( - _fileSystem.path.join(targetDirectory, '.dart_tool', 'version')); - final File currentVersion = _fileSystem.file( - _fileSystem.path.join(Cache.flutterRoot!, 'version')); - lastVersion.writeAsStringSync(currentVersion.readAsStringSync()); - await _updatePackageConfig( - packageConfigFile, - generatedDirectory, - generateSyntheticPackage, - ); + if (touchesPackageConfig && project != null) { + await _updateVersionAndPackageConfig(project); } } @@ -766,23 +711,46 @@ class _DefaultPub implements Pub { return environment; } - /// Update the package configuration file. + /// Updates the .dart_tool/version file to be equal to current Flutter + /// version. + /// + /// Calls [_updatePackageConfig] for [project] and [project.example] (if it + /// exists). + /// + /// This should be called after pub invocations that are expected to update + /// the packageConfig. + Future _updateVersionAndPackageConfig(FlutterProject project) async { + if (!project.packageConfigFile.existsSync()) { + throwToolExit('${project.directory}: pub did not create .dart_tools/package_config.json file.'); + } + final File lastVersion = _fileSystem.file( + _fileSystem.path.join(project.directory.path, '.dart_tool', 'version'), + ); + final File currentVersion = _fileSystem.file( + _fileSystem.path.join(Cache.flutterRoot!, 'version')); + lastVersion.writeAsStringSync(currentVersion.readAsStringSync()); + + await _updatePackageConfig(project); + if (project.hasExampleApp && project.example.pubspecFile.existsSync()) { + await _updatePackageConfig(project.example); + } + } + + /// Update the package configuration file in [project]. /// - /// Creates a corresponding `package_config_subset` file that is used by the build - /// system to avoid rebuilds caused by an updated pub timestamp. + /// Creates a corresponding `package_config_subset` file that is used by the + /// build system to avoid rebuilds caused by an updated pub timestamp. /// - /// if [generateSyntheticPackage] is true then insert flutter_gen synthetic - /// package into the package configuration. This is used by the l10n localization - /// tooling to insert a new reference into the package_config file, allowing the import - /// of a package URI that is not specified in the pubspec.yaml + /// if `project.generateSyntheticPackage` is `true` then insert flutter_gen + /// synthetic package into the package configuration. This is used by the l10n + /// localization tooling to insert a new reference into the package_config + /// file, allowing the import of a package URI that is not specified in the + /// pubspec.yaml /// /// For more information, see: /// * [generateLocalizations], `in lib/src/localizations/gen_l10n.dart` - Future _updatePackageConfig( - File packageConfigFile, - Directory generatedDirectory, - bool generateSyntheticPackage, - ) async { + Future _updatePackageConfig(FlutterProject project) async { + final File packageConfigFile = project.packageConfigFile; final PackageConfig packageConfig = await loadPackageConfigWithLogging(packageConfigFile, logger: _logger); packageConfigFile.parent @@ -792,7 +760,7 @@ class _DefaultPub implements Pub { _fileSystem, )); - if (!generateSyntheticPackage) { + if (!project.manifest.generateSyntheticPackage) { return; } if (packageConfig.packages.any((Package package) => package.name == 'flutter_gen')) { diff --git a/packages/flutter_tools/test/commands.shard/hermetic/create_usage_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/create_usage_test.dart index 9c419c3567f42..4a617ff70e126 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/create_usage_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/create_usage_test.dart @@ -29,7 +29,6 @@ class FakePub extends Fake implements Pub { Future get({ PubContext? context, required FlutterProject project, - bool skipIfAbsent = false, bool upgrade = false, bool offline = false, bool generateSyntheticPackage = false, diff --git a/packages/flutter_tools/test/commands.shard/hermetic/drive_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/drive_test.dart index 6e10ff510afab..a7445131369d8 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/drive_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/drive_test.dart @@ -480,7 +480,6 @@ class FakePub extends Fake implements Pub { Future get({ PubContext? context, required FlutterProject project, - bool skipIfAbsent = false, bool upgrade = false, bool offline = false, bool generateSyntheticPackage = false, diff --git a/packages/flutter_tools/test/commands.shard/hermetic/pub_get_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/pub_get_test.dart index e8b9db01ac265..4ab290199c6d4 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/pub_get_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/pub_get_test.dart @@ -35,7 +35,7 @@ void main() { fileSystem.currentDirectory.childFile('.flutter-plugins').createSync(); fileSystem.currentDirectory.childFile('.flutter-plugins-dependencies').createSync(); - final PackagesGetCommand command = PackagesGetCommand('get', false); + final PackagesGetCommand command = PackagesGetCommand('get', '', PubContext.pubGet); final CommandRunner commandRunner = createTestCommandRunner(command); await commandRunner.run(['get']); @@ -60,7 +60,7 @@ void main() { ..createSync(recursive: true) ..writeAsBytesSync([0]); - final PackagesGetCommand command = PackagesGetCommand('get', false); + final PackagesGetCommand command = PackagesGetCommand('get', '', PubContext.pubGet); final CommandRunner commandRunner = createTestCommandRunner(command); await commandRunner.run(['get']); @@ -81,7 +81,7 @@ void main() { final Directory targetDirectory = fileSystem.currentDirectory.childDirectory('target'); targetDirectory.childFile('pubspec.yaml').createSync(); - final PackagesGetCommand command = PackagesGetCommand('get', false); + final PackagesGetCommand command = PackagesGetCommand('get', '', PubContext.pubGet); final CommandRunner commandRunner = createTestCommandRunner(command); await commandRunner.run(['get', targetDirectory.path]); @@ -98,7 +98,7 @@ void main() { fileSystem.currentDirectory.childFile('pubspec.yaml').createSync(); fileSystem.currentDirectory.childDirectory('example').createSync(recursive: true); - final PackagesGetCommand command = PackagesGetCommand('get', false); + final PackagesGetCommand command = PackagesGetCommand('get', '', PubContext.pubGet); final CommandRunner commandRunner = createTestCommandRunner(command); await commandRunner.run(['get']); @@ -115,7 +115,7 @@ void main() { }); testUsingContext('pub get throws error on missing directory', () async { - final PackagesGetCommand command = PackagesGetCommand('get', false); + final PackagesGetCommand command = PackagesGetCommand('get', '', PubContext.pubGet); final CommandRunner commandRunner = createTestCommandRunner(command); try { @@ -159,7 +159,7 @@ void main() { ''' ); - final PackagesGetCommand command = PackagesGetCommand('get', false); + final PackagesGetCommand command = PackagesGetCommand('get', '', PubContext.pubGet); final CommandRunner commandRunner = createTestCommandRunner(command); await commandRunner.run(['get']); @@ -183,23 +183,21 @@ class FakePub extends Fake implements Pub { final FileSystem fileSystem; @override - Future get({ + Future interactively( + List arguments, { + FlutterProject? project, required PubContext context, - required FlutterProject project, - bool skipIfAbsent = false, - bool upgrade = false, - bool offline = false, + required String command, + bool touchesPackageConfig = false, bool generateSyntheticPackage = false, - bool generateSyntheticPackageForExample = false, - String? flutterRootOverride, - bool checkUpToDate = false, - bool shouldSkipThirdPartyGenerator = true, bool printProgress = true, }) async { - fileSystem.directory(project.directory) - .childDirectory('.dart_tool') - .childFile('package_config.json') - ..createSync(recursive: true) - ..writeAsStringSync('{"configVersion":2,"packages":[]}'); + if (project != null) { + fileSystem.directory(project.directory) + .childDirectory('.dart_tool') + .childFile('package_config.json') + ..createSync(recursive: true) + ..writeAsStringSync('{"configVersion":2,"packages":[]}'); + } } } diff --git a/packages/flutter_tools/test/commands.shard/hermetic/update_packages_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/update_packages_test.dart index 1456bacc1ca1c..56b9fa0d7a120 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/update_packages_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/update_packages_test.dart @@ -275,7 +275,6 @@ class FakePub extends Fake implements Pub { Future get({ required PubContext context, required FlutterProject project, - bool skipIfAbsent = false, bool upgrade = false, bool offline = false, bool generateSyntheticPackage = false, diff --git a/packages/flutter_tools/test/commands.shard/permeable/packages_test.dart b/packages/flutter_tools/test/commands.shard/permeable/packages_test.dart index c96b1474e7c4b..4bd4f811aace3 100644 --- a/packages/flutter_tools/test/commands.shard/permeable/packages_test.dart +++ b/packages/flutter_tools/test/commands.shard/permeable/packages_test.dart @@ -72,6 +72,7 @@ void main() { 'packages', verb, ...?args, + '--directory', projectPath, ]); return command; diff --git a/packages/flutter_tools/test/general.shard/cache_test.dart b/packages/flutter_tools/test/general.shard/cache_test.dart index 9ae86725b343c..de4229c2d59c0 100644 --- a/packages/flutter_tools/test/general.shard/cache_test.dart +++ b/packages/flutter_tools/test/general.shard/cache_test.dart @@ -1208,7 +1208,6 @@ class FakePub extends Fake implements Pub { Future get({ PubContext? context, required FlutterProject project, - bool skipIfAbsent = false, bool upgrade = false, bool offline = false, bool generateSyntheticPackage = false, diff --git a/packages/flutter_tools/test/general.shard/dart/pub_get_test.dart b/packages/flutter_tools/test/general.shard/dart/pub_get_test.dart index d3a8bc50068c5..173a1a7b50eb8 100644 --- a/packages/flutter_tools/test/general.shard/dart/pub_get_test.dart +++ b/packages/flutter_tools/test/general.shard/dart/pub_get_test.dart @@ -557,7 +557,7 @@ exit code: 66 ), throwsA(isA().having((ToolExit error) => error.message, 'message', toolExitMessage)), ); - expect(logger.statusText, 'Running "flutter pub get" in /...\n'); + expect(logger.statusText, isEmpty); expect( mockStdio.stdout.writes.map(utf8.decode), [ @@ -634,9 +634,7 @@ exit code: 66 ), ), ); - expect(logger.statusText, - 'Running "flutter pub get" in /...\n' - ); + expect(logger.statusText, isEmpty); expect(logger.errorText, isEmpty); expect(processManager, hasNoRemainingExpectations); }); @@ -1074,7 +1072,6 @@ exit code: 66 context: PubContext.flutterTests, ); // pub sets date of .packages to 2002 - expect(logger.statusText, 'Running "flutter pub get" in /...\n'); expect(logger.errorText, isEmpty); expect(fileSystem.file('pubspec.yaml').lastModifiedSync(), DateTime(2001)); // because nothing should touch it logger.clear(); @@ -1089,7 +1086,7 @@ exit code: 66 context: PubContext.flutterTests, ); // pub does nothing - expect(logger.statusText, 'Running "flutter pub get" in /...\n'); + expect(logger.statusText, isEmpty); expect(logger.errorText, isEmpty); expect(fileSystem.file('pubspec.yaml').lastModifiedSync(), DateTime(2001)); // because nothing should touch it logger.clear(); diff --git a/packages/flutter_tools/test/general.shard/runner/flutter_command_test.dart b/packages/flutter_tools/test/general.shard/runner/flutter_command_test.dart index 765773ed9dd4b..4f5d774a6d429 100644 --- a/packages/flutter_tools/test/general.shard/runner/flutter_command_test.dart +++ b/packages/flutter_tools/test/general.shard/runner/flutter_command_test.dart @@ -951,7 +951,6 @@ class FakePub extends Fake implements Pub { Future get({ required PubContext context, required FlutterProject project, - bool skipIfAbsent = false, bool upgrade = false, bool offline = false, String? flutterRootOverride, diff --git a/packages/flutter_tools/test/src/fake_process_manager.dart b/packages/flutter_tools/test/src/fake_process_manager.dart index fb87570c873c8..e0fc5102db676 100644 --- a/packages/flutter_tools/test/src/fake_process_manager.dart +++ b/packages/flutter_tools/test/src/fake_process_manager.dart @@ -110,15 +110,8 @@ class FakeCommand { Map? environment, Encoding? encoding, ) { - expect(command.length, this.command.length); - for(int i = 0; i < command.length; i++) { - final Pattern expected = this.command[i]; - if (expected is String) { - expect(command[i], expected); - } else { - expect(command[i], matches(this.command[i])); - } - } + final List matchers = this.command.map((Pattern x) => x is String ? x : matches(x)).toList(); + expect(command, matchers); if (this.workingDirectory != null) { expect(this.workingDirectory, workingDirectory); } diff --git a/packages/flutter_tools/test/src/throwing_pub.dart b/packages/flutter_tools/test/src/throwing_pub.dart index c00a7f12d5d92..a96d13375ab00 100644 --- a/packages/flutter_tools/test/src/throwing_pub.dart +++ b/packages/flutter_tools/test/src/throwing_pub.dart @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:flutter_tools/src/base/io.dart'; import 'package:flutter_tools/src/dart/pub.dart'; import 'package:flutter_tools/src/project.dart'; @@ -21,7 +20,6 @@ class ThrowingPub implements Pub { Future get({ PubContext? context, required FlutterProject project, - bool skipIfAbsent = false, bool upgrade = false, bool offline = false, bool checkLastModified = true, @@ -39,10 +37,12 @@ class ThrowingPub implements Pub { @override Future interactively( List arguments, { - String? directory, - required Stdio stdio, + FlutterProject? project, + required PubContext context, + required String command, bool touchesPackageConfig = false, bool generateSyntheticPackage = false, + bool printProgress = true, }) { throw UnsupportedError('Attempted to invoke pub during test.'); } From 12b43ed8a3c775339e484a6457f88d0bd035942c Mon Sep 17 00:00:00 2001 From: engine-flutter-autoroll Date: Tue, 10 Jan 2023 20:39:25 -0500 Subject: [PATCH 12/17] ae9e181e3 Roll Dart SDK from 5e344de60564 to 7b4d49402252 (1 revision) (flutter/engine#38756) (#118287) --- bin/internal/engine.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/internal/engine.version b/bin/internal/engine.version index 5bb9105ab93a3..198e1443880e2 100644 --- a/bin/internal/engine.version +++ b/bin/internal/engine.version @@ -1 +1 @@ -c1d61cf11da89cfcf83e8df2c20aa0ebe4dd9995 +ae9e181e30c28f295361c534fd255daa84e8c4a9 From b13f83a2ba1853fac21f7f7a50d0a62e2383441e Mon Sep 17 00:00:00 2001 From: Tae Hyung Kim Date: Tue, 10 Jan 2023 17:41:54 -0800 Subject: [PATCH 13/17] Fix Finnish TimeOfDate format (#118204) * init * add test --- .../lib/src/l10n/generated_material_localizations.dart | 2 +- packages/flutter_localizations/lib/src/l10n/material_fi.arb | 2 +- .../flutter_localizations/test/material/date_time_test.dart | 5 +++++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/flutter_localizations/lib/src/l10n/generated_material_localizations.dart b/packages/flutter_localizations/lib/src/l10n/generated_material_localizations.dart index f9783e28b1737..1d3f7d9dfab3c 100644 --- a/packages/flutter_localizations/lib/src/l10n/generated_material_localizations.dart +++ b/packages/flutter_localizations/lib/src/l10n/generated_material_localizations.dart @@ -13227,7 +13227,7 @@ class MaterialLocalizationFi extends GlobalMaterialLocalizations { String get tabLabelRaw => r'Välilehti $tabIndex/$tabCount'; @override - TimeOfDayFormat get timeOfDayFormatRaw => TimeOfDayFormat.HH_colon_mm; + TimeOfDayFormat get timeOfDayFormatRaw => TimeOfDayFormat.HH_dot_mm; @override String get timePickerDialHelpText => 'VALITSE AIKA'; diff --git a/packages/flutter_localizations/lib/src/l10n/material_fi.arb b/packages/flutter_localizations/lib/src/l10n/material_fi.arb index 5459422ecae89..451d30d8c5e09 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_fi.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_fi.arb @@ -1,6 +1,6 @@ { "scriptCategory": "English-like", - "timeOfDayFormat": "HH:mm", + "timeOfDayFormat": "HH.mm", "openAppDrawerTooltip": "Avaa navigointivalikko", "backButtonTooltip": "Takaisin", "closeButtonTooltip": "Sulje", diff --git a/packages/flutter_localizations/test/material/date_time_test.dart b/packages/flutter_localizations/test/material/date_time_test.dart index 5b544b8a131b0..9b32c582bd78e 100644 --- a/packages/flutter_localizations/test/material/date_time_test.dart +++ b/packages/flutter_localizations/test/material/date_time_test.dart @@ -107,6 +107,11 @@ void main() { expect(await formatTimeOfDay(tester, const Locale('ja'), const TimeOfDay(hour: 20, minute: 32)), '20:32'); }); + testWidgets('formats ${TimeOfDayFormat.HH_dot_mm}', (WidgetTester tester) async { + expect(await formatTimeOfDay(tester, const Locale('fi'), const TimeOfDay(hour: 20, minute: 32)), '20.32'); + expect(await formatTimeOfDay(tester, const Locale('fi'), const TimeOfDay(hour: 9, minute: 32)), '09.32'); + }); + testWidgets('formats ${TimeOfDayFormat.frenchCanadian}', (WidgetTester tester) async { expect(await formatTimeOfDay(tester, const Locale('fr', 'CA'), const TimeOfDay(hour: 9, minute: 32)), '09 h 32'); }); From 55e3894a8ca39c82e7a24af5d8732b7aba3e7b37 Mon Sep 17 00:00:00 2001 From: engine-flutter-autoroll Date: Tue, 10 Jan 2023 21:37:34 -0500 Subject: [PATCH 14/17] Roll Flutter Engine from ae9e181e30c2 to 53bd4bbf9646 (3 revisions) (#118289) * b9a723482 [web] retain GL/Gr context on window resize (flutter/engine#38576) * fd4360671 Add SpringAnimation.js from React Native (flutter/engine#38750) * 53bd4bbf9 Roll Skia from b8c0a78a2378 to e1f3980272f3 (24 revisions) (flutter/engine#38758) --- bin/internal/engine.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/internal/engine.version b/bin/internal/engine.version index 198e1443880e2..909ba6e97b5bf 100644 --- a/bin/internal/engine.version +++ b/bin/internal/engine.version @@ -1 +1 @@ -ae9e181e30c28f295361c534fd255daa84e8c4a9 +53bd4bbf9646b5a0300785474db643e7e5696ce0 From a40fb9bdd76a5d8a3f135feaedc3b41b8996d482 Mon Sep 17 00:00:00 2001 From: engine-flutter-autoroll Date: Wed, 11 Jan 2023 00:57:24 -0500 Subject: [PATCH 15/17] 9ade91c8b removed forbidden skia include (flutter/engine#38761) (#118296) --- bin/internal/engine.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/internal/engine.version b/bin/internal/engine.version index 909ba6e97b5bf..3ffac4ce004aa 100644 --- a/bin/internal/engine.version +++ b/bin/internal/engine.version @@ -1 +1 @@ -53bd4bbf9646b5a0300785474db643e7e5696ce0 +9ade91c8b3134dcd618691529f28ef6e87c16ce1 From 32b1ea3b58cb08570972ef8972a8edfa50fdfb58 Mon Sep 17 00:00:00 2001 From: engine-flutter-autoroll Date: Wed, 11 Jan 2023 01:46:08 -0500 Subject: [PATCH 16/17] 8d7beac82 Roll Dart SDK from 7b4d49402252 to 23cbd61a1327 (1 revision) (flutter/engine#38764) (#118297) --- bin/internal/engine.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/internal/engine.version b/bin/internal/engine.version index 3ffac4ce004aa..de4e77c8b804a 100644 --- a/bin/internal/engine.version +++ b/bin/internal/engine.version @@ -1 +1 @@ -9ade91c8b3134dcd618691529f28ef6e87c16ce1 +8d7beac8220dd534ecb18044619c284093707a28 From 957781a108ff3a555e4df36beb8c1ebe12c85051 Mon Sep 17 00:00:00 2001 From: engine-flutter-autoroll Date: Wed, 11 Jan 2023 04:04:39 -0500 Subject: [PATCH 17/17] 6256f05db Roll Fuchsia Mac SDK from 6xysoRPCXJ3cJX12x... to a9NpYJbjhDRX9P9u4... (flutter/engine#38767) (#118300) --- bin/internal/engine.version | 2 +- bin/internal/fuchsia-mac.version | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/internal/engine.version b/bin/internal/engine.version index de4e77c8b804a..f44d1d2b3c30d 100644 --- a/bin/internal/engine.version +++ b/bin/internal/engine.version @@ -1 +1 @@ -8d7beac8220dd534ecb18044619c284093707a28 +6256f05db145b2bb8b690901cf128389599e0282 diff --git a/bin/internal/fuchsia-mac.version b/bin/internal/fuchsia-mac.version index 394b1f208b385..d5422472020e9 100644 --- a/bin/internal/fuchsia-mac.version +++ b/bin/internal/fuchsia-mac.version @@ -1 +1 @@ -6xysoRPCXJ3cJX12x2Z-uYCsDxak4cGAcywM84p3TSkC +a9NpYJbjhDRX9P9u4EU-v-v3y5U7jG4VvhvYLzR8a9QC