Я написал AggregateTransformer, который должен перезаписать файл main.dart с обновленной версией (изменить импорт).Dart Transformer не может перезаписать Asset
Asset mainAsset = await _getFileAsset(transform, "main.dart");
Asset updatedMainAsset = await _replaceDefaultImport(mainAsset, transform.package, "default.dart", newLibFileName);
//overwrite mainAsset because mainAsset and updatedMainAsset have the same id
transform.addOutput(updatedMainAsset);
(удаление актива перед добавлением новой версии ничего не меняет :)
transform.consumePrimary(mainAsset.id);
transform.addOutput(updatedMainAsset);
Но обновленная версия исчезает без следа. Попытка получить его по идентификатору дает исходное содержание:
Asset updatedMainAssetRetrieved = await transform.getInput(updatedMainAsset.id);
трансформатор выводит содержание mainAsset и updatedMainAsset, так что вы можете проверить, что содержание updatedMainAsset действительно обновляется. Вызовите трансформатор, вызвав pub run main.dart.
Полный код/псевдо-код выглядит следующим образом:
class ReplacePackageTransformer extends AggregateTransformer {
ReplacePackageTransformer.asPlugin();
@override
String classifyPrimary(AssetId id) => id.toString().endsWith(".dart") ? "dart-files" : null;
@override
apply(AggregateTransform transform) {
//capture the whole execution to allow better stacktraces if an error occurs
Chain.capture(() async {
//create a file lib/replacement.dart that defines the same method as lib/default.dart
final newLibFileName = "replacement.dart";
final newLibAsset = _createReplacementAsset(...);
//add this new asset
transform.addOutput(newLibAsset);
//rewrite main.dart to import replacement.dart instead of default.dart. To that end:
//1) retrieve the asset for main.dart
Asset mainAsset = await _getFileAsset(transform, "main.dart");
//2) create a new asset with the same id as mainAsset but with updated content
Asset updatedMainAsset = await _replaceDefaultImport(mainAsset, ...);
//3) adding this asset should overwrite/replace the original main.dart-asset because they use the same id
transform.addOutput(updatedMainAsset);
});
}
//helper methods ...
}
Вы можете найти весь трансформатор (и остальную часть проекта) here.
Update/Решение
Деннис Kaselow прав! Метод apply моего метода трансформатора должен вернуть будущее (так что последующие трансформаторы могут дождаться, когда это будет сделано)! Добавив , ответьте до того, как вызов Chain.capture был бы достаточным (поскольку захват i-обратного вызова имеет тело асинхронизации и, следовательно, возвращает Будущее, которое захват будет пересылать/возвращать).
Так изменение
apply(AggregateTransform transform) {
Chain.capture(() async {...});
//no return statement so void is returned
}
в
Future apply(AggregateTransform transform) {
return Chain.capture(() async {...});
//() async {...} returns a Future that Chain.capture and apply forward/return
}
решает мою проблему!
Это похоже на https://groups.google.com/a/dartlang.org/forum/#!topic/editor/vz-arQ_KEFM. Не знаю, помогает ли это. Я предлагаю вам отправить ссылку на этот вопрос SO на https://groups.google.com/a/dartlang.org/forum/#!forum/misc –
Не уверен, что моя проблема связана с той, которую вы связали, потому что что речь идет о частичном файле, и они предложили вложение. Хотя мой актив был единственной файловой библиотекой (без частей), поэтому он уже был встроен. Я добавил сообщение в dart-misc, которого еще нет в сети, потому что первое сообщение модерируется. – StephanS