Skip to content

Commit 06ac042

Browse files
authored
Enable asset transformation for flutter run -d <browser> and flutter test (#144734)
Partial implementation of flutter/flutter#143348. The title says it all. Feel free to experiment with the feature using this project: https://github.com/andrewkolos/asset_transformers_test.
1 parent dfbf3d2 commit 06ac042

File tree

5 files changed

+113
-2
lines changed

5 files changed

+113
-2
lines changed

packages/flutter_tools/lib/src/bundle_builder.dart

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import 'base/logger.dart';
1414
import 'build_info.dart';
1515
import 'build_system/build_system.dart';
1616
import 'build_system/depfile.dart';
17+
import 'build_system/tools/asset_transformer.dart';
1718
import 'build_system/tools/scene_importer.dart';
1819
import 'build_system/tools/shader_compiler.dart';
1920
import 'bundle.dart';
@@ -145,6 +146,7 @@ Future<void> writeBundle(
145146
required FileSystem fileSystem,
146147
required Artifacts artifacts,
147148
required Logger logger,
149+
required Directory projectDir,
148150
}) async {
149151
if (bundleDir.existsSync()) {
150152
try {
@@ -172,6 +174,12 @@ Future<void> writeBundle(
172174
artifacts: artifacts,
173175
);
174176

177+
final AssetTransformer assetTransformer = AssetTransformer(
178+
processManager: processManager,
179+
fileSystem: fileSystem,
180+
dartBinaryPath: artifacts.getArtifactPath(Artifact.engineDartBinary),
181+
);
182+
175183
// Limit number of open files to avoid running out of file descriptors.
176184
final Pool pool = Pool(64);
177185
await Future.wait<void>(
@@ -190,8 +198,20 @@ Future<void> writeBundle(
190198
final File input = devFSContent.file as File;
191199
bool doCopy = true;
192200
switch (entry.value.kind) {
193-
case AssetKind.regular:
201+
case AssetKind.regular:
202+
if (entry.value.transformers.isEmpty) {
194203
break;
204+
}
205+
final AssetTransformationFailure? failure = await assetTransformer.transformAsset(
206+
asset: input,
207+
outputPath: file.path,
208+
workingDirectory: projectDir.path,
209+
transformerEntries: entry.value.transformers,
210+
);
211+
doCopy = false;
212+
if (failure != null) {
213+
throwToolExit(failure.message);
214+
}
195215
case AssetKind.font:
196216
break;
197217
case AssetKind.shader:

packages/flutter_tools/lib/src/commands/test.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,7 @@ class TestCommand extends FlutterCommand with DeviceBasedDevelopmentArtifacts {
675675
fileSystem: globals.fs,
676676
artifacts: globals.artifacts!,
677677
logger: globals.logger,
678+
projectDir: globals.fs.currentDirectory,
678679
);
679680
}
680681
}

packages/flutter_tools/lib/src/isolated/devfs_web.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -946,6 +946,7 @@ class WebDevFS implements DevFS {
946946
fileSystem: globals.fs,
947947
artifacts: globals.artifacts!,
948948
logger: globals.logger,
949+
projectDir: rootDirectory,
949950
);
950951
}
951952
}

packages/flutter_tools/test/general.shard/asset_bundle_test.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,7 @@ flutter:
543543
fileSystem: globals.fs,
544544
artifacts: globals.artifacts!,
545545
logger: testLogger,
546+
projectDir: globals.fs.currentDirectory
546547
);
547548

548549
expect(testLogger.warningText, contains('Expected Error Text'));
@@ -668,6 +669,7 @@ flutter:
668669
fileSystem: globals.fs,
669670
artifacts: globals.artifacts!,
670671
logger: testLogger,
672+
projectDir: globals.fs.currentDirectory,
671673
);
672674

673675
}, overrides: <Type, Generator>{
@@ -719,6 +721,7 @@ flutter:
719721
fileSystem: globals.fs,
720722
artifacts: globals.artifacts!,
721723
logger: testLogger,
724+
projectDir: globals.fs.currentDirectory,
722725
);
723726

