normalizeProjectPath function
Utility responsible for normalizing file paths and URIs into clean, portable, project-relative locations.
Designed per Master Prompt Section 8:
- Detects project
lib/path where possible. - Removes absolute workspace prefixes (Windows or Unix).
- Normalizes Windows backslashes (
\) to standard forward slashes (/). - Preserves
lib/...or relative directories. - Falls back safely if the project root cannot be determined.
Implementation
String normalizeProjectPath(String path) {
if (path.isEmpty) return path;
// 1. Decode URI schemes (e.g. file:///... or file://...)
String normalized = path;
if (normalized.startsWith('file://')) {
try {
final uri = Uri.parse(normalized);
normalized = uri.toFilePath();
} catch (_) {
normalized = normalized.replaceFirst(RegExp(r'^file://+'), '');
}
}
// 2. Handle package: URIs (e.g. package:app_name/feature/foo.dart -> lib/feature/foo.dart)
if (normalized.startsWith('package:')) {
final slashIndex = normalized.indexOf('/');
if (slashIndex != -1) {
return 'lib/${normalized.substring(slashIndex + 1)}';
}
}
// 3. Normalize all backslashes to forward slashes
normalized = normalized.replaceAll(r'\', '/');
// Strip leading slash on Windows paths (e.g. /C:/... -> C:/...)
if (RegExp(r'^/[a-zA-Z]:').hasMatch(normalized)) {
normalized = normalized.substring(1);
}
// 4. Locate project-relative directory markers: 'lib/', 'test/', 'example/', 'bin/'
const markers = ['lib/', 'test/', 'example/', 'bin/'];
for (final marker in markers) {
final index = normalized.lastIndexOf(marker);
if (index != -1) {
// Check if there is an enclosing project segment before example/
// e.g. /app/example/lib/main.dart -> example/lib/main.dart
final sub = normalized.substring(index);
return sub;
}
}
// 5. If no standard directory marker found, return clean trimmed path
return normalized;
}