copyFiles static method
Copies files from source directory to target directory with optional filtering.
This method recursively copies files from the source directory to the target directory. It can filter files by file type and supports different build modes.
Parameters:
source- The source directory path to copy fromtarget- The target directory path to copy tofileType- List of file extensions to filter by (without dots, e.g.,['apk', 'aab'])mode- Build mode filter (defaults to "release")
Returns the path of the first copied file.
Throws an Exception if:
- No files are found in the source directory
- No files match the specified file type filter
Implementation
static Future<String?> copyFiles(
String source,
String target, {
List<String> fileType = const [],
String mode = "release",
String? flavor,
}) async {
final sourceDir = Directory(source);
if (!sourceDir.existsSync()) {
throw Exception("No files found in ${sourceDir.path}");
}
final targetDir = Directory(target);
if (!targetDir.existsSync()) {
await targetDir.create(recursive: true);
}
final entities = await sourceDir.list(recursive: true).toList();
final extensions = fileType.map((value) => value.toLowerCase()).toSet();
final candidates = <_FileCandidate>[];
for (final entity in entities) {
if (entity is! File) continue;
if (extensions.isNotEmpty) {
final extension = path.extension(entity.path).toLowerCase();
if (!extensions.contains(extension.replaceFirst('.', ''))) {
continue;
}
}
final sourcePath = entity.path.toLowerCase();
final score = _artifactScore(sourcePath, mode: mode, flavor: flavor);
final modifiedAt = entity.lastModifiedSync();
candidates.add(
_FileCandidate(path: entity.path, score: score, modifiedAt: modifiedAt),
);
}
if (candidates.isEmpty) {
throw Exception(
"Does not contain any files with the specified type: $fileType",
);
}
candidates.sort((a, b) {
final scoreComparison = b.score.compareTo(a.score);
if (scoreComparison != 0) return scoreComparison;
return b.modifiedAt.compareTo(a.modifiedAt);
});
final output = <String>[];
for (final candidate in candidates) {
final fileName = path.basename(candidate.path);
final targetPath = path.join(target, fileName);
output.add(targetPath);
if (File(targetPath).existsSync()) {
await File(targetPath).delete();
}
await File(candidate.path).copy(targetPath);
}
return output.first;
}