724727
}, overrides: <Type, Generator>{
@@ -805,6 +808,7 @@ flutter:
805808
fileSystem: globals.fs,
806809
artifacts: globals.artifacts!,
807810
logger: testLogger,
811+
projectDir: globals.fs.currentDirectory,
808812
);
809813
expect((globals.processManager as FakeProcessManager).hasRemainingExpectations, false);
810814
}, overrides: <Type, Generator>{

packages/flutter_tools/test/general.shard/bundle_builder_test.dart

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,26 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5+
import 'dart:typed_data';
6+
7+
import 'package:args/args.dart';
58
import 'package:file/memory.dart';
9+
import 'package:file_testing/file_testing.dart';
10+
import 'package:flutter_tools/src/artifacts.dart';
11+
import 'package:flutter_tools/src/asset.dart';
612
import 'package:flutter_tools/src/base/config.dart';
713
import 'package:flutter_tools/src/base/file_system.dart';
14+
import 'package:flutter_tools/src/base/logger.dart';
815
import 'package:flutter_tools/src/build_info.dart';
916
import 'package:flutter_tools/src/build_system/build_system.dart';
10-
import 'package:flutter_tools/src/bundle.dart';
17+
import 'package:flutter_tools/src/bundle.dart' hide defaultManifestPath;
1118
import 'package:flutter_tools/src/bundle_builder.dart';
19+
import 'package:flutter_tools/src/devfs.dart';
20+
import 'package:flutter_tools/src/device.dart';
21+
import 'package:flutter_tools/src/flutter_manifest.dart';
1222
import 'package:flutter_tools/src/globals.dart' as globals;
1323
import 'package:flutter_tools/src/project.dart';
24+
import 'package:test/fake.dart';
1425

1526
import '../src/common.dart';
1627
import '../src/context.dart';
@@ -46,6 +57,75 @@ void main() {
4657
ProcessManager: () => FakeProcessManager.any(),
4758
});
4859

60+
testWithoutContext('writeBundle applies transformations to any assets that have them defined', () async {
61+
final MemoryFileSystem fileSystem = MemoryFileSystem.test();
62+
final File asset = fileSystem.file('my-asset.txt')
63+
..createSync()
64+
..writeAsBytesSync(<int>[1, 2, 3]);
65+
final Artifacts artifacts = Artifacts.test();
66+
67+
final FakeProcessManager processManager = FakeProcessManager.list(
68+
<FakeCommand>[
69+
FakeCommand(
70+
command: <Pattern>[
71+
artifacts.getArtifactPath(Artifact.engineDartBinary),
72+
'run',
73+
'increment',
74+
'--input=/.tmp_rand0/my-asset.txt-transformOutput0.txt',
75+
'--output=/.tmp_rand0/my-asset.txt-transformOutput1.txt'
76+
],
77+
onRun: (List<String> command) {
78+
final ArgResults argParseResults = (ArgParser()
79+
..addOption('input', mandatory: true)
80+
..addOption('output', mandatory: true))
81+
.parse(command);
82+
83+
final File inputFile = fileSystem.file(argParseResults['input']);
84+
final File outputFile = fileSystem.file(argParseResults['output']);
85+
86+
expect(inputFile, exists);
87+
outputFile
88+
..createSync()
89+
..writeAsBytesSync(
90+
Uint8List.fromList(
91+
inputFile.readAsBytesSync().map((int b) => b + 1).toList(),
92+
),
93+
);
94+
},
95+
),
96+
],
97+
);
98+
99+
final FakeAssetBundle bundle = FakeAssetBundle()
100+
..entries['my-asset.txt'] = AssetBundleEntry(
101+
DevFSFileContent(asset),
102+
kind: AssetKind.regular,
103+
transformers: const <AssetTransformerEntry>[
104+
AssetTransformerEntry(package: 'increment', args: <String>[]),
105+
],
106+
);
107+
108+
final Directory bundleDir = fileSystem.directory(
109+
getAssetBuildDirectory(Config.test(), fileSystem),
110+
);
111+
112+
await writeBundle(
113+
bundleDir,
114+
bundle.entries,
115+
targetPlatform: TargetPlatform.tester,
116+
impellerStatus: ImpellerStatus.platformDefault,
117+
processManager: processManager,
118+
fileSystem: fileSystem,
119+
artifacts: artifacts,
120+
logger: BufferLogger.test(),
121+
projectDir: fileSystem.currentDirectory,
122+
);
123+
124+
final File outputAssetFile = fileSystem.file('build/flutter_assets/my-asset.txt');
125+
expect(outputAssetFile, exists);
126+
expect(outputAssetFile.readAsBytesSync(), orderedEquals(<int>[2, 3, 4]));
127+
});
128+
49129
testUsingContext('Handles build system failure', () {
50130
expect(
51131
() => BundleBuilder().build(
@@ -157,3 +237,8 @@ void main() {
157237
), 'build/95b595cca01caa5f0ca0a690339dd7f6.cache.dill.track.dill');
158238
});
159239
}
240+
241+
class FakeAssetBundle extends Fake implements AssetBundle {
242+
@override
243+
final Map<String, AssetBundleEntry> entries = <String, AssetBundleEntry>{};
244+
}

0 commit comments

Comments
 (0)