mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00

Work towards https://github.com/flutter/flutter/issues/56591.
I explicitly want an LGTM from @andrewkolos @jmagman @jonahwilliams before merging.
---
After this PR, `<Plugin>.isDevDependency` is resolved based on the following logic, IFF:
- The plugin comes from a package _A_ listed in the app's package's `dev_dependencies: ...`
- The package _A_ is not a normal dependency of any transitive non-dev dependency of the app
See [`compute_dev_dependencies_test.dart`](51676093a3/packages/flutter_tools/test/general.shard/compute_dev_dependencies_test.dart
) for probably the best specification of this behavior.
We (still) do not write the property to disk (i.e. it never makes it to `.flutter-plugins-dependencies`), so there is no impact to build artifacts at this time; that would come in a follow-up PR (and then follow-up follow-up PRs for the various build systems in both Gradle and Xcode to actually use that value to omit dependencies).
Some tests had to be updated; for the most part it was updating the default `ProcessManager` because a call to `dart pub deps --json` is now made in code that computes what plugins are available, but there should be no change in behavior.
_/cc @jonasfj @sigurdm for FYI only (we talked on an internal thread about this; see https://github.com/dart-lang/sdk/issues/56968)._
_/cc @camsim99 @cbracken @johnmccutchan for visibility on the change._
187 lines
6.0 KiB
Dart
187 lines
6.0 KiB
Dart
// 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:file/memory.dart';
|
|
import 'package:flutter_tools/src/base/logger.dart';
|
|
import 'package:flutter_tools/src/build_info.dart';
|
|
import 'package:flutter_tools/src/build_system/build_system.dart';
|
|
import 'package:flutter_tools/src/build_system/targets/web.dart';
|
|
import 'package:flutter_tools/src/project.dart';
|
|
import 'package:flutter_tools/src/reporting/reporting.dart';
|
|
import 'package:flutter_tools/src/web/compile.dart';
|
|
import 'package:flutter_tools/src/web/file_generators/flutter_service_worker_js.dart';
|
|
import 'package:unified_analytics/unified_analytics.dart';
|
|
|
|
import '../../src/common.dart';
|
|
import '../../src/context.dart';
|
|
import '../../src/fakes.dart';
|
|
import '../../src/test_build_system.dart';
|
|
|
|
void main() {
|
|
late MemoryFileSystem fileSystem;
|
|
late TestUsage testUsage;
|
|
late FakeAnalytics fakeAnalytics;
|
|
late BufferLogger logger;
|
|
late FakeFlutterVersion flutterVersion;
|
|
late FlutterProject flutterProject;
|
|
|
|
setUp(() {
|
|
fileSystem = MemoryFileSystem.test();
|
|
testUsage = TestUsage();
|
|
logger = BufferLogger.test();
|
|
flutterVersion = FakeFlutterVersion(frameworkVersion: '1.0.0', engineRevision: '9.8.7');
|
|
fakeAnalytics = getInitializedFakeAnalyticsInstance(
|
|
fs: fileSystem,
|
|
fakeFlutterVersion: flutterVersion,
|
|
);
|
|
|
|
flutterProject = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory);
|
|
|
|
fileSystem
|
|
.directory('.dart_tool')
|
|
.childFile('package_config.json')
|
|
.createSync(recursive: true);
|
|
});
|
|
|
|
testUsingContext('WebBuilder sets environment on success', () async {
|
|
final TestBuildSystem buildSystem =
|
|
TestBuildSystem.all(BuildResult(success: true), (Target target, Environment environment) {
|
|
expect(target, isA<WebServiceWorker>());
|
|
expect(environment.defines, <String, String>{
|
|
'TargetFile': 'target',
|
|
'HasWebPlugins': 'false',
|
|
'ServiceWorkerStrategy': ServiceWorkerStrategy.offlineFirst.cliName,
|
|
'BuildMode': 'debug',
|
|
'DartObfuscation': 'false',
|
|
'TrackWidgetCreation': 'true',
|
|
'TreeShakeIcons': 'false',
|
|
});
|
|
|
|
expect(environment.engineVersion, '9.8.7');
|
|
expect(environment.generateDartPluginRegistry, isFalse);
|
|
});
|
|
|
|
final WebBuilder webBuilder = WebBuilder(
|
|
logger: logger,
|
|
processManager: FakeProcessManager.any(),
|
|
buildSystem: buildSystem,
|
|
usage: testUsage,
|
|
flutterVersion: flutterVersion,
|
|
fileSystem: fileSystem,
|
|
analytics: fakeAnalytics,
|
|
useImplicitPubspecResolution: true,
|
|
);
|
|
await webBuilder.buildWeb(
|
|
flutterProject,
|
|
'target',
|
|
BuildInfo.debug,
|
|
ServiceWorkerStrategy.offlineFirst,
|
|
compilerConfigs: <WebCompilerConfig>[
|
|
const WasmCompilerConfig(
|
|
optimizationLevel: 0,
|
|
stripWasm: false,
|
|
),
|
|
const JsCompilerConfig.run(
|
|
nativeNullAssertions: true,
|
|
renderer: WebRendererMode.canvaskit,
|
|
),
|
|
],
|
|
);
|
|
|
|
expect(logger.statusText, contains('Compiling target for the Web...'));
|
|
expect(logger.errorText, isEmpty);
|
|
// Runs ScrubGeneratedPluginRegistrant migrator.
|
|
expect(
|
|
logger.traceText,
|
|
contains('generated_plugin_registrant.dart not found. Skipping.'),
|
|
);
|
|
|
|
// Sends build config event
|
|
expect(
|
|
testUsage.events,
|
|
unorderedEquals(
|
|
<TestUsageEvent>[
|
|
const TestUsageEvent(
|
|
'build',
|
|
'web',
|
|
label: 'web-compile',
|
|
parameters: CustomDimensions(
|
|
buildEventSettings:
|
|
'optimizationLevel: 0; web-renderer: skwasm,canvaskit; web-target: wasm,js;',
|
|
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
|
|
expect(
|
|
fakeAnalytics.sentEvents,
|
|
containsAll(<Event>[
|
|
Event.flutterBuildInfo(
|
|
label: 'web-compile',
|
|
buildType: 'web',
|
|
settings: 'optimizationLevel: 0; web-renderer: skwasm,canvaskit; web-target: wasm,js;',
|
|
),
|
|
]),
|
|
);
|
|
|
|
// Sends timing event.
|
|
final TestTimingEvent timingEvent = testUsage.timings.single;
|
|
expect(timingEvent.category, 'build');
|
|
expect(timingEvent.variableName, 'dual-compile');
|
|
expect(
|
|
analyticsTimingEventExists(
|
|
sentEvents: fakeAnalytics.sentEvents,
|
|
workflow: 'build',
|
|
variableName: 'dual-compile',
|
|
),
|
|
true,
|
|
);
|
|
}, overrides: <Type, Generator>{
|
|
ProcessManager: () => FakeProcessManager.any(),
|
|
});
|
|
|
|
testUsingContext('WebBuilder throws tool exit on failure', () async {
|
|
final TestBuildSystem buildSystem = TestBuildSystem.all(BuildResult(
|
|
success: false,
|
|
exceptions: <String, ExceptionMeasurement>{
|
|
'hello': ExceptionMeasurement(
|
|
'hello',
|
|
const FormatException('illegal character in input string'),
|
|
StackTrace.current,
|
|
),
|
|
},
|
|
));
|
|
|
|
final WebBuilder webBuilder = WebBuilder(
|
|
logger: logger,
|
|
processManager: FakeProcessManager.any(),
|
|
buildSystem: buildSystem,
|
|
usage: testUsage,
|
|
flutterVersion: flutterVersion,
|
|
fileSystem: fileSystem,
|
|
analytics: fakeAnalytics,
|
|
useImplicitPubspecResolution: true,
|
|
);
|
|
await expectLater(
|
|
() async => webBuilder.buildWeb(
|
|
flutterProject,
|
|
'target',
|
|
BuildInfo.debug,
|
|
ServiceWorkerStrategy.offlineFirst,
|
|
compilerConfigs: <WebCompilerConfig>[
|
|
const JsCompilerConfig.run(nativeNullAssertions: true, renderer: WebRendererMode.canvaskit),
|
|
]
|
|
),
|
|
throwsToolExit(message: 'Failed to compile application for the Web.'));
|
|
|
|
expect(logger.errorText, contains('Target hello failed: FormatException: illegal character in input string'));
|
|
expect(testUsage.timings, isEmpty);
|
|
expect(fakeAnalytics.sentEvents, isEmpty);
|
|
}, overrides: <Type, Generator>{
|
|
ProcessManager: () => FakeProcessManager.any(),
|
|
});
|
|
}
|