From 0223a3230fd15d538aa63f6d7bb0b1060ea2bba6 Mon Sep 17 00:00:00 2001 From: Kenzie Davisson <43759233+kenzieschmoll@users.noreply.github.com> Date: Tue, 26 Mar 2024 15:38:26 -0700 Subject: [PATCH] Use DTD project roots instead of workspace roots for Deep links tool (#7431) --- .../select_project_view.dart | 17 +++---- .../lib/src/shared/directory_picker.dart | 12 ++--- .../lib/src/shared/primitives/utils.dart | 7 +++ packages/devtools_app/pubspec.yaml | 2 +- .../release_notes/NEXT_RELEASE_NOTES.md | 2 +- .../deep_links_screen_test.dart | 4 +- .../test/primitives/utils_test.dart | 11 ++++ packages/devtools_app_shared/CHANGELOG.md | 5 ++ .../lib/src/service/dtd_manager.dart | 50 +++++++++++++++++++ packages/devtools_app_shared/pubspec.yaml | 4 +- packages/devtools_extensions/CHANGELOG.md | 2 +- packages/devtools_extensions/pubspec.yaml | 2 +- packages/devtools_shared/CHANGELOG.md | 7 ++- packages/devtools_shared/pubspec.yaml | 4 +- 14 files changed, 99 insertions(+), 30 deletions(-) diff --git a/packages/devtools_app/lib/src/screens/deep_link_validation/select_project_view.dart b/packages/devtools_app/lib/src/screens/deep_link_validation/select_project_view.dart index 9422bc2ce38..6d372beeef1 100644 --- a/packages/devtools_app/lib/src/screens/deep_link_validation/select_project_view.dart +++ b/packages/devtools_app/lib/src/screens/deep_link_validation/select_project_view.dart @@ -5,13 +5,13 @@ import 'dart:async'; import 'package:devtools_app_shared/ui.dart'; -import 'package:dtd/dtd.dart'; import 'package:flutter/material.dart'; import '../../shared/analytics/analytics.dart' as ga; import '../../shared/analytics/constants.dart' as gac; import '../../shared/directory_picker.dart'; import '../../shared/globals.dart'; +import '../../shared/primitives/utils.dart'; import '../../shared/server/server.dart' as server; import '../../shared/utils.dart'; import 'deep_links_controller.dart'; @@ -31,7 +31,7 @@ class _SelectProjectViewState extends State with ProvidedControllerMixin { bool _retrievingFlutterProject = false; - IDEWorkspaceRoots? workspaceRoots; + List? projectRoots; @override void initState() { @@ -40,13 +40,9 @@ class _SelectProjectViewState extends State } Future _initWorkspaceRoots() async { - // TODO(kenz): this does not work well for mono-repos. What we really need - // to do is add a DevTools server API that looks through the DevTools - // project roots and returns all subdirectories that contain a pubspec.yaml - // file (maybe with a Flutter dependency?). - final roots = await dtdManager.workspaceRoots(); + final roots = await dtdManager.projectRoots(); setState(() { - workspaceRoots = roots; + projectRoots = roots?.uris; }); } @@ -127,10 +123,9 @@ class _SelectProjectViewState extends State style: Theme.of(context).textTheme.titleSmall, ), ), - if (workspaceRoots != null && - workspaceRoots!.ideWorkspaceRoots.isNotEmpty) ...[ + if (!projectRoots.isNullOrEmpty) ...[ ProjectRootsDropdown( - workspaceRoots: workspaceRoots!, + projectRoots: projectRoots!, onValidatePressed: _handleValidateProject, ), const SizedBox(height: largeSpacing), diff --git a/packages/devtools_app/lib/src/shared/directory_picker.dart b/packages/devtools_app/lib/src/shared/directory_picker.dart index 420742aecd8..f160365af78 100644 --- a/packages/devtools_app/lib/src/shared/directory_picker.dart +++ b/packages/devtools_app/lib/src/shared/directory_picker.dart @@ -4,7 +4,6 @@ import 'package:devtools_app_shared/ui.dart'; import 'package:devtools_app_shared/utils.dart'; -import 'package:dtd/dtd.dart'; import 'package:flutter/material.dart'; import 'common_widgets.dart'; @@ -86,12 +85,12 @@ class _ProjectRootTextFieldState extends State class ProjectRootsDropdown extends StatefulWidget { ProjectRootsDropdown({ - required this.workspaceRoots, + required this.projectRoots, required this.onValidatePressed, super.key, - }) : assert(workspaceRoots.ideWorkspaceRoots.isNotEmpty); + }) : assert(projectRoots.isNotEmpty); - final IDEWorkspaceRoots workspaceRoots; + final List projectRoots; final void Function(String) onValidatePressed; @@ -105,7 +104,7 @@ class _ProjectRootsDropdownState extends State { @override void initState() { super.initState(); - selectedUri = widget.workspaceRoots.ideWorkspaceRoots.safeFirst; + selectedUri = widget.projectRoots.safeFirst; } @override @@ -116,8 +115,7 @@ class _ProjectRootsDropdownState extends State { RoundedDropDownButton( value: selectedUri, items: [ - for (final uri in widget.workspaceRoots.ideWorkspaceRoots) - _buildMenuItem(uri), + for (final uri in widget.projectRoots) _buildMenuItem(uri), ], onChanged: (uri) => setState(() { selectedUri = uri; diff --git a/packages/devtools_app/lib/src/shared/primitives/utils.dart b/packages/devtools_app/lib/src/shared/primitives/utils.dart index 4aeeeeb5462..1f93d1cfe77 100644 --- a/packages/devtools_app/lib/src/shared/primitives/utils.dart +++ b/packages/devtools_app/lib/src/shared/primitives/utils.dart @@ -1061,6 +1061,13 @@ extension ListExtension on List { } } +extension NullableListExtension on List? { + bool get isNullOrEmpty { + final self = this; + return self == null || self.isEmpty; + } +} + extension SetExtension on Set { bool containsWhere(bool Function(T element) test) { for (var e in this) { diff --git a/packages/devtools_app/pubspec.yaml b/packages/devtools_app/pubspec.yaml index 9fb032aa3a5..abc70b9f9f0 100644 --- a/packages/devtools_app/pubspec.yaml +++ b/packages/devtools_app/pubspec.yaml @@ -27,7 +27,7 @@ dependencies: devtools_app_shared: ^0.1.0 devtools_extensions: ^0.0.10 devtools_shared: ^6.0.1 - dtd: ^2.0.0 + dtd: ^2.1.0 file: ">=6.0.0 <8.0.0" file_selector: ^1.0.0 fixnum: ^1.1.0 diff --git a/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md b/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md index ebf0528f8d7..6c5bba59130 100644 --- a/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md +++ b/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md @@ -59,7 +59,7 @@ TODO: Remove this section if there are not any general updates. ## Deep Links tool updates * Automatically populate a list of Flutter projects from the connected -IDE. - [#7415](https://github.com/flutter/devtools/pull/7415) +IDE. - [#7415](https://github.com/flutter/devtools/pull/7415), [#7431](https://github.com/flutter/devtools/pull/7431) ## App size tool updates diff --git a/packages/devtools_app/test/deep_link_vlidation/deep_links_screen_test.dart b/packages/devtools_app/test/deep_link_vlidation/deep_links_screen_test.dart index 203b8fbe322..a3885b85018 100644 --- a/packages/devtools_app/test/deep_link_vlidation/deep_links_screen_test.dart +++ b/packages/devtools_app/test/deep_link_vlidation/deep_links_screen_test.dart @@ -74,8 +74,8 @@ void main() { final mockDtdManager = MockDTDManager(); final rootUri1 = Uri.parse('file:///Users/me/package_root_1'); final rootUri2 = Uri.parse('file:///Users/me/package_root_2'); - when(mockDtdManager.workspaceRoots()).thenAnswer((_) async { - return IDEWorkspaceRoots(ideWorkspaceRoots: [rootUri1, rootUri2]); + when(mockDtdManager.projectRoots()).thenAnswer((_) async { + return UriList(uris: [rootUri1, rootUri2]); }); setGlobal(DTDManager, mockDtdManager); }); diff --git a/packages/devtools_app/test/primitives/utils_test.dart b/packages/devtools_app/test/primitives/utils_test.dart index 659bf763d05..e9b66a5ba1e 100644 --- a/packages/devtools_app/test/primitives/utils_test.dart +++ b/packages/devtools_app/test/primitives/utils_test.dart @@ -1125,6 +1125,17 @@ void main() { }); }); + group('NullableListExtension', () { + test('isNullOrEmpty', () { + List? nullableList; + expect(nullableList.isNullOrEmpty, true); + nullableList = []; + expect(nullableList.isNullOrEmpty, true); + nullableList.add(1); + expect(nullableList.isNullOrEmpty, false); + }); + }); + group('SetExtension', () { test('containsWhere', () { final set = {1, 2, 3, 4}; diff --git a/packages/devtools_app_shared/CHANGELOG.md b/packages/devtools_app_shared/CHANGELOG.md index f3bdd5d7761..a1aca695a84 100644 --- a/packages/devtools_app_shared/CHANGELOG.md +++ b/packages/devtools_app_shared/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.1-dev.0 +* Update `package:dtd` to `^2.1.0` +* Add `DTDManager.projectRoots` method. + ## 0.1.0 * Remove deprecated `background` and `onBackground` values for `lightColorScheme` and `darkColorScheme`. @@ -6,6 +10,7 @@ and `darkColorScheme`. * Update readme to use `pub add` instead of explicit package version. * Update `package:dtd` to `^2.0.0` * Update `package:devtools_shared` to `^8.1.0` +* Add `DTDManager.workspaceRoots` method. ## 0.0.10 * Add `DTDManager` class and export from `service.dart`. diff --git a/packages/devtools_app_shared/lib/src/service/dtd_manager.dart b/packages/devtools_app_shared/lib/src/service/dtd_manager.dart index b8cc8d2b552..a12499b3244 100644 --- a/packages/devtools_app_shared/lib/src/service/dtd_manager.dart +++ b/packages/devtools_app_shared/lib/src/service/dtd_manager.dart @@ -48,8 +48,25 @@ class DTDManager { _connection.value = null; _uri = null; + _workspaceRoots = null; + _projectRoots = null; } + /// Returns the workspace roots for the Dart Tooling Daemon connection. + /// + /// These roots are set by the tool that started DTD, which may be the IDE, + /// DevTools server, or DDS (the Dart Development Service managed by the Dart + /// or Flutter CLI tools). + /// + /// A workspace root is considered any directory that is at the root of the + /// IDE's open project or workspace, or in the case where the Dart Tooling + /// Daemon was started from the DevTools server or DDS (e.g. an app ran from + /// the CLI), a workspace root is the root directory for the Dart or Flutter + /// program connected to DevTools. + /// + /// By default, the cached value [_workspaceRoots] will be returned when + /// available. When [forceRefresh] is true, the cached value will be cleared + /// and recomputed. Future workspaceRoots({bool forceRefresh = false}) async { if (hasConnection) { if (_workspaceRoots != null && forceRefresh) { @@ -67,4 +84,37 @@ class DTDManager { } IDEWorkspaceRoots? _workspaceRoots; + + /// Returns the project roots for the Dart Tooling Daemon connection. + /// + /// A project root is any directory, contained within the current set of + /// [workspaceRoots], that contains a 'pubspec.yaml' file. + /// + /// By default, the cached value [_projectRoots] will be returned when + /// available. When [forceRefresh] is true, the cached value will be cleared + /// and recomputed. + /// + /// [depth] is the maximum depth that each workspace root directory tree will + /// will be searched for project roots. Setting [depth] to a large number + /// may have performance implications when traversing large trees. + Future projectRoots({ + int? depth = defaultGetProjectRootsDepth, + bool forceRefresh = false, + }) async { + if (hasConnection) { + if (_projectRoots != null && forceRefresh) { + _projectRoots = null; + } + try { + return _projectRoots ??= + await _connection.value!.getProjectRoots(depth: depth!); + } catch (e) { + _log.fine('Error fetching project roots: $e'); + return null; + } + } + return null; + } + + UriList? _projectRoots; } diff --git a/packages/devtools_app_shared/pubspec.yaml b/packages/devtools_app_shared/pubspec.yaml index 4be862285f6..6f1963d26e0 100644 --- a/packages/devtools_app_shared/pubspec.yaml +++ b/packages/devtools_app_shared/pubspec.yaml @@ -1,6 +1,6 @@ name: devtools_app_shared description: Package of Dart & Flutter structures shared between devtools_app and devtools extensions. -version: 0.1.0 +version: 0.1.1-dev.0 repository: https://github.com/flutter/devtools/tree/master/packages/devtools_app_shared environment: @@ -10,7 +10,7 @@ environment: dependencies: collection: ^1.15.0 devtools_shared: ^8.1.0 - dtd: ^2.0.0 + dtd: ^2.1.0 flutter: sdk: flutter logging: ^1.1.1 diff --git a/packages/devtools_extensions/CHANGELOG.md b/packages/devtools_extensions/CHANGELOG.md index 81a9fff82fc..8a87c5d3e52 100644 --- a/packages/devtools_extensions/CHANGELOG.md +++ b/packages/devtools_extensions/CHANGELOG.md @@ -1,4 +1,4 @@ -## 0.1.1-wip +## 0.1.1-dev.0 * Update the simulated environment help dialogs with information about the new `--print-dtd` CLI flag. diff --git a/packages/devtools_extensions/pubspec.yaml b/packages/devtools_extensions/pubspec.yaml index 49cd653a9fa..89b11b74975 100644 --- a/packages/devtools_extensions/pubspec.yaml +++ b/packages/devtools_extensions/pubspec.yaml @@ -1,6 +1,6 @@ name: devtools_extensions description: A package for building and supporting extensions for Dart DevTools. -version: 0.1.1-wip +version: 0.1.1-dev.0 repository: https://github.com/flutter/devtools/tree/master/packages/devtools_extensions diff --git a/packages/devtools_shared/CHANGELOG.md b/packages/devtools_shared/CHANGELOG.md index 2e2dbc771ed..a4299415e3e 100644 --- a/packages/devtools_shared/CHANGELOG.md +++ b/packages/devtools_shared/CHANGELOG.md @@ -1,6 +1,9 @@ +# 8.1.1-wip +* Update `package:dtd` to `2.1.0`. + # 8.1.0 -* Update `package:dtd` to `2.0.0` -* Update `package:unified_analytics` to `5.8.8` +* Update `package:dtd` to `2.0.0`. +* Update `package:unified_analytics` to `5.8.8`. # 8.0.1 * **Breaking change:** rename `ServerApi.getCompleted` to `ServerApi.success` and make the diff --git a/packages/devtools_shared/pubspec.yaml b/packages/devtools_shared/pubspec.yaml index b66320e90de..122dbd08744 100644 --- a/packages/devtools_shared/pubspec.yaml +++ b/packages/devtools_shared/pubspec.yaml @@ -1,7 +1,7 @@ name: devtools_shared description: Package of shared Dart structures between devtools_app, dds, and other tools. -version: 8.1.0 +version: 8.1.1-wip repository: https://github.com/flutter/devtools/tree/master/packages/devtools_shared @@ -11,7 +11,7 @@ environment: dependencies: args: ^2.4.2 collection: ^1.15.0 - dtd: ^2.0.0 + dtd: ^2.1.0 extension_discovery: ^2.0.0 meta: ^1.9.1 path: ^1.8.0