Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions packages/arcade_cli/lib/commands/serve.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,23 @@ class ServeCommand extends Command {
@override
String get description => 'Locally serve your app';

/// Builds the dart run arguments, including --packages flag if package
/// config is found.
List<String> _buildDartRunArgs(String serverPath, String? packageConfig) {
final runArgs = ['run', '-r'];
if (packageConfig != null) {
runArgs.addAll(['--packages=$packageConfig']);
}
runArgs.add(serverPath);
return runArgs;
}

@override
Future<void> run() async {
Process? process;
final serverFile = await getServerFile();
final cwd = Directory.current.path;
final packageConfig = findPackageConfig();

bool shouldReload(WatchEvent event) {
return path.isWithin(path.join(cwd, 'bin'), event.path) ||
Expand All @@ -29,7 +41,7 @@ class ServeCommand extends Command {

process = await Process.start(
'dart',
['run', '-r', serverFile.path],
_buildDartRunArgs(serverFile.path, packageConfig),
workingDirectory: cwd,
);

Expand All @@ -55,9 +67,10 @@ class ServeCommand extends Command {
process?.kill();
process = null;
final now = DateTime.now();

process = await Process.start(
'dart',
['run', '-r', serverFile.path],
_buildDartRunArgs(serverFile.path, packageConfig),
workingDirectory: cwd,
);
stdoutSubscription = process!.stdout.listen((event) {
Expand Down
32 changes: 32 additions & 0 deletions packages/arcade_cli/lib/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,35 @@ Future<File> getServerFile() async {
}
return file;
}

/// Finds the package_config.json file by recursively searching parent
/// directories. This supports Dart workspaces where the package_config.json
/// may be in a parent directory.
///
/// Returns the path to the package_config.json file, or null if not found.
String? findPackageConfig([String? startDir]) {
var dir = Directory(startDir ?? Directory.current.path);

// Search up to the root directory
while (true) {
final packageConfigPath = join(
dir.path,
'.dart_tool',
'package_config.json',
);
final packageConfigFile = File(packageConfigPath);

if (packageConfigFile.existsSync()) {
return packageConfigPath;
}

// Check if we've reached the root directory
final parent = dir.parent;
if (parent.path == dir.path) {
// We've reached the root
return null;
}

dir = parent;
}
}
81 changes: 81 additions & 0 deletions packages/arcade_cli/test/utils_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import 'dart:io';

import 'package:arcade_cli/utils.dart';
import 'package:path/path.dart' as path;
import 'package:test/test.dart';

void main() {
group('findPackageConfig', () {
late Directory tempDir;
late Directory subDir;

setUp(() {
// Create a temporary directory structure for testing
tempDir = Directory.systemTemp.createTempSync('package_config_test');
subDir = Directory(path.join(tempDir.path, 'subdir'))..createSync();
});

tearDown(() {
// Clean up temporary directory
if (tempDir.existsSync()) {
tempDir.deleteSync(recursive: true);
}
});

test('should find package_config.json in current directory', () {
final dartToolDir = Directory(path.join(tempDir.path, '.dart_tool'))
..createSync();
final packageConfigFile = File(
path.join(dartToolDir.path, 'package_config.json'),
)..createSync();

final result = findPackageConfig(tempDir.path);

expect(result, equals(packageConfigFile.path));
});

test('should find package_config.json in parent directory', () {
final dartToolDir = Directory(path.join(tempDir.path, '.dart_tool'))
..createSync();
final packageConfigFile = File(
path.join(dartToolDir.path, 'package_config.json'),
)..createSync();

final result = findPackageConfig(subDir.path);

expect(result, equals(packageConfigFile.path));
});

test('should return null if package_config.json not found', () {
final result = findPackageConfig(tempDir.path);

expect(result, isNull);
});

test('should search recursively up to root', () {
final deepDir = Directory(
path.join(tempDir.path, 'a', 'b', 'c'),
)..createSync(recursive: true);

final dartToolDir = Directory(path.join(tempDir.path, '.dart_tool'))
..createSync();
final packageConfigFile = File(
path.join(dartToolDir.path, 'package_config.json'),
)..createSync();

final result = findPackageConfig(deepDir.path);

expect(result, equals(packageConfigFile.path));
});

test('should use current directory when no start dir provided', () {
// This test verifies that findPackageConfig works with no arguments
// It should find the actual package_config.json in the project
final result = findPackageConfig();

// The result should be non-null for a valid Dart project
expect(result, isNotNull);
expect(result, endsWith('package_config.json'));
});
});
}