Skip to content

Commit 58acf4e

Browse files
Revert "[flutter_tools] surgically remove outputs from shared directory (flutter#53773)" (flutter#53956)
This reverts commit 8a3bede.
1 parent d5795b6 commit 58acf4e

File tree

5 files changed

+73
-170
lines changed

5 files changed

+73
-170
lines changed

packages/flutter_tools/lib/src/build_system/build_system.dart

Lines changed: 2 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -394,11 +394,8 @@ class Environment {
394394

395395
/// The `BUILD_DIR` environment variable.
396396
///
397-
/// The root of the output directory where build step intermediates and
398-
/// outputs are written. Current usages of assemble configure ths to be
399-
/// a unique directory under `.dart_tool/flutter_build`, though it can
400-
/// be placed anywhere. The uniqueness is only enforced by callers, and
401-
/// is currently done by hashing the build configuration.
397+
/// Defaults to `{PROJECT_ROOT}/build`. The root of the output directory where
398+
/// build step intermediates and outputs are written.
402399
final Directory buildDir;
403400

404401
/// The `CACHE_DIR` environment variable.
@@ -522,12 +519,6 @@ class BuildSystem {
522519
path.contains('.dart_tool');
523520
});
524521
}
525-
trackSharedBuildDirectory(
526-
environment, _fileSystem, buildInstance.outputFiles,
527-
);
528-
environment.buildDir.childFile('outputs.json')
529-
.writeAsStringSync(json.encode(buildInstance.outputFiles.keys.toList()));
530-
531522
return BuildResult(
532523
success: passed,
533524
exceptions: buildInstance.exceptionMeasurements,
@@ -538,61 +529,6 @@ class BuildSystem {
538529
..sort((File a, File b) => a.path.compareTo(b.path)),
539530
);
540531
}
541-
542-
/// Write the identifier of the last build into the output directory and
543-
/// remove the previous build's output.
544-
///
545-
/// The build identifier is the basename of the build directory where
546-
/// outputs and intermediaries are written, under `.dart_tool/flutter_build`.
547-
/// This is computed from a hash of the build's configuration.
548-
///
549-
/// This identifier is used to perform a targeted cleanup of the last output
550-
/// files, if these were not already covered by the built-in cleanup. This
551-
/// cleanup is only necessary when multiple different build configurations
552-
/// output to the same directory.
553-
@visibleForTesting
554-
static void trackSharedBuildDirectory(
555-
Environment environment,
556-
FileSystem fileSystem,
557-
Map<String, File> currentOutputs,
558-
) {
559-
final String currentBuildId = fileSystem.path.basename(environment.buildDir.path);
560-
final File lastBuildIdFile = environment.outputDir.childFile('.last_build_id');
561-
if (!lastBuildIdFile.existsSync()) {
562-
lastBuildIdFile.writeAsStringSync(currentBuildId);
563-
// No config file, either output was cleaned or this is the first build.
564-
return;
565-
}
566-
final String lastBuildId = lastBuildIdFile.readAsStringSync().trim();
567-
if (lastBuildId == currentBuildId) {
568-
// The last build was the same configuration as the current build
569-
return;
570-
}
571-
// Update the output dir with the latest config.
572-
lastBuildIdFile
573-
..createSync()
574-
..writeAsStringSync(currentBuildId);
575-
final File outputsFile = environment.buildDir
576-
.parent
577-
.childDirectory(lastBuildId)
578-
.childFile('outputs.json');
579-
580-
if (!outputsFile.existsSync()) {
581-
// There is no output list. This could happen if the user manually
582-
// edited .last_config or deleted .dart_tool.
583-
return;
584-
}
585-
final List<String> lastOutputs = (json.decode(outputsFile.readAsStringSync()) as List<Object>)
586-
.cast<String>();
587-
for (final String lastOutput in lastOutputs) {
588-
if (!currentOutputs.containsKey(lastOutput)) {
589-
final File lastOutputFile = fileSystem.file(lastOutput);
590-
if (lastOutputFile.existsSync()) {
591-
lastOutputFile.deleteSync();
592-
}
593-
}
594-
}
595-
}
596532
}
597533

