blob: 5a425574bf89462f70eb2d00bf9be6745bee6a9c [file] [edit]
// Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:typed_data';
import 'package:build_integration/file_system/multi_root.dart'
as front_end
show MultiRootFileSystem;
import 'package:file/file.dart' as file;
import 'package:file/memory.dart' as file;
import 'package:front_end/src/api_unstable/vm.dart'
as front_end
show FileSystem, FileSystemEntity;
/// Creates an in-memory [file.FileSystem] populated with [fileContents].
///
/// Wraps it in a [front_end.MultiRootFileSystem] under the given [root] path.
(front_end.FileSystem, file.FileSystem) fssForTests(
String root,
Map<String, String> fileContents,
) {
final fs = file.MemoryFileSystem();
for (final entry in fileContents.entries) {
final file = fs.file(fs.path.join(root, entry.key));
file.parent.createSync(recursive: true);
file.writeAsStringSync(entry.value);
}
final primaryFs = FileBackedFrontendFileSystem(fs);
final roots = [root, '$root/blaze-bin', '$root/blaze-genfiles'];
final secondaryFs = front_end.MultiRootFileSystem(
'google3',
roots.map(Uri.parse).toList(),
primaryFs,
);
return (secondaryFs, fs);
}
/// A [front_end.FileSystem] implementation backed by a [file.FileSystem].
class FileBackedFrontendFileSystem implements front_end.FileSystem {
final file.FileSystem fs;
FileBackedFrontendFileSystem(this.fs);
@override
front_end.FileSystemEntity entityForUri(Uri uri) =>
FileBackedFrontendFileSystemEntity(fs, uri);
}
/// A [front_end.FileSystemEntity] implementation backed by a [file.FileSystem].
class FileBackedFrontendFileSystemEntity implements front_end.FileSystemEntity {
final file.FileSystem fs;
@override
final Uri uri;
var _resolved = false;
late final file.FileSystemEntity _entity;
Future<file.FileSystemEntity> get entity async {
await _resolve();
return _entity;
}
FileBackedFrontendFileSystemEntity(this.fs, this.uri);
Future<void> _resolve() async {
if (_resolved) return;
final path = fs.path.fromUri(uri);
final stat = await fs.stat(path);
switch (stat.type) {
case file.FileSystemEntityType.directory:
_entity = fs.directory(path);
default:
_entity = fs.file(path);
}
_resolved = true;
}
@override
Future<bool> exists() async => (await entity).exists();
@override
Future<bool> existsAsyncIfPossible() => exists();
@override
Future<Uint8List> readAsBytes() async =>
((await entity) as file.File).readAsBytes();
@override
Future<Uint8List> readAsBytesAsyncIfPossible() => readAsBytes();
@override
Future<String> readAsString() async =>
((await entity) as file.File).readAsString();
}