Skip to content

Commit 034b3a7

Browse files
jason-simmonsokorohelijah
authored andcommitted
[ Tool ] Use a separate output directory when the native hooks run the build system (flutter#178840)
FlutterBuildSystem.trackSharedBuildDirectory stores a hash of the most recently run build configuration in the output directory defined in the environment. If the build executed by FlutterHookRunnerNative uses the same output directory as other builds, then trackSharedBuildDirectory may think that the hook build's output list replaces the outputs of those previous builds. trackSharedBuildDirectory will then incorrectly delete files in the previous output list because they are not part of the hook build's outputs. See flutter#178529
1 parent c3815be commit 034b3a7

File tree

3 files changed

+94
-2
lines changed

3 files changed

+94
-2
lines changed

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,28 @@ class Environment {
455455
required this.generateDartPluginRegistry,
456456
});
457457

458+
Environment copyWith({Directory? outputDir}) {
459+
return Environment._(
460+
outputDir: outputDir ?? this.outputDir,
461+
projectDir: projectDir,
462+
packageConfigPath: packageConfigPath,
463+
buildDir: buildDir,
464+
rootBuildDir: rootBuildDir,
465+
cacheDir: cacheDir,
466+
defines: defines,
467+
flutterRootDir: flutterRootDir,
468+
fileSystem: fileSystem,
469+
logger: logger,
470+
artifacts: artifacts,
471+
processManager: processManager,
472+
platform: platform,
473+
analytics: analytics,
474+
engineVersion: engineVersion,
475+
inputs: inputs,
476+
generateDartPluginRegistry: generateDartPluginRegistry,
477+
);
478+
}
479+
458480
/// The [Source] value which is substituted with the path to [projectDir].
459481
static const kProjectDirectory = '{PROJECT_DIR}';
460482

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

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
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 'package:meta/meta.dart';
6+
57
import '../../asset.dart';
68
import '../../base/logger.dart' show Logger;
79
import '../../build_info.dart';
@@ -14,22 +16,35 @@ import 'native_assets.dart' show DartBuild;
1416
class FlutterHookRunnerNative implements FlutterHookRunner {
1517
FlutterHookResult? _flutterHookResult;
1618

19+
@visibleForTesting
20+
static const kHooksOutputDirectory = 'native_hooks';
21+
1722
@override
1823
Future<FlutterHookResult> runHooks({
1924
required TargetPlatform targetPlatform,
2025
required Environment environment,
2126
Logger? logger,
2227
}) async {
2328
logger?.printTrace('runHooks() with ${environment.defines} and $targetPlatform');
24-
if (_flutterHookResult != null && !_flutterHookResult!.hasAnyModifiedFiles(globals.fs)) {
29+
if (_flutterHookResult != null &&
30+
!_flutterHookResult!.hasAnyModifiedFiles(environment.fileSystem)) {
2531
logger?.printTrace('runHooks() - up-to-date already');
2632
return _flutterHookResult!;
2733
}
2834
logger?.printTrace('runHooks() - will perform dart build');
2935

36+
// Use a clone of the environment with a different output directory
37+
// to avoid conflicts with the primary build's outputs.
38+
final String outputDirPath = environment.fileSystem.path.join(
39+
environment.outputDir.path,
40+
kHooksOutputDirectory,
41+
);
42+
final Environment hooksEnvironment = environment.copyWith(
43+
outputDir: environment.fileSystem.directory(outputDirPath),
44+
);
3045
final BuildResult lastBuild = await globals.buildSystem.build(
3146
DartBuild(specifiedTargetPlatform: targetPlatform),
32-
environment,
47+
hooksEnvironment,
3348
);
3449
if (!lastBuild.success) {
3550
for (final ExceptionMeasurement exceptionMeasurement in lastBuild.exceptions.values) {
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:file/memory.dart';
6+
import 'package:flutter_tools/src/artifacts.dart';
7+
import 'package:flutter_tools/src/base/file_system.dart';
8+
import 'package:flutter_tools/src/base/logger.dart';
9+
import 'package:flutter_tools/src/base/platform.dart';
10+
import 'package:flutter_tools/src/build_info.dart';
11+
import 'package:flutter_tools/src/build_system/build_system.dart';
12+
import 'package:flutter_tools/src/build_system/targets/hook_runner_native.dart';
13+
14+
import '../../../src/common.dart';
15+
import '../../../src/context.dart';
16+
import '../../../src/test_build_system.dart';
17+
18+
void main() {
19+
late FileSystem fs;
20+
21+
setUp(() {
22+
fs = MemoryFileSystem.test();
23+
});
24+
25+
testUsingContext(
26+
'FlutterHookRunnerNative uses a separate output directory',
27+
() async {
28+
final hookRunner = FlutterHookRunnerNative();
29+
final environment = Environment.test(
30+
fs.currentDirectory,
31+
processManager: FakeProcessManager.any(),
32+
artifacts: Artifacts.test(),
33+
fileSystem: fs,
34+
logger: BufferLogger.test(),
35+
platform: FakePlatform(),
36+
defines: {},
37+
);
38+
39+
await hookRunner.runHooks(
40+
targetPlatform: TargetPlatform.linux_x64,
41+
environment: environment,
42+
logger: environment.logger,
43+
);
44+
},
45+
overrides: <Type, Generator>{
46+
BuildSystem: () =>
47+
TestBuildSystem.all(BuildResult(success: true), (Target target, Environment environment) {
48+
expect(
49+
fs.path.basename(environment.outputDir.path),
50+
FlutterHookRunnerNative.kHooksOutputDirectory,
51+
);
52+
}),
53+
},
54+
);
55+
}

0 commit comments

Comments
 (0)