598534

packages/flutter_tools/lib/src/build_system/targets/ios.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,13 @@ abstract class IosAssetBundle extends Target {
276276
final Directory frameworkDirectory = environment.outputDir.childDirectory('App.framework');
277277
final Directory assetDirectory = frameworkDirectory.childDirectory('flutter_assets');
278278
frameworkDirectory.createSync(recursive: true);
279+
280+
// This is necessary because multiple different build configurations will
281+
// output different files here. Build cleaning only works when the files
282+
// change within a build configuration.
283+
if (assetDirectory.existsSync()) {
284+
assetDirectory.deleteSync(recursive: true);
285+
}
279286
assetDirectory.createSync();
280287

281288
// Only copy the prebuilt runtimes and kernel blob in debug mode.

packages/flutter_tools/lib/src/build_system/targets/macos.dart

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,12 @@ abstract class UnpackMacOS extends Target {
5656
final Directory targetDirectory = environment
5757
.outputDir
5858
.childDirectory('FlutterMacOS.framework');
59-
targetDirectory.createSync(recursive: true);
59+
// This is necessary because multiple different build configurations will
60+
// output different files here. Build cleaning only works when the files
61+
// change within a build configuration.
62+
if (targetDirectory.existsSync()) {
63+
targetDirectory.deleteSync(recursive: true);
64+
}
6065
final List<File> inputs = globals.fs.directory(basePath)
6166
.listSync(recursive: true)
6267
.whereType<File>()
@@ -286,6 +291,12 @@ abstract class MacOSBundleFlutterAssets extends Target {
286291
final Directory assetDirectory = outputDirectory
287292
.childDirectory('Resources')
288293
.childDirectory('flutter_assets');
294+
// This is necessary because multiple different build configurations will
295+
// output different files here. Build cleaning only works when the files
296+
// change within a build configuration.
297+
if (assetDirectory.existsSync()) {
298+
assetDirectory.deleteSync(recursive: true);
299+
}
289300
assetDirectory.createSync(recursive: true);
290301
final Depfile depfile = await copyAssets(environment, assetDirectory);
291302
final DepfileService depfileService = DepfileService(

packages/flutter_tools/test/general.shard/build_system/build_system_test.dart

Lines changed: 0 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -409,109 +409,6 @@ void main() {
409409
expect(fileSystem.file('c.txt'), isNot(exists));
410410
expect(called, 2);
411411
});
412-
413-
testWithoutContext('trackSharedBuildDirectory handles a missing .last_build_id', () {
414-
BuildSystem.trackSharedBuildDirectory(environment, fileSystem, <String, File>{});
415-
416-
expect(environment.outputDir.childFile('.last_build_id'), exists);
417-
expect(environment.outputDir.childFile('.last_build_id').readAsStringSync(),
418-
'6666cd76f96956469e7be39d750cc7d9');
419-
});
420-
421-
testWithoutContext('trackSharedBuildDirectory does not modify .last_build_id when config is identical', () {
422-
environment.outputDir.childFile('.last_build_id')
423-
..writeAsStringSync('6666cd76f96956469e7be39d750cc7d9')
424-
..setLastModifiedSync(DateTime(1991, 8, 23));
425-
BuildSystem.trackSharedBuildDirectory(environment, fileSystem, <String, File>{});
426-
427-
expect(environment.outputDir.childFile('.last_build_id').lastModifiedSync(),
428-
DateTime(1991, 8, 23));
429-
});
430-
431-
testWithoutContext('trackSharedBuildDirectory does not delete files when outputs.json is missing', () {
432-
environment.outputDir
433-
.childFile('.last_build_id')
434-
.writeAsStringSync('foo');
435-
environment.buildDir.parent
436-
.childDirectory('foo')
437-
.createSync(recursive: true);
438-
environment.outputDir
439-
.childFile('stale')
440-
.createSync();
441-
BuildSystem.trackSharedBuildDirectory(environment, fileSystem, <String, File>{});
442-
443-
expect(environment.outputDir.childFile('.last_build_id').readAsStringSync(),
444-
'6666cd76f96956469e7be39d750cc7d9');
445-
expect(environment.outputDir.childFile('stale'), exists);
446-
});
447-
448-
testWithoutContext('trackSharedBuildDirectory deletes files in outputs.json but not in current outputs', () {
449-
environment.outputDir
450-
.childFile('.last_build_id')
451-
.writeAsStringSync('foo');
452-
final Directory otherBuildDir = environment.buildDir.parent
453-
.childDirectory('foo')
454-
..createSync(recursive: true);
455-
final File staleFile = environment.outputDir
456-
.childFile('stale')
457-
..createSync();
458-
otherBuildDir.childFile('outputs.json')
459-
.writeAsStringSync(json.encode(<String>[staleFile.absolute.path]));
460-
BuildSystem.trackSharedBuildDirectory(environment, fileSystem, <String, File>{});
461-
462-
expect(environment.outputDir.childFile('.last_build_id').readAsStringSync(),
463-
'6666cd76f96956469e7be39d750cc7d9');
464-
expect(environment.outputDir.childFile('stale'), isNot(exists));
465-
});
466-
467-
testWithoutContext('multiple builds to the same output directory do no leave stale artifacts', () async {
468-
final BuildSystem buildSystem = setUpBuildSystem(fileSystem);
469-
final Environment testEnvironmentDebug = Environment.test(
470-
fileSystem.currentDirectory,
471-
outputDir: fileSystem.directory('output'),
472-
defines: <String, String>{
473-
'config': 'debug',
474-
},
475-
artifacts: MockArtifacts(),
476-
processManager: FakeProcessManager.any(),
477-
logger: BufferLogger.test(),
478-
fileSystem: fileSystem,
479-
);
480-
final Environment testEnvironmentProfle = Environment.test(
481-
fileSystem.currentDirectory,
482-
outputDir: fileSystem.directory('output'),
483-
defines: <String, String>{
484-
'config': 'profile',
485-
},
486-
artifacts: MockArtifacts(),
487-
processManager: FakeProcessManager.any(),
488-
logger: BufferLogger.test(),
489-
fileSystem: fileSystem,
490-
);
491-
492-
final TestTarget debugTarget = TestTarget((Environment environment) async {
493-
environment.outputDir.childFile('debug').createSync();
494-
})..outputs = const <Source>[Source.pattern('{OUTPUT_DIR}/debug')];
495-
final TestTarget releaseTarget = TestTarget((Environment environment) async {
496-
environment.outputDir.childFile('release').createSync();
497-
})..outputs = const <Source>[Source.pattern('{OUTPUT_DIR}/release')];
498-
499-
await buildSystem.build(debugTarget, testEnvironmentDebug);
500-
501-
// Verify debug output was created
502-
expect(fileSystem.file('output/debug'), exists);
503-
504-
await buildSystem.build(releaseTarget, testEnvironmentProfle);
505-
506-
// Last build config is updated properly
507-
expect(testEnvironmentProfle.outputDir.childFile('.last_build_id'), exists);
508-
expect(testEnvironmentProfle.outputDir.childFile('.last_build_id').readAsStringSync(),
509-
'c20b3747fb2aa148cc4fd39bfbbd894f');
510-
511-
// Verify debug output removeds
512-
expect(fileSystem.file('output/debug'), isNot(exists));
513-
expect(fileSystem.file('output/release'), exists);
514-
});
515412
}
516413

517414
BuildSystem setUpBuildSystem(FileSystem fileSystem) {

packages/flutter_tools/test/general.shard/build_system/targets/macos_test.dart

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,10 @@ void main() {
101101
final Directory source = globals.fs.directory(sourcePath);
102102
final Directory target = globals.fs.directory(targetPath);
103103

104+
// verify directory was deleted by command.
105+
expect(target.existsSync(), false);
106+
target.createSync(recursive: true);
107+
104108
for (final FileSystemEntity entity in source.listSync(recursive: true)) {
105109
if (entity is File) {
106110
final String relative = globals.fs.path.relative(entity.path, from: source.path);
@@ -174,6 +178,54 @@ void main() {
174178
expect(globals.fs.file(precompiledIsolate), isNot(exists));
175179
}));
176180

181+
test('release/profile macOS application has no blob or precompiled runtime when '
182+
'run ontop of different configuration', () => testbed.run(() async {
183+
globals.fs.file(globals.fs.path.join('bin', 'cache', 'artifacts', 'engine', 'darwin-x64',
184+
'vm_isolate_snapshot.bin')).createSync(recursive: true);
185+
globals.fs.file(globals.fs.path.join('bin', 'cache', 'artifacts', 'engine', 'darwin-x64',
186+
'isolate_snapshot.bin')).createSync(recursive: true);
187+
globals.fs.file(globals.fs.path.join(environment.buildDir.path, 'App.framework', 'App'))
188+
.createSync(recursive: true);
189+
190+
final String inputKernel = globals.fs.path.join(environment.buildDir.path, 'app.dill');
191+
final String outputKernel = globals.fs.path.join('App.framework', 'Versions', 'A', 'Resources',
192+
'flutter_assets', 'kernel_blob.bin');
193+
globals.fs.file(inputKernel)
194+
..createSync(recursive: true)
195+
..writeAsStringSync('testing');
196+
197+
await const DebugMacOSBundleFlutterAssets().build(environment);
198+
199+
globals.fs.file(globals.fs.path.join('bin', 'cache', 'artifacts', 'engine', 'darwin-x64',
200+
'vm_isolate_snapshot.bin')).createSync(recursive: true);
201+
globals.fs.file(globals.fs.path.join('bin', 'cache', 'artifacts', 'engine', 'darwin-x64',
202+
'isolate_snapshot.bin')).createSync(recursive: true);
203+
204+
final Environment testEnvironment = Environment.test(
205+
globals.fs.currentDirectory,
206+
defines: <String, String>{
207+
kBuildMode: 'profile',
208+
kTargetPlatform: 'darwin-x64',
209+
},
210+
artifacts: MockArtifacts(),
211+
processManager: FakeProcessManager.any(),
212+
logger: globals.logger,
213+
fileSystem: globals.fs,
214+
);
215+
testEnvironment.buildDir.createSync(recursive: true);
216+
globals.fs.file(globals.fs.path.join(testEnvironment.buildDir.path, 'App.framework', 'App'))
217+
.createSync(recursive: true);
218+
final String precompiledVm = globals.fs.path.join('App.framework', 'Resources',
219+
'flutter_assets', 'vm_snapshot_data');
220+
final String precompiledIsolate = globals.fs.path.join('App.framework', 'Resources',
221+
'flutter_assets', 'isolate_snapshot_data');
222+
await const ProfileMacOSBundleFlutterAssets().build(testEnvironment);
223+
224+
expect(globals.fs.file(outputKernel), isNot(exists));
225+
expect(globals.fs.file(precompiledVm), isNot(exists));
226+
expect(globals.fs.file(precompiledIsolate), isNot(exists));
227+
}));
228+
177229
test('release/profile macOS application updates when App.framework updates', () => testbed.run(() async {
178230
globals.fs.file(globals.fs.path.join('bin', 'cache', 'artifacts', 'engine', 'darwin-x64',
179231
'vm_isolate_snapshot.bin')).createSync(recursive: true);

0 commit comments

Comments
 (0)