Remove the Flutter pub root directory if it was accidentally cached (#6911)
diff --git a/packages/devtools_app/lib/src/shared/preferences.dart b/packages/devtools_app/lib/src/shared/preferences.dart index 45acca3..1cd671b 100644 --- a/packages/devtools_app/lib/src/shared/preferences.dart +++ b/packages/devtools_app/lib/src/shared/preferences.dart
@@ -159,6 +159,7 @@ static const _customPubRootDirectoriesStoragePrefix = 'inspector.customPubRootDirectories'; String? _mainScriptDir; + bool _checkedFlutterPubRoot = false; Future<void> _updateMainScriptRef() async { final rootLibUriString = @@ -252,6 +253,7 @@ @visibleForTesting Future<void> handleConnectionToNewService() async { + _checkedFlutterPubRoot = false; await _updateMainScriptRef(); await _updateHoverEvalMode(); await loadPubRootDirectories(); @@ -277,12 +279,30 @@ final cachedDirectoriesJson = await storage.getValue(_customPubRootStorageId()); if (cachedDirectoriesJson == null) return <String>[]; - - return List<String>.from( + final cachedDirectories = List<String>.from( jsonDecode(cachedDirectoriesJson), ); + + // Remove the Flutter pub root directory if it was accidentally cached. + // See: + // - https://github.com/flutter/devtools/issues/6882 + // - https://github.com/flutter/devtools/issues/6841 + if (!_checkedFlutterPubRoot && cachedDirectories.any(_isFlutterPubRoot)) { + // Set [_checkedFlutterPubRoot] to true to avoid an infinite loop on the + // next call to [removePubRootDirectories]: + _checkedFlutterPubRoot = true; + final flutterPubRootDirectories = + cachedDirectories.where(_isFlutterPubRoot).toList(); + await removePubRootDirectories(flutterPubRootDirectories); + cachedDirectories.removeWhere(_isFlutterPubRoot); + } + + return cachedDirectories; } + bool _isFlutterPubRoot(String directory) => + directory.endsWith('packages/flutter'); + /// As we aren't running from an IDE, we don't know exactly what the pub root /// directories are for the current project so we make a best guess based on /// the root library for the main isolate.
diff --git a/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md b/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md index 59ced0c..cfd2c3f 100644 --- a/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md +++ b/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md
@@ -15,6 +15,7 @@ ## Inspector updates * Only cache pub root directories added by the user - [6897](https://github.com/flutter/devtools/pull/6897) +* Remove Flutter pub root if it was accidently cached - [6911](https://github.com/flutter/devtools/pull/6911) ## Performance updates
diff --git a/packages/devtools_app/test/shared/preferences_controller_test.dart b/packages/devtools_app/test/shared/preferences_controller_test.dart index b7dc518..0235212 100644 --- a/packages/devtools_app/test/shared/preferences_controller_test.dart +++ b/packages/devtools_app/test/shared/preferences_controller_test.dart
@@ -270,11 +270,8 @@ test( 'does not save inferred directory to local cache', () async { - final cachedDirectoriesJson = await storage - .getValue('inspector.customPubRootDirectories_myPackage'); - final cachedDirectories = List<String>.from( - jsonDecode(cachedDirectoriesJson!), - ); + final cachedDirectories = + await controller.readCachedPubRootDirectories(); expect(cachedDirectories, isNot(contains('test_dir/fake_app'))); }, @@ -286,12 +283,8 @@ await controller.addPubRootDirectories( ['test_dir/fake_app/do_not_cache_dir'], ); - - final cachedDirectoriesJson = await storage - .getValue('inspector.customPubRootDirectories_myPackage'); - final cachedDirectories = List<String>.from( - jsonDecode(cachedDirectoriesJson!), - ); + final cachedDirectories = + await controller.readCachedPubRootDirectories(); expect( cachedDirectories, @@ -300,6 +293,78 @@ }, ); }); + + test('Flutter pub root is removed from cache on app connection', () async { + updateMainIsolateRootLibrary('test_dir/fake_app/lib/main.dart'); + await storage.setValue( + 'inspector.customPubRootDirectories_myPackage', + jsonEncode( + [ + 'flutter_dir/flutter/packages/flutter', + 'test_dir/fake_app/custom_dir1', + ], + ), + ); + await controller.handleConnectionToNewService(); + final cachedDirectories = await controller.readCachedPubRootDirectories(); + + expect( + cachedDirectories, + isNot(contains('flutter_dir/flutter/packages/flutter')), + ); + expect( + cachedDirectories, + contains('test_dir/fake_app/custom_dir1'), + ); + }); + + test( + 'Flutter pub root is removed from cache across multiple app connections', + () async { + updateMainIsolateRootLibrary('test_dir/fake_app/lib/main.dart'); + await storage.setValue( + 'inspector.customPubRootDirectories_myPackage', + jsonEncode( + [ + 'flutter_dir/flutter/packages/flutter', + 'test_dir/fake_app/custom_dir1', + ], + ), + ); + await controller.handleConnectionToNewService(); + var cachedDirectories = await controller.readCachedPubRootDirectories(); + + expect( + cachedDirectories, + isNot(contains('flutter_dir/flutter/packages/flutter')), + ); + expect( + cachedDirectories, + contains('test_dir/fake_app/custom_dir1'), + ); + + await storage.setValue( + 'inspector.customPubRootDirectories_myPackage', + jsonEncode( + [ + 'flutter_dir/flutter/packages/flutter', + 'test_dir/fake_app/custom_dir2', + ], + ), + ); + await controller.handleConnectionToNewService(); + cachedDirectories = await controller.readCachedPubRootDirectories(); + + expect( + cachedDirectories, + isNot(contains('flutter_dir/flutter/packages/flutter')), + ); + expect( + cachedDirectories, + contains('test_dir/fake_app/custom_dir2'), + ); + }, + ); }); group('$MemoryPreferencesController', () {