Skip to content

Commit 2a5eb30

Browse files
authored
pass the provided root instead of the resolved root for project type detection (#150)
Changed `commandForRoot` and `inferProjectRoot` to take a String (the root uri) instead of a Root or support this.
1 parent 16799ee commit 2a5eb30

File tree

2 files changed

+41
-11
lines changed

2 files changed

+41
-11
lines changed

pkgs/dart_mcp_server/lib/src/utils/cli_utils.dart

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,16 @@ enum ProjectKind {
2626
unknown,
2727
}
2828

29-
/// Infers the [ProjectKind] of a given [Root].
29+
/// Infers the [ProjectKind] of a given project at [rootUri].
3030
///
3131
/// Currently, this is done by checking for the existence of a `pubspec.yaml`
3232
/// file and whether it contains a Flutter SDK dependency.
33-
Future<ProjectKind> inferProjectKind(Root root, FileSystem fileSystem) async {
33+
Future<ProjectKind> inferProjectKind(
34+
String rootUri,
35+
FileSystem fileSystem,
36+
) async {
3437
final pubspecFile = fileSystem
35-
.directory(Uri.parse(root.uri))
38+
.directory(Uri.parse(rootUri))
3639
.childFile('pubspec.yaml');
3740
if (!await pubspecFile.exists()) {
3841
return ProjectKind.unknown;
@@ -73,7 +76,7 @@ Future<ProjectKind> inferProjectKind(Root root, FileSystem fileSystem) async {
7376
/// root's 'paths'.
7477
Future<CallToolResult> runCommandInRoots(
7578
CallToolRequest request, {
76-
FutureOr<String> Function(Root, FileSystem, Sdk) commandForRoot =
79+
FutureOr<String> Function(String, FileSystem, Sdk) commandForRoot =
7780
defaultCommandForRoot,
7881
List<String> arguments = const [],
7982
required String commandDescription,
@@ -138,7 +141,7 @@ Future<CallToolResult> runCommandInRoots(
138141
Future<CallToolResult> runCommandInRoot(
139142
CallToolRequest request, {
140143
Map<String, Object?>? rootConfig,
141-
FutureOr<String> Function(Root, FileSystem, Sdk) commandForRoot =
144+
FutureOr<String> Function(String, FileSystem, Sdk) commandForRoot =
142145
defaultCommandForRoot,
143146
List<String> arguments = const [],
144147
required String commandDescription,
@@ -192,7 +195,7 @@ Future<CallToolResult> runCommandInRoot(
192195
final projectRoot = fileSystem.directory(rootUri);
193196

194197
final commandWithPaths = <String>[
195-
await commandForRoot(root, fileSystem, sdk),
198+
await commandForRoot(rootUriString, fileSystem, sdk),
196199
...arguments,
197200
];
198201
final paths =
@@ -247,17 +250,17 @@ Future<CallToolResult> runCommandInRoot(
247250
///
248251
/// Throws an [ArgumentError] if there is no pubspec.
249252
Future<String> defaultCommandForRoot(
250-
Root root,
253+
String rootUri,
251254
FileSystem fileSystem,
252255
Sdk sdk,
253-
) async => switch (await inferProjectKind(root, fileSystem)) {
256+
) async => switch (await inferProjectKind(rootUri, fileSystem)) {
254257
ProjectKind.dart => sdk.dartExecutablePath,
255258
ProjectKind.flutter => sdk.flutterExecutablePath,
256259
ProjectKind.unknown =>
257260
throw ArgumentError.value(
258-
root.uri,
259-
'root.uri',
260-
'Unknown project kind at root ${root.uri}. All projects must have a '
261+
rootUri,
262+
'rootUri',
263+
'Unknown project kind at root $rootUri. All projects must have a '
261264
'pubspec.',
262265
),
263266
};

pkgs/dart_mcp_server/test/tools/pub_test.dart

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,33 @@ void main() {
141141
]);
142142
});
143143

144+
test('in a subdir of an a root', () async {
145+
fileSystem.file(p.join(fakeAppPath, 'subdir', 'pubspec.yaml'))
146+
..createSync(recursive: true)
147+
..writeAsStringSync(
148+
appKind == 'flutter' ? flutterPubspec : dartPubspec,
149+
);
150+
final request = CallToolRequest(
151+
name: dartPubTool.name,
152+
arguments: {
153+
ParameterNames.command: 'get',
154+
ParameterNames.roots: [
155+
{ParameterNames.root: p.join(testRoot.uri, 'subdir')},
156+
],
157+
},
158+
);
159+
final result = await testHarness.callToolWithRetry(request);
160+
161+
// Verify the command was sent to the process manager without error.
162+
expect(result.isError, isNot(true));
163+
expect(testProcessManager.commandsRan, [
164+
equalsCommand((
165+
command: [endsWith(appKind), 'pub', 'get'],
166+
workingDirectory: p.join(fakeAppPath, 'subdir'),
167+
)),
168+
]);
169+
});
170+
144171
group('returns error', () {
145172
test('for missing command', () async {
146173
final request = CallToolRequest(name: dartPubTool.name);

0 commit comments

Comments
 (0)