Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
1af8cc11
Unverified
Commit
1af8cc11
authored
May 12, 2022
by
David Iglesias
Committed by
GitHub
May 12, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[tools][web] Make Plugin Registrant file ephemeral. (#102185)
parent
40627e9e
Changes
17
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
690 additions
and
344 deletions
+690
-344
service_worker_test.dart
dev/bots/service_worker_test.dart
+0
-4
web.dart
packages/flutter_tools/lib/src/build_system/targets/web.dart
+12
-246
flutter_plugins.dart
packages/flutter_tools/lib/src/flutter_plugins.dart
+60
-22
devfs_web.dart
packages/flutter_tools/lib/src/isolated/devfs_web.dart
+1
-1
resident_web_runner.dart
...s/flutter_tools/lib/src/isolated/resident_web_runner.dart
+12
-43
project.dart
packages/flutter_tools/lib/src/project.dart
+0
-1
compile.dart
packages/flutter_tools/lib/src/web/compile.dart
+12
-1
flutter_js.dart
...flutter_tools/lib/src/web/file_generators/flutter_js.dart
+0
-0
flutter_service_worker_js.dart
...ib/src/web/file_generators/flutter_service_worker_js.dart
+203
-0
main_dart.dart
.../flutter_tools/lib/src/web/file_generators/main_dart.dart
+46
-0
scrub_generated_plugin_registrant.dart
...src/web/migrations/scrub_generated_plugin_registrant.dart
+56
-0
.gitignore.tmpl
packages/flutter_tools/templates/app_shared/.gitignore.tmpl
+0
-3
build_web_test.dart
...er_tools/test/commands.shard/hermetic/build_web_test.dart
+3
-1
web_test.dart
...ols/test/general.shard/build_system/targets/web_test.dart
+31
-14
plugins_test.dart
packages/flutter_tools/test/general.shard/plugins_test.dart
+3
-2
scrub_generated_plugin_registrant_test.dart
...eb/migrations/scrub_generated_plugin_registrant_test.dart
+200
-0
web_plugin_registrant_test.dart
...ls/test/integration.shard/web_plugin_registrant_test.dart
+51
-6
No files found.
dev/bots/service_worker_test.dart
View file @
1af8cc11
...
@@ -231,7 +231,6 @@ Future<void> runWebServiceWorkerTest({
...
@@ -231,7 +231,6 @@ Future<void> runWebServiceWorkerTest({
'main.dart.js'
:
1
,
'main.dart.js'
:
1
,
'flutter_service_worker.js'
:
1
,
'flutter_service_worker.js'
:
1
,
'assets/FontManifest.json'
:
1
,
'assets/FontManifest.json'
:
1
,
'assets/NOTICES'
:
1
,
'assets/AssetManifest.json'
:
1
,
'assets/AssetManifest.json'
:
1
,
'CLOSE'
:
1
,
'CLOSE'
:
1
,
// In headless mode Chrome does not load 'manifest.json' and 'favicon.ico'.
// In headless mode Chrome does not load 'manifest.json' and 'favicon.ico'.
...
@@ -273,7 +272,6 @@ Future<void> runWebServiceWorkerTest({
...
@@ -273,7 +272,6 @@ Future<void> runWebServiceWorkerTest({
'flutter.js'
:
1
,
'flutter.js'
:
1
,
'flutter_service_worker.js'
:
2
,
'flutter_service_worker.js'
:
2
,
'main.dart.js'
:
1
,
'main.dart.js'
:
1
,
'assets/NOTICES'
:
1
,
'assets/AssetManifest.json'
:
1
,
'assets/AssetManifest.json'
:
1
,
'assets/FontManifest.json'
:
1
,
'assets/FontManifest.json'
:
1
,
'CLOSE'
:
1
,
'CLOSE'
:
1
,
...
@@ -305,7 +303,6 @@ Future<void> runWebServiceWorkerTest({
...
@@ -305,7 +303,6 @@ Future<void> runWebServiceWorkerTest({
'main.dart.js'
:
2
,
'main.dart.js'
:
2
,
'assets/FontManifest.json'
:
2
,
'assets/FontManifest.json'
:
2
,
'flutter_service_worker.js'
:
1
,
'flutter_service_worker.js'
:
1
,
'assets/NOTICES'
:
1
,
'assets/AssetManifest.json'
:
1
,
'assets/AssetManifest.json'
:
1
,
'CLOSE'
:
1
,
'CLOSE'
:
1
,
// In headless mode Chrome does not load 'manifest.json' and 'favicon.ico'.
// In headless mode Chrome does not load 'manifest.json' and 'favicon.ico'.
...
@@ -358,7 +355,6 @@ Future<void> runWebServiceWorkerTest({
...
@@ -358,7 +355,6 @@ Future<void> runWebServiceWorkerTest({
'flutter.js'
:
1
,
'flutter.js'
:
1
,
'flutter_service_worker.js'
:
2
,
'flutter_service_worker.js'
:
2
,
'main.dart.js'
:
2
,
'main.dart.js'
:
2
,
'assets/NOTICES'
:
1
,
'assets/AssetManifest.json'
:
1
,
'assets/AssetManifest.json'
:
1
,
'assets/FontManifest.json'
:
2
,
'assets/FontManifest.json'
:
2
,
'CLOSE'
:
1
,
'CLOSE'
:
1
,
...
...
packages/flutter_tools/lib/src/build_system/targets/web.dart
View file @
1af8cc11
This diff is collapsed.
Click to expand it.
packages/flutter_tools/lib/src/flutter_plugins.dart
View file @
1af8cc11
...
@@ -550,23 +550,32 @@ Depends on all your plugins, and provides a function to register them.
...
@@ -550,23 +550,32 @@ Depends on all your plugins, and provides a function to register them.
end
end
''';
''';
const String _noopDartPluginRegistryTemplate = '''
// Flutter web plugin registrant file.
//
// Generated file. Do not edit.
//
// ignore_for_file: type=lint
void
registerPlugins
(
)
{}
''';
const String _dartPluginRegistryTemplate = '''
const String _dartPluginRegistryTemplate = '''
// Flutter web plugin registrant file.
//
//
// Generated file. Do not edit.
// Generated file. Do not edit.
//
//
// ignore_for_file: directives_ordering
// ignore_for_file: type=lint
// ignore_for_file: lines_longer_than_80_chars
// ignore_for_file: depend_on_referenced_packages
{{
#methodChannelPlugins
}}
{{
#methodChannelPlugins
}}
import
'package:{{name}}/{{file}}'
;
import
'package:{{name}}/{{file}}'
;
{{/
methodChannelPlugins
}}
{{/
methodChannelPlugins
}}
import
'package:flutter_web_plugins/flutter_web_plugins.dart'
;
import
'package:flutter_web_plugins/flutter_web_plugins.dart'
;
// ignore: public_member_api_docs
void
registerPlugins
(
[
final
Registrar
?
pluginRegistrar
])
{
void
registerPlugins
(
final
Registrar
registrar
)
{
final
Registrar
registrar
=
pluginRegistrar
??
webPluginRegistrar
;
{{
#methodChannelPlugins
}}
{{
#methodChannelPlugins
}}
{{
class
}}.
registerWith
(
registrar
);
{{
class
}}.
registerWith
(
registrar
);
{{/
methodChannelPlugins
}}
{{/
methodChannelPlugins
}}
...
@@ -937,22 +946,22 @@ Future<void> _writeCppPluginRegistrant(Directory destination, Map<String, Object
...
@@ -937,22 +946,22 @@ Future<void> _writeCppPluginRegistrant(Directory destination, Map<String, Object
);
);
}
}
Future
<
void
>
_writeWebPluginRegistrant
(
FlutterProject
project
,
List
<
Plugin
>
plugins
)
async
{
Future
<
void
>
_writeWebPluginRegistrant
(
FlutterProject
project
,
List
<
Plugin
>
plugins
,
Directory
destination
)
async
{
final
List
<
Map
<
String
,
Object
?>>
webPlugins
=
_extractPlatformMaps
(
plugins
,
WebPlugin
.
kConfigKey
);
final
List
<
Map
<
String
,
Object
?>>
webPlugins
=
_extractPlatformMaps
(
plugins
,
WebPlugin
.
kConfigKey
);
final
Map
<
String
,
Object
>
context
=
<
String
,
Object
>{
final
Map
<
String
,
Object
>
context
=
<
String
,
Object
>{
'methodChannelPlugins'
:
webPlugins
,
'methodChannelPlugins'
:
webPlugins
,
};
};
final
File
pluginFile
=
project
.
web
.
libDirectory
.
childFile
(
'generated_plugin_registrant.dart'
);
if
(
webPlugins
.
isEmpty
)
{
final
File
pluginFile
=
destination
.
childFile
(
'web_plugin_registrant.dart'
);
ErrorHandlingFileSystem
.
deleteIfExists
(
pluginFile
);
}
else
{
final
String
template
=
webPlugins
.
isEmpty
?
_noopDartPluginRegistryTemplate
:
_dartPluginRegistryTemplate
;
_renderTemplateToFile
(
_dartPluginRegistryTemplate
,
_renderTemplateToFile
(
context
,
template
,
pluginFile
,
context
,
globals
.
templateRenderer
,
pluginFile
,
);
globals
.
templateRenderer
,
}
);
}
}
/// For each platform that uses them, creates symlinks within the platform
/// For each platform that uses them, creates symlinks within the platform
...
@@ -1068,8 +1077,41 @@ Future<void> refreshPluginsList(
...
@@ -1068,8 +1077,41 @@ Future<void> refreshPluginsList(
}
}
}
}
/// Injects plugins found in `pubspec.yaml` into the platform-specific projects
/// only at build-time.
///
/// This method is similar to [injectPlugins], but used only for platforms where
/// the plugin files are not required when the app is created (currently: Web).
///
/// This method will create files in the temporary flutter build directory
/// specified by `destination`.
///
/// In the Web platform, `destination` can point to a real filesystem (`flutter build`)
/// or an in-memory filesystem (`flutter run`).
Future
<
void
>
injectBuildTimePluginFiles
(
FlutterProject
project
,
{
required
Directory
destination
,
bool
webPlatform
=
false
,
})
async
{
final
List
<
Plugin
>
plugins
=
await
findPlugins
(
project
);
// Sort the plugins by name to keep ordering stable in generated files.
plugins
.
sort
((
Plugin
left
,
Plugin
right
)
=>
left
.
name
.
compareTo
(
right
.
name
));
if
(
webPlatform
)
{
await
_writeWebPluginRegistrant
(
project
,
plugins
,
destination
);
}
}
/// Injects plugins found in `pubspec.yaml` into the platform-specific projects.
/// Injects plugins found in `pubspec.yaml` into the platform-specific projects.
///
///
/// The injected files are required by the flutter app as soon as possible, so
/// it can be built.
///
/// Files written by this method end up in platform-specific locations that are
/// configured by each [FlutterProject] subclass (except for the Web).
///
/// Web tooling uses [injectBuildTimePluginFiles] instead, which places files in the
/// current build (temp) directory, and doesn't modify the users' working copy.
///
/// Assumes [refreshPluginsList] has been called since last change to `pubspec.yaml`.
/// Assumes [refreshPluginsList] has been called since last change to `pubspec.yaml`.
Future
<
void
>
injectPlugins
(
Future
<
void
>
injectPlugins
(
FlutterProject
project
,
{
FlutterProject
project
,
{
...
@@ -1078,7 +1120,6 @@ Future<void> injectPlugins(
...
@@ -1078,7 +1120,6 @@ Future<void> injectPlugins(
bool
linuxPlatform
=
false
,
bool
linuxPlatform
=
false
,
bool
macOSPlatform
=
false
,
bool
macOSPlatform
=
false
,
bool
windowsPlatform
=
false
,
bool
windowsPlatform
=
false
,
bool
webPlatform
=
false
,
})
async
{
})
async
{
final
List
<
Plugin
>
plugins
=
await
findPlugins
(
project
);
final
List
<
Plugin
>
plugins
=
await
findPlugins
(
project
);
// Sort the plugins by name to keep ordering stable in generated files.
// Sort the plugins by name to keep ordering stable in generated files.
...
@@ -1114,9 +1155,6 @@ Future<void> injectPlugins(
...
@@ -1114,9 +1155,6 @@ Future<void> injectPlugins(
}
}
}
}
}
}
if
(
webPlatform
)
{
await
_writeWebPluginRegistrant
(
project
,
plugins
);
}
}
}
/// Returns whether the specified Flutter [project] has any plugin dependencies.
/// Returns whether the specified Flutter [project] has any plugin dependencies.
...
...
packages/flutter_tools/lib/src/isolated/devfs_web.dart
View file @
1af8cc11
...
@@ -41,7 +41,7 @@ import '../vmservice.dart';
...
@@ -41,7 +41,7 @@ import '../vmservice.dart';
import
'../web/bootstrap.dart'
;
import
'../web/bootstrap.dart'
;
import
'../web/chrome.dart'
;
import
'../web/chrome.dart'
;
import
'../web/compile.dart'
;
import
'../web/compile.dart'
;
import
'../web/flutter_js.dart'
as
flutter_js
;
import
'../web/f
ile_generators/f
lutter_js.dart'
as
flutter_js
;
import
'../web/memory_fs.dart'
;
import
'../web/memory_fs.dart'
;
import
'sdk_web_configuration.dart'
;
import
'sdk_web_configuration.dart'
;
...
...
packages/flutter_tools/lib/src/isolated/resident_web_runner.dart
View file @
1af8cc11
...
@@ -30,8 +30,6 @@ import '../dart/language_version.dart';
...
@@ -30,8 +30,6 @@ import '../dart/language_version.dart';
import
'../devfs.dart'
;
import
'../devfs.dart'
;
import
'../device.dart'
;
import
'../device.dart'
;
import
'../flutter_plugins.dart'
;
import
'../flutter_plugins.dart'
;
import
'../platform_plugins.dart'
;
import
'../plugins.dart'
;
import
'../project.dart'
;
import
'../project.dart'
;
import
'../reporting/reporting.dart'
;
import
'../reporting/reporting.dart'
;
import
'../resident_devtools_handler.dart'
;
import
'../resident_devtools_handler.dart'
;
...
@@ -40,6 +38,7 @@ import '../run_hot.dart';
...
@@ -40,6 +38,7 @@ import '../run_hot.dart';
import
'../vmservice.dart'
;
import
'../vmservice.dart'
;
import
'../web/chrome.dart'
;
import
'../web/chrome.dart'
;
import
'../web/compile.dart'
;
import
'../web/compile.dart'
;
import
'../web/file_generators/main_dart.dart'
as
main_dart
;
import
'../web/web_device.dart'
;
import
'../web/web_device.dart'
;
import
'../web/web_runner.dart'
;
import
'../web/web_runner.dart'
;
import
'devfs_web.dart'
;
import
'devfs_web.dart'
;
...
@@ -433,15 +432,12 @@ class ResidentWebRunner extends ResidentRunner {
...
@@ -433,15 +432,12 @@ class ResidentWebRunner extends ResidentRunner {
..
createSync
();
..
createSync
();
result
=
_generatedEntrypointDirectory
.
childFile
(
'web_entrypoint.dart'
);
result
=
_generatedEntrypointDirectory
.
childFile
(
'web_entrypoint.dart'
);
final
bool
hasWebPlugins
=
(
await
findPlugins
(
flutterProject
))
// Generates the generated_plugin_registrar
.
any
((
Plugin
p
)
=>
p
.
platforms
.
containsKey
(
WebPlugin
.
kConfigKey
));
await
injectBuildTimePluginFiles
(
flutterProject
,
webPlatform:
true
,
destination:
_generatedEntrypointDirectory
);
await
injectPlugins
(
flutterProject
,
webPlatform:
true
);
// The below works because `injectBuildTimePluginFiles` is configured to write
// the web_plugin_registrant.dart file alongside the generated main.dart
const
String
/*?*/
generatedImport
=
'web_plugin_registrant.dart'
;
final
Uri
generatedUri
=
_fileSystem
.
currentDirectory
.
childDirectory
(
'lib'
)
.
childFile
(
'generated_plugin_registrant.dart'
)
.
absolute
.
uri
;
final
Uri
generatedImport
=
packageConfig
.
toPackageUri
(
generatedUri
);
Uri
importedEntrypoint
=
packageConfig
.
toPackageUri
(
mainUri
);
Uri
importedEntrypoint
=
packageConfig
.
toPackageUri
(
mainUri
);
// Special handling for entrypoints that are not under lib, such as test scripts.
// Special handling for entrypoints that are not under lib, such as test scripts.
if
(
importedEntrypoint
==
null
)
{
if
(
importedEntrypoint
==
null
)
{
...
@@ -453,44 +449,17 @@ class ResidentWebRunner extends ResidentRunner {
...
@@ -453,44 +449,17 @@ class ResidentWebRunner extends ResidentRunner {
path:
'/
${mainUri.pathSegments.last}
'
,
path:
'/
${mainUri.pathSegments.last}
'
,
);
);
}
}
final
LanguageVersion
languageVersion
=
determineLanguageVersion
(
final
LanguageVersion
languageVersion
=
determineLanguageVersion
(
_fileSystem
.
file
(
mainUri
),
_fileSystem
.
file
(
mainUri
),
packageConfig
[
flutterProject
.
manifest
.
appName
],
packageConfig
[
flutterProject
.
manifest
.
appName
],
Cache
.
flutterRoot
,
Cache
.
flutterRoot
,
);
);
final
String
entrypoint
=
<
String
>[
final
String
entrypoint
=
main_dart
.
generateMainDartFile
(
importedEntrypoint
.
toString
(),
'// @dart=
${languageVersion.major}
.
${languageVersion.minor}
'
,
languageVersion:
languageVersion
,
'// Flutter web bootstrap script for
$importedEntrypoint
.'
,
pluginRegistrantEntrypoint:
generatedImport
,
''
,
);
"import 'dart:ui' as ui;"
,
"import 'dart:async';"
,
''
,
"import '
$importedEntrypoint
' as entrypoint;"
,
if
(
hasWebPlugins
)
"import 'package:flutter_web_plugins/flutter_web_plugins.dart';"
,
if
(
hasWebPlugins
)
"import '
$generatedImport
';"
,
''
,
'typedef _UnaryFunction = dynamic Function(List<String> args);'
,
'typedef _NullaryFunction = dynamic Function();'
,
'Future<void> main() async {'
,
' await ui.webOnlyWarmupEngine('
,
' runApp: () {'
,
' if (entrypoint.main is _UnaryFunction) {'
,
' return (entrypoint.main as _UnaryFunction)(<String>[]);'
,
' }'
,
' return (entrypoint.main as _NullaryFunction)();'
,
' },'
,
if
(
hasWebPlugins
)
...<
String
>[
' registerPlugins: () {'
,
' registerPlugins(webPluginRegistrar);'
,
' },'
,
],
' );'
,
'}'
,
''
,
].
join
(
'
\n
'
);
result
.
writeAsStringSync
(
entrypoint
);
result
.
writeAsStringSync
(
entrypoint
);
}
}
return
result
.
absolute
.
uri
;
return
result
.
absolute
.
uri
;
...
...
packages/flutter_tools/lib/src/project.dart
View file @
1af8cc11
...
@@ -373,7 +373,6 @@ class FlutterProject {
...
@@ -373,7 +373,6 @@ class FlutterProject {
linuxPlatform:
linuxPlatform
,
linuxPlatform:
linuxPlatform
,
macOSPlatform:
macOSPlatform
,
macOSPlatform:
macOSPlatform
,
windowsPlatform:
windowsPlatform
,
windowsPlatform:
windowsPlatform
,
webPlatform:
webPlatform
,
);
);
}
}
...
...
packages/flutter_tools/lib/src/web/compile.dart
View file @
1af8cc11
...
@@ -6,6 +6,7 @@ import '../artifacts.dart';
...
@@ -6,6 +6,7 @@ import '../artifacts.dart';
import
'../base/common.dart'
;
import
'../base/common.dart'
;
import
'../base/file_system.dart'
;
import
'../base/file_system.dart'
;
import
'../base/logger.dart'
;
import
'../base/logger.dart'
;
import
'../base/project_migrator.dart'
;
import
'../build_info.dart'
;
import
'../build_info.dart'
;
import
'../build_system/build_system.dart'
;
import
'../build_system/build_system.dart'
;
import
'../build_system/targets/web.dart'
;
import
'../build_system/targets/web.dart'
;
...
@@ -15,6 +16,7 @@ import '../globals.dart' as globals;
...
@@ -15,6 +16,7 @@ import '../globals.dart' as globals;
import
'../platform_plugins.dart'
;
import
'../platform_plugins.dart'
;
import
'../plugins.dart'
;
import
'../plugins.dart'
;
import
'../project.dart'
;
import
'../project.dart'
;
import
'migrations/scrub_generated_plugin_registrant.dart'
;
Future
<
void
>
buildWeb
(
Future
<
void
>
buildWeb
(
FlutterProject
flutterProject
,
FlutterProject
flutterProject
,
...
@@ -32,7 +34,16 @@ Future<void> buildWeb(
...
@@ -32,7 +34,16 @@ Future<void> buildWeb(
final
Directory
outputDirectory
=
globals
.
fs
.
directory
(
getWebBuildDirectory
());
final
Directory
outputDirectory
=
globals
.
fs
.
directory
(
getWebBuildDirectory
());
outputDirectory
.
createSync
(
recursive:
true
);
outputDirectory
.
createSync
(
recursive:
true
);
await
injectPlugins
(
flutterProject
,
webPlatform:
true
);
// The migrators to apply to a Web project.
final
List
<
ProjectMigrator
>
migrators
=
<
ProjectMigrator
>[
ScrubGeneratedPluginRegistrant
(
flutterProject
.
web
,
globals
.
logger
),
];
final
ProjectMigration
migration
=
ProjectMigration
(
migrators
);
if
(!
migration
.
run
())
{
throwToolExit
(
'Failed to run all web migrations.'
);
}
final
Status
status
=
globals
.
logger
.
startProgress
(
'Compiling
$target
for the Web...'
);
final
Status
status
=
globals
.
logger
.
startProgress
(
'Compiling
$target
for the Web...'
);
final
Stopwatch
sw
=
Stopwatch
()..
start
();
final
Stopwatch
sw
=
Stopwatch
()..
start
();
try
{
try
{
...
...
packages/flutter_tools/lib/src/web/flutter_js.dart
→
packages/flutter_tools/lib/src/web/f
ile_generators/f
lutter_js.dart
View file @
1af8cc11
File moved
packages/flutter_tools/lib/src/web/file_generators/flutter_service_worker_js.dart
0 → 100644
View file @
1af8cc11
// 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.
/// The caching strategy for the generated service worker.
enum
ServiceWorkerStrategy
{
/// Download the app shell eagerly and all other assets lazily.
/// Prefer the offline cached version.
offlineFirst
,
/// Do not generate a service worker,
none
,
}
/// Generate a service worker with an app-specific cache name a map of
/// resource files.
///
/// The tool embeds file hashes directly into the worker so that the byte for byte
/// invalidation will automatically reactivate workers whenever a new
/// version is deployed.
String
generateServiceWorker
(
Map
<
String
,
String
>
resources
,
List
<
String
>
coreBundle
,
{
required
ServiceWorkerStrategy
serviceWorkerStrategy
,
})
{
if
(
serviceWorkerStrategy
==
ServiceWorkerStrategy
.
none
)
{
return
''
;
}
return
'''
'
use
strict
';
const MANIFEST = '
flutter
-
app
-
manifest
';
const TEMP = '
flutter
-
temp
-
cache
';
const CACHE_NAME = '
flutter
-
app
-
cache
';
const RESOURCES = {
${resources.entries.map((MapEntry<String, String> entry) => '"${entry.key}
": "
${entry.value}
"'
).
join
(
",
\n
"
)}
};
// The application shell files that are downloaded before a service worker can
// start.
const
CORE
=
[
$
{
coreBundle
.
map
((
String
file
)
=>
'"
$file
"'
).
join
(
',
\n
'
)}];
// During install, the TEMP cache is populated with the application shell files.
self
.
addEventListener
(
"install"
,
(
event
)
=>
{
self
.
skipWaiting
();
return
event
.
waitUntil
(
caches
.
open
(
TEMP
).
then
((
cache
)
=>
{
return
cache
.
addAll
(
CORE
.
map
((
value
)
=>
new
Request
(
value
,
{
'cache'
:
'reload'
})));
})
);
});
// During activate, the cache is populated with the temp files downloaded in
// install. If this service worker is upgrading from one with a saved
// MANIFEST, then use this to retain unchanged resource files.
self
.
addEventListener
(
"activate"
,
function
(
event
)
{
return
event
.
waitUntil
(
async
function
()
{
try
{
var
contentCache
=
await
caches
.
open
(
CACHE_NAME
);
var
tempCache
=
await
caches
.
open
(
TEMP
);
var
manifestCache
=
await
caches
.
open
(
MANIFEST
);
var
manifest
=
await
manifestCache
.
match
(
'manifest'
);
// When there is no prior manifest, clear the entire cache.
if
(!
manifest
)
{
await
caches
.
delete
(
CACHE_NAME
);
contentCache
=
await
caches
.
open
(
CACHE_NAME
);
for
(
var
request
of
await
tempCache
.
keys
())
{
var
response
=
await
tempCache
.
match
(
request
);
await
contentCache
.
put
(
request
,
response
);
}
await
caches
.
delete
(
TEMP
);
// Save the manifest to make future upgrades efficient.
await
manifestCache
.
put
(
'manifest'
,
new
Response
(
JSON
.
stringify
(
RESOURCES
)));
return
;
}
var
oldManifest
=
await
manifest
.
json
();
var
origin
=
self
.
location
.
origin
;
for
(
var
request
of
await
contentCache
.
keys
())
{
var
key
=
request
.
url
.
substring
(
origin
.
length
+
1
);
if
(
key
==
""
)
{
key
=
"/"
;
}
// If a resource from the old manifest is not in the new cache, or if
// the MD5 sum has changed, delete it. Otherwise the resource is left
// in the cache and can be reused by the new service worker.
if
(!
RESOURCES
[
key
]
||
RESOURCES
[
key
]
!=
oldManifest
[
key
])
{
await
contentCache
.
delete
(
request
);
}
}
// Populate the cache with the app shell TEMP files, potentially overwriting
// cache files preserved above.
for
(
var
request
of
await
tempCache
.
keys
())
{
var
response
=
await
tempCache
.
match
(
request
);
await
contentCache
.
put
(
request
,
response
);
}
await
caches
.
delete
(
TEMP
);
// Save the manifest to make future upgrades efficient.
await
manifestCache
.
put
(
'manifest'
,
new
Response
(
JSON
.
stringify
(
RESOURCES
)));
return
;
}
catch
(
err
)
{
// On an unhandled exception the state of the cache cannot be guaranteed.
console
.
error
(
'Failed to upgrade service worker: '
+
err
);
await
caches
.
delete
(
CACHE_NAME
);
await
caches
.
delete
(
TEMP
);
await
caches
.
delete
(
MANIFEST
);
}
}());
});
// The fetch handler redirects requests for RESOURCE files to the service
// worker cache.
self
.
addEventListener
(
"fetch"
,
(
event
)
=>
{
if
(
event
.
request
.
method
!==
'GET'
)
{
return
;
}
var
origin
=
self
.
location
.
origin
;
var
key
=
event
.
request
.
url
.
substring
(
origin
.
length
+
1
);
// Redirect URLs to the index.html
if
(
key
.
indexOf
(
'?v='
)
!=
-
1
)
{
key
=
key
.
split
(
'?v='
)[
0
];
}
if
(
event
.
request
.
url
==
origin
||
event
.
request
.
url
.
startsWith
(
origin
+
'/#'
)
||
key
==
''
)
{
key
=
'/'
;
}
// If the URL is not the RESOURCE list then return to signal that the
// browser should take over.
if
(!
RESOURCES
[
key
])
{
return
;
}
// If the URL is the index.html, perform an online-first request.
if
(
key
==
'/'
)
{
return
onlineFirst
(
event
);
}
event
.
respondWith
(
caches
.
open
(
CACHE_NAME
)
.
then
((
cache
)
=>
{
return
cache
.
match
(
event
.
request
).
then
((
response
)
=>
{
// Either respond with the cached resource, or perform a fetch and
// lazily populate the cache.
return
response
||
fetch
(
event
.
request
).
then
((
response
)
=>
{
cache
.
put
(
event
.
request
,
response
.
clone
());
return
response
;
});
})
})
);
});
self
.
addEventListener
(
'message'
,
(
event
)
=>
{
// SkipWaiting can be used to immediately activate a waiting service worker.
// This will also require a page refresh triggered by the main worker.
if
(
event
.
data
===
'skipWaiting'
)
{
self
.
skipWaiting
();
return
;
}
if
(
event
.
data
===
'downloadOffline'
)
{
downloadOffline
();
return
;
}
});
// Download offline will check the RESOURCES for all files not in the cache
// and populate them.
async
function
downloadOffline
(
)
{
var
resources
=
[];
var
contentCache
=
await
caches
.
open
(
CACHE_NAME
);
var
currentContent
=
{};
for
(
var
request
of
await
contentCache
.
keys
())
{
var
key
=
request
.
url
.
substring
(
origin
.
length
+
1
);
if
(
key
==
""
)
{
key
=
"/"
;
}
currentContent
[
key
]
=
true
;
}
for
(
var
resourceKey
of
Object
.
keys
(
RESOURCES
))
{
if
(!
currentContent
[
resourceKey
])
{
resources
.
push
(
resourceKey
);
}
}
return
contentCache
.
addAll
(
resources
);
}
// Attempt to download the resource online before falling back to
// the offline cache.
function
onlineFirst
(
event
)
{
return
event
.
respondWith
(
fetch
(
event
.
request
).
then
((
response
)
=>
{
return
caches
.
open
(
CACHE_NAME
).
then
((
cache
)
=>
{
cache
.
put
(
event
.
request
,
response
.
clone
());
return
response
;
});
}).
catch
((
error
)
=>
{
return
caches
.
open
(
CACHE_NAME
).
then
((
cache
)
=>
{
return
cache
.
match
(
event
.
request
).
then
((
response
)
=>
{
if
(
response
!=
null
)
{
return
response
;
}
throw
error
;
});
});
})
);
}
''';
}
packages/flutter_tools/lib/src/web/file_generators/main_dart.dart
0 → 100644
View file @
1af8cc11
// 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:package_config/package_config.dart'
;
/// Generates the main.dart file.
String
generateMainDartFile
(
String
appEntrypoint
,
{
required
String
pluginRegistrantEntrypoint
,
LanguageVersion
?
languageVersion
,
})
{
return
<
String
>[
if
(
languageVersion
!=
null
)
'// @dart=
${languageVersion.major}
.
${languageVersion.minor}
'
,
'// Flutter web bootstrap script for
$appEntrypoint
.'
,
'//'
,
'// Generated file. Do not edit.'
,
'//'
,
''
,
'// ignore_for_file: type=lint'
,
''
,
"import 'dart:ui' as ui;"
,
"import 'dart:async';"
,
''
,
"import '
$appEntrypoint
' as entrypoint;"
,
"import '
$pluginRegistrantEntrypoint
' as pluginRegistrant;"
,
''
,
'typedef _UnaryFunction = dynamic Function(List<String> args);'
,
'typedef _NullaryFunction = dynamic Function();'
,
''
,
'Future<void> main() async {'
,
' await ui.webOnlyWarmupEngine('
,
' runApp: () {'
,
' if (entrypoint.main is _UnaryFunction) {'
,
' return (entrypoint.main as _UnaryFunction)(<String>[]);'
,
' }'
,
' return (entrypoint.main as _NullaryFunction)();'
,
' },'
,
' registerPlugins: () {'
,
' pluginRegistrant.registerPlugins();'
,
' },'
,
' );'
,
'}'
,
''
,
].
join
(
'
\n
'
);
}
packages/flutter_tools/lib/src/web/migrations/scrub_generated_plugin_registrant.dart
0 → 100644
View file @
1af8cc11
// 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
'../../base/file_system.dart'
;
import
'../../base/logger.dart'
;
import
'../../base/project_migrator.dart'
;
import
'../../project.dart'
;
/// Remove lib/generated_plugin_registrant.dart if it exists.
class
ScrubGeneratedPluginRegistrant
extends
ProjectMigrator
{
ScrubGeneratedPluginRegistrant
(
WebProject
project
,
super
.
logger
,
)
:
_project
=
project
,
_logger
=
logger
;
final
WebProject
_project
;
final
Logger
_logger
;
@override
bool
migrate
()
{
final
File
registrant
=
_project
.
libDirectory
.
childFile
(
'generated_plugin_registrant.dart'
);
final
File
gitignore
=
_project
.
parent
.
directory
.
childFile
(
'.gitignore'
);
if
(!
removeFile
(
registrant
))
{
return
false
;
}
if
(
gitignore
.
existsSync
())
{
processFileLines
(
gitignore
);
}
return
true
;
}
// Cleans up the .gitignore by removing the line that mentions generated_plugin_registrant.
@override
String
?
migrateLine
(
String
line
)
{
return
line
.
contains
(
'lib/generated_plugin_registrant.dart'
)
?
null
:
line
;
}
bool
removeFile
(
File
file
)
{
if
(!
file
.
existsSync
())
{
_logger
.
printTrace
(
'
${file.basename}
not found. Skipping.'
);
return
true
;
}
try
{
file
.
deleteSync
();
_logger
.
printStatus
(
'
${file.basename}
found. Deleted.'
);
return
true
;
}
on
FileSystemException
catch
(
e
,
s
)
{
_logger
.
printError
(
e
.
message
,
stackTrace:
s
);
}
return
false
;
}
}
packages/flutter_tools/templates/app_shared/.gitignore.tmpl
View file @
1af8cc11
...
@@ -32,9 +32,6 @@ migrate_working_dir/
...
@@ -32,9 +32,6 @@ migrate_working_dir/
.pub/
.pub/
/build/
/build/
# Web related
lib/generated_plugin_registrant.dart
# Symbolication related
# Symbolication related
app.*.symbols
app.*.symbols
...
...
packages/flutter_tools/test/commands.shard/hermetic/build_web_test.dart
View file @
1af8cc11
...
@@ -92,7 +92,9 @@ void main() {
...
@@ -92,7 +92,9 @@ void main() {
setupFileSystemForEndToEndTest
(
fileSystem
);
setupFileSystemForEndToEndTest
(
fileSystem
);
await
runner
.
run
(<
String
>[
'build'
,
'web'
,
'--no-pub'
,
'--dart-define=foo=a'
,
'--dart2js-optimization=O3'
]);
await
runner
.
run
(<
String
>[
'build'
,
'web'
,
'--no-pub'
,
'--dart-define=foo=a'
,
'--dart2js-optimization=O3'
]);
expect
(
fileSystem
.
file
(
fileSystem
.
path
.
join
(
'lib'
,
'generated_plugin_registrant.dart'
)).
existsSync
(),
true
);
final
Directory
buildDir
=
fileSystem
.
directory
(
fileSystem
.
path
.
join
(
'build'
,
'web'
));
expect
(
buildDir
.
existsSync
(),
true
);
},
overrides:
<
Type
,
Generator
>{
},
overrides:
<
Type
,
Generator
>{
Platform:
()
=>
fakePlatform
,
Platform:
()
=>
fakePlatform
,
FileSystem:
()
=>
fileSystem
,
FileSystem:
()
=>
fileSystem
,
...
...
packages/flutter_tools/test/general.shard/build_system/targets/web_test.dart
View file @
1af8cc11
...
@@ -8,12 +8,15 @@ import 'package:file_testing/file_testing.dart';
...
@@ -8,12 +8,15 @@ import 'package:file_testing/file_testing.dart';
import
'package:flutter_tools/src/artifacts.dart'
;
import
'package:flutter_tools/src/artifacts.dart'
;
import
'package:flutter_tools/src/base/file_system.dart'
;
import
'package:flutter_tools/src/base/file_system.dart'
;
import
'package:flutter_tools/src/base/platform.dart'
;
import
'package:flutter_tools/src/base/platform.dart'
;
import
'package:flutter_tools/src/base/template.dart'
;
import
'package:flutter_tools/src/build_info.dart'
;
import
'package:flutter_tools/src/build_info.dart'
;
import
'package:flutter_tools/src/build_system/build_system.dart'
;
import
'package:flutter_tools/src/build_system/build_system.dart'
;
import
'package:flutter_tools/src/build_system/depfile.dart'
;
import
'package:flutter_tools/src/build_system/depfile.dart'
;
import
'package:flutter_tools/src/build_system/targets/web.dart'
;
import
'package:flutter_tools/src/build_system/targets/web.dart'
;
import
'package:flutter_tools/src/globals.dart'
as
globals
;
import
'package:flutter_tools/src/globals.dart'
as
globals
;
import
'package:flutter_tools/src/web/flutter_js.dart'
as
flutter_js
;
import
'package:flutter_tools/src/isolated/mustache_template.dart'
;
import
'package:flutter_tools/src/web/file_generators/flutter_js.dart'
as
flutter_js
;
import
'package:flutter_tools/src/web/file_generators/flutter_service_worker_js.dart'
;
import
'../../../src/common.dart'
;
import
'../../../src/common.dart'
;
import
'../../../src/fake_process_manager.dart'
;
import
'../../../src/fake_process_manager.dart'
;
...
@@ -80,8 +83,8 @@ void main() {
...
@@ -80,8 +83,8 @@ void main() {
final
String
generated
=
environment
.
buildDir
.
childFile
(
'main.dart'
).
readAsStringSync
();
final
String
generated
=
environment
.
buildDir
.
childFile
(
'main.dart'
).
readAsStringSync
();
// Plugins
// Plugins
expect
(
generated
,
contains
(
"import '
package:foo/generated_plugin_registrant.dart'
;"
));
expect
(
generated
,
contains
(
"import '
web_plugin_registrant.dart' as pluginRegistrant
;"
));
expect
(
generated
,
contains
(
'
registerPlugins(webPluginRegistrar
);'
));
expect
(
generated
,
contains
(
'
pluginRegistrant.registerPlugins(
);'
));
// Import.
// Import.
expect
(
generated
,
contains
(
"import 'package:foo/main.dart' as entrypoint;"
));
expect
(
generated
,
contains
(
"import 'package:foo/main.dart' as entrypoint;"
));
...
@@ -89,6 +92,8 @@ void main() {
...
@@ -89,6 +92,8 @@ void main() {
// Main
// Main
expect
(
generated
,
contains
(
'ui.webOnlyWarmupEngine('
));
expect
(
generated
,
contains
(
'ui.webOnlyWarmupEngine('
));
expect
(
generated
,
contains
(
'entrypoint.main as _'
));
expect
(
generated
,
contains
(
'entrypoint.main as _'
));
},
overrides:
<
Type
,
Generator
>{
TemplateRenderer:
()
=>
const
MustacheTemplateRenderer
(),
}));
}));
test
(
'version.json is created after release build'
,
()
=>
testbed
.
run
(()
async
{
test
(
'version.json is created after release build'
,
()
=>
testbed
.
run
(()
async
{
...
@@ -196,6 +201,8 @@ void main() {
...
@@ -196,6 +201,8 @@ void main() {
// Import.
// Import.
expect
(
generated
,
contains
(
"import 'file:///other/lib/main.dart' as entrypoint;"
));
expect
(
generated
,
contains
(
"import 'file:///other/lib/main.dart' as entrypoint;"
));
},
overrides:
<
Type
,
Generator
>{
TemplateRenderer:
()
=>
const
MustacheTemplateRenderer
(),
}));
}));
test
(
'WebEntrypointTarget generates a plugin registrant for a file outside of main'
,
()
=>
testbed
.
run
(()
async
{
test
(
'WebEntrypointTarget generates a plugin registrant for a file outside of main'
,
()
=>
testbed
.
run
(()
async
{
...
@@ -210,7 +217,9 @@ void main() {
...
@@ -210,7 +217,9 @@ void main() {
// Import.
// Import.
expect
(
generated
,
contains
(
"import 'file:///other/lib/main.dart' as entrypoint;"
));
expect
(
generated
,
contains
(
"import 'file:///other/lib/main.dart' as entrypoint;"
));
expect
(
generated
,
contains
(
"import 'package:foo/generated_plugin_registrant.dart';"
));
expect
(
generated
,
contains
(
"import 'web_plugin_registrant.dart' as pluginRegistrant;"
));
},
overrides:
<
Type
,
Generator
>{
TemplateRenderer:
()
=>
const
MustacheTemplateRenderer
(),
}));
}));
...
@@ -226,8 +235,8 @@ void main() {
...
@@ -226,8 +235,8 @@ void main() {
final
String
generated
=
environment
.
buildDir
.
childFile
(
'main.dart'
).
readAsStringSync
();
final
String
generated
=
environment
.
buildDir
.
childFile
(
'main.dart'
).
readAsStringSync
();
// Plugins
// Plugins
expect
(
generated
,
contains
(
"import '
package:foo/generated_plugin_registrant.dart'
;"
));
expect
(
generated
,
contains
(
"import '
web_plugin_registrant.dart' as pluginRegistrant
;"
));
expect
(
generated
,
contains
(
'
registerPlugins(webPluginRegistrar
);'
));
expect
(
generated
,
contains
(
'
pluginRegistrant.registerPlugins(
);'
));
// Import.
// Import.
expect
(
generated
,
contains
(
"import 'package:foo/main.dart' as entrypoint;"
));
expect
(
generated
,
contains
(
"import 'package:foo/main.dart' as entrypoint;"
));
...
@@ -237,6 +246,7 @@ void main() {
...
@@ -237,6 +246,7 @@ void main() {
expect
(
generated
,
contains
(
'entrypoint.main as _'
));
expect
(
generated
,
contains
(
'entrypoint.main as _'
));
},
overrides:
<
Type
,
Generator
>{
},
overrides:
<
Type
,
Generator
>{
Platform:
()
=>
windows
,
Platform:
()
=>
windows
,
TemplateRenderer:
()
=>
const
MustacheTemplateRenderer
(),
}));
}));
test
(
'WebEntrypointTarget generates an entrypoint without plugins and init platform'
,
()
=>
testbed
.
run
(()
async
{
test
(
'WebEntrypointTarget generates an entrypoint without plugins and init platform'
,
()
=>
testbed
.
run
(()
async
{
...
@@ -249,9 +259,9 @@ void main() {
...
@@ -249,9 +259,9 @@ void main() {
final
String
generated
=
environment
.
buildDir
.
childFile
(
'main.dart'
).
readAsStringSync
();
final
String
generated
=
environment
.
buildDir
.
childFile
(
'main.dart'
).
readAsStringSync
();
// Plugins
// Plugins
(the generated file is a noop)
expect
(
generated
,
isNot
(
contains
(
"import 'package:foo/generated_plugin_registrant.dart';"
)
));
expect
(
generated
,
contains
(
"import 'web_plugin_registrant.dart' as pluginRegistrant;"
));
expect
(
generated
,
isNot
(
contains
(
'registerPlugins(webPluginRegistrar);'
)
));
expect
(
generated
,
contains
(
'pluginRegistrant.registerPlugins();'
));
// Import.
// Import.
expect
(
generated
,
contains
(
"import 'package:foo/main.dart' as entrypoint;"
));
expect
(
generated
,
contains
(
"import 'package:foo/main.dart' as entrypoint;"
));
...
@@ -259,7 +269,8 @@ void main() {
...
@@ -259,7 +269,8 @@ void main() {
// Main
// Main
expect
(
generated
,
contains
(
'ui.webOnlyWarmupEngine('
));
expect
(
generated
,
contains
(
'ui.webOnlyWarmupEngine('
));
expect
(
generated
,
contains
(
'entrypoint.main as _'
));
expect
(
generated
,
contains
(
'entrypoint.main as _'
));
},
overrides:
<
Type
,
Generator
>{
TemplateRenderer:
()
=>
const
MustacheTemplateRenderer
(),
}));
}));
test
(
'WebEntrypointTarget generates an entrypoint with a language version'
,
()
=>
testbed
.
run
(()
async
{
test
(
'WebEntrypointTarget generates an entrypoint with a language version'
,
()
=>
testbed
.
run
(()
async
{
...
@@ -273,6 +284,8 @@ void main() {
...
@@ -273,6 +284,8 @@ void main() {
// Language version
// Language version
expect
(
generated
,
contains
(
'// @dart=2.8'
));
expect
(
generated
,
contains
(
'// @dart=2.8'
));
},
overrides:
<
Type
,
Generator
>{
TemplateRenderer:
()
=>
const
MustacheTemplateRenderer
(),
}));
}));
test
(
'WebEntrypointTarget generates an entrypoint with a language version from a package config'
,
()
=>
testbed
.
run
(()
async
{
test
(
'WebEntrypointTarget generates an entrypoint with a language version from a package config'
,
()
=>
testbed
.
run
(()
async
{
...
@@ -288,6 +301,8 @@ void main() {
...
@@ -288,6 +301,8 @@ void main() {
// Language version
// Language version
expect
(
generated
,
contains
(
'// @dart=2.7'
));
expect
(
generated
,
contains
(
'// @dart=2.7'
));
},
overrides:
<
Type
,
Generator
>{
TemplateRenderer:
()
=>
const
MustacheTemplateRenderer
(),
}));
}));
test
(
'WebEntrypointTarget generates an entrypoint without plugins and without init platform'
,
()
=>
testbed
.
run
(()
async
{
test
(
'WebEntrypointTarget generates an entrypoint without plugins and without init platform'
,
()
=>
testbed
.
run
(()
async
{
...
@@ -301,8 +316,8 @@ void main() {
...
@@ -301,8 +316,8 @@ void main() {
final
String
generated
=
environment
.
buildDir
.
childFile
(
'main.dart'
).
readAsStringSync
();
final
String
generated
=
environment
.
buildDir
.
childFile
(
'main.dart'
).
readAsStringSync
();
// Plugins
// Plugins
expect
(
generated
,
isNot
(
contains
(
"import 'package:foo/generated_plugin_registrant.dart';"
)
));
expect
(
generated
,
contains
(
"import 'web_plugin_registrant.dart' as pluginRegistrant;"
));
expect
(
generated
,
isNot
(
contains
(
'registerPlugins(webPluginRegistrar);'
)
));
expect
(
generated
,
contains
(
'pluginRegistrant.registerPlugins();'
));
// Import.
// Import.
expect
(
generated
,
contains
(
"import 'package:foo/main.dart' as entrypoint;"
));
expect
(
generated
,
contains
(
"import 'package:foo/main.dart' as entrypoint;"
));
...
@@ -310,6 +325,8 @@ void main() {
...
@@ -310,6 +325,8 @@ void main() {
// Main
// Main
expect
(
generated
,
contains
(
'ui.webOnlyWarmupEngine('
));
expect
(
generated
,
contains
(
'ui.webOnlyWarmupEngine('
));
expect
(
generated
,
contains
(
'entrypoint.main as _'
));
expect
(
generated
,
contains
(
'entrypoint.main as _'
));
},
overrides:
<
Type
,
Generator
>{
TemplateRenderer:
()
=>
const
MustacheTemplateRenderer
(),
}));
}));
test
(
'Dart2JSTarget calls dart2js with expected args with csp'
,
()
=>
testbed
.
run
(()
async
{
test
(
'Dart2JSTarget calls dart2js with expected args with csp'
,
()
=>
testbed
.
run
(()
async
{
...
@@ -676,9 +693,9 @@ void main() {
...
@@ -676,9 +693,9 @@ void main() {
// Depends on resource file.
// Depends on resource file.
expect
(
environment
.
buildDir
.
childFile
(
'service_worker.d'
).
readAsStringSync
(),
expect
(
environment
.
buildDir
.
childFile
(
'service_worker.d'
).
readAsStringSync
(),
contains
(
'a/a.txt'
));
contains
(
'a/a.txt'
));
//
Contains
NOTICES
//
Does NOT contain
NOTICES
expect
(
environment
.
outputDir
.
childFile
(
'flutter_service_worker.js'
).
readAsStringSync
(),
expect
(
environment
.
outputDir
.
childFile
(
'flutter_service_worker.js'
).
readAsStringSync
(),
contains
(
'NOTICES'
));
isNot
(
contains
(
'NOTICES'
)
));
}));
}));
test
(
'WebServiceWorker contains baseUrl cache'
,
()
=>
testbed
.
run
(()
async
{
test
(
'WebServiceWorker contains baseUrl cache'
,
()
=>
testbed
.
run
(()
async
{
...
...
packages/flutter_tools/test/general.shard/plugins_test.dart
View file @
1af8cc11
...
@@ -1079,11 +1079,12 @@ dependencies:
...
@@ -1079,11 +1079,12 @@ dependencies:
web_plugin_with_nested:
${webPluginWithNestedFile.childDirectory('lib').uri}
web_plugin_with_nested:
${webPluginWithNestedFile.childDirectory('lib').uri}
'''
);
'''
);
await
injectPlugins
(
flutterProject
,
webPlatform:
true
);
final
Directory
destination
=
flutterProject
.
directory
.
childDirectory
(
'lib'
);
await
injectBuildTimePluginFiles
(
flutterProject
,
webPlatform:
true
,
destination:
destination
);
final
File
registrant
=
flutterProject
.
directory
final
File
registrant
=
flutterProject
.
directory
.
childDirectory
(
'lib'
)
.
childDirectory
(
'lib'
)
.
childFile
(
'
generated
_plugin_registrant.dart'
);
.
childFile
(
'
web
_plugin_registrant.dart'
);
expect
(
registrant
.
existsSync
(),
isTrue
);
expect
(
registrant
.
existsSync
(),
isTrue
);
expect
(
registrant
.
readAsStringSync
(),
contains
(
"import 'package:web_plugin_with_nested/src/web_plugin.dart';"
));
expect
(
registrant
.
readAsStringSync
(),
contains
(
"import 'package:web_plugin_with_nested/src/web_plugin.dart';"
));
...
...
packages/flutter_tools/test/general.shard/web/migrations/scrub_generated_plugin_registrant_test.dart
0 → 100644
View file @
1af8cc11
// 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.
// @dart = 2.8
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/cache.dart'
;
import
'package:flutter_tools/src/commands/build.dart'
;
import
'../../../src/context.dart'
;
// legacy
import
'../../../src/test_build_system.dart'
;
import
'../../../src/test_flutter_command_runner.dart'
;
// legacy
void
main
(
)
{
setUpAll
(()
{
Cache
.
flutterRoot
=
''
;
Cache
.
disableLocking
();
});
group
(
'ScrubGeneratedPluginRegistrant'
,
()
{
// The files this migration deals with
File
gitignore
;
File
registrant
;
// Environment overrides
FileSystem
fileSystem
;
ProcessManager
processManager
;
BuildSystem
buildSystem
;
setUp
(()
{
// Prepare environment overrides
fileSystem
=
MemoryFileSystem
.
test
();
processManager
=
FakeProcessManager
.
any
();
buildSystem
=
TestBuildSystem
.
all
(
BuildResult
(
success:
true
));
// Write some initial state into our testing filesystem
setupFileSystemForEndToEndTest
(
fileSystem
);
// Initialize fileSystem references
gitignore
=
fileSystem
.
file
(
'.gitignore'
);
registrant
=
fileSystem
.
file
(
fileSystem
.
path
.
join
(
'lib'
,
'generated_plugin_registrant.dart'
));
});
testUsingContext
(
'noop - nothing to do - build runs'
,
()
async
{
expect
(
gitignore
.
existsSync
(),
isFalse
);
expect
(
registrant
.
existsSync
(),
isFalse
);
await
createTestCommandRunner
(
BuildCommand
())
.
run
(<
String
>[
'build'
,
'web'
,
'--no-pub'
]);
final
Directory
buildDir
=
fileSystem
.
directory
(
fileSystem
.
path
.
join
(
'build'
,
'web'
));
expect
(
buildDir
.
existsSync
(),
true
);
},
overrides:
<
Type
,
Generator
>
{
FileSystem:
()
=>
fileSystem
,
ProcessManager:
()
=>
processManager
,
BuildSystem:
()
=>
buildSystem
,
});
testUsingContext
(
'noop - .gitignore does not reference generated_plugin_registrant.dart - untouched'
,
()
async
{
writeGitignore
(
fileSystem
,
mentionsPluginRegistrant:
false
);
final
String
contentsBeforeBuild
=
gitignore
.
readAsStringSync
();
expect
(
contentsBeforeBuild
,
isNot
(
contains
(
'lib/generated_plugin_registrant.dart'
)));
await
createTestCommandRunner
(
BuildCommand
())
.
run
(<
String
>[
'build'
,
'web'
,
'--no-pub'
]);
expect
(
gitignore
.
readAsStringSync
(),
contentsBeforeBuild
);
},
overrides:
<
Type
,
Generator
>
{
FileSystem:
()
=>
fileSystem
,
ProcessManager:
()
=>
processManager
,
BuildSystem:
()
=>
buildSystem
,
});
testUsingContext
(
'.gitignore references generated_plugin_registrant - cleans it up'
,
()
async
{
writeGitignore
(
fileSystem
);
expect
(
gitignore
.
existsSync
(),
isTrue
);
expect
(
gitignore
.
readAsStringSync
(),
contains
(
'lib/generated_plugin_registrant.dart'
));
await
createTestCommandRunner
(
BuildCommand
())
.
run
(<
String
>[
'build'
,
'web'
,
'--no-pub'
]);
expect
(
gitignore
.
readAsStringSync
(),
isNot
(
contains
(
'lib/generated_plugin_registrant.dart'
)));
},
overrides:
<
Type
,
Generator
>
{
FileSystem:
()
=>
fileSystem
,
ProcessManager:
()
=>
processManager
,
BuildSystem:
()
=>
buildSystem
,
});
testUsingContext
(
'generated_plugin_registrant.dart exists - gets deleted'
,
()
async
{
writeGeneratedPluginRegistrant
(
fileSystem
);
expect
(
registrant
.
existsSync
(),
isTrue
);
await
createTestCommandRunner
(
BuildCommand
())
.
run
(<
String
>[
'build'
,
'web'
,
'--no-pub'
]);
expect
(
registrant
.
existsSync
(),
isFalse
);
},
overrides:
<
Type
,
Generator
>
{
FileSystem:
()
=>
fileSystem
,
ProcessManager:
()
=>
processManager
,
BuildSystem:
()
=>
buildSystem
,
});
testUsingContext
(
'scrubs generated_plugin_registrant file and cleans .gitignore'
,
()
async
{
writeGitignore
(
fileSystem
);
writeGeneratedPluginRegistrant
(
fileSystem
);
expect
(
registrant
.
existsSync
(),
isTrue
);
expect
(
gitignore
.
readAsStringSync
(),
contains
(
'lib/generated_plugin_registrant.dart'
));
await
createTestCommandRunner
(
BuildCommand
())
.
run
(<
String
>[
'build'
,
'web'
,
'--no-pub'
]);
expect
(
registrant
.
existsSync
(),
isFalse
);
expect
(
gitignore
.
readAsStringSync
(),
isNot
(
contains
(
'lib/generated_plugin_registrant.dart'
)));
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
fileSystem
,
ProcessManager:
()
=>
processManager
,
BuildSystem:
()
=>
buildSystem
,
});
});
}
// Writes something that resembles the contents of Flutter's .gitignore file
void
writeGitignore
(
FileSystem
fs
,
{
bool
mentionsPluginRegistrant
=
true
})
{
fs
.
file
(
'.gitignore'
).
createSync
(
recursive:
true
);
fs
.
file
(
'.gitignore'
)
.
writeAsStringSync
(
'''
/build/
# Web related
${mentionsPluginRegistrant ? 'lib/generated_plugin_registrant.dart':'another_file.dart'}
# Symbolication related
'''
);
}
// Creates an empty generated_plugin_registrant.dart file
void
writeGeneratedPluginRegistrant
(
FileSystem
fs
)
{
final
String
path
=
fs
.
path
.
join
(
'lib'
,
'generated_plugin_registrant.dart'
);
fs
.
file
(
path
).
createSync
(
recursive:
true
);
}
// Adds a bunch of files to the filesystem
// (taken from commands.shard/hermetic/build_web_test.dart)
void
setupFileSystemForEndToEndTest
(
FileSystem
fileSystem
)
{
final
List
<
String
>
dependencies
=
<
String
>[
'.packages'
,
fileSystem
.
path
.
join
(
'web'
,
'index.html'
),
fileSystem
.
path
.
join
(
'lib'
,
'main.dart'
),
fileSystem
.
path
.
join
(
'packages'
,
'flutter_tools'
,
'lib'
,
'src'
,
'build_system'
,
'targets'
,
'web.dart'
),
fileSystem
.
path
.
join
(
'bin'
,
'cache'
,
'flutter_web_sdk'
),
fileSystem
.
path
.
join
(
'bin'
,
'cache'
,
'dart-sdk'
,
'bin'
,
'snapshots'
,
'dart2js.dart.snapshot'
),
fileSystem
.
path
.
join
(
'bin'
,
'cache'
,
'dart-sdk'
,
'bin'
,
'dart'
),
fileSystem
.
path
.
join
(
'bin'
,
'cache'
,
'dart-sdk '
),
];
for
(
final
String
dependency
in
dependencies
)
{
fileSystem
.
file
(
dependency
).
createSync
(
recursive:
true
);
}
// Project files.
fileSystem
.
file
(
'.packages'
)
.
writeAsStringSync
(
'''
foo:lib/
fizz:bar/lib/
'''
);
fileSystem
.
file
(
'pubspec.yaml'
)
.
writeAsStringSync
(
'''
name: foo
dependencies:
flutter:
sdk: flutter
fizz:
path:
bar/
'''
);
fileSystem
.
file
(
fileSystem
.
path
.
join
(
'bar'
,
'pubspec.yaml'
))
..
createSync
(
recursive:
true
)
..
writeAsStringSync
(
'''
name: bar
flutter:
plugin:
platforms:
web:
pluginClass: UrlLauncherPlugin
fileName: url_launcher_web.dart
'''
);
fileSystem
.
file
(
fileSystem
.
path
.
join
(
'bar'
,
'lib'
,
'url_launcher_web.dart'
))
..
createSync
(
recursive:
true
)
..
writeAsStringSync
(
'''
class UrlLauncherPlugin {}
'''
);
fileSystem
.
file
(
fileSystem
.
path
.
join
(
'lib'
,
'main.dart'
))
.
writeAsStringSync
(
'void main() { }'
);
}
packages/flutter_tools/test/integration.shard/
generated
_plugin_registrant_test.dart
→
packages/flutter_tools/test/integration.shard/
web
_plugin_registrant_test.dart
View file @
1af8cc11
...
@@ -49,12 +49,20 @@ void main() {
...
@@ -49,12 +49,20 @@ void main() {
// the generated_plugin_registrant generation.
// the generated_plugin_registrant generation.
await
_addDependency
(
projectDir
,
'shared_preferences'
,
await
_addDependency
(
projectDir
,
'shared_preferences'
,
version:
'^2.0.0'
);
version:
'^2.0.0'
);
await
_analyzeProject
(
projectDir
);
// The plugin registrant is only created after a build...
await
_buildWebProject
(
projectDir
);
// Find the web_plugin_registrant, now that it lives outside "lib":
final
Directory
buildDir
=
projectDir
.
childDirectory
(
'.dart_tool/flutter_build'
)
.
listSync
()
.
firstWhere
((
FileSystemEntity
entity
)
=>
entity
is
Directory
)
as
Directory
;
expect
(
expect
(
projectDir
.
childFile
(
'lib/generated
_plugin_registrant.dart'
),
buildDir
.
childFile
(
'web
_plugin_registrant.dart'
),
exists
,
exists
,
);
);
await
_analyzeEntity
(
buildDir
.
childFile
(
'web_plugin_registrant.dart'
));
},
overrides:
<
Type
,
Generator
>{
},
overrides:
<
Type
,
Generator
>{
Pub:
()
=>
Pub
(
Pub:
()
=>
Pub
(
fileSystem:
globals
.
fs
,
fileSystem:
globals
.
fs
,
...
@@ -88,12 +96,20 @@ void main() {
...
@@ -88,12 +96,20 @@ void main() {
'test_web_plugin_with_a_purposefully_extremely_long_package_name'
,
'test_web_plugin_with_a_purposefully_extremely_long_package_name'
,
path:
'../test_plugin'
,
path:
'../test_plugin'
,
);
);
await
_analyzeProject
(
projectDir
);
// The plugin registrant is only created after a build...
await
_buildWebProject
(
projectDir
);
// Find the web_plugin_registrant, now that it lives outside "lib":
final
Directory
buildDir
=
projectDir
.
childDirectory
(
'.dart_tool/flutter_build'
)
.
listSync
()
.
firstWhere
((
FileSystemEntity
entity
)
=>
entity
is
Directory
)
as
Directory
;
expect
(
expect
(
projectDir
.
childFile
(
'lib/generated
_plugin_registrant.dart'
),
buildDir
.
childFile
(
'web
_plugin_registrant.dart'
),
exists
,
exists
,
);
);
await
_analyzeEntity
(
buildDir
.
childFile
(
'web_plugin_registrant.dart'
));
},
overrides:
<
Type
,
Generator
>{
},
overrides:
<
Type
,
Generator
>{
Pub:
()
=>
Pub
(
Pub:
()
=>
Pub
(
fileSystem:
globals
.
fs
,
fileSystem:
globals
.
fs
,
...
@@ -215,7 +231,7 @@ ${linterRules.map((String rule) => ' - $rule').join('\n')}
...
@@ -215,7 +231,7 @@ ${linterRules.map((String rule) => ' - $rule').join('\n')}
'''
);
'''
);
}
}
Future
<
void
>
_analyze
Project
(
Directory
workingDir
)
async
{
Future
<
void
>
_analyze
Entity
(
FileSystemEntity
target
)
async
{
final
String
flutterToolsSnapshotPath
=
globals
.
fs
.
path
.
absolute
(
final
String
flutterToolsSnapshotPath
=
globals
.
fs
.
path
.
absolute
(
globals
.
fs
.
path
.
join
(
globals
.
fs
.
path
.
join
(
'..'
,
'..'
,
...
@@ -229,15 +245,44 @@ Future<void> _analyzeProject(Directory workingDir) async {
...
@@ -229,15 +245,44 @@ Future<void> _analyzeProject(Directory workingDir) async {
final
List
<
String
>
args
=
<
String
>[
final
List
<
String
>
args
=
<
String
>[
flutterToolsSnapshotPath
,
flutterToolsSnapshotPath
,
'analyze'
,
'analyze'
,
target
.
path
,
];
];
final
ProcessResult
exec
=
await
Process
.
run
(
final
ProcessResult
exec
=
await
Process
.
run
(
globals
.
artifacts
.
getHostArtifact
(
HostArtifact
.
engineDartBinary
).
path
,
globals
.
artifacts
.
getHostArtifact
(
HostArtifact
.
engineDartBinary
).
path
,
args
,
args
,
workingDirectory:
workingDir
.
path
,
workingDirectory:
target
is
Directory
?
target
.
path
:
target
.
dirname
,
);
);
printOnFailure
(
'Output of flutter analyze:'
);
printOnFailure
(
'Output of flutter analyze:'
);
printOnFailure
(
exec
.
stdout
.
toString
());
printOnFailure
(
exec
.
stdout
.
toString
());
printOnFailure
(
exec
.
stderr
.
toString
());
printOnFailure
(
exec
.
stderr
.
toString
());
expect
(
exec
.
exitCode
,
0
);
expect
(
exec
.
exitCode
,
0
);
}
}
Future
<
void
>
_buildWebProject
(
Directory
workingDir
)
async
{
final
String
flutterToolsSnapshotPath
=
globals
.
fs
.
path
.
absolute
(
globals
.
fs
.
path
.
join
(
'..'
,
'..'
,
'bin'
,
'cache'
,
'flutter_tools.snapshot'
,
),
);
final
List
<
String
>
args
=
<
String
>[
flutterToolsSnapshotPath
,
'build'
,
'web'
,
];
final
ProcessResult
exec
=
await
Process
.
run
(
globals
.
artifacts
.
getHostArtifact
(
HostArtifact
.
engineDartBinary
).
path
,
args
,
workingDirectory:
workingDir
.
path
,
);
printOnFailure
(
'Output of flutter build web:'
);
printOnFailure
(
exec
.
stdout
.
toString
());
printOnFailure
(
exec
.
stderr
.
toString
());
expect
(
exec
.
exitCode
,
0
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment