Unverified Commit 72343ee0 authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[flutter_tools] refactor build_system and targets to be context-free (#53268)

parent 4605b51a
...@@ -95,7 +95,11 @@ class AotBuilder { ...@@ -95,7 +95,11 @@ class AotBuilder {
kExtraFrontEndOptions: buildInfo.extraFrontEndOptions.join(','), kExtraFrontEndOptions: buildInfo.extraFrontEndOptions.join(','),
if (platform == TargetPlatform.ios) if (platform == TargetPlatform.ios)
kIosArchs: iosBuildArchs.map(getNameForDarwinArch).join(' ') kIosArchs: iosBuildArchs.map(getNameForDarwinArch).join(' ')
} },
artifacts: globals.artifacts,
fileSystem: globals.fs,
logger: globals.logger,
processManager: globals.processManager,
); );
final BuildResult result = await globals.buildSystem.build(target, environment); final BuildResult result = await globals.buildSystem.build(target, environment);
status?.stop(); status?.stop();
......
...@@ -382,7 +382,7 @@ class BufferLogger extends Logger { ...@@ -382,7 +382,7 @@ class BufferLogger extends Logger {
_timeoutConfiguration = timeoutConfiguration, _timeoutConfiguration = timeoutConfiguration,
_stopwatchFactory = stopwatchFactory; _stopwatchFactory = stopwatchFactory;
@visibleForTesting /// Create a [BufferLogger] with test preferences.
BufferLogger.test({ BufferLogger.test({
Terminal terminal, Terminal terminal,
OutputPreferences outputPreferences, OutputPreferences outputPreferences,
......
...@@ -8,13 +8,16 @@ import 'package:async/async.dart'; ...@@ -8,13 +8,16 @@ import 'package:async/async.dart';
import 'package:convert/convert.dart'; import 'package:convert/convert.dart';
import 'package:crypto/crypto.dart'; import 'package:crypto/crypto.dart';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import 'package:platform/platform.dart';
import 'package:pool/pool.dart'; import 'package:pool/pool.dart';
import 'package:process/process.dart';
import '../artifacts.dart';
import '../base/file_system.dart'; import '../base/file_system.dart';
import '../base/logger.dart';
import '../base/utils.dart'; import '../base/utils.dart';
import '../cache.dart'; import '../cache.dart';
import '../convert.dart'; import '../convert.dart';
import '../globals.dart' as globals;
import 'exceptions.dart'; import 'exceptions.dart';
import 'file_hash_store.dart'; import 'file_hash_store.dart';
import 'source.dart'; import 'source.dart';
...@@ -286,6 +289,10 @@ class Environment { ...@@ -286,6 +289,10 @@ class Environment {
@required Directory outputDir, @required Directory outputDir,
@required Directory cacheDir, @required Directory cacheDir,
@required Directory flutterRootDir, @required Directory flutterRootDir,
@required FileSystem fileSystem,
@required Logger logger,
@required Artifacts artifacts,
@required ProcessManager processManager,
Directory buildDir, Directory buildDir,
Map<String, String> defines = const <String, String>{}, Map<String, String> defines = const <String, String>{},
}) { }) {
...@@ -314,6 +321,10 @@ class Environment { ...@@ -314,6 +321,10 @@ class Environment {
cacheDir: cacheDir, cacheDir: cacheDir,
defines: defines, defines: defines,
flutterRootDir: flutterRootDir, flutterRootDir: flutterRootDir,
fileSystem: fileSystem,
logger: logger,
artifacts: artifacts,
processManager: processManager,
); );
} }
...@@ -327,6 +338,10 @@ class Environment { ...@@ -327,6 +338,10 @@ class Environment {
Directory flutterRootDir, Directory flutterRootDir,
Directory buildDir, Directory buildDir,
Map<String, String> defines = const <String, String>{}, Map<String, String> defines = const <String, String>{},
@required FileSystem fileSystem,
@required Logger logger,
@required Artifacts artifacts,
@required ProcessManager processManager,
}) { }) {
return Environment( return Environment(
projectDir: projectDir ?? testDirectory, projectDir: projectDir ?? testDirectory,
...@@ -335,6 +350,10 @@ class Environment { ...@@ -335,6 +350,10 @@ class Environment {
flutterRootDir: flutterRootDir ?? testDirectory, flutterRootDir: flutterRootDir ?? testDirectory,
buildDir: buildDir, buildDir: buildDir,
defines: defines, defines: defines,
fileSystem: fileSystem,
logger: logger,
artifacts: artifacts,
processManager: processManager,
); );
} }
...@@ -346,6 +365,10 @@ class Environment { ...@@ -346,6 +365,10 @@ class Environment {
@required this.cacheDir, @required this.cacheDir,
@required this.defines, @required this.defines,
@required this.flutterRootDir, @required this.flutterRootDir,
@required this.processManager,
@required this.logger,
@required this.fileSystem,
@required this.artifacts,
}); });
/// The [Source] value which is substituted with the path to [projectDir]. /// The [Source] value which is substituted with the path to [projectDir].
...@@ -399,6 +422,14 @@ class Environment { ...@@ -399,6 +422,14 @@ class Environment {
/// The root build directory shared by all builds. /// The root build directory shared by all builds.
final Directory rootBuildDir; final Directory rootBuildDir;
final ProcessManager processManager;
final Logger logger;
final Artifacts artifacts;
final FileSystem fileSystem;
} }
/// The result information from the build system. /// The result information from the build system.
...@@ -422,7 +453,17 @@ class BuildResult { ...@@ -422,7 +453,17 @@ class BuildResult {
/// The build system is responsible for invoking and ordering [Target]s. /// The build system is responsible for invoking and ordering [Target]s.
class BuildSystem { class BuildSystem {
const BuildSystem(); const BuildSystem({
@required FileSystem fileSystem,
@required Platform platform,
@required Logger logger,
}) : _fileSystem = fileSystem,
_platform = platform,
_logger = logger;
final FileSystem _fileSystem;
final Platform _platform;
final Logger _logger;
/// Build `target` and all of its dependencies. /// Build `target` and all of its dependencies.
Future<BuildResult> build( Future<BuildResult> build(
...@@ -436,15 +477,22 @@ class BuildSystem { ...@@ -436,15 +477,22 @@ class BuildSystem {
// Load file hash store from previous builds. // Load file hash store from previous builds.
final FileHashStore fileCache = FileHashStore( final FileHashStore fileCache = FileHashStore(
environment: environment, environment: environment,
fileSystem: globals.fs, fileSystem: _fileSystem,
logger: globals.logger, logger: _logger,
)..initialize(); )..initialize();
// Perform sanity checks on build. // Perform sanity checks on build.
checkCycles(target); checkCycles(target);
final Node node = target._toNode(environment); final Node node = target._toNode(environment);
final _BuildInstance buildInstance = _BuildInstance(environment, fileCache, buildSystemConfig); final _BuildInstance buildInstance = _BuildInstance(
environment: environment,
fileCache: fileCache,
buildSystemConfig: buildSystemConfig,
logger: _logger,
fileSystem: _fileSystem,
platform: _platform,
);
bool passed = true; bool passed = true;
try { try {
passed = await buildInstance.invokeTarget(node); passed = await buildInstance.invokeTarget(node);
...@@ -486,9 +534,18 @@ class BuildSystem { ...@@ -486,9 +534,18 @@ class BuildSystem {
/// An active instance of a build. /// An active instance of a build.
class _BuildInstance { class _BuildInstance {
_BuildInstance(this.environment, this.fileCache, this.buildSystemConfig) _BuildInstance({
: resourcePool = Pool(buildSystemConfig.resourcePoolSize ?? globals.platform?.numberOfProcessors ?? 1); this.environment,
this.fileCache,
this.buildSystemConfig,
this.logger,
this.fileSystem,
Platform platform,
})
: resourcePool = Pool(buildSystemConfig.resourcePoolSize ?? platform?.numberOfProcessors ?? 1);
final Logger logger;
final FileSystem fileSystem;
final BuildSystemConfig buildSystemConfig; final BuildSystemConfig buildSystemConfig;
final Pool resourcePool; final Pool resourcePool;
final Map<String, AsyncMemoizer<bool>> pending = <String, AsyncMemoizer<bool>>{}; final Map<String, AsyncMemoizer<bool>> pending = <String, AsyncMemoizer<bool>>{};
...@@ -545,17 +602,17 @@ class _BuildInstance { ...@@ -545,17 +602,17 @@ class _BuildInstance {
// If we're missing a depfile, wait until after evaluating the target to // If we're missing a depfile, wait until after evaluating the target to
// compute changes. // compute changes.
final bool canSkip = !node.missingDepfile && final bool canSkip = !node.missingDepfile &&
await node.computeChanges(environment, fileCache); await node.computeChanges(environment, fileCache, fileSystem, logger);
if (canSkip) { if (canSkip) {
skipped = true; skipped = true;
globals.printTrace('Skipping target: ${node.target.name}'); logger.printTrace('Skipping target: ${node.target.name}');
updateGraph(); updateGraph();
return passed; return passed;
} }
globals.printTrace('${node.target.name}: Starting due to ${node.invalidatedReasons}'); logger.printTrace('${node.target.name}: Starting due to ${node.invalidatedReasons}');
await node.target.build(environment); await node.target.build(environment);
globals.printTrace('${node.target.name}: Complete'); logger.printTrace('${node.target.name}: Complete');
node.inputs node.inputs
..clear() ..clear()
...@@ -581,7 +638,7 @@ class _BuildInstance { ...@@ -581,7 +638,7 @@ class _BuildInstance {
if (outputFiles.containsKey(previousOutput)) { if (outputFiles.containsKey(previousOutput)) {
continue; continue;
} }
final File previousFile = globals.fs.file(previousOutput); final File previousFile = fileSystem.file(previousOutput);
if (previousFile.existsSync()) { if (previousFile.existsSync()) {
previousFile.deleteSync(); previousFile.deleteSync();
} }
...@@ -771,6 +828,8 @@ class Node { ...@@ -771,6 +828,8 @@ class Node {
Future<bool> computeChanges( Future<bool> computeChanges(
Environment environment, Environment environment,
FileHashStore fileHashStore, FileHashStore fileHashStore,
FileSystem fileSystem,
Logger logger,
) async { ) async {
final Set<String> currentOutputPaths = <String>{ final Set<String> currentOutputPaths = <String>{
for (final File file in outputs) file.path, for (final File file in outputs) file.path,
...@@ -808,7 +867,7 @@ class Node { ...@@ -808,7 +867,7 @@ class Node {
// if this isn't a current output file there is no reason to compute the hash. // if this isn't a current output file there is no reason to compute the hash.
continue; continue;
} }
final File file = globals.fs.file(previousOutput); final File file = fileSystem.file(previousOutput);
if (!file.existsSync()) { if (!file.existsSync()) {
invalidatedReasons.add(InvalidatedReason.outputMissing); invalidatedReasons.add(InvalidatedReason.outputMissing);
_dirty = true; _dirty = true;
...@@ -833,7 +892,7 @@ class Node { ...@@ -833,7 +892,7 @@ class Node {
if (missingInputs.isNotEmpty) { if (missingInputs.isNotEmpty) {
_dirty = true; _dirty = true;
final String missingMessage = missingInputs.map((File file) => file.path).join(', '); final String missingMessage = missingInputs.map((File file) => file.path).join(', ');
globals.printTrace('invalidated build due to missing files: $missingMessage'); logger.printTrace('invalidated build due to missing files: $missingMessage');
invalidatedReasons.add(InvalidatedReason.inputMissing); invalidatedReasons.add(InvalidatedReason.inputMissing);
} }
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
import '../artifacts.dart'; import '../artifacts.dart';
import '../base/file_system.dart'; import '../base/file_system.dart';
import '../build_info.dart'; import '../build_info.dart';
import '../globals.dart' as globals;
import 'build_system.dart'; import 'build_system.dart';
import 'exceptions.dart'; import 'exceptions.dart';
...@@ -24,7 +23,7 @@ abstract class ResolvedFiles { ...@@ -24,7 +23,7 @@ abstract class ResolvedFiles {
/// Collects sources for a [Target] into a single list of [FileSystemEntities]. /// Collects sources for a [Target] into a single list of [FileSystemEntities].
class SourceVisitor implements ResolvedFiles { class SourceVisitor implements ResolvedFiles {
/// Create a new [SourceVisitor] from an [Environment]. /// Create a new [SourceVisitor] from an [Environment].
SourceVisitor(this.environment, [this.inputs = true]); SourceVisitor(this.environment, [ this.inputs = true ]);
/// The current environment. /// The current environment.
final Environment environment; final Environment environment;
...@@ -56,7 +55,7 @@ class SourceVisitor implements ResolvedFiles { ...@@ -56,7 +55,7 @@ class SourceVisitor implements ResolvedFiles {
final String contents = depfile.readAsStringSync(); final String contents = depfile.readAsStringSync();
final List<String> colonSeparated = contents.split(': '); final List<String> colonSeparated = contents.split(': ');
if (colonSeparated.length != 2) { if (colonSeparated.length != 2) {
globals.printError('Invalid depfile: ${depfile.path}'); environment.logger.printError('Invalid depfile: ${depfile.path}');
return; return;
} }
if (inputs) { if (inputs) {
...@@ -78,7 +77,7 @@ class SourceVisitor implements ResolvedFiles { ...@@ -78,7 +77,7 @@ class SourceVisitor implements ResolvedFiles {
.map<String>((String path) => path.replaceAllMapped(_escapeExpr, (Match match) => match.group(1)).trim()) .map<String>((String path) => path.replaceAllMapped(_escapeExpr, (Match match) => match.group(1)).trim())
.where((String path) => path.isNotEmpty) .where((String path) => path.isNotEmpty)
.toSet() .toSet()
.map((String path) => globals.fs.file(path)); .map(environment.fileSystem.file);
} }
/// Visit a [Source] which contains a file URL. /// Visit a [Source] which contains a file URL.
...@@ -101,35 +100,36 @@ class SourceVisitor implements ResolvedFiles { ...@@ -101,35 +100,36 @@ class SourceVisitor implements ResolvedFiles {
switch (rawParts.first) { switch (rawParts.first) {
case Environment.kProjectDirectory: case Environment.kProjectDirectory:
segments.addAll( segments.addAll(
globals.fs.path.split(environment.projectDir.resolveSymbolicLinksSync())); environment.fileSystem.path.split(environment.projectDir.resolveSymbolicLinksSync()));
break; break;
case Environment.kBuildDirectory: case Environment.kBuildDirectory:
segments.addAll(globals.fs.path.split( segments.addAll(environment.fileSystem.path.split(
environment.buildDir.resolveSymbolicLinksSync())); environment.buildDir.resolveSymbolicLinksSync()));
break; break;
case Environment.kCacheDirectory: case Environment.kCacheDirectory:
segments.addAll( segments.addAll(
globals.fs.path.split(environment.cacheDir.resolveSymbolicLinksSync())); environment.fileSystem.path.split(environment.cacheDir.resolveSymbolicLinksSync()));
break; break;
case Environment.kFlutterRootDirectory: case Environment.kFlutterRootDirectory:
// flutter root will not contain a symbolic link. // flutter root will not contain a symbolic link.
segments.addAll( segments.addAll(
globals.fs.path.split(environment.flutterRootDir.absolute.path)); environment.fileSystem.path.split(environment.flutterRootDir.absolute.path));
break; break;
case Environment.kOutputDirectory: case Environment.kOutputDirectory:
segments.addAll( segments.addAll(
globals.fs.path.split(environment.outputDir.resolveSymbolicLinksSync())); environment.fileSystem.path.split(environment.outputDir.resolveSymbolicLinksSync()));
break; break;
default: default:
throw InvalidPatternException(pattern); throw InvalidPatternException(pattern);
} }
rawParts.skip(1).forEach(segments.add); rawParts.skip(1).forEach(segments.add);
final String filePath = globals.fs.path.joinAll(segments); final String filePath = environment.fileSystem.path.joinAll(segments);
if (!hasWildcard) { if (!hasWildcard) {
if (optional && !globals.fs.isFileSync(filePath)) { if (optional && !environment.fileSystem.isFileSync(filePath)) {
return; return;
} }
sources.add(globals.fs.file(globals.fs.path.normalize(filePath))); sources.add(environment.fileSystem.file(
environment.fileSystem.path.normalize(filePath)));
return; return;
} }
// Perform a simple match by splitting the wildcard containing file one // Perform a simple match by splitting the wildcard containing file one
...@@ -143,21 +143,21 @@ class SourceVisitor implements ResolvedFiles { ...@@ -143,21 +143,21 @@ class SourceVisitor implements ResolvedFiles {
if (wildcardSegments.length > 2) { if (wildcardSegments.length > 2) {
throw InvalidPatternException(pattern); throw InvalidPatternException(pattern);
} }
if (!globals.fs.directory(filePath).existsSync()) { if (!environment.fileSystem.directory(filePath).existsSync()) {
throw Exception('$filePath does not exist!'); throw Exception('$filePath does not exist!');
} }
for (final FileSystemEntity entity in globals.fs.directory(filePath).listSync()) { for (final FileSystemEntity entity in environment.fileSystem.directory(filePath).listSync()) {
final String filename = globals.fs.path.basename(entity.path); final String filename = environment.fileSystem.path.basename(entity.path);
if (wildcardSegments.isEmpty) { if (wildcardSegments.isEmpty) {
sources.add(globals.fs.file(entity.absolute)); sources.add(environment.fileSystem.file(entity.absolute));
} else if (wildcardSegments.length == 1) { } else if (wildcardSegments.length == 1) {
if (filename.startsWith(wildcardSegments[0]) || if (filename.startsWith(wildcardSegments[0]) ||
filename.endsWith(wildcardSegments[0])) { filename.endsWith(wildcardSegments[0])) {
sources.add(globals.fs.file(entity.absolute)); sources.add(environment.fileSystem.file(entity.absolute));
} }
} else if (filename.startsWith(wildcardSegments[0])) { } else if (filename.startsWith(wildcardSegments[0])) {
if (filename.substring(wildcardSegments[0].length).endsWith(wildcardSegments[1])) { if (filename.substring(wildcardSegments[0].length).endsWith(wildcardSegments[1])) {
sources.add(globals.fs.file(entity.absolute)); sources.add(environment.fileSystem.file(entity.absolute));
} }
} }
} }
...@@ -167,15 +167,16 @@ class SourceVisitor implements ResolvedFiles { ...@@ -167,15 +167,16 @@ class SourceVisitor implements ResolvedFiles {
/// ///
/// If the [Artifact] points to a directory then all child files are included. /// If the [Artifact] points to a directory then all child files are included.
void visitArtifact(Artifact artifact, TargetPlatform platform, BuildMode mode) { void visitArtifact(Artifact artifact, TargetPlatform platform, BuildMode mode) {
final String path = globals.artifacts.getArtifactPath(artifact, platform: platform, mode: mode); final String path = environment.artifacts
if (globals.fs.isDirectorySync(path)) { .getArtifactPath(artifact, platform: platform, mode: mode);
if (environment.fileSystem.isDirectorySync(path)) {
sources.addAll(<File>[ sources.addAll(<File>[
for (FileSystemEntity entity in globals.fs.directory(path).listSync(recursive: true)) for (FileSystemEntity entity in environment.fileSystem.directory(path).listSync(recursive: true))
if (entity is File) if (entity is File)
entity, entity,
]); ]);
} else { } else {
sources.add(globals.fs.file(path)); sources.add(environment.fileSystem.file(path));
} }
} }
} }
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
import '../../artifacts.dart'; import '../../artifacts.dart';
import '../../base/file_system.dart'; import '../../base/file_system.dart';
import '../../build_info.dart'; import '../../build_info.dart';
import '../../globals.dart' as globals;
import '../build_system.dart'; import '../build_system.dart';
/// Copies the Windows desktop embedding files to the copy directory. /// Copies the Windows desktop embedding files to the copy directory.
...@@ -40,21 +39,24 @@ class UnpackWindows extends Target { ...@@ -40,21 +39,24 @@ class UnpackWindows extends Target {
@override @override
Future<void> build(Environment environment) async { Future<void> build(Environment environment) async {
// This path needs to match the prefix in the rule below. // This path needs to match the prefix in the rule below.
final String basePath = globals.artifacts.getArtifactPath(Artifact.windowsDesktopPath); final String basePath = environment.artifacts
for (final File input in globals.fs.directory(basePath) .getArtifactPath(Artifact.windowsDesktopPath);
for (final File input in environment.fileSystem.directory(basePath)
.listSync(recursive: true) .listSync(recursive: true)
.whereType<File>()) { .whereType<File>()) {
final String outputPath = globals.fs.path.join( final String outputPath = environment.fileSystem.path.join(
environment.projectDir.path, environment.projectDir.path,
'windows', 'windows',
'flutter', 'flutter',
globals.fs.path.relative(input.path, from: basePath), environment.fileSystem.path
.relative(input.path, from: basePath),
); );
final File destinationFile = globals.fs.file(outputPath); final File destinationFile = environment.fileSystem.file(outputPath);
if (!destinationFile.parent.existsSync()) { if (!destinationFile.parent.existsSync()) {
destinationFile.parent.createSync(recursive: true); destinationFile.parent.createSync(recursive: true);
} }
globals.fs.file(input).copySync(destinationFile.path); environment.fileSystem
.file(input).copySync(destinationFile.path);
} }
} }
} }
...@@ -132,6 +132,10 @@ Future<void> buildWithAssemble({ ...@@ -132,6 +132,10 @@ Future<void> buildWithAssemble({
if (dartDefines != null && dartDefines.isNotEmpty) if (dartDefines != null && dartDefines.isNotEmpty)
kDartDefines: jsonEncode(dartDefines), kDartDefines: jsonEncode(dartDefines),
}, },
artifacts: globals.artifacts,
fileSystem: globals.fs,
logger: globals.logger,
processManager: globals.processManager,
); );
final Target target = buildMode == BuildMode.debug final Target target = buildMode == BuildMode.debug
? const CopyFlutterBundle() ? const CopyFlutterBundle()
......
...@@ -151,6 +151,10 @@ class AssembleCommand extends FlutterCommand { ...@@ -151,6 +151,10 @@ class AssembleCommand extends FlutterCommand {
defines: _parseDefines(stringsArg('define')), defines: _parseDefines(stringsArg('define')),
cacheDir: globals.cache.getRoot(), cacheDir: globals.cache.getRoot(),
flutterRootDir: globals.fs.directory(Cache.flutterRoot), flutterRootDir: globals.fs.directory(Cache.flutterRoot),
artifacts: globals.artifacts,
fileSystem: globals.fs,
logger: globals.logger,
processManager: globals.processManager,
); );
return result; return result;
} }
......
...@@ -89,7 +89,11 @@ Future<T> runInContext<T>( ...@@ -89,7 +89,11 @@ Future<T> runInContext<T>(
platform: globals.platform, platform: globals.platform,
), ),
AssetBundleFactory: () => AssetBundleFactory.defaultInstance, AssetBundleFactory: () => AssetBundleFactory.defaultInstance,
BuildSystem: () => const BuildSystem(), BuildSystem: () => BuildSystem(
fileSystem: globals.fs,
logger: globals.logger,
platform: globals.platform,
),
Cache: () => Cache( Cache: () => Cache(
fileSystem: globals.fs, fileSystem: globals.fs,
logger: globals.logger, logger: globals.logger,
......
...@@ -53,6 +53,10 @@ Future<void> buildWeb( ...@@ -53,6 +53,10 @@ Future<void> buildWeb(
kCspMode: csp.toString(), kCspMode: csp.toString(),
kIconTreeShakerFlag: buildInfo.treeShakeIcons.toString(), kIconTreeShakerFlag: buildInfo.treeShakeIcons.toString(),
}, },
artifacts: globals.artifacts,
fileSystem: globals.fs,
logger: globals.logger,
processManager: globals.processManager,
)); ));
if (!result.success) { if (!result.success) {
for (final ExceptionMeasurement measurement in result.exceptions.values) { for (final ExceptionMeasurement measurement in result.exceptions.values) {
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:file/memory.dart'; import 'package:file/memory.dart';
import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart'; import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/terminal.dart'; import 'package:flutter_tools/src/base/terminal.dart';
...@@ -14,6 +15,7 @@ import 'package:mockito/mockito.dart'; ...@@ -14,6 +15,7 @@ import 'package:mockito/mockito.dart';
import 'package:platform/platform.dart'; import 'package:platform/platform.dart';
import '../../src/common.dart'; import '../../src/common.dart';
import '../../src/fake_process_manager.dart';
void main() { void main() {
Environment environment; Environment environment;
...@@ -29,6 +31,10 @@ void main() { ...@@ -29,6 +31,10 @@ void main() {
fileSystem.directory('build').createSync(); fileSystem.directory('build').createSync();
environment = Environment.test( environment = Environment.test(
fileSystem.currentDirectory, fileSystem.currentDirectory,
artifacts: MockArtifacts(),
processManager: FakeProcessManager.any(),
logger: logger,
fileSystem: fileSystem,
); );
environment.buildDir.createSync(recursive: true); environment.buildDir.createSync(recursive: true);
}); });
...@@ -168,4 +174,6 @@ class FakeForwardingFileSystem extends ForwardingFileSystem { ...@@ -168,4 +174,6 @@ class FakeForwardingFileSystem extends ForwardingFileSystem {
@override @override
File file(dynamic path) => files[path] ?? super.file(path); File file(dynamic path) => files[path] ?? super.file(path);
} }
class MockFile extends Mock implements File {} class MockFile extends Mock implements File {}
class MockArtifacts extends Mock implements Artifacts {}
...@@ -14,6 +14,7 @@ import 'package:mockito/mockito.dart'; ...@@ -14,6 +14,7 @@ import 'package:mockito/mockito.dart';
import 'package:platform/platform.dart'; import 'package:platform/platform.dart';
import '../../src/common.dart'; import '../../src/common.dart';
import '../../src/context.dart';
import '../../src/testbed.dart'; import '../../src/testbed.dart';
void main() { void main() {
...@@ -32,6 +33,10 @@ void main() { ...@@ -32,6 +33,10 @@ void main() {
environment = Environment.test( environment = Environment.test(
globals.fs.currentDirectory, globals.fs.currentDirectory,
outputDir: outputs, outputDir: outputs,
artifacts: globals.artifacts, // using real artifacts
processManager: FakeProcessManager.any(),
fileSystem: globals.fs,
logger: globals.logger,
); );
visitor = SourceVisitor(environment); visitor = SourceVisitor(environment);
environment.buildDir.createSync(recursive: true); environment.buildDir.createSync(recursive: true);
...@@ -212,3 +217,4 @@ void main() { ...@@ -212,3 +217,4 @@ void main() {
} }
class MockPlatform extends Mock implements Platform {} class MockPlatform extends Mock implements Platform {}
class MockArtifacts extends Mock implements Artifacts {}
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/build_info.dart'; import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/build_system/build_system.dart'; import 'package:flutter_tools/src/build_system/build_system.dart';
...@@ -9,6 +10,7 @@ import 'package:flutter_tools/src/build_system/targets/android.dart'; ...@@ -9,6 +10,7 @@ import 'package:flutter_tools/src/build_system/targets/android.dart';
import 'package:flutter_tools/src/build_system/targets/dart.dart'; import 'package:flutter_tools/src/build_system/targets/dart.dart';
import 'package:flutter_tools/src/globals.dart' as globals; import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:flutter_tools/src/cache.dart'; import 'package:flutter_tools/src/cache.dart';
import 'package:mockito/mockito.dart';
import 'package:platform/platform.dart'; import 'package:platform/platform.dart';
import '../../../src/common.dart'; import '../../../src/common.dart';
...@@ -32,7 +34,11 @@ void main() { ...@@ -32,7 +34,11 @@ void main() {
outputDir: globals.fs.directory('out')..createSync(), outputDir: globals.fs.directory('out')..createSync(),
defines: <String, String>{ defines: <String, String>{
kBuildMode: 'debug', kBuildMode: 'debug',
} },
processManager: fakeProcessManager,
artifacts: MockArtifacts(),
fileSystem: globals.fs,
logger: globals.logger,
); );
environment.buildDir.createSync(recursive: true); environment.buildDir.createSync(recursive: true);
...@@ -45,7 +51,6 @@ void main() { ...@@ -45,7 +51,6 @@ void main() {
hostDirectory.childFile('vm_isolate_snapshot.bin').createSync(); hostDirectory.childFile('vm_isolate_snapshot.bin').createSync();
hostDirectory.childFile('isolate_snapshot.bin').createSync(); hostDirectory.childFile('isolate_snapshot.bin').createSync();
await const DebugAndroidApplication().build(environment); await const DebugAndroidApplication().build(environment);
expect(globals.fs.file(globals.fs.path.join('out', 'flutter_assets', 'isolate_snapshot_data')).existsSync(), true); expect(globals.fs.file(globals.fs.path.join('out', 'flutter_assets', 'isolate_snapshot_data')).existsSync(), true);
...@@ -59,7 +64,11 @@ void main() { ...@@ -59,7 +64,11 @@ void main() {
outputDir: globals.fs.directory('out')..createSync(), outputDir: globals.fs.directory('out')..createSync(),
defines: <String, String>{ defines: <String, String>{
kBuildMode: 'profile', kBuildMode: 'profile',
} },
artifacts: MockArtifacts(),
processManager: fakeProcessManager,
fileSystem: globals.fs,
logger: globals.logger,
); );
environment.buildDir.createSync(recursive: true); environment.buildDir.createSync(recursive: true);
...@@ -78,7 +87,11 @@ void main() { ...@@ -78,7 +87,11 @@ void main() {
outputDir: globals.fs.directory('out')..createSync(), outputDir: globals.fs.directory('out')..createSync(),
defines: <String, String>{ defines: <String, String>{
kBuildMode: 'release', kBuildMode: 'release',
} },
artifacts: MockArtifacts(),
processManager: fakeProcessManager,
fileSystem: globals.fs,
logger: globals.logger,
); );
environment.buildDir.createSync(recursive: true); environment.buildDir.createSync(recursive: true);
...@@ -92,15 +105,19 @@ void main() { ...@@ -92,15 +105,19 @@ void main() {
}); });
testbed.test('AndroidAot can build provided target platform', () async { testbed.test('AndroidAot can build provided target platform', () async {
fakeProcessManager = FakeProcessManager.list(<FakeCommand>[]);
final Environment environment = Environment.test( final Environment environment = Environment.test(
globals.fs.currentDirectory, globals.fs.currentDirectory,
outputDir: globals.fs.directory('out')..createSync(), outputDir: globals.fs.directory('out')..createSync(),
defines: <String, String>{ defines: <String, String>{
kBuildMode: 'release', kBuildMode: 'release',
} },
artifacts: MockArtifacts(),
processManager: FakeProcessManager.list(<FakeCommand>[]),
fileSystem: globals.fs,
logger: globals.logger,
); );
fakeProcessManager = FakeProcessManager.list(<FakeCommand>[ fakeProcessManager.addCommand(FakeCommand(command: <String>[
FakeCommand(command: <String>[
globals.fs.path.absolute(globals.fs.path.join('android-arm64-release', 'linux-x64', 'gen_snapshot')), globals.fs.path.absolute(globals.fs.path.join('android-arm64-release', 'linux-x64', 'gen_snapshot')),
'--deterministic', '--deterministic',
'--snapshot_kind=app-aot-elf', '--snapshot_kind=app-aot-elf',
...@@ -111,18 +128,21 @@ void main() { ...@@ -111,18 +128,21 @@ void main() {
environment.buildDir.childFile('app.dill').path, environment.buildDir.childFile('app.dill').path,
], ],
) )
]); );
environment.buildDir.createSync(recursive: true); environment.buildDir.createSync(recursive: true);
environment.buildDir.childFile('app.dill').createSync(); environment.buildDir.childFile('app.dill').createSync();
environment.projectDir.childFile('.packages').writeAsStringSync('\n'); environment.projectDir.childFile('.packages').writeAsStringSync('\n');
const AndroidAot androidAot = AndroidAot(TargetPlatform.android_arm64, BuildMode.release); const AndroidAot androidAot = AndroidAot(TargetPlatform.android_arm64, BuildMode.release);
await androidAot.build(environment); await androidAot.build(environment);
expect(fakeProcessManager.hasRemainingExpectations, false);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
ProcessManager: () => fakeProcessManager, ProcessManager: () => fakeProcessManager,
}); });
testbed.test('kExtraGenSnapshotOptions passes values to gen_snapshot', () async { testbed.test('kExtraGenSnapshotOptions passes values to gen_snapshot', () async {
fakeProcessManager = FakeProcessManager.list(<FakeCommand>[]);
final Environment environment = Environment.test( final Environment environment = Environment.test(
globals.fs.currentDirectory, globals.fs.currentDirectory,
outputDir: globals.fs.directory('out')..createSync(), outputDir: globals.fs.directory('out')..createSync(),
...@@ -130,9 +150,13 @@ void main() { ...@@ -130,9 +150,13 @@ void main() {
kBuildMode: 'release', kBuildMode: 'release',
kExtraGenSnapshotOptions: 'foo,bar,baz=2', kExtraGenSnapshotOptions: 'foo,bar,baz=2',
kTargetPlatform: 'android-arm', kTargetPlatform: 'android-arm',
} },
processManager: fakeProcessManager,
artifacts: MockArtifacts(),
fileSystem: globals.fs,
logger: globals.logger,
); );
fakeProcessManager = FakeProcessManager.list(<FakeCommand>[ fakeProcessManager.addCommand(
FakeCommand(command: <String>[ FakeCommand(command: <String>[
globals.fs.path.absolute(globals.fs.path.join('android-arm64-release', 'linux-x64', 'gen_snapshot')), globals.fs.path.absolute(globals.fs.path.join('android-arm64-release', 'linux-x64', 'gen_snapshot')),
'--deterministic', '--deterministic',
...@@ -145,8 +169,7 @@ void main() { ...@@ -145,8 +169,7 @@ void main() {
'--no-causal-async-stacks', '--no-causal-async-stacks',
'--lazy-async-stacks', '--lazy-async-stacks',
environment.buildDir.childFile('app.dill').path environment.buildDir.childFile('app.dill').path
]) ]));
]);
environment.buildDir.createSync(recursive: true); environment.buildDir.createSync(recursive: true);
environment.buildDir.childFile('app.dill').createSync(); environment.buildDir.childFile('app.dill').createSync();
environment.projectDir.childFile('.packages').writeAsStringSync('\n'); environment.projectDir.childFile('.packages').writeAsStringSync('\n');
...@@ -163,7 +186,11 @@ void main() { ...@@ -163,7 +186,11 @@ void main() {
outputDir: globals.fs.directory('out')..createSync(), outputDir: globals.fs.directory('out')..createSync(),
defines: <String, String>{ defines: <String, String>{
kBuildMode: 'release', kBuildMode: 'release',
} },
processManager: fakeProcessManager,
artifacts: MockArtifacts(),
fileSystem: globals.fs,
logger: globals.logger,
); );
environment.buildDir.createSync(recursive: true); environment.buildDir.createSync(recursive: true);
const AndroidAot androidAot = AndroidAot(TargetPlatform.android_arm64, BuildMode.release); const AndroidAot androidAot = AndroidAot(TargetPlatform.android_arm64, BuildMode.release);
...@@ -181,3 +208,5 @@ void main() { ...@@ -181,3 +208,5 @@ void main() {
.childFile('app.so').existsSync(), true); .childFile('app.so').existsSync(), true);
}); });
} }
class MockArtifacts extends Mock implements Artifacts {}
\ No newline at end of file
...@@ -4,10 +4,13 @@ ...@@ -4,10 +4,13 @@
import 'package:file/memory.dart'; import 'package:file/memory.dart';
import 'package:file_testing/file_testing.dart'; import 'package:file_testing/file_testing.dart';
import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/build_system/build_system.dart'; import 'package:flutter_tools/src/build_system/build_system.dart';
import 'package:flutter_tools/src/build_system/depfile.dart'; import 'package:flutter_tools/src/build_system/depfile.dart';
import 'package:flutter_tools/src/build_system/targets/assets.dart'; import 'package:flutter_tools/src/build_system/targets/assets.dart';
import 'package:mockito/mockito.dart';
import 'package:platform/platform.dart'; import 'package:platform/platform.dart';
import '../../../src/common.dart'; import '../../../src/common.dart';
...@@ -23,6 +26,10 @@ void main() { ...@@ -23,6 +26,10 @@ void main() {
fileSystem = MemoryFileSystem.test(); fileSystem = MemoryFileSystem.test();
environment = Environment.test( environment = Environment.test(
fileSystem.currentDirectory, fileSystem.currentDirectory,
processManager: FakeProcessManager.any(),
artifacts: MockArtifacts(),
fileSystem: fileSystem,
logger: BufferLogger.test(),
); );
fileSystem.file(environment.buildDir.childFile('app.dill')).createSync(recursive: true); fileSystem.file(environment.buildDir.childFile('app.dill')).createSync(recursive: true);
fileSystem.file('packages/flutter_tools/lib/src/build_system/targets/assets.dart') fileSystem.file('packages/flutter_tools/lib/src/build_system/targets/assets.dart')
...@@ -91,3 +98,5 @@ flutter: ...@@ -91,3 +98,5 @@ flutter:
Platform: () => platform, Platform: () => platform,
}); });
} }
class MockArtifacts extends Mock implements Artifacts {}
...@@ -43,6 +43,10 @@ void main() { ...@@ -43,6 +43,10 @@ void main() {
kBuildMode: getNameForBuildMode(BuildMode.profile), kBuildMode: getNameForBuildMode(BuildMode.profile),
kTargetPlatform: getNameForTargetPlatform(TargetPlatform.android_arm), kTargetPlatform: getNameForTargetPlatform(TargetPlatform.android_arm),
}, },
artifacts: artifacts,
processManager: processManager,
fileSystem: globals.fs,
logger: globals.logger,
); );
androidEnvironment.buildDir.createSync(recursive: true); androidEnvironment.buildDir.createSync(recursive: true);
iosEnvironment = Environment.test( iosEnvironment = Environment.test(
...@@ -51,6 +55,10 @@ void main() { ...@@ -51,6 +55,10 @@ void main() {
kBuildMode: getNameForBuildMode(BuildMode.profile), kBuildMode: getNameForBuildMode(BuildMode.profile),
kTargetPlatform: getNameForTargetPlatform(TargetPlatform.ios), kTargetPlatform: getNameForTargetPlatform(TargetPlatform.ios),
}, },
artifacts: artifacts,
processManager: processManager,
fileSystem: globals.fs,
logger: globals.logger,
); );
iosEnvironment.buildDir.createSync(recursive: true); iosEnvironment.buildDir.createSync(recursive: true);
artifacts = CachedArtifacts( artifacts = CachedArtifacts(
...@@ -261,6 +269,10 @@ void main() { ...@@ -261,6 +269,10 @@ void main() {
kBuildMode: getNameForBuildMode(BuildMode.debug), kBuildMode: getNameForBuildMode(BuildMode.debug),
kTargetPlatform: getNameForTargetPlatform(TargetPlatform.android_arm), kTargetPlatform: getNameForTargetPlatform(TargetPlatform.android_arm),
}, },
processManager: processManager,
artifacts: artifacts,
fileSystem: globals.fs,
logger: globals.logger,
); );
final String build = testEnvironment.buildDir.path; final String build = testEnvironment.buildDir.path;
processManager = FakeProcessManager.list(<FakeCommand>[ processManager = FakeProcessManager.list(<FakeCommand>[
......
...@@ -113,6 +113,10 @@ void main() { ...@@ -113,6 +113,10 @@ void main() {
return Environment.test( return Environment.test(
fs.directory('/icon_test')..createSync(recursive: true), fs.directory('/icon_test')..createSync(recursive: true),
defines: defines, defines: defines,
artifacts: mockArtifacts,
processManager: FakeProcessManager.any(),
fileSystem: fs,
logger: BufferLogger.test(),
); );
} }
......
...@@ -39,9 +39,16 @@ void main() { ...@@ -39,9 +39,16 @@ void main() {
setUp(() { setUp(() {
testbed = Testbed(setup: () { testbed = Testbed(setup: () {
environment = Environment.test(globals.fs.currentDirectory, defines: <String, String>{ environment = Environment.test(
kTargetPlatform: 'ios', globals.fs.currentDirectory,
}); defines: <String, String>{
kTargetPlatform: 'ios',
},
processManager: processManager,
artifacts: MockArtifacts(),
logger: globals.logger,
fileSystem: globals.fs,
);
}); });
}); });
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'package:flutter_tools/src/artifacts.dart';
import 'package:platform/platform.dart'; import 'package:platform/platform.dart';
import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/build_system/build_system.dart'; import 'package:flutter_tools/src/build_system/build_system.dart';
...@@ -12,11 +13,12 @@ import 'package:flutter_tools/src/globals.dart' as globals; ...@@ -12,11 +13,12 @@ import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:mockito/mockito.dart'; import 'package:mockito/mockito.dart';
import '../../../src/common.dart'; import '../../../src/common.dart';
import '../../../src/context.dart';
import '../../../src/testbed.dart'; import '../../../src/testbed.dart';
void main() { void main() {
Testbed testbed; Testbed testbed;
const BuildSystem buildSystem = BuildSystem(); BuildSystem buildSystem;
Environment environment; Environment environment;
MockPlatform mockPlatform; MockPlatform mockPlatform;
...@@ -33,11 +35,20 @@ void main() { ...@@ -33,11 +35,20 @@ void main() {
when(mockPlatform.environment).thenReturn(Map<String, String>.unmodifiable(<String, String>{})); when(mockPlatform.environment).thenReturn(Map<String, String>.unmodifiable(<String, String>{}));
testbed = Testbed(setup: () { testbed = Testbed(setup: () {
Cache.flutterRoot = ''; Cache.flutterRoot = '';
buildSystem = BuildSystem(
logger: globals.logger,
platform: globals.platform,
fileSystem: globals.fs,
);
environment = Environment.test( environment = Environment.test(
globals.fs.currentDirectory, globals.fs.currentDirectory,
defines: <String, String>{ defines: <String, String>{
kBuildMode: 'debug', kBuildMode: 'debug',
} },
artifacts: MockArtifacts(),
processManager: FakeProcessManager.any(),
fileSystem: globals.fs,
logger: globals.logger,
); );
globals.fs.file('bin/cache/artifacts/engine/linux-x64/unrelated-stuff').createSync(recursive: true); globals.fs.file('bin/cache/artifacts/engine/linux-x64/unrelated-stuff').createSync(recursive: true);
globals.fs.file('bin/cache/artifacts/engine/linux-x64/libflutter_linux_glfw.so').createSync(recursive: true); globals.fs.file('bin/cache/artifacts/engine/linux-x64/libflutter_linux_glfw.so').createSync(recursive: true);
...@@ -105,3 +116,4 @@ void main() { ...@@ -105,3 +116,4 @@ void main() {
} }
class MockPlatform extends Mock implements Platform {} class MockPlatform extends Mock implements Platform {}
class MockArtifacts extends Mock implements Artifacts {}
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/build.dart'; import 'package:flutter_tools/src/base/build.dart';
import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/io.dart'; import 'package:flutter_tools/src/base/io.dart';
...@@ -16,6 +17,7 @@ import 'package:process/process.dart'; ...@@ -16,6 +17,7 @@ import 'package:process/process.dart';
import 'package:platform/platform.dart'; import 'package:platform/platform.dart';
import '../../../src/common.dart'; import '../../../src/common.dart';
import '../../../src/fake_process_manager.dart';
import '../../../src/testbed.dart'; import '../../../src/testbed.dart';
const String _kInputPrefix = 'bin/cache/artifacts/engine/darwin-x64/FlutterMacOS.framework'; const String _kInputPrefix = 'bin/cache/artifacts/engine/darwin-x64/FlutterMacOS.framework';
...@@ -70,8 +72,12 @@ void main() { ...@@ -70,8 +72,12 @@ void main() {
defines: <String, String>{ defines: <String, String>{
kBuildMode: 'debug', kBuildMode: 'debug',
kTargetPlatform: 'darwin-x64', kTargetPlatform: 'darwin-x64',
}, },
); artifacts: MockArtifacts(),
processManager: FakeProcessManager.any(),
logger: globals.logger,
fileSystem: globals.fs,
);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
ProcessManager: () => MockProcessManager(), ProcessManager: () => MockProcessManager(),
Platform: () => mockPlatform, Platform: () => mockPlatform,
...@@ -195,6 +201,7 @@ class MockPlatform extends Mock implements Platform {} ...@@ -195,6 +201,7 @@ class MockPlatform extends Mock implements Platform {}
class MockProcessManager extends Mock implements ProcessManager {} class MockProcessManager extends Mock implements ProcessManager {}
class MockGenSnapshot extends Mock implements GenSnapshot {} class MockGenSnapshot extends Mock implements GenSnapshot {}
class MockXcode extends Mock implements Xcode {} class MockXcode extends Mock implements Xcode {}
class MockArtifacts extends Mock implements Artifacts {}
class FakeProcessResult implements ProcessResult { class FakeProcessResult implements ProcessResult {
@override @override
int exitCode; int exitCode;
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
// found in the LICENSE file. // found in the LICENSE file.
import 'package:file_testing/file_testing.dart'; import 'package:file_testing/file_testing.dart';
import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/build_system/build_system.dart'; import 'package:flutter_tools/src/build_system/build_system.dart';
...@@ -55,7 +56,11 @@ void main() { ...@@ -55,7 +56,11 @@ void main() {
outputDir: globals.fs.currentDirectory.childDirectory('bar'), outputDir: globals.fs.currentDirectory.childDirectory('bar'),
defines: <String, String>{ defines: <String, String>{
kTargetFile: globals.fs.path.join('foo', 'lib', 'main.dart'), kTargetFile: globals.fs.path.join('foo', 'lib', 'main.dart'),
} },
artifacts: MockArtifacts(),
processManager: FakeProcessManager.any(),
logger: globals.logger,
fileSystem: globals.fs,
); );
depfileService = DepfileService( depfileService = DepfileService(
fileSystem: globals.fs, fileSystem: globals.fs,
...@@ -460,3 +465,4 @@ void main() { ...@@ -460,3 +465,4 @@ void main() {
} }
class MockProcessManager extends Mock implements ProcessManager {} class MockProcessManager extends Mock implements ProcessManager {}
class MockArtifacts extends Mock implements Artifacts {}
...@@ -3,102 +3,77 @@ ...@@ -3,102 +3,77 @@
// found in the LICENSE file. // found in the LICENSE file.
import 'package:file/memory.dart'; import 'package:file/memory.dart';
import 'package:file_testing/file_testing.dart';
import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:mockito/mockito.dart';
import 'package:platform/platform.dart';
import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/build_system/build_system.dart'; import 'package:flutter_tools/src/build_system/build_system.dart';
import 'package:flutter_tools/src/build_system/targets/windows.dart'; import 'package:flutter_tools/src/build_system/targets/windows.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:mockito/mockito.dart';
import 'package:platform/platform.dart';
import '../../../src/common.dart'; import '../../../src/common.dart';
import '../../../src/fake_process_manager.dart'; import '../../../src/fake_process_manager.dart';
import '../../../src/testbed.dart';
final Platform kWindowsPlatform = FakePlatform(
operatingSystem: 'windows',
environment: <String, String>{},
);
const List<String> kRequiredFiles = <String>[
r'C:\bin\cache\artifacts\engine\windows-x64\flutter_export.h',
r'C:\bin\cache\artifacts\engine\windows-x64\flutter_messenger.h',
r'C:\bin\cache\artifacts\engine\windows-x64\flutter_windows.dll',
r'C:\bin\cache\artifacts\engine\windows-x64\flutter_windows.dll.exp',
r'C:\bin\cache\artifacts\engine\windows-x64\flutter_windows.dll.lib',
r'C:\bin\cache\artifacts\engine\windows-x64\flutter_windows.dll.pdb',
r'C:\bin\cache\artifacts\engine\windows-x64\lutter_export.h',
r'C:\bin\cache\artifacts\engine\windows-x64\flutter_messenger.h',
r'C:\bin\cache\artifacts\engine\windows-x64\flutter_plugin_registrar.h',
r'C:\bin\cache\artifacts\engine\windows-x64\flutter_windows.h',
r'C:\bin\cache\artifacts\engine\windows-x64\icudtl.dat',
r'C:\bin\cache\artifacts\engine\windows-x64\cpp_client_wrapper\foo',
r'C:\packages\flutter_tools\lib\src\build_system\targets\windows.dart',
];
void main() { void main() {
Testbed testbed;
const BuildSystem buildSystem = BuildSystem();
Environment environment; Environment environment;
Platform platform; FileSystem fileSystem;
setUpAll(() {
Cache.disableLocking();
Cache.flutterRoot = '';
});
setUp(() { setUp(() {
platform = MockPlatform(); final MockArtifacts artifacts = MockArtifacts();
when(platform.isWindows).thenReturn(true); when(artifacts.getArtifactPath(Artifact.windowsDesktopPath))
when(platform.isMacOS).thenReturn(false); .thenReturn(r'C:\bin\cache\artifacts\engine\windows-x64\');
when(platform.isLinux).thenReturn(false); fileSystem = MemoryFileSystem.test(style: FileSystemStyle.windows);
when(platform.pathSeparator).thenReturn(r'\'); environment = Environment.test(
testbed = Testbed(setup: () { fileSystem.currentDirectory,
environment = Environment.test( artifacts: artifacts,
globals.fs.currentDirectory, processManager: FakeProcessManager.any(),
); fileSystem: fileSystem,
globals.fs.file(r'C:\bin\cache\artifacts\engine\windows-x64\flutter_export.h').createSync(recursive: true); logger: BufferLogger.test(),
globals.fs.file(r'C:\bin\cache\artifacts\engine\windows-x64\flutter_messenger.h').createSync(); );
globals.fs.file(r'C:\bin\cache\artifacts\engine\windows-x64\flutter_windows.dll').createSync(); for (final String path in kRequiredFiles) {
globals.fs.file(r'C:\bin\cache\artifacts\engine\windows-x64\flutter_windows.dll.exp').createSync(); fileSystem.file(path).createSync(recursive: true);
globals.fs.file(r'C:\bin\cache\artifacts\engine\windows-x64\flutter_windows.dll.lib').createSync(); }
globals.fs.file(r'C:\bin\cache\artifacts\engine\windows-x64\flutter_windows.dll.pdb').createSync(); fileSystem.directory('windows').createSync();
globals.fs.file(r'C:\bin\cache\artifacts\engine\windows-x64\lutter_export.h').createSync();
globals.fs.file(r'C:\bin\cache\artifacts\engine\windows-x64\flutter_messenger.h').createSync();
globals.fs.file(r'C:\bin\cache\artifacts\engine\windows-x64\flutter_plugin_registrar.h').createSync();
globals.fs.file(r'C:\bin\cache\artifacts\engine\windows-x64\flutter_windows.h').createSync();
globals.fs.file(r'C:\bin\cache\artifacts\engine\windows-x64\icudtl.dat').createSync();
globals.fs.file(r'C:\bin\cache\artifacts\engine\windows-x64\cpp_client_wrapper\foo').createSync(recursive: true);
globals.fs.file(r'C:\packages\flutter_tools\lib\src\build_system\targets\windows.dart').createSync(recursive: true);
globals.fs.directory('windows').createSync();
}, overrides: <Type, Generator>{
FileSystem: () => MemoryFileSystem(style: FileSystemStyle.windows),
ProcessManager: () => FakeProcessManager.any(),
Platform: () => platform,
});
}); });
test('Copies files to correct cache directory', () => testbed.run(() async { testWithoutContext('UnpackWindows copies files to the correct cache directory', () async {
await buildSystem.build(const UnpackWindows(), environment); await const UnpackWindows().build(environment);
expect(globals.fs.file(r'C:\windows\flutter\flutter_export.h').existsSync(), true);
expect(globals.fs.file(r'C:\windows\flutter\flutter_messenger.h').existsSync(), true);
expect(globals.fs.file(r'C:\windows\flutter\flutter_windows.dll').existsSync(), true);
expect(globals.fs.file(r'C:\windows\flutter\flutter_windows.dll.exp').existsSync(), true);
expect(globals.fs.file(r'C:\windows\flutter\flutter_windows.dll.lib').existsSync(), true);
expect(globals.fs.file(r'C:\windows\flutter\flutter_windows.dll.pdb').existsSync(), true);
expect(globals.fs.file(r'C:\windows\flutter\flutter_export.h').existsSync(), true);
expect(globals.fs.file(r'C:\windows\flutter\flutter_messenger.h').existsSync(), true);
expect(globals.fs.file(r'C:\windows\flutter\flutter_plugin_registrar.h').existsSync(), true);
expect(globals.fs.file(r'C:\windows\flutter\flutter_windows.h').existsSync(), true);
expect(globals.fs.file(r'C:\windows\flutter\icudtl.dat').existsSync(), true);
expect(globals.fs.file(r'C:\windows\flutter\cpp_client_wrapper\foo').existsSync(), true);
}));
test('Does not re-copy files unecessarily', () => testbed.run(() async {
await buildSystem.build(const UnpackWindows(), environment);
// Set a date in the far distant past to deal with the limited resolution
// of the windows filesystem.
final DateTime theDistantPast = DateTime(1991, 8, 23);
globals.fs.file(r'C:\windows\flutter\flutter_export.h').setLastModifiedSync(theDistantPast);
await buildSystem.build(const UnpackWindows(), environment);
expect(globals.fs.file(r'C:\windows\flutter\flutter_export.h').statSync().modified, equals(theDistantPast));
}));
test('Detects changes in input cache files', () => testbed.run(() async { expect(fileSystem.file(r'C:\windows\flutter\flutter_export.h'), exists);
await buildSystem.build(const UnpackWindows(), environment); expect(fileSystem.file(r'C:\windows\flutter\flutter_messenger.h'), exists);
// Set a date in the far distant past to deal with the limited resolution expect(fileSystem.file(r'C:\windows\flutter\flutter_windows.dll'), exists);
// of the windows filesystem. expect(fileSystem.file(r'C:\windows\flutter\flutter_windows.dll.exp'), exists);
final DateTime theDistantPast = DateTime(1991, 8, 23); expect(fileSystem.file(r'C:\windows\flutter\flutter_windows.dll.lib'), exists);
globals.fs.file(r'C:\windows\flutter\flutter_export.h').setLastModifiedSync(theDistantPast); expect(fileSystem.file(r'C:\windows\flutter\flutter_windows.dll.pdb'), exists);
final DateTime modified = globals.fs.file(r'C:\windows\flutter\flutter_export.h').statSync().modified; expect(fileSystem.file(r'C:\windows\flutter\flutter_export.h'), exists);
globals.fs.file(r'C:\bin\cache\artifacts\engine\windows-x64\flutter_export.h').writeAsStringSync('asd'); // modify cache. expect(fileSystem.file(r'C:\windows\flutter\flutter_messenger.h'), exists);
expect(fileSystem.file(r'C:\windows\flutter\flutter_plugin_registrar.h'), exists);
await buildSystem.build(const UnpackWindows(), environment); expect(fileSystem.file(r'C:\windows\flutter\flutter_windows.h'), exists);
expect(fileSystem.file(r'C:\windows\flutter\icudtl.dat'), exists);
expect(globals.fs.file(r'C:\windows\flutter\flutter_export.h').statSync().modified, isNot(modified)); expect(fileSystem.file(r'C:\windows\flutter\cpp_client_wrapper\foo'), exists);
})); });
} }
class MockPlatform extends Mock implements Platform {} class MockArtifacts extends Mock implements Artifacts {}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment