mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[flutter_tools] refactor build_system and targets to be context-free (#53268)
This commit is contained in:
parent
4605b51a7e
commit
72343ee0e4
@ -95,7 +95,11 @@ class AotBuilder {
|
||||
kExtraFrontEndOptions: buildInfo.extraFrontEndOptions.join(','),
|
||||
if (platform == TargetPlatform.ios)
|
||||
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);
|
||||
status?.stop();
|
||||
|
||||
@ -382,7 +382,7 @@ class BufferLogger extends Logger {
|
||||
_timeoutConfiguration = timeoutConfiguration,
|
||||
_stopwatchFactory = stopwatchFactory;
|
||||
|
||||
@visibleForTesting
|
||||
/// Create a [BufferLogger] with test preferences.
|
||||
BufferLogger.test({
|
||||
Terminal terminal,
|
||||
OutputPreferences outputPreferences,
|
||||
|
||||
@ -8,13 +8,16 @@ import 'package:async/async.dart';
|
||||
import 'package:convert/convert.dart';
|
||||
import 'package:crypto/crypto.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:platform/platform.dart';
|
||||
import 'package:pool/pool.dart';
|
||||
import 'package:process/process.dart';
|
||||
|
||||
import '../artifacts.dart';
|
||||
import '../base/file_system.dart';
|
||||
import '../base/logger.dart';
|
||||
import '../base/utils.dart';
|
||||
import '../cache.dart';
|
||||
import '../convert.dart';
|
||||
import '../globals.dart' as globals;
|
||||
import 'exceptions.dart';
|
||||
import 'file_hash_store.dart';
|
||||
import 'source.dart';
|
||||
@ -286,6 +289,10 @@ class Environment {
|
||||
@required Directory outputDir,
|
||||
@required Directory cacheDir,
|
||||
@required Directory flutterRootDir,
|
||||
@required FileSystem fileSystem,
|
||||
@required Logger logger,
|
||||
@required Artifacts artifacts,
|
||||
@required ProcessManager processManager,
|
||||
Directory buildDir,
|
||||
Map<String, String> defines = const <String, String>{},
|
||||
}) {
|
||||
@ -314,6 +321,10 @@ class Environment {
|
||||
cacheDir: cacheDir,
|
||||
defines: defines,
|
||||
flutterRootDir: flutterRootDir,
|
||||
fileSystem: fileSystem,
|
||||
logger: logger,
|
||||
artifacts: artifacts,
|
||||
processManager: processManager,
|
||||
);
|
||||
}
|
||||
|
||||
@ -327,6 +338,10 @@ class Environment {
|
||||
Directory flutterRootDir,
|
||||
Directory buildDir,
|
||||
Map<String, String> defines = const <String, String>{},
|
||||
@required FileSystem fileSystem,
|
||||
@required Logger logger,
|
||||
@required Artifacts artifacts,
|
||||
@required ProcessManager processManager,
|
||||
}) {
|
||||
return Environment(
|
||||
projectDir: projectDir ?? testDirectory,
|
||||
@ -335,6 +350,10 @@ class Environment {
|
||||
flutterRootDir: flutterRootDir ?? testDirectory,
|
||||
buildDir: buildDir,
|
||||
defines: defines,
|
||||
fileSystem: fileSystem,
|
||||
logger: logger,
|
||||
artifacts: artifacts,
|
||||
processManager: processManager,
|
||||
);
|
||||
}
|
||||
|
||||
@ -346,6 +365,10 @@ class Environment {
|
||||
@required this.cacheDir,
|
||||
@required this.defines,
|
||||
@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].
|
||||
@ -399,6 +422,14 @@ class Environment {
|
||||
|
||||
/// The root build directory shared by all builds.
|
||||
final Directory rootBuildDir;
|
||||
|
||||
final ProcessManager processManager;
|
||||
|
||||
final Logger logger;
|
||||
|
||||
final Artifacts artifacts;
|
||||
|
||||
final FileSystem fileSystem;
|
||||
}
|
||||
|
||||
/// The result information from the build system.
|
||||
@ -422,7 +453,17 @@ class BuildResult {
|
||||
|
||||
/// The build system is responsible for invoking and ordering [Target]s.
|
||||
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.
|
||||
Future<BuildResult> build(
|
||||
@ -436,15 +477,22 @@ class BuildSystem {
|
||||
// Load file hash store from previous builds.
|
||||
final FileHashStore fileCache = FileHashStore(
|
||||
environment: environment,
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
fileSystem: _fileSystem,
|
||||
logger: _logger,
|
||||
)..initialize();
|
||||
|
||||
// Perform sanity checks on build.
|
||||
checkCycles(target);
|
||||
|
||||
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;
|
||||
try {
|
||||
passed = await buildInstance.invokeTarget(node);
|
||||
@ -486,9 +534,18 @@ class BuildSystem {
|
||||
|
||||
/// An active instance of a build.
|
||||
class _BuildInstance {
|
||||
_BuildInstance(this.environment, this.fileCache, this.buildSystemConfig)
|
||||
: resourcePool = Pool(buildSystemConfig.resourcePoolSize ?? globals.platform?.numberOfProcessors ?? 1);
|
||||
_BuildInstance({
|
||||
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 Pool resourcePool;
|
||||
final Map<String, AsyncMemoizer<bool>> pending = <String, AsyncMemoizer<bool>>{};
|
||||
@ -545,17 +602,17 @@ class _BuildInstance {
|
||||
// If we're missing a depfile, wait until after evaluating the target to
|
||||
// compute changes.
|
||||
final bool canSkip = !node.missingDepfile &&
|
||||
await node.computeChanges(environment, fileCache);
|
||||
await node.computeChanges(environment, fileCache, fileSystem, logger);
|
||||
|
||||
if (canSkip) {
|
||||
skipped = true;
|
||||
globals.printTrace('Skipping target: ${node.target.name}');
|
||||
logger.printTrace('Skipping target: ${node.target.name}');
|
||||
updateGraph();
|
||||
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);
|
||||
globals.printTrace('${node.target.name}: Complete');
|
||||
logger.printTrace('${node.target.name}: Complete');
|
||||
|
||||
node.inputs
|
||||
..clear()
|
||||
@ -581,7 +638,7 @@ class _BuildInstance {
|
||||
if (outputFiles.containsKey(previousOutput)) {
|
||||
continue;
|
||||
}
|
||||
final File previousFile = globals.fs.file(previousOutput);
|
||||
final File previousFile = fileSystem.file(previousOutput);
|
||||
if (previousFile.existsSync()) {
|
||||
previousFile.deleteSync();
|
||||
}
|
||||
@ -771,6 +828,8 @@ class Node {
|
||||
Future<bool> computeChanges(
|
||||
Environment environment,
|
||||
FileHashStore fileHashStore,
|
||||
FileSystem fileSystem,
|
||||
Logger logger,
|
||||
) async {
|
||||
final Set<String> currentOutputPaths = <String>{
|
||||
for (final File file in outputs) file.path,
|
||||
@ -808,7 +867,7 @@ class Node {
|
||||
// if this isn't a current output file there is no reason to compute the hash.
|
||||
continue;
|
||||
}
|
||||
final File file = globals.fs.file(previousOutput);
|
||||
final File file = fileSystem.file(previousOutput);
|
||||
if (!file.existsSync()) {
|
||||
invalidatedReasons.add(InvalidatedReason.outputMissing);
|
||||
_dirty = true;
|
||||
@ -833,7 +892,7 @@ class Node {
|
||||
if (missingInputs.isNotEmpty) {
|
||||
_dirty = true;
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@ -5,7 +5,6 @@
|
||||
import '../artifacts.dart';
|
||||
import '../base/file_system.dart';
|
||||
import '../build_info.dart';
|
||||
import '../globals.dart' as globals;
|
||||
import 'build_system.dart';
|
||||
import 'exceptions.dart';
|
||||
|
||||
@ -24,7 +23,7 @@ abstract class ResolvedFiles {
|
||||
/// Collects sources for a [Target] into a single list of [FileSystemEntities].
|
||||
class SourceVisitor implements ResolvedFiles {
|
||||
/// Create a new [SourceVisitor] from an [Environment].
|
||||
SourceVisitor(this.environment, [this.inputs = true]);
|
||||
SourceVisitor(this.environment, [ this.inputs = true ]);
|
||||
|
||||
/// The current environment.
|
||||
final Environment environment;
|
||||
@ -56,7 +55,7 @@ class SourceVisitor implements ResolvedFiles {
|
||||
final String contents = depfile.readAsStringSync();
|
||||
final List<String> colonSeparated = contents.split(': ');
|
||||
if (colonSeparated.length != 2) {
|
||||
globals.printError('Invalid depfile: ${depfile.path}');
|
||||
environment.logger.printError('Invalid depfile: ${depfile.path}');
|
||||
return;
|
||||
}
|
||||
if (inputs) {
|
||||
@ -78,7 +77,7 @@ class SourceVisitor implements ResolvedFiles {
|
||||
.map<String>((String path) => path.replaceAllMapped(_escapeExpr, (Match match) => match.group(1)).trim())
|
||||
.where((String path) => path.isNotEmpty)
|
||||
.toSet()
|
||||
.map((String path) => globals.fs.file(path));
|
||||
.map(environment.fileSystem.file);
|
||||
}
|
||||
|
||||
/// Visit a [Source] which contains a file URL.
|
||||
@ -101,35 +100,36 @@ class SourceVisitor implements ResolvedFiles {
|
||||
switch (rawParts.first) {
|
||||
case Environment.kProjectDirectory:
|
||||
segments.addAll(
|
||||
globals.fs.path.split(environment.projectDir.resolveSymbolicLinksSync()));
|
||||
environment.fileSystem.path.split(environment.projectDir.resolveSymbolicLinksSync()));
|
||||
break;
|
||||
case Environment.kBuildDirectory:
|
||||
segments.addAll(globals.fs.path.split(
|
||||
environment.buildDir.resolveSymbolicLinksSync()));
|
||||
segments.addAll(environment.fileSystem.path.split(
|
||||
environment.buildDir.resolveSymbolicLinksSync()));
|
||||
break;
|
||||
case Environment.kCacheDirectory:
|
||||
segments.addAll(
|
||||
globals.fs.path.split(environment.cacheDir.resolveSymbolicLinksSync()));
|
||||
environment.fileSystem.path.split(environment.cacheDir.resolveSymbolicLinksSync()));
|
||||
break;
|
||||
case Environment.kFlutterRootDirectory:
|
||||
// flutter root will not contain a symbolic link.
|
||||
segments.addAll(
|
||||
globals.fs.path.split(environment.flutterRootDir.absolute.path));
|
||||
environment.fileSystem.path.split(environment.flutterRootDir.absolute.path));
|
||||
break;
|
||||
case Environment.kOutputDirectory:
|
||||
segments.addAll(
|
||||
globals.fs.path.split(environment.outputDir.resolveSymbolicLinksSync()));
|
||||
environment.fileSystem.path.split(environment.outputDir.resolveSymbolicLinksSync()));
|
||||
break;
|
||||
default:
|
||||
throw InvalidPatternException(pattern);
|
||||
}
|
||||
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 (optional && !globals.fs.isFileSync(filePath)) {
|
||||
if (optional && !environment.fileSystem.isFileSync(filePath)) {
|
||||
return;
|
||||
}
|
||||
sources.add(globals.fs.file(globals.fs.path.normalize(filePath)));
|
||||
sources.add(environment.fileSystem.file(
|
||||
environment.fileSystem.path.normalize(filePath)));
|
||||
return;
|
||||
}
|
||||
// Perform a simple match by splitting the wildcard containing file one
|
||||
@ -143,21 +143,21 @@ class SourceVisitor implements ResolvedFiles {
|
||||
if (wildcardSegments.length > 2) {
|
||||
throw InvalidPatternException(pattern);
|
||||
}
|
||||
if (!globals.fs.directory(filePath).existsSync()) {
|
||||
if (!environment.fileSystem.directory(filePath).existsSync()) {
|
||||
throw Exception('$filePath does not exist!');
|
||||
}
|
||||
for (final FileSystemEntity entity in globals.fs.directory(filePath).listSync()) {
|
||||
final String filename = globals.fs.path.basename(entity.path);
|
||||
for (final FileSystemEntity entity in environment.fileSystem.directory(filePath).listSync()) {
|
||||
final String filename = environment.fileSystem.path.basename(entity.path);
|
||||
if (wildcardSegments.isEmpty) {
|
||||
sources.add(globals.fs.file(entity.absolute));
|
||||
sources.add(environment.fileSystem.file(entity.absolute));
|
||||
} else if (wildcardSegments.length == 1) {
|
||||
if (filename.startsWith(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])) {
|
||||
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 {
|
||||
///
|
||||
/// If the [Artifact] points to a directory then all child files are included.
|
||||
void visitArtifact(Artifact artifact, TargetPlatform platform, BuildMode mode) {
|
||||
final String path = globals.artifacts.getArtifactPath(artifact, platform: platform, mode: mode);
|
||||
if (globals.fs.isDirectorySync(path)) {
|
||||
final String path = environment.artifacts
|
||||
.getArtifactPath(artifact, platform: platform, mode: mode);
|
||||
if (environment.fileSystem.isDirectorySync(path)) {
|
||||
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)
|
||||
entity,
|
||||
]);
|
||||
} else {
|
||||
sources.add(globals.fs.file(path));
|
||||
sources.add(environment.fileSystem.file(path));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,7 +5,6 @@
|
||||
import '../../artifacts.dart';
|
||||
import '../../base/file_system.dart';
|
||||
import '../../build_info.dart';
|
||||
import '../../globals.dart' as globals;
|
||||
import '../build_system.dart';
|
||||
|
||||
/// Copies the Windows desktop embedding files to the copy directory.
|
||||
@ -40,21 +39,24 @@ class UnpackWindows extends Target {
|
||||
@override
|
||||
Future<void> build(Environment environment) async {
|
||||
// This path needs to match the prefix in the rule below.
|
||||
final String basePath = globals.artifacts.getArtifactPath(Artifact.windowsDesktopPath);
|
||||
for (final File input in globals.fs.directory(basePath)
|
||||
final String basePath = environment.artifacts
|
||||
.getArtifactPath(Artifact.windowsDesktopPath);
|
||||
for (final File input in environment.fileSystem.directory(basePath)
|
||||
.listSync(recursive: true)
|
||||
.whereType<File>()) {
|
||||
final String outputPath = globals.fs.path.join(
|
||||
final String outputPath = environment.fileSystem.path.join(
|
||||
environment.projectDir.path,
|
||||
'windows',
|
||||
'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()) {
|
||||
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({
|
||||
if (dartDefines != null && dartDefines.isNotEmpty)
|
||||
kDartDefines: jsonEncode(dartDefines),
|
||||
},
|
||||
artifacts: globals.artifacts,
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
);
|
||||
final Target target = buildMode == BuildMode.debug
|
||||
? const CopyFlutterBundle()
|
||||
|
||||
@ -151,6 +151,10 @@ class AssembleCommand extends FlutterCommand {
|
||||
defines: _parseDefines(stringsArg('define')),
|
||||
cacheDir: globals.cache.getRoot(),
|
||||
flutterRootDir: globals.fs.directory(Cache.flutterRoot),
|
||||
artifacts: globals.artifacts,
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -89,7 +89,11 @@ Future<T> runInContext<T>(
|
||||
platform: globals.platform,
|
||||
),
|
||||
AssetBundleFactory: () => AssetBundleFactory.defaultInstance,
|
||||
BuildSystem: () => const BuildSystem(),
|
||||
BuildSystem: () => BuildSystem(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
platform: globals.platform,
|
||||
),
|
||||
Cache: () => Cache(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
|
||||
@ -53,6 +53,10 @@ Future<void> buildWeb(
|
||||
kCspMode: csp.toString(),
|
||||
kIconTreeShakerFlag: buildInfo.treeShakeIcons.toString(),
|
||||
},
|
||||
artifacts: globals.artifacts,
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
));
|
||||
if (!result.success) {
|
||||
for (final ExceptionMeasurement measurement in result.exceptions.values) {
|
||||
|
||||
@ -2,28 +2,23 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
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/utils.dart';
|
||||
import 'package:flutter_tools/src/build_system/build_system.dart';
|
||||
import 'package:flutter_tools/src/build_system/exceptions.dart';
|
||||
import 'package:flutter_tools/src/cache.dart';
|
||||
import 'package:flutter_tools/src/convert.dart';
|
||||
import 'package:flutter_tools/src/globals.dart' as globals;
|
||||
import 'package:mockito/mockito.dart';
|
||||
|
||||
import '../../src/common.dart';
|
||||
import '../../src/context.dart';
|
||||
import '../../src/testbed.dart';
|
||||
|
||||
void main() {
|
||||
setUpAll(() {
|
||||
Cache.disableLocking();
|
||||
});
|
||||
|
||||
const BuildSystem buildSystem = BuildSystem();
|
||||
Testbed testbed;
|
||||
MockPlatform mockPlatform;
|
||||
FileSystem fileSystem;
|
||||
Environment environment;
|
||||
Target fooTarget;
|
||||
Target barTarget;
|
||||
@ -34,14 +29,12 @@ void main() {
|
||||
int shared;
|
||||
|
||||
setUp(() {
|
||||
fileSystem = MemoryFileSystem.test();
|
||||
fooInvocations = 0;
|
||||
barInvocations = 0;
|
||||
shared = 0;
|
||||
mockPlatform = MockPlatform();
|
||||
// Keep file paths the same.
|
||||
when(mockPlatform.isWindows).thenReturn(false);
|
||||
|
||||
/// Create various testing targets.
|
||||
/// Create various test targets.
|
||||
fooTarget = TestTarget((Environment environment) async {
|
||||
environment
|
||||
.buildDir
|
||||
@ -91,31 +84,34 @@ void main() {
|
||||
..inputs = const <Source>[
|
||||
Source.pattern('{PROJECT_DIR}/foo.dart'),
|
||||
];
|
||||
testbed = Testbed(
|
||||
setup: () {
|
||||
environment = Environment.test(
|
||||
globals.fs.currentDirectory,
|
||||
);
|
||||
globals.fs.file('foo.dart')
|
||||
..createSync(recursive: true)
|
||||
..writeAsStringSync('');
|
||||
globals.fs.file('pubspec.yaml').createSync();
|
||||
},
|
||||
overrides: <Type, Generator>{
|
||||
Platform: () => mockPlatform,
|
||||
},
|
||||
environment = Environment.test(
|
||||
fileSystem.currentDirectory,
|
||||
artifacts: MockArtifacts(),
|
||||
processManager: FakeProcessManager.any(),
|
||||
fileSystem: fileSystem,
|
||||
logger: BufferLogger.test(),
|
||||
);
|
||||
fileSystem.file('foo.dart')
|
||||
..createSync(recursive: true)
|
||||
..writeAsStringSync('');
|
||||
fileSystem.file('pubspec.yaml').createSync();
|
||||
});
|
||||
|
||||
test('Does not throw exception if asked to build with missing inputs', () => testbed.run(() async {
|
||||
testWithoutContext('Does not throw exception if asked to build with missing inputs', () async {
|
||||
final BuildSystem buildSystem = setUpBuildSystem(fileSystem);
|
||||
|
||||
// Delete required input file.
|
||||
globals.fs.file('foo.dart').deleteSync();
|
||||
fileSystem.file('foo.dart').deleteSync();
|
||||
final BuildResult buildResult = await buildSystem.build(fooTarget, environment);
|
||||
|
||||
expect(buildResult.hasException, false);
|
||||
}));
|
||||
});
|
||||
|
||||
test('Does not throw exception if it does not produce a specified output', () => testbed.run(() async {
|
||||
testWithoutContext('Does not throw exception if it does not produce a specified output', () async {
|
||||
final BuildSystem buildSystem = setUpBuildSystem(fileSystem);
|
||||
|
||||
// This target is document as producing foo.dart but does not actually
|
||||
// output this value.
|
||||
final Target badTarget = TestTarget((Environment environment) async {})
|
||||
..inputs = const <Source>[
|
||||
Source.pattern('{PROJECT_DIR}/foo.dart'),
|
||||
@ -126,81 +122,98 @@ void main() {
|
||||
final BuildResult result = await buildSystem.build(badTarget, environment);
|
||||
|
||||
expect(result.hasException, false);
|
||||
}));
|
||||
});
|
||||
|
||||
test('Saves a stamp file with inputs and outputs', () => testbed.run(() async {
|
||||
testWithoutContext('Saves a stamp file with inputs and outputs', () async {
|
||||
final BuildSystem buildSystem = setUpBuildSystem(fileSystem);
|
||||
await buildSystem.build(fooTarget, environment);
|
||||
final File stampFile = fileSystem.file(
|
||||
'${environment.buildDir.path}/foo.stamp');
|
||||
|
||||
final File stampFile = globals.fs.file(globals.fs.path.join(environment.buildDir.path, 'foo.stamp'));
|
||||
expect(stampFile.existsSync(), true);
|
||||
expect(stampFile, exists);
|
||||
|
||||
final Map<String, dynamic> stampContents = castStringKeyedMap(json.decode(stampFile.readAsStringSync()));
|
||||
expect(stampContents['inputs'], <Object>['/foo.dart']);
|
||||
}));
|
||||
final Map<String, dynamic> stampContents = castStringKeyedMap(
|
||||
json.decode(stampFile.readAsStringSync()));
|
||||
|
||||
test('Creates a BuildResult with inputs and outputs', () => testbed.run(() async {
|
||||
expect(stampContents, containsPair('inputs', <Object>['/foo.dart']));
|
||||
});
|
||||
|
||||
testWithoutContext('Creates a BuildResult with inputs and outputs', () async {
|
||||
final BuildSystem buildSystem = setUpBuildSystem(fileSystem);
|
||||
final BuildResult result = await buildSystem.build(fooTarget, environment);
|
||||
|
||||
expect(result.inputFiles.single.path, globals.fs.path.absolute('foo.dart'));
|
||||
expect(result.outputFiles.single.path,
|
||||
globals.fs.path.absolute(globals.fs.path.join(environment.buildDir.path, 'out')));
|
||||
}));
|
||||
expect(result.inputFiles.single.path, '/foo.dart');
|
||||
expect(result.outputFiles.single.path, '${environment.buildDir.path}/out');
|
||||
});
|
||||
|
||||
testWithoutContext('Does not re-invoke build if stamp is valid', () async {
|
||||
final BuildSystem buildSystem = setUpBuildSystem(fileSystem);
|
||||
|
||||
test('Does not re-invoke build if stamp is valid', () => testbed.run(() async {
|
||||
await buildSystem.build(fooTarget, environment);
|
||||
await buildSystem.build(fooTarget, environment);
|
||||
|
||||
expect(fooInvocations, 1);
|
||||
}));
|
||||
});
|
||||
|
||||
test('Re-invoke build if input is modified', () => testbed.run(() async {
|
||||
testWithoutContext('Re-invoke build if input is modified', () async {
|
||||
final BuildSystem buildSystem = setUpBuildSystem(fileSystem);
|
||||
await buildSystem.build(fooTarget, environment);
|
||||
|
||||
globals.fs.file('foo.dart').writeAsStringSync('new contents');
|
||||
fileSystem.file('foo.dart').writeAsStringSync('new contents');
|
||||
|
||||
await buildSystem.build(fooTarget, environment);
|
||||
|
||||
expect(fooInvocations, 2);
|
||||
}));
|
||||
});
|
||||
|
||||
test('does not re-invoke build if input timestamp changes', () => testbed.run(() async {
|
||||
testWithoutContext('does not re-invoke build if input timestamp changes', () async {
|
||||
final BuildSystem buildSystem = setUpBuildSystem(fileSystem);
|
||||
await buildSystem.build(fooTarget, environment);
|
||||
|
||||
globals.fs.file('foo.dart').writeAsStringSync('');
|
||||
|
||||
// The file was previously empty so this does not modify it.
|
||||
fileSystem.file('foo.dart').writeAsStringSync('');
|
||||
await buildSystem.build(fooTarget, environment);
|
||||
|
||||
expect(fooInvocations, 1);
|
||||
}));
|
||||
});
|
||||
|
||||
test('does not re-invoke build if output timestamp changes', () => testbed.run(() async {
|
||||
testWithoutContext('does not re-invoke build if output timestamp changes', () async {
|
||||
final BuildSystem buildSystem = setUpBuildSystem(fileSystem);
|
||||
await buildSystem.build(fooTarget, environment);
|
||||
|
||||
// This is the same content that the output file previously
|
||||
// contained.
|
||||
environment.buildDir.childFile('out').writeAsStringSync('hey');
|
||||
|
||||
await buildSystem.build(fooTarget, environment);
|
||||
|
||||
expect(fooInvocations, 1);
|
||||
}));
|
||||
});
|
||||
|
||||
|
||||
test('Re-invoke build if output is modified', () => testbed.run(() async {
|
||||
testWithoutContext('Re-invoke build if output is modified', () async {
|
||||
final BuildSystem buildSystem = setUpBuildSystem(fileSystem);
|
||||
await buildSystem.build(fooTarget, environment);
|
||||
|
||||
environment.buildDir.childFile('out').writeAsStringSync('Something different');
|
||||
|
||||
await buildSystem.build(fooTarget, environment);
|
||||
expect(fooInvocations, 2);
|
||||
}));
|
||||
|
||||
test('Runs dependencies of targets', () => testbed.run(() async {
|
||||
expect(fooInvocations, 2);
|
||||
});
|
||||
|
||||
testWithoutContext('Runs dependencies of targets', () async {
|
||||
final BuildSystem buildSystem = setUpBuildSystem(fileSystem);
|
||||
barTarget.dependencies.add(fooTarget);
|
||||
|
||||
await buildSystem.build(barTarget, environment);
|
||||
|
||||
expect(globals.fs.file(globals.fs.path.join(environment.buildDir.path, 'bar')).existsSync(), true);
|
||||
expect(fileSystem.file('${environment.buildDir.path}/bar'), exists);
|
||||
expect(fooInvocations, 1);
|
||||
expect(barInvocations, 1);
|
||||
}));
|
||||
});
|
||||
|
||||
test('Only invokes shared dependencies once', () => testbed.run(() async {
|
||||
testWithoutContext('Only invokes shared dependencies once', () async {
|
||||
final BuildSystem buildSystem = setUpBuildSystem(fileSystem);
|
||||
fooTarget.dependencies.add(sharedTarget);
|
||||
barTarget.dependencies.add(sharedTarget);
|
||||
barTarget.dependencies.add(fooTarget);
|
||||
@ -208,19 +221,20 @@ void main() {
|
||||
await buildSystem.build(barTarget, environment);
|
||||
|
||||
expect(shared, 1);
|
||||
}));
|
||||
});
|
||||
|
||||
test('Automatically cleans old outputs when dag changes', () => testbed.run(() async {
|
||||
testWithoutContext('Automatically cleans old outputs when build graph changes', () async {
|
||||
final BuildSystem buildSystem = setUpBuildSystem(fileSystem);
|
||||
final TestTarget testTarget = TestTarget((Environment envionment) async {
|
||||
environment.buildDir.childFile('foo.out').createSync();
|
||||
})
|
||||
..inputs = const <Source>[Source.pattern('{PROJECT_DIR}/foo.dart')]
|
||||
..outputs = const <Source>[Source.pattern('{BUILD_DIR}/foo.out')];
|
||||
globals.fs.file('foo.dart').createSync();
|
||||
fileSystem.file('foo.dart').createSync();
|
||||
|
||||
await buildSystem.build(testTarget, environment);
|
||||
|
||||
expect(environment.buildDir.childFile('foo.out').existsSync(), true);
|
||||
expect(environment.buildDir.childFile('foo.out'), exists);
|
||||
|
||||
final TestTarget testTarget2 = TestTarget((Environment envionment) async {
|
||||
environment.buildDir.childFile('bar.out').createSync();
|
||||
@ -230,80 +244,84 @@ void main() {
|
||||
|
||||
await buildSystem.build(testTarget2, environment);
|
||||
|
||||
expect(environment.buildDir.childFile('bar.out').existsSync(), true);
|
||||
expect(environment.buildDir.childFile('foo.out').existsSync(), false);
|
||||
}));
|
||||
expect(environment.buildDir.childFile('bar.out'), exists);
|
||||
expect(environment.buildDir.childFile('foo.out'), isNot(exists));
|
||||
});
|
||||
|
||||
test('Does not crash when filesytem and cache are out of sync', () => testbed.run(() async {
|
||||
final TestTarget testTarget = TestTarget((Environment environment) async {
|
||||
testWithoutContext('Does not crash when filesytem and cache are out of sync', () async {
|
||||
final BuildSystem buildSystem = setUpBuildSystem(fileSystem);
|
||||
final TestTarget testWithoutContextTarget = TestTarget((Environment environment) async {
|
||||
environment.buildDir.childFile('foo.out').createSync();
|
||||
})
|
||||
..inputs = const <Source>[Source.pattern('{PROJECT_DIR}/foo.dart')]
|
||||
..outputs = const <Source>[Source.pattern('{BUILD_DIR}/foo.out')];
|
||||
globals.fs.file('foo.dart').createSync();
|
||||
fileSystem.file('foo.dart').createSync();
|
||||
|
||||
await buildSystem.build(testTarget, environment);
|
||||
await buildSystem.build(testWithoutContextTarget, environment);
|
||||
|
||||
expect(environment.buildDir.childFile('foo.out').existsSync(), true);
|
||||
expect(environment.buildDir.childFile('foo.out'), exists);
|
||||
environment.buildDir.childFile('foo.out').deleteSync();
|
||||
|
||||
final TestTarget testTarget2 = TestTarget((Environment environment) async {
|
||||
final TestTarget testWithoutContextTarget2 = TestTarget((Environment environment) async {
|
||||
environment.buildDir.childFile('bar.out').createSync();
|
||||
})
|
||||
..inputs = const <Source>[Source.pattern('{PROJECT_DIR}/foo.dart')]
|
||||
..outputs = const <Source>[Source.pattern('{BUILD_DIR}/bar.out')];
|
||||
|
||||
await buildSystem.build(testTarget2, environment);
|
||||
await buildSystem.build(testWithoutContextTarget2, environment);
|
||||
|
||||
expect(environment.buildDir.childFile('bar.out').existsSync(), true);
|
||||
expect(environment.buildDir.childFile('foo.out').existsSync(), false);
|
||||
}));
|
||||
expect(environment.buildDir.childFile('bar.out'), exists);
|
||||
expect(environment.buildDir.childFile('foo.out'), isNot(exists));
|
||||
});
|
||||
|
||||
test('reruns build if stamp is corrupted', () => testbed.run(() async {
|
||||
final TestTarget testTarget = TestTarget((Environment envionment) async {
|
||||
testWithoutContext('Reruns build if stamp is corrupted', () async {
|
||||
final BuildSystem buildSystem = setUpBuildSystem(fileSystem);
|
||||
final TestTarget testWithoutContextTarget = TestTarget((Environment envionment) async {
|
||||
environment.buildDir.childFile('foo.out').createSync();
|
||||
})
|
||||
..inputs = const <Source>[Source.pattern('{PROJECT_DIR}/foo.dart')]
|
||||
..outputs = const <Source>[Source.pattern('{BUILD_DIR}/foo.out')];
|
||||
globals.fs.file('foo.dart').createSync();
|
||||
await buildSystem.build(testTarget, environment);
|
||||
fileSystem.file('foo.dart').createSync();
|
||||
await buildSystem.build(testWithoutContextTarget, environment);
|
||||
|
||||
// invalid JSON
|
||||
environment.buildDir.childFile('test.stamp').writeAsStringSync('{X');
|
||||
await buildSystem.build(testTarget, environment);
|
||||
environment.buildDir.childFile('testWithoutContext.stamp').writeAsStringSync('{X');
|
||||
await buildSystem.build(testWithoutContextTarget, environment);
|
||||
|
||||
// empty file
|
||||
environment.buildDir.childFile('test.stamp').writeAsStringSync('');
|
||||
await buildSystem.build(testTarget, environment);
|
||||
environment.buildDir.childFile('testWithoutContext.stamp').writeAsStringSync('');
|
||||
await buildSystem.build(testWithoutContextTarget, environment);
|
||||
|
||||
// invalid format
|
||||
environment.buildDir.childFile('test.stamp').writeAsStringSync('{"inputs": 2, "outputs": 3}');
|
||||
await buildSystem.build(testTarget, environment);
|
||||
}));
|
||||
environment.buildDir.childFile('testWithoutContext.stamp').writeAsStringSync('{"inputs": 2, "outputs": 3}');
|
||||
await buildSystem.build(testWithoutContextTarget, environment);
|
||||
});
|
||||
|
||||
|
||||
test('handles a throwing build action', () => testbed.run(() async {
|
||||
testWithoutContext('handles a throwing build action without crashing', () async {
|
||||
final BuildSystem buildSystem = setUpBuildSystem(fileSystem);
|
||||
final BuildResult result = await buildSystem.build(fizzTarget, environment);
|
||||
|
||||
expect(result.hasException, true);
|
||||
}));
|
||||
});
|
||||
|
||||
test('Can describe itself with JSON output', () => testbed.run(() {
|
||||
testWithoutContext('Can describe itself with JSON output', () {
|
||||
environment.buildDir.createSync(recursive: true);
|
||||
|
||||
expect(fooTarget.toJson(environment), <String, dynamic>{
|
||||
'inputs': <Object>[
|
||||
'/foo.dart',
|
||||
],
|
||||
'outputs': <Object>[
|
||||
globals.fs.path.join(environment.buildDir.path, 'out'),
|
||||
fileSystem.path.join(environment.buildDir.path, 'out'),
|
||||
],
|
||||
'dependencies': <Object>[],
|
||||
'name': 'foo',
|
||||
'stamp': globals.fs.path.join(environment.buildDir.path, 'foo.stamp'),
|
||||
'stamp': fileSystem.path.join(environment.buildDir.path, 'foo.stamp'),
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
test('Can find dependency cycles', () {
|
||||
testWithoutContext('Can find dependency cycles', () {
|
||||
final Target barTarget = TestTarget()..name = 'bar';
|
||||
final Target fooTarget = TestTarget()..name = 'foo';
|
||||
barTarget.dependencies.add(fooTarget);
|
||||
@ -312,73 +330,94 @@ void main() {
|
||||
expect(() => checkCycles(barTarget), throwsA(isA<CycleException>()));
|
||||
});
|
||||
|
||||
test('Target with depfile dependency will not run twice without invalidation', () => testbed.run(() async {
|
||||
testWithoutContext('Target with depfile dependency will not run twice without invalidation', () async {
|
||||
final BuildSystem buildSystem = setUpBuildSystem(fileSystem);
|
||||
int called = 0;
|
||||
final TestTarget target = TestTarget((Environment environment) async {
|
||||
environment.buildDir.childFile('example.d')
|
||||
environment.buildDir
|
||||
.childFile('example.d')
|
||||
.writeAsStringSync('a.txt: b.txt');
|
||||
globals.fs.file('a.txt').writeAsStringSync('a');
|
||||
fileSystem.file('a.txt').writeAsStringSync('a');
|
||||
called += 1;
|
||||
})
|
||||
..depfiles = <String>['example.d'];
|
||||
globals.fs.file('b.txt').writeAsStringSync('b');
|
||||
fileSystem.file('b.txt').writeAsStringSync('b');
|
||||
|
||||
await buildSystem.build(target, environment);
|
||||
|
||||
expect(globals.fs.file('a.txt').existsSync(), true);
|
||||
expect(fileSystem.file('a.txt'), exists);
|
||||
expect(called, 1);
|
||||
|
||||
// Second build is up to date due to depfil parse.
|
||||
// Second build is up to date due to depfile parse.
|
||||
await buildSystem.build(target, environment);
|
||||
expect(called, 1);
|
||||
}));
|
||||
|
||||
test('output directory is an input to the build', () => testbed.run(() async {
|
||||
final Environment environmentA = Environment.test(globals.fs.currentDirectory, outputDir: globals.fs.directory('a'));
|
||||
final Environment environmentB = Environment.test(globals.fs.currentDirectory, outputDir: globals.fs.directory('b'));
|
||||
expect(called, 1);
|
||||
});
|
||||
|
||||
testWithoutContext('output directory is an input to the build', () async {
|
||||
final Environment environmentA = Environment.test(
|
||||
fileSystem.currentDirectory,
|
||||
outputDir: fileSystem.directory('a'),
|
||||
artifacts: MockArtifacts(),
|
||||
processManager: FakeProcessManager.any(),
|
||||
fileSystem: fileSystem,
|
||||
logger: BufferLogger.test(),
|
||||
);
|
||||
final Environment environmentB = Environment.test(
|
||||
fileSystem.currentDirectory,
|
||||
outputDir: fileSystem.directory('b'),
|
||||
artifacts: MockArtifacts(),
|
||||
processManager: FakeProcessManager.any(),
|
||||
fileSystem: fileSystem,
|
||||
logger: BufferLogger.test(),
|
||||
);
|
||||
|
||||
expect(environmentA.buildDir.path, isNot(environmentB.buildDir.path));
|
||||
}));
|
||||
});
|
||||
|
||||
test('A target with depfile dependencies can delete stale outputs on the first run', () => testbed.run(() async {
|
||||
testWithoutContext('A target with depfile dependencies can delete stale outputs on the first run', () async {
|
||||
final BuildSystem buildSystem = setUpBuildSystem(fileSystem);
|
||||
int called = 0;
|
||||
final TestTarget target = TestTarget((Environment environment) async {
|
||||
if (called == 0) {
|
||||
environment.buildDir.childFile('example.d')
|
||||
.writeAsStringSync('a.txt c.txt: b.txt');
|
||||
globals.fs.file('a.txt').writeAsStringSync('a');
|
||||
globals.fs.file('c.txt').writeAsStringSync('a');
|
||||
fileSystem.file('a.txt').writeAsStringSync('a');
|
||||
fileSystem.file('c.txt').writeAsStringSync('a');
|
||||
} else {
|
||||
// On second run, we no longer claim c.txt as an output.
|
||||
environment.buildDir.childFile('example.d')
|
||||
.writeAsStringSync('a.txt: b.txt');
|
||||
globals.fs.file('a.txt').writeAsStringSync('a');
|
||||
fileSystem.file('a.txt').writeAsStringSync('a');
|
||||
}
|
||||
called += 1;
|
||||
})
|
||||
..depfiles = const <String>['example.d'];
|
||||
globals.fs.file('b.txt').writeAsStringSync('b');
|
||||
fileSystem.file('b.txt').writeAsStringSync('b');
|
||||
|
||||
await buildSystem.build(target, environment);
|
||||
|
||||
expect(globals.fs.file('a.txt').existsSync(), true);
|
||||
expect(globals.fs.file('c.txt').existsSync(), true);
|
||||
expect(fileSystem.file('a.txt'), exists);
|
||||
expect(fileSystem.file('c.txt'), exists);
|
||||
expect(called, 1);
|
||||
|
||||
// rewrite an input to force a rerun, espect that the old c.txt is deleted.
|
||||
globals.fs.file('b.txt').writeAsStringSync('ba');
|
||||
// rewrite an input to force a rerun, expect that the old c.txt is deleted.
|
||||
fileSystem.file('b.txt').writeAsStringSync('ba');
|
||||
await buildSystem.build(target, environment);
|
||||
|
||||
expect(globals.fs.file('a.txt').existsSync(), true);
|
||||
expect(globals.fs.file('c.txt').existsSync(), false);
|
||||
expect(fileSystem.file('a.txt'), exists);
|
||||
expect(fileSystem.file('c.txt'), isNot(exists));
|
||||
expect(called, 2);
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
class MockPlatform extends Mock implements Platform {}
|
||||
|
||||
// Work-around for silly lint check.
|
||||
T nonconst<T>(T input) => input;
|
||||
BuildSystem setUpBuildSystem(FileSystem fileSystem) {
|
||||
return BuildSystem(
|
||||
fileSystem: fileSystem,
|
||||
logger: BufferLogger.test(),
|
||||
platform: FakePlatform(operatingSystem: 'linux'),
|
||||
);
|
||||
}
|
||||
|
||||
class TestTarget extends Target {
|
||||
TestTarget([this._build]);
|
||||
@ -403,3 +442,5 @@ class TestTarget extends Target {
|
||||
@override
|
||||
List<Source> outputs = <Source>[];
|
||||
}
|
||||
|
||||
class MockArtifacts extends Mock implements Artifacts {}
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
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/logger.dart';
|
||||
import 'package:flutter_tools/src/base/terminal.dart';
|
||||
@ -14,6 +15,7 @@ import 'package:mockito/mockito.dart';
|
||||
import 'package:platform/platform.dart';
|
||||
|
||||
import '../../src/common.dart';
|
||||
import '../../src/fake_process_manager.dart';
|
||||
|
||||
void main() {
|
||||
Environment environment;
|
||||
@ -29,6 +31,10 @@ void main() {
|
||||
fileSystem.directory('build').createSync();
|
||||
environment = Environment.test(
|
||||
fileSystem.currentDirectory,
|
||||
artifacts: MockArtifacts(),
|
||||
processManager: FakeProcessManager.any(),
|
||||
logger: logger,
|
||||
fileSystem: fileSystem,
|
||||
);
|
||||
environment.buildDir.createSync(recursive: true);
|
||||
});
|
||||
@ -168,4 +174,6 @@ class FakeForwardingFileSystem extends ForwardingFileSystem {
|
||||
@override
|
||||
File file(dynamic path) => files[path] ?? super.file(path);
|
||||
}
|
||||
|
||||
class MockFile extends Mock implements File {}
|
||||
class MockArtifacts extends Mock implements Artifacts {}
|
||||
|
||||
@ -14,6 +14,7 @@ import 'package:mockito/mockito.dart';
|
||||
import 'package:platform/platform.dart';
|
||||
|
||||
import '../../src/common.dart';
|
||||
import '../../src/context.dart';
|
||||
import '../../src/testbed.dart';
|
||||
|
||||
void main() {
|
||||
@ -32,6 +33,10 @@ void main() {
|
||||
environment = Environment.test(
|
||||
globals.fs.currentDirectory,
|
||||
outputDir: outputs,
|
||||
artifacts: globals.artifacts, // using real artifacts
|
||||
processManager: FakeProcessManager.any(),
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
);
|
||||
visitor = SourceVisitor(environment);
|
||||
environment.buildDir.createSync(recursive: true);
|
||||
@ -212,3 +217,4 @@ void main() {
|
||||
}
|
||||
|
||||
class MockPlatform extends Mock implements Platform {}
|
||||
class MockArtifacts extends Mock implements Artifacts {}
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// 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/build_info.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';
|
||||
import 'package:flutter_tools/src/build_system/targets/dart.dart';
|
||||
import 'package:flutter_tools/src/globals.dart' as globals;
|
||||
import 'package:flutter_tools/src/cache.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:platform/platform.dart';
|
||||
|
||||
import '../../../src/common.dart';
|
||||
@ -32,7 +34,11 @@ void main() {
|
||||
outputDir: globals.fs.directory('out')..createSync(),
|
||||
defines: <String, String>{
|
||||
kBuildMode: 'debug',
|
||||
}
|
||||
},
|
||||
processManager: fakeProcessManager,
|
||||
artifacts: MockArtifacts(),
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
);
|
||||
environment.buildDir.createSync(recursive: true);
|
||||
|
||||
@ -45,7 +51,6 @@ void main() {
|
||||
hostDirectory.childFile('vm_isolate_snapshot.bin').createSync();
|
||||
hostDirectory.childFile('isolate_snapshot.bin').createSync();
|
||||
|
||||
|
||||
await const DebugAndroidApplication().build(environment);
|
||||
|
||||
expect(globals.fs.file(globals.fs.path.join('out', 'flutter_assets', 'isolate_snapshot_data')).existsSync(), true);
|
||||
@ -59,7 +64,11 @@ void main() {
|
||||
outputDir: globals.fs.directory('out')..createSync(),
|
||||
defines: <String, String>{
|
||||
kBuildMode: 'profile',
|
||||
}
|
||||
},
|
||||
artifacts: MockArtifacts(),
|
||||
processManager: fakeProcessManager,
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
);
|
||||
environment.buildDir.createSync(recursive: true);
|
||||
|
||||
@ -78,7 +87,11 @@ void main() {
|
||||
outputDir: globals.fs.directory('out')..createSync(),
|
||||
defines: <String, String>{
|
||||
kBuildMode: 'release',
|
||||
}
|
||||
},
|
||||
artifacts: MockArtifacts(),
|
||||
processManager: fakeProcessManager,
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
);
|
||||
environment.buildDir.createSync(recursive: true);
|
||||
|
||||
@ -92,15 +105,19 @@ void main() {
|
||||
});
|
||||
|
||||
testbed.test('AndroidAot can build provided target platform', () async {
|
||||
fakeProcessManager = FakeProcessManager.list(<FakeCommand>[]);
|
||||
final Environment environment = Environment.test(
|
||||
globals.fs.currentDirectory,
|
||||
outputDir: globals.fs.directory('out')..createSync(),
|
||||
defines: <String, String>{
|
||||
kBuildMode: 'release',
|
||||
}
|
||||
},
|
||||
artifacts: MockArtifacts(),
|
||||
processManager: FakeProcessManager.list(<FakeCommand>[]),
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
);
|
||||
fakeProcessManager = FakeProcessManager.list(<FakeCommand>[
|
||||
FakeCommand(command: <String>[
|
||||
fakeProcessManager.addCommand(FakeCommand(command: <String>[
|
||||
globals.fs.path.absolute(globals.fs.path.join('android-arm64-release', 'linux-x64', 'gen_snapshot')),
|
||||
'--deterministic',
|
||||
'--snapshot_kind=app-aot-elf',
|
||||
@ -111,18 +128,21 @@ void main() {
|
||||
environment.buildDir.childFile('app.dill').path,
|
||||
],
|
||||
)
|
||||
]);
|
||||
);
|
||||
environment.buildDir.createSync(recursive: true);
|
||||
environment.buildDir.childFile('app.dill').createSync();
|
||||
environment.projectDir.childFile('.packages').writeAsStringSync('\n');
|
||||
const AndroidAot androidAot = AndroidAot(TargetPlatform.android_arm64, BuildMode.release);
|
||||
|
||||
await androidAot.build(environment);
|
||||
|
||||
expect(fakeProcessManager.hasRemainingExpectations, false);
|
||||
}, overrides: <Type, Generator>{
|
||||
ProcessManager: () => fakeProcessManager,
|
||||
});
|
||||
|
||||
testbed.test('kExtraGenSnapshotOptions passes values to gen_snapshot', () async {
|
||||
fakeProcessManager = FakeProcessManager.list(<FakeCommand>[]);
|
||||
final Environment environment = Environment.test(
|
||||
globals.fs.currentDirectory,
|
||||
outputDir: globals.fs.directory('out')..createSync(),
|
||||
@ -130,9 +150,13 @@ void main() {
|
||||
kBuildMode: 'release',
|
||||
kExtraGenSnapshotOptions: 'foo,bar,baz=2',
|
||||
kTargetPlatform: 'android-arm',
|
||||
}
|
||||
},
|
||||
processManager: fakeProcessManager,
|
||||
artifacts: MockArtifacts(),
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
);
|
||||
fakeProcessManager = FakeProcessManager.list(<FakeCommand>[
|
||||
fakeProcessManager.addCommand(
|
||||
FakeCommand(command: <String>[
|
||||
globals.fs.path.absolute(globals.fs.path.join('android-arm64-release', 'linux-x64', 'gen_snapshot')),
|
||||
'--deterministic',
|
||||
@ -145,8 +169,7 @@ void main() {
|
||||
'--no-causal-async-stacks',
|
||||
'--lazy-async-stacks',
|
||||
environment.buildDir.childFile('app.dill').path
|
||||
])
|
||||
]);
|
||||
]));
|
||||
environment.buildDir.createSync(recursive: true);
|
||||
environment.buildDir.childFile('app.dill').createSync();
|
||||
environment.projectDir.childFile('.packages').writeAsStringSync('\n');
|
||||
@ -163,7 +186,11 @@ void main() {
|
||||
outputDir: globals.fs.directory('out')..createSync(),
|
||||
defines: <String, String>{
|
||||
kBuildMode: 'release',
|
||||
}
|
||||
},
|
||||
processManager: fakeProcessManager,
|
||||
artifacts: MockArtifacts(),
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
);
|
||||
environment.buildDir.createSync(recursive: true);
|
||||
const AndroidAot androidAot = AndroidAot(TargetPlatform.android_arm64, BuildMode.release);
|
||||
@ -181,3 +208,5 @@ void main() {
|
||||
.childFile('app.so').existsSync(), true);
|
||||
});
|
||||
}
|
||||
|
||||
class MockArtifacts extends Mock implements Artifacts {}
|
||||
@ -4,10 +4,13 @@
|
||||
|
||||
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/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/depfile.dart';
|
||||
import 'package:flutter_tools/src/build_system/targets/assets.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:platform/platform.dart';
|
||||
|
||||
import '../../../src/common.dart';
|
||||
@ -23,6 +26,10 @@ void main() {
|
||||
fileSystem = MemoryFileSystem.test();
|
||||
environment = Environment.test(
|
||||
fileSystem.currentDirectory,
|
||||
processManager: FakeProcessManager.any(),
|
||||
artifacts: MockArtifacts(),
|
||||
fileSystem: fileSystem,
|
||||
logger: BufferLogger.test(),
|
||||
);
|
||||
fileSystem.file(environment.buildDir.childFile('app.dill')).createSync(recursive: true);
|
||||
fileSystem.file('packages/flutter_tools/lib/src/build_system/targets/assets.dart')
|
||||
@ -91,3 +98,5 @@ flutter:
|
||||
Platform: () => platform,
|
||||
});
|
||||
}
|
||||
|
||||
class MockArtifacts extends Mock implements Artifacts {}
|
||||
|
||||
@ -43,6 +43,10 @@ void main() {
|
||||
kBuildMode: getNameForBuildMode(BuildMode.profile),
|
||||
kTargetPlatform: getNameForTargetPlatform(TargetPlatform.android_arm),
|
||||
},
|
||||
artifacts: artifacts,
|
||||
processManager: processManager,
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
);
|
||||
androidEnvironment.buildDir.createSync(recursive: true);
|
||||
iosEnvironment = Environment.test(
|
||||
@ -51,6 +55,10 @@ void main() {
|
||||
kBuildMode: getNameForBuildMode(BuildMode.profile),
|
||||
kTargetPlatform: getNameForTargetPlatform(TargetPlatform.ios),
|
||||
},
|
||||
artifacts: artifacts,
|
||||
processManager: processManager,
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
);
|
||||
iosEnvironment.buildDir.createSync(recursive: true);
|
||||
artifacts = CachedArtifacts(
|
||||
@ -261,6 +269,10 @@ void main() {
|
||||
kBuildMode: getNameForBuildMode(BuildMode.debug),
|
||||
kTargetPlatform: getNameForTargetPlatform(TargetPlatform.android_arm),
|
||||
},
|
||||
processManager: processManager,
|
||||
artifacts: artifacts,
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
);
|
||||
final String build = testEnvironment.buildDir.path;
|
||||
processManager = FakeProcessManager.list(<FakeCommand>[
|
||||
|
||||
@ -113,6 +113,10 @@ void main() {
|
||||
return Environment.test(
|
||||
fs.directory('/icon_test')..createSync(recursive: true),
|
||||
defines: defines,
|
||||
artifacts: mockArtifacts,
|
||||
processManager: FakeProcessManager.any(),
|
||||
fileSystem: fs,
|
||||
logger: BufferLogger.test(),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -39,9 +39,16 @@ void main() {
|
||||
|
||||
setUp(() {
|
||||
testbed = Testbed(setup: () {
|
||||
environment = Environment.test(globals.fs.currentDirectory, defines: <String, String>{
|
||||
kTargetPlatform: 'ios',
|
||||
});
|
||||
environment = Environment.test(
|
||||
globals.fs.currentDirectory,
|
||||
defines: <String, String>{
|
||||
kTargetPlatform: 'ios',
|
||||
},
|
||||
processManager: processManager,
|
||||
artifacts: MockArtifacts(),
|
||||
logger: globals.logger,
|
||||
fileSystem: globals.fs,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter_tools/src/artifacts.dart';
|
||||
import 'package:platform/platform.dart';
|
||||
import 'package:flutter_tools/src/base/file_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;
|
||||
import 'package:mockito/mockito.dart';
|
||||
|
||||
import '../../../src/common.dart';
|
||||
import '../../../src/context.dart';
|
||||
import '../../../src/testbed.dart';
|
||||
|
||||
void main() {
|
||||
Testbed testbed;
|
||||
const BuildSystem buildSystem = BuildSystem();
|
||||
BuildSystem buildSystem;
|
||||
Environment environment;
|
||||
MockPlatform mockPlatform;
|
||||
|
||||
@ -33,11 +35,20 @@ void main() {
|
||||
when(mockPlatform.environment).thenReturn(Map<String, String>.unmodifiable(<String, String>{}));
|
||||
testbed = Testbed(setup: () {
|
||||
Cache.flutterRoot = '';
|
||||
buildSystem = BuildSystem(
|
||||
logger: globals.logger,
|
||||
platform: globals.platform,
|
||||
fileSystem: globals.fs,
|
||||
);
|
||||
environment = Environment.test(
|
||||
globals.fs.currentDirectory,
|
||||
defines: <String, String>{
|
||||
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/libflutter_linux_glfw.so').createSync(recursive: true);
|
||||
@ -105,3 +116,4 @@ void main() {
|
||||
}
|
||||
|
||||
class MockPlatform extends Mock implements Platform {}
|
||||
class MockArtifacts extends Mock implements Artifacts {}
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// 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/file_system.dart';
|
||||
import 'package:flutter_tools/src/base/io.dart';
|
||||
@ -16,6 +17,7 @@ import 'package:process/process.dart';
|
||||
import 'package:platform/platform.dart';
|
||||
|
||||
import '../../../src/common.dart';
|
||||
import '../../../src/fake_process_manager.dart';
|
||||
import '../../../src/testbed.dart';
|
||||
|
||||
const String _kInputPrefix = 'bin/cache/artifacts/engine/darwin-x64/FlutterMacOS.framework';
|
||||
@ -70,8 +72,12 @@ void main() {
|
||||
defines: <String, String>{
|
||||
kBuildMode: 'debug',
|
||||
kTargetPlatform: 'darwin-x64',
|
||||
},
|
||||
);
|
||||
},
|
||||
artifacts: MockArtifacts(),
|
||||
processManager: FakeProcessManager.any(),
|
||||
logger: globals.logger,
|
||||
fileSystem: globals.fs,
|
||||
);
|
||||
}, overrides: <Type, Generator>{
|
||||
ProcessManager: () => MockProcessManager(),
|
||||
Platform: () => mockPlatform,
|
||||
@ -195,6 +201,7 @@ class MockPlatform extends Mock implements Platform {}
|
||||
class MockProcessManager extends Mock implements ProcessManager {}
|
||||
class MockGenSnapshot extends Mock implements GenSnapshot {}
|
||||
class MockXcode extends Mock implements Xcode {}
|
||||
class MockArtifacts extends Mock implements Artifacts {}
|
||||
class FakeProcessResult implements ProcessResult {
|
||||
@override
|
||||
int exitCode;
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
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/build_system/build_system.dart';
|
||||
@ -55,7 +56,11 @@ void main() {
|
||||
outputDir: globals.fs.currentDirectory.childDirectory('bar'),
|
||||
defines: <String, String>{
|
||||
kTargetFile: globals.fs.path.join('foo', 'lib', 'main.dart'),
|
||||
}
|
||||
},
|
||||
artifacts: MockArtifacts(),
|
||||
processManager: FakeProcessManager.any(),
|
||||
logger: globals.logger,
|
||||
fileSystem: globals.fs,
|
||||
);
|
||||
depfileService = DepfileService(
|
||||
fileSystem: globals.fs,
|
||||
@ -460,3 +465,4 @@ void main() {
|
||||
}
|
||||
|
||||
class MockProcessManager extends Mock implements ProcessManager {}
|
||||
class MockArtifacts extends Mock implements Artifacts {}
|
||||
|
||||
@ -3,102 +3,77 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:file/memory.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/targets/windows.dart';
|
||||
import 'package:flutter_tools/src/cache.dart';
|
||||
import 'package:flutter_tools/src/globals.dart' as globals;
|
||||
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/build_system/build_system.dart';
|
||||
import 'package:flutter_tools/src/build_system/targets/windows.dart';
|
||||
|
||||
import '../../../src/common.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() {
|
||||
Testbed testbed;
|
||||
const BuildSystem buildSystem = BuildSystem();
|
||||
Environment environment;
|
||||
Platform platform;
|
||||
|
||||
setUpAll(() {
|
||||
Cache.disableLocking();
|
||||
Cache.flutterRoot = '';
|
||||
});
|
||||
FileSystem fileSystem;
|
||||
|
||||
setUp(() {
|
||||
platform = MockPlatform();
|
||||
when(platform.isWindows).thenReturn(true);
|
||||
when(platform.isMacOS).thenReturn(false);
|
||||
when(platform.isLinux).thenReturn(false);
|
||||
when(platform.pathSeparator).thenReturn(r'\');
|
||||
testbed = Testbed(setup: () {
|
||||
environment = Environment.test(
|
||||
globals.fs.currentDirectory,
|
||||
);
|
||||
globals.fs.file(r'C:\bin\cache\artifacts\engine\windows-x64\flutter_export.h').createSync(recursive: true);
|
||||
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();
|
||||
globals.fs.file(r'C:\bin\cache\artifacts\engine\windows-x64\flutter_windows.dll.exp').createSync();
|
||||
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();
|
||||
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,
|
||||
});
|
||||
final MockArtifacts artifacts = MockArtifacts();
|
||||
when(artifacts.getArtifactPath(Artifact.windowsDesktopPath))
|
||||
.thenReturn(r'C:\bin\cache\artifacts\engine\windows-x64\');
|
||||
fileSystem = MemoryFileSystem.test(style: FileSystemStyle.windows);
|
||||
environment = Environment.test(
|
||||
fileSystem.currentDirectory,
|
||||
artifacts: artifacts,
|
||||
processManager: FakeProcessManager.any(),
|
||||
fileSystem: fileSystem,
|
||||
logger: BufferLogger.test(),
|
||||
);
|
||||
for (final String path in kRequiredFiles) {
|
||||
fileSystem.file(path).createSync(recursive: true);
|
||||
}
|
||||
fileSystem.directory('windows').createSync();
|
||||
});
|
||||
|
||||
test('Copies files to correct cache directory', () => testbed.run(() async {
|
||||
await buildSystem.build(const UnpackWindows(), environment);
|
||||
testWithoutContext('UnpackWindows copies files to the correct cache directory', () async {
|
||||
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 {
|
||||
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);
|
||||
final DateTime modified = globals.fs.file(r'C:\windows\flutter\flutter_export.h').statSync().modified;
|
||||
globals.fs.file(r'C:\bin\cache\artifacts\engine\windows-x64\flutter_export.h').writeAsStringSync('asd'); // modify cache.
|
||||
|
||||
await buildSystem.build(const UnpackWindows(), environment);
|
||||
|
||||
expect(globals.fs.file(r'C:\windows\flutter\flutter_export.h').statSync().modified, isNot(modified));
|
||||
}));
|
||||
expect(fileSystem.file(r'C:\windows\flutter\flutter_export.h'), exists);
|
||||
expect(fileSystem.file(r'C:\windows\flutter\flutter_messenger.h'), exists);
|
||||
expect(fileSystem.file(r'C:\windows\flutter\flutter_windows.dll'), exists);
|
||||
expect(fileSystem.file(r'C:\windows\flutter\flutter_windows.dll.exp'), exists);
|
||||
expect(fileSystem.file(r'C:\windows\flutter\flutter_windows.dll.lib'), exists);
|
||||
expect(fileSystem.file(r'C:\windows\flutter\flutter_windows.dll.pdb'), exists);
|
||||
expect(fileSystem.file(r'C:\windows\flutter\flutter_export.h'), exists);
|
||||
expect(fileSystem.file(r'C:\windows\flutter\flutter_messenger.h'), exists);
|
||||
expect(fileSystem.file(r'C:\windows\flutter\flutter_plugin_registrar.h'), exists);
|
||||
expect(fileSystem.file(r'C:\windows\flutter\flutter_windows.h'), exists);
|
||||
expect(fileSystem.file(r'C:\windows\flutter\icudtl.dat'), exists);
|
||||
expect(fileSystem.file(r'C:\windows\flutter\cpp_client_wrapper\foo'), exists);
|
||||
});
|
||||
}
|
||||
|
||||
class MockPlatform extends Mock implements Platform {}
|
||||
class MockArtifacts extends Mock implements Artifacts {}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user