Unverified Commit 045f3a54 authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[flutter_tools] turn down flutter generate (#61475)

complete removal of all generate functionality

Fixes #61508
parent e2cdc9f9
......@@ -15,11 +15,9 @@ import 'src/base/template.dart';
// avoid introducing the dependency into google3. Not all build* packages
// are synced internally.
import 'src/base/terminal.dart';
import 'src/build_runner/build_runner.dart';
import 'src/build_runner/mustache_template.dart';
import 'src/build_runner/resident_web_runner.dart';
import 'src/build_runner/web_compilation_delegate.dart';
import 'src/codegen.dart';
import 'src/commands/analyze.dart';
import 'src/commands/assemble.dart';
import 'src/commands/attach.dart';
......@@ -130,9 +128,6 @@ Future<void> main(List<String> args) async {
muteCommandLogging: muteCommandLogging,
verboseHelp: verboseHelp,
overrides: <Type, Generator>{
// The build runner instance is not supported in google3 because
// the build runner packages are not synced internally.
CodeGenerator: () => const BuildRunner(),
WebCompilationProxy: () => BuildRunnerWebCompilationProxy(),
// The web runner is not supported in google3 because it depends
// on dwds.
......
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'package:build_daemon/client.dart';
import 'package:build_daemon/data/build_status.dart';
import 'package:build_daemon/data/build_status.dart' as build;
import 'package:build_daemon/data/build_target.dart';
import 'package:build_daemon/data/server_log.dart';
import 'package:crypto/crypto.dart' show md5;
import 'package:yaml/yaml.dart';
import '../artifacts.dart';
import '../base/common.dart';
import '../base/file_system.dart';
import '../base/io.dart';
import '../base/logger.dart';
import '../codegen.dart';
import '../dart/pub.dart';
import '../globals.dart' as globals;
import '../project.dart';
/// The minimum version of build_runner we can support in the flutter tool.
const String kMinimumBuildRunnerVersion = '1.10.0';
const String kSupportedBuildDaemonVersion = '2.1.0';
/// A wrapper for a build_runner process which delegates to a generated
/// build script.
///
/// This is only enabled if [experimentalBuildEnabled] is true, and only for
/// external flutter users.
class BuildRunner extends CodeGenerator {
const BuildRunner();
@override
Future<void> generateBuildScript(FlutterProject flutterProject) async {
final Directory entrypointDirectory = globals.fs.directory(globals.fs.path.join(flutterProject.dartTool.path, 'build', 'entrypoint'));
final Directory generatedDirectory = globals.fs.directory(globals.fs.path.join(flutterProject.dartTool.path, 'flutter_tool'));
final File buildSnapshot = entrypointDirectory.childFile('build.dart.snapshot');
final File scriptIdFile = entrypointDirectory.childFile('id');
final File syntheticPubspec = generatedDirectory.childFile('pubspec.yaml');
// Check if contents of builders changed. If so, invalidate build script
// and regenerate.
final YamlMap builders = flutterProject.builders;
final List<int> appliedBuilderDigest = _produceScriptId(builders);
if (scriptIdFile.existsSync() && buildSnapshot.existsSync()) {
final List<int> previousAppliedBuilderDigest = scriptIdFile.readAsBytesSync();
bool digestsAreEqual = false;
if (appliedBuilderDigest.length == previousAppliedBuilderDigest.length) {
digestsAreEqual = true;
for (int i = 0; i < appliedBuilderDigest.length; i++) {
if (appliedBuilderDigest[i] != previousAppliedBuilderDigest[i]) {
digestsAreEqual = false;
break;
}
}
}
if (digestsAreEqual) {
return;
}
}
// Clean-up all existing artifacts.
if (flutterProject.dartTool.existsSync()) {
flutterProject.dartTool.deleteSync(recursive: true);
}
final Status status = globals.logger.startProgress('generating build script...', timeout: null);
try {
generatedDirectory.createSync(recursive: true);
entrypointDirectory.createSync(recursive: true);
flutterProject.dartTool.childDirectory('build').childDirectory('generated').createSync(recursive: true);
final StringBuffer stringBuffer = StringBuffer();
stringBuffer.writeln('name: flutter_tool');
stringBuffer.writeln('dependencies:');
final YamlMap builders = flutterProject.builders;
if (builders != null) {
for (final String name in builders.keys.cast<String>()) {
final Object node = builders[name];
// For relative paths, make sure it is accounted for
// parent directories.
if (node is YamlMap && node['path'] != null) {
final String path = node['path'] as String;
if (globals.fs.path.isRelative(path)) {
final String convertedPath = globals.fs.path.join('..', '..', path);
stringBuffer.writeln(' $name:');
stringBuffer.writeln(' path: $convertedPath');
} else {
stringBuffer.writeln(' $name: $node');
}
} else {
stringBuffer.writeln(' $name: $node');
}
}
}
stringBuffer.writeln(' build_runner: $kMinimumBuildRunnerVersion');
stringBuffer.writeln(' build_daemon: $kSupportedBuildDaemonVersion');
syntheticPubspec.writeAsStringSync(stringBuffer.toString());
await pub.get(
context: PubContext.pubGet,
directory: generatedDirectory.path,
upgrade: false,
checkLastModified: false,
generateSyntheticPackage: false,
);
if (!scriptIdFile.existsSync()) {
scriptIdFile.createSync(recursive: true);
}
scriptIdFile.writeAsBytesSync(appliedBuilderDigest);
final ProcessResult generateResult = await globals.processManager.run(<String>[
globals.fs.path.join(
globals.artifacts.getArtifactPath(Artifact.engineDartSdkPath),
'bin',
(globals.platform.isWindows) ? 'pub.bat' : 'pub'
),
'run',
'build_runner',
'generate-build-script',
], workingDirectory: syntheticPubspec.parent.path);
if (generateResult.exitCode != 0) {
throwToolExit('Error generating build_script snapshot: ${generateResult.stderr}');
}
final File buildScript = globals.fs.file(generateResult.stdout.trim());
final ProcessResult result = await globals.processManager.run(<String>[
globals.artifacts.getArtifactPath(Artifact.engineDartBinary),
'--disable-dart-dev',
'--snapshot=${buildSnapshot.path}',
'--snapshot-kind=app-jit',
'--packages=${globals.fs.path.join(generatedDirectory.path, '.packages')}',
buildScript.path,
]);
if (result.exitCode != 0) {
throwToolExit('Error generating build_script snapshot: ${result.stderr}');
}
} finally {
status.stop();
}
}
@override
Future<CodegenDaemon> daemon(
FlutterProject flutterProject, {
String mainPath,
bool linkPlatformKernelIn = false,
bool trackWidgetCreation = false,
List<String> extraFrontEndOptions = const <String> [],
}) async {
await generateBuildScript(flutterProject);
final String engineDartBinaryPath = globals.artifacts.getArtifactPath(Artifact.engineDartBinary);
final File buildSnapshot = flutterProject
.dartTool
.childDirectory('build')
.childDirectory('entrypoint')
.childFile('build.dart.snapshot');
final String scriptPackagesPath = flutterProject
.dartTool
.childDirectory('flutter_tool')
.childFile('.packages')
.path;
final Status status = globals.logger.startProgress('starting build daemon...', timeout: null);
BuildDaemonClient buildDaemonClient;
try {
final List<String> command = <String>[
engineDartBinaryPath,
'--packages=$scriptPackagesPath',
buildSnapshot.path,
'daemon',
'--skip-build-script-check',
'--delete-conflicting-outputs',
];
buildDaemonClient = await BuildDaemonClient.connect(
flutterProject.directory.path,
command,
logHandler: (ServerLog log) {
if (log.message != null) {
globals.printTrace(log.message);
}
},
);
} finally {
status.stop();
}
// Empty string indicates we should build everything.
final OutputLocation outputLocation = OutputLocation((OutputLocationBuilder b) => b
..output = ''
..useSymlinks = false
..hoist = false,
);
buildDaemonClient.registerBuildTarget(DefaultBuildTarget((DefaultBuildTargetBuilder builder) {
builder.target = 'lib';
builder.outputLocation = outputLocation.toBuilder();
}));
buildDaemonClient.registerBuildTarget(DefaultBuildTarget((DefaultBuildTargetBuilder builder) {
builder.target = 'test';
builder.outputLocation = outputLocation.toBuilder();
}));
return _BuildRunnerCodegenDaemon(buildDaemonClient);
}
}
class _BuildRunnerCodegenDaemon implements CodegenDaemon {
_BuildRunnerCodegenDaemon(this.buildDaemonClient);
final BuildDaemonClient buildDaemonClient;
@override
CodegenStatus get lastStatus => _lastStatus;
CodegenStatus _lastStatus;
@override
Stream<CodegenStatus> get buildResults => buildDaemonClient.buildResults.map((build.BuildResults results) {
if (results.results.first.status == BuildStatus.failed) {
return _lastStatus = CodegenStatus.Failed;
}
if (results.results.first.status == BuildStatus.started) {
return _lastStatus = CodegenStatus.Started;
}
if (results.results.first.status == BuildStatus.succeeded) {
return _lastStatus = CodegenStatus.Succeeded;
}
_lastStatus = null;
return null;
});
@override
void startBuild() {
buildDaemonClient.startBuild();
}
}
// Sorts the builders by name and produces a hashcode of the resulting iterable.
List<int> _produceScriptId(YamlMap builders) {
if (builders == null || builders.isEmpty) {
return md5.convert(globals.platform.version.codeUnits).bytes;
}
final List<String> orderedBuilderNames = builders.keys
.cast<String>()
.toList()..sort();
final List<String> orderedBuilderValues = builders.values
.map((dynamic value) => value.toString())
.toList()..sort();
return md5.convert(<String>[
...orderedBuilderNames,
...orderedBuilderValues,
globals.platform.version,
].join('').codeUnits).bytes;
}
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:meta/meta.dart';
import 'package:package_config/package_config.dart';
import 'package:process/process.dart';
import 'artifacts.dart';
import 'base/context.dart';
import 'base/file_system.dart';
import 'base/logger.dart';
import 'build_info.dart';
import 'compile.dart';
import 'globals.dart' as globals;
import 'project.dart';
/// The [CodeGenerator] instance.
///
/// If [experimentalBuildEnabled] is false, this will contain an unsupported
/// implementation.
CodeGenerator get codeGenerator => context.get<CodeGenerator>();
/// A wrapper for a build_runner process which delegates to a generated
/// build script.
abstract class CodeGenerator {
const CodeGenerator();
/// Starts a persistent code generating daemon.
///
/// The defines of the daemon command are the arguments required in the
/// flutter_build kernel builder.
Future<CodegenDaemon> daemon(FlutterProject flutterProject);
// Generates a synthetic package under .dart_tool/flutter_tool which is in turn
// used to generate a build script.
Future<void> generateBuildScript(FlutterProject flutterProject);
}
class UnsupportedCodeGenerator extends CodeGenerator {
const UnsupportedCodeGenerator();
@override
Future<void> generateBuildScript(FlutterProject flutterProject) {
throw UnsupportedError('build_runner is not currently supported.');
}
@override
Future<CodegenDaemon> daemon(FlutterProject flutterProject) {
throw UnsupportedError('build_runner is not currently supported.');
}
}
abstract class CodegenDaemon {
/// Whether the previously enqueued build was successful.
Stream<CodegenStatus> get buildResults;
CodegenStatus get lastStatus;
/// Starts a new build.
void startBuild();
}
/// An implementation of the [KernelCompiler] which delegates to build_runner.
///
/// Only a subset of the arguments provided to the [KernelCompiler] are
/// supported here. Using the build pipeline implies a fixed multi-root
/// filesystem and requires a pubspec.
class CodeGeneratingKernelCompiler implements KernelCompiler {
CodeGeneratingKernelCompiler({
@required FileSystem fileSystem,
@required Artifacts artifacts,
@required ProcessManager processManager,
@required Logger logger,
}) : _delegate = KernelCompiler(
logger: logger,
artifacts: artifacts,
processManager: processManager,
fileSystem: fileSystem,
);
final KernelCompiler _delegate;
@override
Future<CompilerOutput> compile({
String mainPath,
String outputFilePath,
bool linkPlatformKernelIn = false,
bool aot = false,
bool trackWidgetCreation,
List<String> extraFrontEndOptions,
String sdkRoot,
String packagesPath,
List<String> fileSystemRoots,
String fileSystemScheme,
String depFilePath,
TargetModel targetModel = TargetModel.flutter,
String initializeFromDill,
String platformDill,
List<String> dartDefines,
@required BuildMode buildMode,
@required PackageConfig packageConfig,
}) async {
final FlutterProject flutterProject = FlutterProject.current();
final CodegenDaemon codegenDaemon = await codeGenerator.daemon(flutterProject);
codegenDaemon.startBuild();
await for (final CodegenStatus codegenStatus in codegenDaemon.buildResults) {
if (codegenStatus == CodegenStatus.Failed) {
globals.printError('Code generation failed, build may have compile errors.');
break;
}
if (codegenStatus == CodegenStatus.Succeeded) {
break;
}
}
return _delegate.compile(
mainPath: mainPath,
outputFilePath: outputFilePath,
linkPlatformKernelIn: linkPlatformKernelIn,
aot: aot,
buildMode: buildMode,
trackWidgetCreation: trackWidgetCreation,
extraFrontEndOptions: extraFrontEndOptions,
sdkRoot: sdkRoot,
packagesPath: packagesPath,
fileSystemRoots: fileSystemRoots,
fileSystemScheme: fileSystemScheme,
depFilePath: depFilePath,
targetModel: targetModel,
initializeFromDill: initializeFromDill,
dartDefines: dartDefines,
packageConfig: packageConfig,
);
}
}
/// An implementation of a [ResidentCompiler] which runs a [BuildRunner] before
/// talking to the CFE.
class CodeGeneratingResidentCompiler implements ResidentCompiler {
CodeGeneratingResidentCompiler._(this._residentCompiler, this._codegenDaemon);
/// Creates a new [ResidentCompiler] and configures a [BuildDaemonClient] to
/// run builds.
///
/// If `runCold` is true, then no codegen daemon will be created. Instead the
/// compiler will only be initialized with the correct configuration for
/// codegen mode.
static Future<ResidentCompiler> create({
@required ResidentCompiler residentCompiler,
@required FlutterProject flutterProject,
bool runCold = false,
}) async {
if (runCold) {
return residentCompiler;
}
globals.printError(<String>[
'"flutter generate" is deprecated, use "dart pub run build_runner" instead. ',
'The following dependencies must be added to dev_dependencies in pubspec.yaml:',
'build_runner: 1.10.0',
for (Object dependency in flutterProject.builders?.keys ?? const <Object>[])
'$dependency: ${flutterProject.builders[dependency]}'
].join('\n'));
final CodegenDaemon codegenDaemon = await codeGenerator.daemon(flutterProject);
codegenDaemon.startBuild();
final CodegenStatus status = await codegenDaemon.buildResults.firstWhere((CodegenStatus status) {
return status == CodegenStatus.Succeeded || status == CodegenStatus.Failed;
});
if (status == CodegenStatus.Failed) {
globals.printError('Code generation failed, build may have compile errors.');
}
return CodeGeneratingResidentCompiler._(residentCompiler, codegenDaemon);
}
final ResidentCompiler _residentCompiler;
final CodegenDaemon _codegenDaemon;
@override
void accept() {
_residentCompiler.accept();
}
@override
Future<CompilerOutput> compileExpression(String expression, List<String> definitions, List<String> typeDefinitions, String libraryUri, String klass, bool isStatic) {
return _residentCompiler.compileExpression(expression, definitions, typeDefinitions, libraryUri, klass, isStatic);
}
@override
Future<CompilerOutput> compileExpressionToJs(
String libraryUri, int line, int column, Map<String, String> jsModules,
Map<String, String> jsFrameValues, String moduleName, String expression
) {
return _residentCompiler.compileExpressionToJs(
libraryUri, line, column, jsModules, jsFrameValues, moduleName, expression);
}
@override
Future<CompilerOutput> recompile(
Uri mainUri,
List<Uri> invalidatedFiles, {
String outputPath,
PackageConfig packageConfig,
bool suppressErrors = false,
}) async {
if (_codegenDaemon.lastStatus != CodegenStatus.Succeeded && _codegenDaemon.lastStatus != CodegenStatus.Failed) {
await _codegenDaemon.buildResults.firstWhere((CodegenStatus status) {
return status == CodegenStatus.Succeeded || status == CodegenStatus.Failed;
});
}
if (_codegenDaemon.lastStatus == CodegenStatus.Failed) {
globals.printError('Code generation failed, build may have compile errors.');
}
return _residentCompiler.recompile(
mainUri,
invalidatedFiles,
outputPath: outputPath,
packageConfig: packageConfig,
suppressErrors: suppressErrors,
);
}
@override
Future<CompilerOutput> reject() {
return _residentCompiler.reject();
}
@override
void reset() {
_residentCompiler.reset();
}
@override
Future<void> shutdown() {
return _residentCompiler.shutdown();
}
@override
void addFileSystemRoot(String root) {
_residentCompiler.addFileSystemRoot(root);
}
}
/// The current status of a codegen build.
enum CodegenStatus {
/// The build has started running.
///
/// If this is the current status when running a hot reload, an additional build does
/// not need to be started.
Started,
/// The build succeeded.
Succeeded,
/// The build failed.
Failed
}
......@@ -2,11 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import '../base/file_system.dart';
import '../codegen.dart';
import '../convert.dart';
import '../globals.dart' as globals;
import '../project.dart';
import '../runner/flutter_command.dart';
class GenerateCommand extends FlutterCommand {
......@@ -24,47 +20,12 @@ class GenerateCommand extends FlutterCommand {
@override
Future<FlutterCommandResult> runCommand() async {
final FlutterProject flutterProject = FlutterProject.current();
globals.printError(<String>[
'"flutter generate" is deprecated, use "dart pub run build_runner" instead. ',
'The following dependencies must be added to dev_dependencies in pubspec.yaml:',
'build_runner: 1.10.0',
for (Object dependency in flutterProject.builders?.keys ?? const <Object>[])
'$dependency: ${flutterProject.builders[dependency]}'
].join('\n'));
final CodegenDaemon codegenDaemon = await codeGenerator.daemon(flutterProject);
codegenDaemon.startBuild();
await for (final CodegenStatus codegenStatus in codegenDaemon.buildResults) {
if (codegenStatus == CodegenStatus.Failed) {
globals.printError('Code generation failed.');
break;
}
if (codegenStatus == CodegenStatus.Succeeded) {
break;
}
}
// Check for errors output in the build_runner cache.
final Directory buildDirectory = flutterProject.dartTool.childDirectory('build');
final Directory errorCacheParent = buildDirectory.listSync().whereType<Directory>().firstWhere((Directory dir) {
return dir.childDirectory('error_cache').existsSync();
}, orElse: () => null);
if (errorCacheParent == null) {
return FlutterCommandResult.success();
}
final Directory errorCache = errorCacheParent.childDirectory('error_cache');
for (final File errorFile in errorCache.listSync(recursive: true).whereType<File>()) {
try {
final List<Object> errorData = json.decode(errorFile.readAsStringSync()) as List<Object>;
final List<Object> stackData = errorData[1] as List<Object>;
globals.printError(errorData.first as String);
globals.printError(stackData[0] as String);
globals.printError(stackData[1] as String);
globals.printError(StackTrace.fromString(stackData[2] as String).toString());
} on Exception catch (err) {
globals.printError('Error reading error in ${errorFile.path}: $err');
}
}
globals.printError(
'"flutter generate" is deprecated, use "dart pub run build_runner" instead. '
'The following dependencies must be added to dev_dependencies in pubspec.yaml:\n'
'build_runner: ^1.10.0\n'
'including all dependencies under the "builders" key'
);
return FlutterCommandResult.fail();
}
}
......@@ -11,7 +11,6 @@ import '../base/file_system.dart';
import '../build_info.dart';
import '../bundle.dart';
import '../cache.dart';
import '../codegen.dart';
import '../dart/pub.dart';
import '../devfs.dart';
import '../globals.dart' as globals;
......@@ -240,20 +239,6 @@ class TestCommand extends FlutterCommand {
watcher = collector;
}
// Run builders once before all tests.
if (flutterProject.hasBuilders) {
final CodegenDaemon codegenDaemon = await codeGenerator.daemon(flutterProject);
codegenDaemon.startBuild();
await for (final CodegenStatus status in codegenDaemon.buildResults) {
if (status == CodegenStatus.Succeeded) {
break;
}
if (status == CodegenStatus.Failed) {
throwToolExit('Code generation failed.');
}
}
}
final bool disableServiceAuthCodes =
boolArg('disable-service-auth-codes');
......
......@@ -16,7 +16,6 @@ import 'base/file_system.dart';
import 'base/io.dart';
import 'base/logger.dart';
import 'build_info.dart';
import 'codegen.dart';
import 'convert.dart';
import 'globals.dart' as globals;
import 'project.dart';
......@@ -40,15 +39,7 @@ class KernelCompilerFactory {
final FileSystem _fileSystem;
Future<KernelCompiler> create(FlutterProject flutterProject) async {
if (flutterProject == null || !flutterProject.hasBuilders) {
return KernelCompiler(
logger: _logger,
artifacts: _artifacts,
fileSystem: _fileSystem,
processManager: _processManager,
);
}
return CodeGeneratingKernelCompiler(
return KernelCompiler(
logger: _logger,
artifacts: _artifacts,
fileSystem: _fileSystem,
......
......@@ -262,25 +262,6 @@ class FlutterProject {
}
await injectPlugins(this, checkProjects: checkProjects);
}
/// Return the set of builders used by this package.
YamlMap get builders {
if (!pubspecFile.existsSync()) {
return null;
}
final YamlMap pubspec = loadYaml(pubspecFile.readAsStringSync()) as YamlMap;
// If the pubspec file is empty, this will be null.
if (pubspec == null) {
return null;
}
return pubspec['builders'] as YamlMap;
}
/// Whether there are any builders used by this package.
bool get hasBuilders {
final YamlMap result = builders;
return result != null && result.isNotEmpty;
}
}
/// Base class for projects per platform.
......
......@@ -24,7 +24,6 @@ import 'build_system/build_system.dart';
import 'build_system/targets/localizations.dart';
import 'bundle.dart';
import 'cache.dart';
import 'codegen.dart';
import 'compile.dart';
import 'devfs.dart';
import 'device.dart';
......@@ -158,13 +157,6 @@ class FlutterDevice {
);
}
if (flutterProject.hasBuilders) {
generator = await CodeGeneratingResidentCompiler.create(
residentCompiler: generator,
flutterProject: flutterProject,
);
}
return FlutterDevice(
device,
fileSystemRoots: fileSystemRoots,
......
......@@ -11,7 +11,6 @@ import '../artifacts.dart';
import '../base/file_system.dart';
import '../build_info.dart';
import '../bundle.dart';
import '../codegen.dart';
import '../compile.dart';
import '../dart/package_map.dart';
import '../globals.dart' as globals;
......@@ -110,12 +109,6 @@ class TestCompiler {
packagesPath: globalPackagesPath,
extraFrontEndOptions: extraFrontEndOptions,
);
if (flutterProject.hasBuilders) {
return CodeGeneratingResidentCompiler.create(
residentCompiler: residentCompiler,
flutterProject: flutterProject,
);
}
return residentCompiler;
}
......
// Copyright 2014 The Flutter Authors. All rights reserved.
// 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/cache.dart';
import 'package:flutter_tools/src/codegen.dart';
import 'package:flutter_tools/src/commands/generate.dart';
import 'package:flutter_tools/src/convert.dart';
import 'package:mockito/mockito.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
import '../../src/common.dart';
import '../../src/context.dart';
import '../../src/mocks.dart';
import '../../src/testbed.dart';
void main() {
Testbed testbed;
MockCodeGenerator mockCodeGenerator;
MockCodegenDaemon mockCodegenDaemon;
setUpAll(() {
Cache.disableLocking();
});
tearDownAll(() {
Cache.enableLocking();
});
setUp(() {
mockCodegenDaemon = MockCodegenDaemon();
mockCodeGenerator = MockCodeGenerator();
when(mockCodegenDaemon.buildResults).thenAnswer((Invocation invocation) {
return Stream<CodegenStatus>.fromIterable(<CodegenStatus>[
CodegenStatus.Started,
CodegenStatus.Succeeded,
]);
});
when(mockCodeGenerator.daemon(any)).thenAnswer((Invocation invocation) async {
return mockCodegenDaemon;
});
testbed = Testbed(overrides: <Type, Generator>{
CodeGenerator: () => mockCodeGenerator,
});
});
test('Outputs deprecation warning from flutter generate', () => testbed.run(() async {
final GenerateCommand command = GenerateCommand();
applyMocksToCommand(command);
globals.fs.file(globals.fs.path.join('lib', 'main.dart'))
.createSync(recursive: true);
globals.fs.currentDirectory
.childDirectory('.dart_tool')
.childDirectory('build')
.childDirectory('abcdefg')
.createSync(recursive: true);
await createTestCommandRunner(command)
.run(const <String>['generate']);
expect(testLogger.errorText, contains(
'"flutter generate" is deprecated, use "dart pub run build_runner" instead.'
));
expect(testLogger.errorText, contains(
'build_runner: 1.10.0'
));
}));
test('Outputs error information from flutter generate', () => testbed.run(() async {
final GenerateCommand command = GenerateCommand();
applyMocksToCommand(command);
globals.fs.file(globals.fs.path.join('lib', 'main.dart'))
.createSync(recursive: true);
globals.fs.currentDirectory
.childDirectory('.dart_tool')
.childDirectory('build')
.childDirectory('abcdefg')
.childDirectory('error_cache')
.childFile('foo_error')
..createSync(recursive: true)
..writeAsStringSync(json.encode(<dynamic>[
'foo builder',
<dynamic>[
'a',
'b',
StackTrace.current.toString(),
]
]));
await createTestCommandRunner(command)
.run(const <String>['generate']);
expect(testLogger.errorText, contains('a'));
expect(testLogger.errorText, contains('b'));
expect(testLogger.errorText, contains('foo builder'));
expect(testLogger.errorText, isNot(contains('Error reading error')));
}));
}
class MockCodeGenerator extends Mock implements CodeGenerator { }
class MockCodegenDaemon extends Mock implements CodegenDaemon { }
......@@ -568,48 +568,6 @@ apply plugin: 'kotlin-android'
});
});
});
group('Regression test for invalid pubspec', () {
Testbed testbed;
FlutterProjectFactory flutterProjectFactory;
setUp(() {
testbed = Testbed(setup: () {
flutterProjectFactory = FlutterProjectFactory(
fileSystem: globals.fs,
logger: globals.logger,
);
});
});
test('Handles asking for builders from an invalid pubspec', () => testbed.run(() {
globals.fs.file('pubspec.yaml')
..createSync()
..writeAsStringSync(r'''
# Hello, World
''');
final FlutterProject flutterProject = FlutterProject.current();
expect(flutterProject.builders, null);
}, overrides: <Type, Generator>{
FlutterProjectFactory: () => flutterProjectFactory,
}));
test('Handles asking for builders from a trivial pubspec', () => testbed.run(() {
globals.fs.file('pubspec.yaml')
..createSync()
..writeAsStringSync(r'''
# Hello, World
name: foo_bar
''');
final FlutterProject flutterProject = FlutterProject.current();
expect(flutterProject.builders, null);
}, overrides: <Type, Generator>{
FlutterProjectFactory: () => flutterProjectFactory,
}));
});
group('watch companion', () {
MemoryFileSystem fs;
MockPlistUtils mockPlistUtils;
......
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