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
cd803ac7
Unverified
Commit
cd803ac7
authored
Mar 15, 2019
by
Jonah Williams
Committed by
GitHub
Mar 15, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Improve hot reload performance (#28152)
parent
bfac6048
Changes
50
Show whitespace changes
Inline
Side-by-side
Showing
50 changed files
with
434 additions
and
1311 deletions
+434
-1311
pubspec.yaml
dev/bots/pubspec.yaml
+1
-0
fuchsia_attach.dart
packages/flutter_tools/bin/fuchsia_attach.dart
+1
-3
attach.dart
packages/flutter_tools/lib/src/commands/attach.dart
+5
-0
daemon.dart
packages/flutter_tools/lib/src/commands/daemon.dart
+3
-0
run.dart
packages/flutter_tools/lib/src/commands/run.dart
+3
-0
update_packages.dart
packages/flutter_tools/lib/src/commands/update_packages.dart
+1
-1
dependencies.dart
packages/flutter_tools/lib/src/dart/dependencies.dart
+0
-150
dependency_checker.dart
packages/flutter_tools/lib/src/dependency_checker.dart
+0
-46
devfs.dart
packages/flutter_tools/lib/src/devfs.dart
+24
-297
resident_runner.dart
packages/flutter_tools/lib/src/resident_runner.dart
+12
-16
run_hot.dart
packages/flutter_tools/lib/src/run_hot.dart
+137
-96
pubspec.yaml
packages/flutter_tools/pubspec.yaml
+2
-2
attach_test.dart
packages/flutter_tools/test/commands/attach_test.dart
+4
-0
dart_dependencies_test.dart
packages/flutter_tools/test/dart_dependencies_test.dart
+0
-99
.dartignore
...lutter_tools/test/data/dart_dependencies_test/.dartignore
+0
-0
.packages
...ls/test/data/dart_dependencies_test/asci_casing/.packages
+0
-1
This_Import_Has_fuNNy_casING.dart
...encies_test/asci_casing/This_Import_Has_fuNNy_casING.dart
+0
-5
analysis_options.yaml
.../dart_dependencies_test/asci_casing/analysis_options.yaml
+0
-3
main.dart
...ls/test/data/dart_dependencies_test/asci_casing/main.dart
+0
-9
pubspec.yaml
...test/data/dart_dependencies_test/asci_casing/pubspec.yaml
+0
-1
analysis_options.yaml
...a/dart_dependencies_test/bad_import/analysis_options.yaml
+0
-3
main.dart
...ols/test/data/dart_dependencies_test/bad_import/main.dart
+0
-5
pubspec.yaml
.../test/data/dart_dependencies_test/bad_import/pubspec.yaml
+0
-1
.packages
...ls/test/data/dart_dependencies_test/bad_package/.packages
+0
-1
analysis_options.yaml
.../dart_dependencies_test/bad_package/analysis_options.yaml
+0
-3
main.dart
...ls/test/data/dart_dependencies_test/bad_package/main.dart
+0
-6
pubspec.yaml
...test/data/dart_dependencies_test/bad_package/pubspec.yaml
+0
-1
.packages
...tools/test/data/dart_dependencies_test/bad_path/.packages
+0
-1
analysis_options.yaml
...ata/dart_dependencies_test/bad_path/analysis_options.yaml
+0
-3
main.dart
...tools/test/data/dart_dependencies_test/bad_path/main.dart
+0
-5
pubspec.yaml
...ls/test/data/dart_dependencies_test/bad_path/pubspec.yaml
+0
-1
.packages
...ata/dart_dependencies_test/changed_sdk_location/.packages
+0
-2
main.dart
...dart_dependencies_test/changed_sdk_location/lib/main.dart
+0
-5
pubspec.yaml
.../dart_dependencies_test/changed_sdk_location/pubspec.yaml
+0
-9
.packages
...ter_tools/test/data/dart_dependencies_test/good/.packages
+0
-1
analysis_options.yaml
...st/data/dart_dependencies_test/good/analysis_options.yaml
+0
-3
foo.dart
...tter_tools/test/data/dart_dependencies_test/good/foo.dart
+0
-3
bar.dart
..._tools/test/data/dart_dependencies_test/good/lib/bar.dart
+0
-3
main.dart
...ter_tools/test/data/dart_dependencies_test/good/main.dart
+0
-6
pubspec.yaml
..._tools/test/data/dart_dependencies_test/good/pubspec.yaml
+0
-1
.packages
...s/test/data/dart_dependencies_test/syntax_error/.packages
+0
-1
analysis_options.yaml
...dart_dependencies_test/syntax_error/analysis_options.yaml
+0
-3
foo.dart
...ls/test/data/dart_dependencies_test/syntax_error/foo.dart
+0
-5
main.dart
...s/test/data/dart_dependencies_test/syntax_error/main.dart
+0
-5
pubspec.yaml
...est/data/dart_dependencies_test/syntax_error/pubspec.yaml
+0
-1
dependency_checker_test.dart
packages/flutter_tools/test/dependency_checker_test.dart
+0
-112
devfs_test.dart
packages/flutter_tools/test/devfs_test.dart
+1
-364
hot_test.dart
packages/flutter_tools/test/hot_test.dart
+6
-22
project_file_invalidator_test.dart
...ges/flutter_tools/test/project_file_invalidator_test.dart
+234
-0
mocks.dart
packages/flutter_tools/test/src/mocks.dart
+0
-6
No files found.
dev/bots/pubspec.yaml
View file @
cd803ac7
...
@@ -70,4 +70,5 @@ dev_dependencies:
...
@@ -70,4 +70,5 @@ dev_dependencies:
mockito
:
4.0.0
mockito
:
4.0.0
test_api
:
0.2.2
test_api
:
0.2.2
# PUBSPEC CHECKSUM: 422e
# PUBSPEC CHECKSUM: 422e
packages/flutter_tools/bin/fuchsia_attach.dart
View file @
cd803ac7
...
@@ -15,7 +15,6 @@ import 'package:flutter_tools/src/cache.dart';
...
@@ -15,7 +15,6 @@ import 'package:flutter_tools/src/cache.dart';
import
'package:flutter_tools/src/commands/attach.dart'
;
import
'package:flutter_tools/src/commands/attach.dart'
;
import
'package:flutter_tools/src/commands/doctor.dart'
;
import
'package:flutter_tools/src/commands/doctor.dart'
;
import
'package:flutter_tools/src/fuchsia/fuchsia_sdk.dart'
;
import
'package:flutter_tools/src/fuchsia/fuchsia_sdk.dart'
;
import
'package:flutter_tools/src/run_hot.dart'
;
import
'package:flutter_tools/src/runner/flutter_command.dart'
;
import
'package:flutter_tools/src/runner/flutter_command.dart'
;
final
ArgParser
parser
=
ArgParser
()
final
ArgParser
parser
=
ArgParser
()
...
@@ -100,8 +99,7 @@ Future<void> main(List<String> args) async {
...
@@ -100,8 +99,7 @@ Future<void> main(List<String> args) async {
platformKernelDill:
platformKernelDill
,
platformKernelDill:
platformKernelDill
,
flutterPatchedSdk:
flutterPatchedSdk
,
flutterPatchedSdk:
flutterPatchedSdk
,
),
),
HotRunnerConfig:
()
=>
HotRunnerConfig
()..
computeDartDependencies
=
false
,
}
},
);
);
}
}
...
...
packages/flutter_tools/lib/src/commands/attach.dart
View file @
cd803ac7
...
@@ -18,6 +18,7 @@ import '../fuchsia/fuchsia_device.dart';
...
@@ -18,6 +18,7 @@ import '../fuchsia/fuchsia_device.dart';
import
'../globals.dart'
;
import
'../globals.dart'
;
import
'../ios/devices.dart'
;
import
'../ios/devices.dart'
;
import
'../ios/simulators.dart'
;
import
'../ios/simulators.dart'
;
import
'../project.dart'
;
import
'../protocol_discovery.dart'
;
import
'../protocol_discovery.dart'
;
import
'../resident_runner.dart'
;
import
'../resident_runner.dart'
;
import
'../run_cold.dart'
;
import
'../run_cold.dart'
;
...
@@ -129,6 +130,7 @@ class AttachCommand extends FlutterCommand {
...
@@ -129,6 +130,7 @@ class AttachCommand extends FlutterCommand {
Future
<
FlutterCommandResult
>
runCommand
()
async
{
Future
<
FlutterCommandResult
>
runCommand
()
async
{
final
String
ipv4Loopback
=
InternetAddress
.
loopbackIPv4
.
address
;
final
String
ipv4Loopback
=
InternetAddress
.
loopbackIPv4
.
address
;
final
String
ipv6Loopback
=
InternetAddress
.
loopbackIPv6
.
address
;
final
String
ipv6Loopback
=
InternetAddress
.
loopbackIPv6
.
address
;
final
FlutterProject
flutterProject
=
await
FlutterProject
.
current
();
Cache
.
releaseLockEarly
();
Cache
.
releaseLockEarly
();
...
@@ -228,6 +230,7 @@ class AttachCommand extends FlutterCommand {
...
@@ -228,6 +230,7 @@ class AttachCommand extends FlutterCommand {
projectRootPath:
argResults
[
'project-root'
],
projectRootPath:
argResults
[
'project-root'
],
dillOutputPath:
argResults
[
'output-dill'
],
dillOutputPath:
argResults
[
'output-dill'
],
ipv6:
usesIpv6
,
ipv6:
usesIpv6
,
flutterProject:
flutterProject
,
)
)
:
ColdRunner
(
:
ColdRunner
(
flutterDevices
,
flutterDevices
,
...
@@ -289,6 +292,7 @@ class HotRunnerFactory {
...
@@ -289,6 +292,7 @@ class HotRunnerFactory {
String
dillOutputPath
,
String
dillOutputPath
,
bool
stayResident
=
true
,
bool
stayResident
=
true
,
bool
ipv6
=
false
,
bool
ipv6
=
false
,
FlutterProject
flutterProject
,
})
=>
HotRunner
(
})
=>
HotRunner
(
devices
,
devices
,
target:
target
,
target:
target
,
...
@@ -302,6 +306,7 @@ class HotRunnerFactory {
...
@@ -302,6 +306,7 @@ class HotRunnerFactory {
dillOutputPath:
dillOutputPath
,
dillOutputPath:
dillOutputPath
,
stayResident:
stayResident
,
stayResident:
stayResident
,
ipv6:
ipv6
,
ipv6:
ipv6
,
flutterProject:
flutterProject
,
);
);
}
}
...
...
packages/flutter_tools/lib/src/commands/daemon.dart
View file @
cd803ac7
...
@@ -19,6 +19,7 @@ import '../convert.dart';
...
@@ -19,6 +19,7 @@ import '../convert.dart';
import
'../device.dart'
;
import
'../device.dart'
;
import
'../emulator.dart'
;
import
'../emulator.dart'
;
import
'../globals.dart'
;
import
'../globals.dart'
;
import
'../project.dart'
;
import
'../resident_runner.dart'
;
import
'../resident_runner.dart'
;
import
'../run_cold.dart'
;
import
'../run_cold.dart'
;
import
'../run_hot.dart'
;
import
'../run_hot.dart'
;
...
@@ -341,6 +342,7 @@ class AppDomain extends Domain {
...
@@ -341,6 +342,7 @@ class AppDomain extends Domain {
if
(
await
device
.
isLocalEmulator
&&
!
options
.
buildInfo
.
supportsEmulator
)
{
if
(
await
device
.
isLocalEmulator
&&
!
options
.
buildInfo
.
supportsEmulator
)
{
throw
'
${toTitleCase(options.buildInfo.friendlyModeName)}
mode is not supported for emulators.'
;
throw
'
${toTitleCase(options.buildInfo.friendlyModeName)}
mode is not supported for emulators.'
;
}
}
final
FlutterProject
flutterProject
=
await
FlutterProject
.
current
();
// We change the current working directory for the duration of the `start` command.
// We change the current working directory for the duration of the `start` command.
final
Directory
cwd
=
fs
.
currentDirectory
;
final
Directory
cwd
=
fs
.
currentDirectory
;
...
@@ -368,6 +370,7 @@ class AppDomain extends Domain {
...
@@ -368,6 +370,7 @@ class AppDomain extends Domain {
dillOutputPath:
dillOutputPath
,
dillOutputPath:
dillOutputPath
,
ipv6:
ipv6
,
ipv6:
ipv6
,
hostIsIde:
true
,
hostIsIde:
true
,
flutterProject:
flutterProject
,
);
);
}
else
{
}
else
{
runner
=
ColdRunner
(
runner
=
ColdRunner
(
...
...
packages/flutter_tools/lib/src/commands/run.dart
View file @
cd803ac7
...
@@ -13,6 +13,7 @@ import '../cache.dart';
...
@@ -13,6 +13,7 @@ import '../cache.dart';
import
'../device.dart'
;
import
'../device.dart'
;
import
'../globals.dart'
;
import
'../globals.dart'
;
import
'../ios/mac.dart'
;
import
'../ios/mac.dart'
;
import
'../project.dart'
;
import
'../resident_runner.dart'
;
import
'../resident_runner.dart'
;
import
'../run_cold.dart'
;
import
'../run_cold.dart'
;
import
'../run_hot.dart'
;
import
'../run_hot.dart'
;
...
@@ -280,6 +281,7 @@ class RunCommand extends RunCommandBase {
...
@@ -280,6 +281,7 @@ class RunCommand extends RunCommandBase {
// Enable hot mode by default if `--no-hot` was not passed and we are in
// Enable hot mode by default if `--no-hot` was not passed and we are in
// debug mode.
// debug mode.
final
bool
hotMode
=
shouldUseHotMode
();
final
bool
hotMode
=
shouldUseHotMode
();
final
FlutterProject
flutterProject
=
await
FlutterProject
.
current
();
writePidFile
(
argResults
[
'pid-file'
]);
writePidFile
(
argResults
[
'pid-file'
]);
...
@@ -389,6 +391,7 @@ class RunCommand extends RunCommandBase {
...
@@ -389,6 +391,7 @@ class RunCommand extends RunCommandBase {
saveCompilationTrace:
argResults
[
'train'
],
saveCompilationTrace:
argResults
[
'train'
],
stayResident:
stayResident
,
stayResident:
stayResident
,
ipv6:
ipv6
,
ipv6:
ipv6
,
flutterProject:
flutterProject
,
);
);
}
else
{
}
else
{
runner
=
ColdRunner
(
runner
=
ColdRunner
(
...
...
packages/flutter_tools/lib/src/commands/update_packages.dart
View file @
cd803ac7
...
@@ -1093,7 +1093,7 @@ class PubspecDependency extends PubspecLine {
...
@@ -1093,7 +1093,7 @@ class PubspecDependency extends PubspecLine {
/// Generates the File object for the pubspec.yaml file of a given Directory.
/// Generates the File object for the pubspec.yaml file of a given Directory.
File
_pubspecFor
(
Directory
directory
)
{
File
_pubspecFor
(
Directory
directory
)
{
return
fs
.
file
(
'
${directory.path}
/pubspec.yaml'
);
return
fs
.
file
(
fs
.
path
.
join
(
directory
.
path
,
'pubspec.yaml'
)
);
}
}
/// Generates the source of a fake pubspec.yaml file given a list of
/// Generates the source of a fake pubspec.yaml file given a list of
...
...
packages/flutter_tools/lib/src/dart/dependencies.dart
deleted
100644 → 0
View file @
bfac6048
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// TODO(dnfield): This will be removed when @jonahwilliams' work on build lands
// ignore: deprecated_member_use
import
'package:analyzer/analyzer.dart'
as
analyzer
;
import
'../base/file_system.dart'
;
import
'../dart/package_map.dart'
;
// List of flutter specific environment configurations.
// See https://github.com/munificent/dep-interface-libraries/blob/master/Proposal.md
// We will populate this list as required. Potentially, all of dart:* libraries
// supported by flutter would end up here.
final
List
<
String
>
_configurationConstants
=
<
String
>[
'dart.library.io'
];
String
_dottedNameToString
(
analyzer
.
DottedName
dottedName
)
{
String
result
=
''
;
for
(
analyzer
.
SimpleIdentifier
identifier
in
dottedName
.
components
)
{
if
(
result
.
isEmpty
)
{
result
+=
identifier
.
token
.
lexeme
;
}
else
{
result
+=
'.'
+
identifier
.
token
.
lexeme
;
}
}
return
result
;
}
class
DartDependencySetBuilder
{
DartDependencySetBuilder
(
String
mainScriptPath
,
String
packagesFilePath
)
:
_mainScriptPath
=
canonicalizePath
(
mainScriptPath
),
_mainScriptUri
=
fs
.
path
.
toUri
(
mainScriptPath
),
_packagesFilePath
=
canonicalizePath
(
packagesFilePath
);
final
String
_mainScriptPath
;
final
String
_packagesFilePath
;
final
Uri
_mainScriptUri
;
Set
<
String
>
build
()
{
final
List
<
String
>
dependencies
=
<
String
>[
_mainScriptPath
,
_packagesFilePath
];
final
List
<
Uri
>
toProcess
=
<
Uri
>[
_mainScriptUri
];
final
PackageMap
packageMap
=
PackageMap
(
_packagesFilePath
);
while
(
toProcess
.
isNotEmpty
)
{
final
Uri
currentUri
=
toProcess
.
removeLast
();
final
analyzer
.
CompilationUnit
unit
=
_parse
(
currentUri
.
toFilePath
());
for
(
analyzer
.
Directive
directive
in
unit
.
directives
)
{
if
(!(
directive
is
analyzer
.
UriBasedDirective
))
continue
;
String
uriAsString
;
if
(
directive
is
analyzer
.
NamespaceDirective
)
{
final
analyzer
.
NamespaceDirective
namespaceDirective
=
directive
;
// If the directive is a conditional import directive, we should
// select the imported uri based on the condition.
for
(
analyzer
.
Configuration
configuration
in
namespaceDirective
.
configurations
)
{
if
(
_configurationConstants
.
contains
(
_dottedNameToString
(
configuration
.
name
)))
{
uriAsString
=
configuration
.
uri
.
stringValue
;
break
;
}
}
}
if
(
uriAsString
==
null
)
{
final
analyzer
.
UriBasedDirective
uriBasedDirective
=
directive
;
uriAsString
=
uriBasedDirective
.
uri
.
stringValue
;
}
Uri
uri
;
try
{
uri
=
Uri
.
parse
(
uriAsString
);
}
on
FormatException
{
throw
DartDependencyException
(
'Unable to parse URI:
$uriAsString
'
);
}
Uri
resolvedUri
=
analyzer
.
resolveRelativeUri
(
currentUri
,
uri
);
if
(
resolvedUri
.
scheme
.
startsWith
(
'dart'
))
continue
;
if
(
resolvedUri
.
scheme
==
'package'
)
{
final
Uri
newResolvedUri
=
packageMap
.
uriForPackage
(
resolvedUri
);
if
(
newResolvedUri
==
null
)
{
throw
DartDependencyException
(
'The following Dart file:
\n
'
'
${currentUri.toFilePath()}
\n
'
'...refers, in an import, to the following library:
\n
'
'
$resolvedUri
\n
'
'That library is in a package that is not known. Maybe you forgot to '
'mention it in your pubspec.yaml file?'
);
}
resolvedUri
=
newResolvedUri
;
}
final
String
path
=
canonicalizePath
(
resolvedUri
.
toFilePath
());
if
(!
dependencies
.
contains
(
path
))
{
if
(!
fs
.
isFileSync
(
path
))
{
throw
DartDependencyException
(
'The following Dart file:
\n
'
'
${currentUri.toFilePath()}
\n
'
'...refers, in an import, to the following library:
\n
'
'
$path
\n
'
'Unfortunately, that library does not appear to exist on your file system.'
);
}
dependencies
.
add
(
path
);
toProcess
.
add
(
resolvedUri
);
}
}
}
return
dependencies
.
toSet
();
}
analyzer
.
CompilationUnit
_parse
(
String
path
)
{
String
body
;
try
{
body
=
fs
.
file
(
path
).
readAsStringSync
();
}
on
FileSystemException
catch
(
error
)
{
throw
DartDependencyException
(
'Could not read "
$path
" when determining Dart dependencies.'
,
error
,
);
}
try
{
return
analyzer
.
parseDirectives
(
body
,
name:
path
);
}
on
analyzer
.
AnalyzerError
catch
(
error
)
{
throw
DartDependencyException
(
'When trying to parse this Dart file to find its dependencies:
\n
'
'
$path
\n
'
'...the analyzer failed with the following error:
\n
'
'
${error.toString().trimRight()}
'
,
error
,
);
}
on
analyzer
.
AnalyzerErrorGroup
catch
(
error
)
{
throw
DartDependencyException
(
'When trying to parse this Dart file to find its dependencies:
\n
'
'
$path
\n
'
'...the analyzer failed with the following error:
\n
'
'
${error.toString().trimRight()}
'
,
error
,
);
}
}
}
class
DartDependencyException
implements
Exception
{
DartDependencyException
(
this
.
message
,
[
this
.
parent
]);
final
String
message
;
final
Exception
parent
;
@override
String
toString
()
=>
message
;
}
packages/flutter_tools/lib/src/dependency_checker.dart
deleted
100644 → 0
View file @
bfac6048
// Copyright 2016 The Chromium 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
'asset.dart'
;
import
'base/file_system.dart'
;
import
'dart/dependencies.dart'
;
import
'globals.dart'
;
class
DependencyChecker
{
DependencyChecker
(
this
.
builder
,
this
.
assets
);
final
DartDependencySetBuilder
builder
;
final
Set
<
String
>
_dependencies
=
<
String
>{};
final
AssetBundle
assets
;
/// Returns [true] if any components have been modified after [threshold] or
/// if it cannot be determined.
bool
check
(
DateTime
threshold
)
{
_dependencies
.
clear
();
// Build the set of Dart dependencies.
try
{
_dependencies
.
addAll
(
builder
.
build
());
}
catch
(
e
,
st
)
{
printTrace
(
'DependencyChecker: error determining .dart dependencies:
\n
$e
\n
$st
'
);
return
true
;
}
// TODO(johnmccutchan): Extract dependencies from the AssetBundle too.
// Check all dependency modification times.
for
(
String
path
in
_dependencies
)
{
final
File
file
=
fs
.
file
(
path
);
final
FileStat
stat
=
file
.
statSync
();
if
(
stat
.
type
==
FileSystemEntityType
.
notFound
)
{
printTrace
(
'DependencyChecker: Error stating
$path
.'
);
return
true
;
}
if
(
stat
.
modified
.
isAfter
(
threshold
))
{
printTrace
(
'DependencyChecker:
$path
is newer than
$threshold
'
);
return
true
;
}
}
printTrace
(
'DependencyChecker: nothing is modified after
$threshold
.'
);
return
false
;
}
}
packages/flutter_tools/lib/src/devfs.dart
View file @
cd803ac7
...
@@ -30,8 +30,6 @@ DevFSConfig get devFSConfig => context[DevFSConfig];
...
@@ -30,8 +30,6 @@ DevFSConfig get devFSConfig => context[DevFSConfig];
/// Common superclass for content copied to the device.
/// Common superclass for content copied to the device.
abstract
class
DevFSContent
{
abstract
class
DevFSContent
{
bool
_exists
=
true
;
/// Return true if this is the first time this method is called
/// Return true if this is the first time this method is called
/// or if the entry has been modified since this method was last called.
/// or if the entry has been modified since this method was last called.
bool
get
isModified
;
bool
get
isModified
;
...
@@ -59,13 +57,6 @@ abstract class DevFSContent {
...
@@ -59,13 +57,6 @@ abstract class DevFSContent {
class
DevFSFileContent
extends
DevFSContent
{
class
DevFSFileContent
extends
DevFSContent
{
DevFSFileContent
(
this
.
file
);
DevFSFileContent
(
this
.
file
);
static
DevFSFileContent
clone
(
DevFSFileContent
fsFileContent
)
{
final
DevFSFileContent
newFsFileContent
=
DevFSFileContent
(
fsFileContent
.
file
);
newFsFileContent
.
_linkTarget
=
fsFileContent
.
_linkTarget
;
newFsFileContent
.
_fileStat
=
fsFileContent
.
_fileStat
;
return
newFsFileContent
;
}
final
FileSystemEntity
file
;
final
FileSystemEntity
file
;
FileSystemEntity
_linkTarget
;
FileSystemEntity
_linkTarget
;
FileStat
_fileStat
;
FileStat
_fileStat
;
...
@@ -218,7 +209,6 @@ abstract class DevFSOperations {
...
@@ -218,7 +209,6 @@ abstract class DevFSOperations {
Future
<
Uri
>
create
(
String
fsName
);
Future
<
Uri
>
create
(
String
fsName
);
Future
<
dynamic
>
destroy
(
String
fsName
);
Future
<
dynamic
>
destroy
(
String
fsName
);
Future
<
dynamic
>
writeFile
(
String
fsName
,
Uri
deviceUri
,
DevFSContent
content
);
Future
<
dynamic
>
writeFile
(
String
fsName
,
Uri
deviceUri
,
DevFSContent
content
);
Future
<
dynamic
>
deleteFile
(
String
fsName
,
Uri
deviceUri
);
}
}
/// An implementation of [DevFSOperations] that speaks to the
/// An implementation of [DevFSOperations] that speaks to the
...
@@ -261,11 +251,6 @@ class ServiceProtocolDevFSOperations implements DevFSOperations {
...
@@ -261,11 +251,6 @@ class ServiceProtocolDevFSOperations implements DevFSOperations {
printTrace
(
'DevFS: Failed to write
$deviceUri
:
$error
'
);
printTrace
(
'DevFS: Failed to write
$deviceUri
:
$error
'
);
}
}
}
}
@override
Future
<
dynamic
>
deleteFile
(
String
fsName
,
Uri
deviceUri
)
async
{
// TODO(johnmccutchan): Add file deletion to the devFS protocol.
}
}
}
class
DevFSException
implements
Exception
{
class
DevFSException
implements
Exception
{
...
@@ -288,16 +273,14 @@ class _DevFSHttpWriter {
...
@@ -288,16 +273,14 @@ class _DevFSHttpWriter {
int
_inFlight
=
0
;
int
_inFlight
=
0
;
Map
<
Uri
,
DevFSContent
>
_outstanding
;
Map
<
Uri
,
DevFSContent
>
_outstanding
;
Completer
<
void
>
_completer
;
Completer
<
void
>
_completer
;
HttpClient
_client
;
final
HttpClient
_client
=
HttpClient
()
;
Future
<
void
>
write
(
Map
<
Uri
,
DevFSContent
>
entries
)
async
{
Future
<
void
>
write
(
Map
<
Uri
,
DevFSContent
>
entries
)
async
{
_client
=
HttpClient
();
_client
.
maxConnectionsPerHost
=
kMaxInFlight
;
_client
.
maxConnectionsPerHost
=
kMaxInFlight
;
_completer
=
Completer
<
void
>();
_completer
=
Completer
<
void
>();
_outstanding
=
Map
<
Uri
,
DevFSContent
>.
from
(
entries
);
_outstanding
=
Map
<
Uri
,
DevFSContent
>.
from
(
entries
);
_scheduleWrites
();
_scheduleWrites
();
await
_completer
.
future
;
await
_completer
.
future
;
_client
.
close
();
}
}
void
_scheduleWrites
()
{
void
_scheduleWrites
()
{
...
@@ -405,9 +388,6 @@ class DevFS {
...
@@ -405,9 +388,6 @@ class DevFS {
final
Map
<
Uri
,
DevFSContent
>
_entries
=
<
Uri
,
DevFSContent
>{};
final
Map
<
Uri
,
DevFSContent
>
_entries
=
<
Uri
,
DevFSContent
>{};
final
Set
<
String
>
assetPathsToEvict
=
<
String
>{};
final
Set
<
String
>
assetPathsToEvict
=
<
String
>{};
final
List
<
Future
<
Map
<
String
,
dynamic
>>>
_pendingOperations
=
<
Future
<
Map
<
String
,
dynamic
>>>[];
Uri
_baseUri
;
Uri
_baseUri
;
Uri
get
baseUri
=>
_baseUri
;
Uri
get
baseUri
=>
_baseUri
;
...
@@ -453,66 +433,33 @@ class DevFS {
...
@@ -453,66 +433,33 @@ class DevFS {
DateTime
firstBuildTime
,
DateTime
firstBuildTime
,
bool
bundleFirstUpload
=
false
,
bool
bundleFirstUpload
=
false
,
bool
bundleDirty
=
false
,
bool
bundleDirty
=
false
,
Set
<
String
>
fileFilter
,
@required
ResidentCompiler
generator
,
@required
ResidentCompiler
generator
,
String
dillOutputPath
,
String
dillOutputPath
,
@required
bool
trackWidgetCreation
,
@required
bool
trackWidgetCreation
,
bool
fullRestart
=
false
,
bool
fullRestart
=
false
,
String
projectRootPath
,
String
projectRootPath
,
@required
String
pathToReload
,
@required
String
pathToReload
,
@required
List
<
String
>
invalidatedFiles
,
})
async
{
})
async
{
assert
(
trackWidgetCreation
!=
null
);
assert
(
trackWidgetCreation
!=
null
);
assert
(
generator
!=
null
);
assert
(
generator
!=
null
);
// Mark all entries as possibly deleted.
for
(
DevFSContent
content
in
_entries
.
values
)
{
content
.
_exists
=
false
;
}
// Scan workspace, packages, and assets
printTrace
(
'DevFS: Starting sync from
$rootDirectory
'
);
logger
.
printTrace
(
'Scanning project files'
);
await
_scanDirectory
(
rootDirectory
,
recursive:
true
,
fileFilter:
fileFilter
);
if
(
fs
.
isFileSync
(
_packagesFilePath
))
{
printTrace
(
'Scanning package files'
);
await
_scanPackages
(
fileFilter
);
}
if
(
bundle
!=
null
)
{
if
(
bundle
!=
null
)
{
printTrace
(
'Scanning asset files'
);
printTrace
(
'Scanning asset files'
);
// We write the assets into the AssetBundle working dir so that they
// are in the same location in DevFS and the iOS simulator.
final
String
assetDirectory
=
getAssetBuildDirectory
();
bundle
.
entries
.
forEach
((
String
archivePath
,
DevFSContent
content
)
{
bundle
.
entries
.
forEach
((
String
archivePath
,
DevFSContent
content
)
{
_scanBundleEntry
(
archivePath
,
content
);
final
Uri
deviceUri
=
fs
.
path
.
toUri
(
fs
.
path
.
join
(
assetDirectory
,
archivePath
));
_entries
[
deviceUri
]
=
content
;
});
});
}
}
// Handle deletions.
// Update modified files
printTrace
(
'Scanning for deleted files'
);
final
String
assetBuildDirPrefix
=
_asUriPath
(
getAssetBuildDirectory
());
final
String
assetBuildDirPrefix
=
_asUriPath
(
getAssetBuildDirectory
());
final
List
<
Uri
>
toRemove
=
<
Uri
>[];
final
Map
<
Uri
,
DevFSContent
>
dirtyEntries
=
<
Uri
,
DevFSContent
>{};
_entries
.
forEach
((
Uri
deviceUri
,
DevFSContent
content
)
{
if
(!
content
.
_exists
)
{
final
Future
<
Map
<
String
,
dynamic
>>
operation
=
_operations
.
deleteFile
(
fsName
,
deviceUri
)
.
then
<
Map
<
String
,
dynamic
>>((
dynamic
v
)
=>
v
?.
cast
<
String
,
dynamic
>());
if
(
operation
!=
null
)
_pendingOperations
.
add
(
operation
);
toRemove
.
add
(
deviceUri
);
if
(
deviceUri
.
path
.
startsWith
(
assetBuildDirPrefix
))
{
final
String
archivePath
=
deviceUri
.
path
.
substring
(
assetBuildDirPrefix
.
length
);
assetPathsToEvict
.
add
(
archivePath
);
}
}
});
if
(
toRemove
.
isNotEmpty
)
{
printTrace
(
'Removing deleted files'
);
toRemove
.
forEach
(
_entries
.
remove
);
await
Future
.
wait
<
Map
<
String
,
dynamic
>>(
_pendingOperations
);
_pendingOperations
.
clear
();
}
// Update modified files
int
syncedBytes
=
0
;
int
syncedBytes
=
0
;
final
Map
<
Uri
,
DevFSContent
>
dirtyEntries
=
<
Uri
,
DevFSContent
>{};
_entries
.
forEach
((
Uri
deviceUri
,
DevFSContent
content
)
{
_entries
.
forEach
((
Uri
deviceUri
,
DevFSContent
content
)
{
String
archivePath
;
String
archivePath
;
if
(
deviceUri
.
path
.
startsWith
(
assetBuildDirPrefix
))
if
(
deviceUri
.
path
.
startsWith
(
assetBuildDirPrefix
))
...
@@ -527,30 +474,10 @@ class DevFS {
...
@@ -527,30 +474,10 @@ class DevFS {
assetPathsToEvict
.
add
(
archivePath
);
assetPathsToEvict
.
add
(
archivePath
);
}
}
});
});
// We run generator even if [dirtyEntries] was empty because we want to
// keep logic of accepting/rejecting generator's output simple: we must
// accept/reject generator's output after every [update] call. Incremental
// run with no changes is supposed to be fast (considering that it is
// initiated by user key press).
final
List
<
String
>
invalidatedFiles
=
<
String
>[];
final
Set
<
Uri
>
filesUris
=
<
Uri
>{};
for
(
Uri
uri
in
dirtyEntries
.
keys
.
toList
())
{
if
(!
uri
.
path
.
startsWith
(
assetBuildDirPrefix
))
{
final
DevFSContent
content
=
dirtyEntries
[
uri
];
if
(
content
is
DevFSFileContent
)
{
filesUris
.
add
(
uri
);
invalidatedFiles
.
add
(
content
.
file
.
uri
.
toString
());
syncedBytes
-=
content
.
size
;
}
}
}
// No need to send source files because all compilation is done on the
// host and result of compilation is single kernel file.
filesUris
.
forEach
(
dirtyEntries
.
remove
);
printTrace
(
'Compiling dart to kernel with
${invalidatedFiles.length}
updated files'
);
if
(
fullRestart
)
{
if
(
fullRestart
)
{
generator
.
reset
();
generator
.
reset
();
}
}
printTrace
(
'Compiling dart to kernel with
${invalidatedFiles.length}
updated files'
);
final
CompilerOutput
compilerOutput
=
await
generator
.
recompile
(
final
CompilerOutput
compilerOutput
=
await
generator
.
recompile
(
mainPath
,
mainPath
,
invalidatedFiles
,
invalidatedFiles
,
...
@@ -566,16 +493,13 @@ class DevFS {
...
@@ -566,16 +493,13 @@ class DevFS {
?
fs
.
path
.
relative
(
pathToReload
,
from:
projectRootPath
)
?
fs
.
path
.
relative
(
pathToReload
,
from:
projectRootPath
)
:
pathToReload
,
:
pathToReload
,
);
);
if
(!
dirtyEntries
.
containsKey
(
entryUri
))
{
final
DevFSFileContent
content
=
DevFSFileContent
(
fs
.
file
(
compiledBinary
));
final
DevFSFileContent
content
=
DevFSFileContent
(
fs
.
file
(
compiledBinary
));
dirtyEntries
[
entryUri
]
=
content
;
syncedBytes
+=
content
.
size
;
syncedBytes
+=
content
.
size
;
dirtyEntries
[
entryUri
]
=
content
;
}
}
}
}
}
if
(
dirtyEntries
.
isNotEmpty
)
{
printTrace
(
'Updating files'
);
printTrace
(
'Updating files'
);
if
(
_httpWriter
!=
null
)
{
if
(
dirtyEntries
.
isNotEmpty
)
{
try
{
try
{
await
_httpWriter
.
write
(
dirtyEntries
);
await
_httpWriter
.
write
(
dirtyEntries
);
}
on
SocketException
catch
(
socketException
,
stackTrace
)
{
}
on
SocketException
catch
(
socketException
,
stackTrace
)
{
...
@@ -585,209 +509,12 @@ class DevFS {
...
@@ -585,209 +509,12 @@ class DevFS {
printError
(
'Could not update files on device:
$exception
'
);
printError
(
'Could not update files on device:
$exception
'
);
throw
DevFSException
(
'Sync failed'
,
exception
,
stackTrace
);
throw
DevFSException
(
'Sync failed'
,
exception
,
stackTrace
);
}
}
}
else
{
// Make service protocol requests for each.
dirtyEntries
.
forEach
((
Uri
deviceUri
,
DevFSContent
content
)
{
final
Future
<
Map
<
String
,
dynamic
>>
operation
=
_operations
.
writeFile
(
fsName
,
deviceUri
,
content
)
.
then
<
Map
<
String
,
dynamic
>>((
dynamic
v
)
=>
v
?.
cast
<
String
,
dynamic
>());
if
(
operation
!=
null
)
_pendingOperations
.
add
(
operation
);
});
await
Future
.
wait
<
Map
<
String
,
dynamic
>>(
_pendingOperations
,
eagerError:
true
);
_pendingOperations
.
clear
();
}
}
}
printTrace
(
'DevFS: Sync finished'
);
printTrace
(
'DevFS: Sync finished'
);
return
UpdateFSReport
(
success:
true
,
syncedBytes:
syncedBytes
,
return
UpdateFSReport
(
success:
true
,
syncedBytes:
syncedBytes
,
invalidatedSourcesCount:
invalidatedFiles
.
length
);
invalidatedSourcesCount:
invalidatedFiles
.
length
);
}
}
void
_scanFile
(
Uri
deviceUri
,
FileSystemEntity
file
)
{
final
DevFSContent
content
=
_entries
.
putIfAbsent
(
deviceUri
,
()
=>
DevFSFileContent
(
file
));
content
.
_exists
=
true
;
}
void
_scanBundleEntry
(
String
archivePath
,
DevFSContent
content
)
{
// We write the assets into the AssetBundle working dir so that they
// are in the same location in DevFS and the iOS simulator.
final
Uri
deviceUri
=
fs
.
path
.
toUri
(
fs
.
path
.
join
(
getAssetBuildDirectory
(),
archivePath
));
_entries
[
deviceUri
]
=
content
;
content
.
_exists
=
true
;
}
bool
_shouldIgnore
(
Uri
deviceUri
)
{
final
List
<
String
>
ignoredUriPrefixes
=
<
String
>[
'android/'
,
_asUriPath
(
getBuildDirectory
()),
'ios/'
,
'.pub/'
];
for
(
String
ignoredUriPrefix
in
ignoredUriPrefixes
)
{
if
(
deviceUri
.
path
.
startsWith
(
ignoredUriPrefix
))
return
true
;
}
return
false
;
}
bool
_shouldSkip
(
FileSystemEntity
file
,
String
relativePath
,
Uri
directoryUriOnDevice
,
{
bool
ignoreDotFiles
=
true
,
})
{
if
(
file
is
Directory
)
{
// Skip non-files.
return
true
;
}
assert
((
file
is
Link
)
||
(
file
is
File
));
final
String
basename
=
fs
.
path
.
basename
(
file
.
path
);
if
(
ignoreDotFiles
&&
basename
.
startsWith
(
'.'
))
{
// Skip dot files, but not the '.packages' file (even though in dart1
// mode devfs['.packages'] will be overwritten with synthesized string content).
return
basename
!=
'.packages'
;
}
return
false
;
}
Uri
_directoryUriOnDevice
(
Uri
directoryUriOnDevice
,
Directory
directory
)
{
if
(
directoryUriOnDevice
==
null
)
{
final
String
relativeRootPath
=
fs
.
path
.
relative
(
directory
.
path
,
from:
rootDirectory
.
path
);
if
(
relativeRootPath
==
'.'
)
{
directoryUriOnDevice
=
Uri
();
}
else
{
directoryUriOnDevice
=
fs
.
path
.
toUri
(
relativeRootPath
);
}
}
return
directoryUriOnDevice
;
}
/// Scan all files from the [fileFilter] that are contained in [directory] and
/// pass various filters (e.g. ignoreDotFiles).
Future
<
bool
>
_scanFilteredDirectory
(
Set
<
String
>
fileFilter
,
Directory
directory
,
{
Uri
directoryUriOnDevice
,
bool
ignoreDotFiles
=
true
,
})
async
{
directoryUriOnDevice
=
_directoryUriOnDevice
(
directoryUriOnDevice
,
directory
);
try
{
final
String
absoluteDirectoryPath
=
canonicalizePath
(
directory
.
path
);
// For each file in the file filter.
for
(
String
filePath
in
fileFilter
)
{
if
(!
filePath
.
startsWith
(
absoluteDirectoryPath
))
{
// File is not in this directory. Skip.
continue
;
}
final
String
relativePath
=
fs
.
path
.
relative
(
filePath
,
from:
directory
.
path
);
final
FileSystemEntity
file
=
fs
.
file
(
filePath
);
if
(
_shouldSkip
(
file
,
relativePath
,
directoryUriOnDevice
,
ignoreDotFiles:
ignoreDotFiles
))
{
continue
;
}
final
Uri
deviceUri
=
directoryUriOnDevice
.
resolveUri
(
fs
.
path
.
toUri
(
relativePath
));
if
(!
_shouldIgnore
(
deviceUri
))
_scanFile
(
deviceUri
,
file
);
}
}
on
FileSystemException
catch
(
e
)
{
_printScanDirectoryError
(
directory
.
path
,
e
);
return
false
;
}
return
true
;
}
/// Scan all files in [directory] that pass various filters (e.g. ignoreDotFiles).
Future
<
bool
>
_scanDirectory
(
Directory
directory
,
{
Uri
directoryUriOnDevice
,
bool
recursive
=
false
,
bool
ignoreDotFiles
=
true
,
Set
<
String
>
fileFilter
,
})
async
{
directoryUriOnDevice
=
_directoryUriOnDevice
(
directoryUriOnDevice
,
directory
);
if
((
fileFilter
!=
null
)
&&
fileFilter
.
isNotEmpty
)
{
// When the fileFilter isn't empty, we can skip crawling the directory
// tree and instead use the fileFilter as the source of potential files.
return
_scanFilteredDirectory
(
fileFilter
,
directory
,
directoryUriOnDevice:
directoryUriOnDevice
,
ignoreDotFiles:
ignoreDotFiles
);
}
try
{
final
Stream
<
FileSystemEntity
>
files
=
directory
.
list
(
recursive:
recursive
,
followLinks:
false
);
await
for
(
FileSystemEntity
file
in
files
)
{
if
(!
devFSConfig
.
noDirectorySymlinks
&&
(
file
is
Link
))
{
// Check if this is a symlink to a directory and skip it.
try
{
final
FileSystemEntityType
linkType
=
fs
.
statSync
(
file
.
resolveSymbolicLinksSync
()).
type
;
if
(
linkType
==
FileSystemEntityType
.
directory
)
continue
;
}
on
FileSystemException
catch
(
e
)
{
_printScanDirectoryError
(
file
.
path
,
e
);
continue
;
}
}
final
String
relativePath
=
fs
.
path
.
relative
(
file
.
path
,
from:
directory
.
path
);
if
(
_shouldSkip
(
file
,
relativePath
,
directoryUriOnDevice
,
ignoreDotFiles:
ignoreDotFiles
))
{
continue
;
}
final
Uri
deviceUri
=
directoryUriOnDevice
.
resolveUri
(
fs
.
path
.
toUri
(
relativePath
));
if
(!
_shouldIgnore
(
deviceUri
))
_scanFile
(
deviceUri
,
file
);
}
}
on
FileSystemException
catch
(
e
)
{
_printScanDirectoryError
(
directory
.
path
,
e
);
return
false
;
}
return
true
;
}
void
_printScanDirectoryError
(
String
path
,
Exception
e
)
{
printError
(
'Error while scanning
$path
.
\n
'
'Hot Reload might not work until the following error is resolved:
\n
'
'
$e
\n
'
);
}
Future
<
void
>
_scanPackages
(
Set
<
String
>
fileFilter
)
async
{
StringBuffer
sb
;
final
PackageMap
packageMap
=
PackageMap
(
_packagesFilePath
);
for
(
String
packageName
in
packageMap
.
map
.
keys
)
{
final
Uri
packageUri
=
packageMap
.
map
[
packageName
];
final
String
packagePath
=
fs
.
path
.
fromUri
(
packageUri
);
final
Directory
packageDirectory
=
fs
.
directory
(
packageUri
);
Uri
directoryUriOnDevice
=
fs
.
path
.
toUri
(
fs
.
path
.
join
(
'packages'
,
packageName
)
+
fs
.
path
.
separator
);
bool
packageExists
=
packageDirectory
.
existsSync
();
if
(!
packageExists
)
{
// If the package directory doesn't exist at all, we ignore it.
continue
;
}
if
(
fs
.
path
.
isWithin
(
rootDirectory
.
path
,
packagePath
))
{
// We already scanned everything under the root directory.
directoryUriOnDevice
=
fs
.
path
.
toUri
(
fs
.
path
.
relative
(
packagePath
,
from:
rootDirectory
.
path
)
+
fs
.
path
.
separator
);
}
else
{
packageExists
=
await
_scanDirectory
(
packageDirectory
,
directoryUriOnDevice:
directoryUriOnDevice
,
recursive:
true
,
fileFilter:
fileFilter
);
}
if
(
packageExists
)
{
sb
??=
StringBuffer
();
sb
.
writeln
(
'
$packageName
:
$directoryUriOnDevice
'
);
}
}
}
}
}
/// Converts a platform-specific file path to a platform-independent Uri path.
/// Converts a platform-specific file path to a platform-independent Uri path.
String
_asUriPath
(
String
filePath
)
=>
fs
.
path
.
toUri
(
filePath
).
path
+
'/'
;
String
_asUriPath
(
String
filePath
)
=>
fs
.
path
.
toUri
(
filePath
).
path
+
'/'
;
packages/flutter_tools/lib/src/resident_runner.dart
View file @
cd803ac7
...
@@ -18,9 +18,7 @@ import 'base/utils.dart';
...
@@ -18,9 +18,7 @@ import 'base/utils.dart';
import
'build_info.dart'
;
import
'build_info.dart'
;
import
'codegen.dart'
;
import
'codegen.dart'
;
import
'compile.dart'
;
import
'compile.dart'
;
import
'dart/dependencies.dart'
;
import
'dart/package_map.dart'
;
import
'dart/package_map.dart'
;
import
'dependency_checker.dart'
;
import
'devfs.dart'
;
import
'devfs.dart'
;
import
'device.dart'
;
import
'device.dart'
;
import
'globals.dart'
;
import
'globals.dart'
;
...
@@ -444,10 +442,10 @@ class FlutterDevice {
...
@@ -444,10 +442,10 @@ class FlutterDevice {
DateTime
firstBuildTime
,
DateTime
firstBuildTime
,
bool
bundleFirstUpload
=
false
,
bool
bundleFirstUpload
=
false
,
bool
bundleDirty
=
false
,
bool
bundleDirty
=
false
,
Set
<
String
>
fileFilter
,
bool
fullRestart
=
false
,
bool
fullRestart
=
false
,
String
projectRootPath
,
String
projectRootPath
,
String
pathToReload
,
String
pathToReload
,
@required
List
<
String
>
invalidatedFiles
,
})
async
{
})
async
{
final
Status
devFSStatus
=
logger
.
startProgress
(
final
Status
devFSStatus
=
logger
.
startProgress
(
'Syncing files to device
${device.name}
...'
,
'Syncing files to device
${device.name}
...'
,
...
@@ -462,13 +460,13 @@ class FlutterDevice {
...
@@ -462,13 +460,13 @@ class FlutterDevice {
firstBuildTime:
firstBuildTime
,
firstBuildTime:
firstBuildTime
,
bundleFirstUpload:
bundleFirstUpload
,
bundleFirstUpload:
bundleFirstUpload
,
bundleDirty:
bundleDirty
,
bundleDirty:
bundleDirty
,
fileFilter:
fileFilter
,
generator:
generator
,
generator:
generator
,
fullRestart:
fullRestart
,
fullRestart:
fullRestart
,
dillOutputPath:
dillOutputPath
,
dillOutputPath:
dillOutputPath
,
trackWidgetCreation:
trackWidgetCreation
,
trackWidgetCreation:
trackWidgetCreation
,
projectRootPath:
projectRootPath
,
projectRootPath:
projectRootPath
,
pathToReload:
pathToReload
,
pathToReload:
pathToReload
,
invalidatedFiles:
invalidatedFiles
,
);
);
}
on
DevFSException
{
}
on
DevFSException
{
devFSStatus
.
cancel
();
devFSStatus
.
cancel
();
...
@@ -945,21 +943,19 @@ abstract class ResidentRunner {
...
@@ -945,21 +943,19 @@ abstract class ResidentRunner {
}
}
bool
hasDirtyDependencies
(
FlutterDevice
device
)
{
bool
hasDirtyDependencies
(
FlutterDevice
device
)
{
/// When using the build system, dependency analysis is handled by build
/// runner instead.
if
(
experimentalBuildEnabled
)
{
return
false
;
}
final
DartDependencySetBuilder
dartDependencySetBuilder
=
DartDependencySetBuilder
(
mainPath
,
packagesFilePath
);
final
DependencyChecker
dependencyChecker
=
DependencyChecker
(
dartDependencySetBuilder
,
assetBundle
);
if
(
device
.
package
.
packagesFile
==
null
||
!
device
.
package
.
packagesFile
.
existsSync
())
{
if
(
device
.
package
.
packagesFile
==
null
||
!
device
.
package
.
packagesFile
.
existsSync
())
{
return
true
;
return
true
;
}
}
final
DateTime
lastBuildTime
=
device
.
package
.
packagesFile
.
statSync
().
modified
;
// Leave pubspec null to check all dependencies.
final
ProjectFileInvalidator
projectFileInvalidator
=
ProjectFileInvalidator
(
device
.
package
.
packagesFile
.
path
,
null
);
return
dependencyChecker
.
check
(
lastBuildTime
);
projectFileInvalidator
.
findInvalidated
();
final
int
lastBuildTime
=
device
.
package
.
packagesFile
.
statSync
().
modified
.
millisecondsSinceEpoch
;
for
(
int
updateTime
in
projectFileInvalidator
.
updateTime
.
values
)
{
if
(
updateTime
>
lastBuildTime
)
{
return
true
;
}
}
return
false
;
}
}
Future
<
void
>
preStop
()
async
{
}
Future
<
void
>
preStop
()
async
{
}
...
...
packages/flutter_tools/lib/src/run_hot.dart
View file @
cd803ac7
...
@@ -7,29 +7,28 @@ import 'dart:async';
...
@@ -7,29 +7,28 @@ import 'dart:async';
import
'package:json_rpc_2/error_code.dart'
as
rpc_error_code
;
import
'package:json_rpc_2/error_code.dart'
as
rpc_error_code
;
import
'package:json_rpc_2/json_rpc_2.dart'
as
rpc
;
import
'package:json_rpc_2/json_rpc_2.dart'
as
rpc
;
import
'package:meta/meta.dart'
;
import
'package:meta/meta.dart'
;
import
'package:yaml/yaml.dart'
;
import
'base/common.dart'
;
import
'base/common.dart'
;
import
'base/context.dart'
;
import
'base/context.dart'
;
import
'base/file_system.dart'
;
import
'base/file_system.dart'
;
import
'base/logger.dart'
;
import
'base/logger.dart'
;
import
'base/platform.dart'
;
import
'base/terminal.dart'
;
import
'base/terminal.dart'
;
import
'base/utils.dart'
;
import
'base/utils.dart'
;
import
'build_info.dart'
;
import
'build_info.dart'
;
import
'codegen.dart'
;
import
'compile.dart'
;
import
'compile.dart'
;
import
'convert.dart'
;
import
'convert.dart'
;
import
'dart/dependencies.dart'
;
import
'dart/package_map.dart'
;
import
'dart/pub.dart'
;
import
'devfs.dart'
;
import
'devfs.dart'
;
import
'device.dart'
;
import
'device.dart'
;
import
'globals.dart'
;
import
'globals.dart'
;
import
'project.dart'
;
import
'resident_runner.dart'
;
import
'resident_runner.dart'
;
import
'usage.dart'
;
import
'usage.dart'
;
import
'vmservice.dart'
;
import
'vmservice.dart'
;
class
HotRunnerConfig
{
class
HotRunnerConfig
{
/// Should the hot runner compute the minimal Dart dependencies?
bool
computeDartDependencies
=
true
;
/// Should the hot runner assume that the minimal Dart dependencies do not change?
/// Should the hot runner assume that the minimal Dart dependencies do not change?
bool
stableDartDependencies
=
false
;
bool
stableDartDependencies
=
false
;
/// A hook for implementations to perform any necessary initialization prior
/// A hook for implementations to perform any necessary initialization prior
...
@@ -71,6 +70,7 @@ class HotRunner extends ResidentRunner {
...
@@ -71,6 +70,7 @@ class HotRunner extends ResidentRunner {
bool
saveCompilationTrace
=
false
,
bool
saveCompilationTrace
=
false
,
bool
stayResident
=
true
,
bool
stayResident
=
true
,
bool
ipv6
=
false
,
bool
ipv6
=
false
,
FlutterProject
flutterProject
,
})
:
super
(
devices
,
})
:
super
(
devices
,
target:
target
,
target:
target
,
debuggingOptions:
debuggingOptions
,
debuggingOptions:
debuggingOptions
,
...
@@ -79,14 +79,19 @@ class HotRunner extends ResidentRunner {
...
@@ -79,14 +79,19 @@ class HotRunner extends ResidentRunner {
packagesFilePath:
packagesFilePath
,
packagesFilePath:
packagesFilePath
,
saveCompilationTrace:
saveCompilationTrace
,
saveCompilationTrace:
saveCompilationTrace
,
stayResident:
stayResident
,
stayResident:
stayResident
,
ipv6:
ipv6
);
ipv6:
ipv6
)
{
fileInvalidator
=
ProjectFileInvalidator
(
packagesFilePath
??
fs
.
path
.
absolute
(
PackageMap
.
globalPackagesPath
),
flutterProject
,
);
}
final
bool
benchmarkMode
;
final
bool
benchmarkMode
;
final
File
applicationBinary
;
final
File
applicationBinary
;
final
bool
hostIsIde
;
final
bool
hostIsIde
;
bool
_didAttach
=
false
;
bool
_didAttach
=
false
;
Set
<
String
>
_dartDependencies
;
final
String
dillOutputPath
;
final
String
dillOutputPath
;
ProjectFileInvalidator
fileInvalidator
;
final
Map
<
String
,
List
<
int
>>
benchmarkData
=
<
String
,
List
<
int
>>{};
final
Map
<
String
,
List
<
int
>>
benchmarkData
=
<
String
,
List
<
int
>>{};
// The initial launch is from a snapshot.
// The initial launch is from a snapshot.
...
@@ -98,54 +103,8 @@ class HotRunner extends ResidentRunner {
...
@@ -98,54 +103,8 @@ class HotRunner extends ResidentRunner {
benchmarkData
[
name
].
add
(
value
);
benchmarkData
[
name
].
add
(
value
);
}
}
Future
<
bool
>
_refreshDartDependencies
()
async
{
Future
<
void
>
_reloadSourcesService
(
String
isolateId
,
if
(!
hotRunnerConfig
.
computeDartDependencies
)
{
{
bool
force
=
false
,
bool
pause
=
false
})
async
{
// Disabled.
return
true
;
}
if
(
_dartDependencies
!=
null
)
{
// Already computed.
return
true
;
}
try
{
// Will return immediately if pubspec.yaml is up-to-date.
await
pubGet
(
context:
PubContext
.
pubGet
,
directory:
projectRootPath
,
);
}
on
ToolExit
catch
(
error
)
{
printError
(
'Unable to reload your application because "flutter packages get" failed to update '
'package dependencies.
\n
'
'
$error
'
);
return
false
;
}
/// When using the build system, dependency analysis is handled by build
/// runner instead.
if
(
experimentalBuildEnabled
)
{
return
true
;
}
final
DartDependencySetBuilder
dartDependencySetBuilder
=
DartDependencySetBuilder
(
mainPath
,
packagesFilePath
);
try
{
_dartDependencies
=
Set
<
String
>.
from
(
dartDependencySetBuilder
.
build
());
}
on
DartDependencyException
catch
(
error
)
{
printError
(
'Your application could not be compiled, because its dependencies could not be established.
\n
'
'
$error
'
);
return
false
;
}
return
true
;
}
Future
<
void
>
_reloadSourcesService
(
String
isolateId
,
{
bool
force
=
false
,
bool
pause
=
false
,
})
async
{
// TODO(cbernaschina): check that isolateId is the id of the UI isolate.
// TODO(cbernaschina): check that isolateId is the id of the UI isolate.
final
OperationResult
result
=
await
restart
(
pauseAfterRestart:
pause
);
final
OperationResult
result
=
await
restart
(
pauseAfterRestart:
pause
);
if
(!
result
.
isOk
)
{
if
(!
result
.
isOk
)
{
...
@@ -257,7 +216,6 @@ class HotRunner extends ResidentRunner {
...
@@ -257,7 +216,6 @@ class HotRunner extends ResidentRunner {
// Measure time to perform a hot restart.
// Measure time to perform a hot restart.
printStatus
(
'Benchmarking hot restart'
);
printStatus
(
'Benchmarking hot restart'
);
await
restart
(
fullRestart:
true
);
await
restart
(
fullRestart:
true
);
// TODO(johnmccutchan): Modify script entry point.
printStatus
(
'Benchmarking hot reload'
);
printStatus
(
'Benchmarking hot reload'
);
// Measure time to perform a hot reload.
// Measure time to perform a hot reload.
await
restart
(
fullRestart:
false
);
await
restart
(
fullRestart:
false
);
...
@@ -296,12 +254,6 @@ class HotRunner extends ResidentRunner {
...
@@ -296,12 +254,6 @@ class HotRunner extends ResidentRunner {
return
1
;
return
1
;
}
}
// Determine the Dart dependencies eagerly.
if
(!
await
_refreshDartDependencies
())
{
// Some kind of source level error or missing file in the Dart code.
return
1
;
}
firstBuildTime
=
DateTime
.
now
();
firstBuildTime
=
DateTime
.
now
();
for
(
FlutterDevice
device
in
flutterDevices
)
{
for
(
FlutterDevice
device
in
flutterDevices
)
{
...
@@ -336,8 +288,6 @@ class HotRunner extends ResidentRunner {
...
@@ -336,8 +288,6 @@ class HotRunner extends ResidentRunner {
result
=
await
restart
(
fullRestart:
false
);
result
=
await
restart
(
fullRestart:
false
);
}
}
if
(!
result
.
isOk
)
{
if
(!
result
.
isOk
)
{
// TODO(johnmccutchan): Attempt to determine the number of errors that
// occurred and tighten this message.
printStatus
(
'Try again after fixing the above error(s).'
,
emphasis:
true
);
printStatus
(
'Try again after fixing the above error(s).'
,
emphasis:
true
);
}
}
}
else
if
(
lower
==
'l'
)
{
}
else
if
(
lower
==
'l'
)
{
...
@@ -364,10 +314,6 @@ class HotRunner extends ResidentRunner {
...
@@ -364,10 +314,6 @@ class HotRunner extends ResidentRunner {
}
}
Future
<
UpdateFSReport
>
_updateDevFS
({
bool
fullRestart
=
false
})
async
{
Future
<
UpdateFSReport
>
_updateDevFS
({
bool
fullRestart
=
false
})
async
{
if
(!
await
_refreshDartDependencies
())
{
// Did not update DevFS because of a Dart source error.
return
UpdateFSReport
(
success:
false
);
}
final
bool
isFirstUpload
=
assetBundle
.
wasBuiltOnce
()
==
false
;
final
bool
isFirstUpload
=
assetBundle
.
wasBuiltOnce
()
==
false
;
final
bool
rebuildBundle
=
assetBundle
.
needsBuild
();
final
bool
rebuildBundle
=
assetBundle
.
needsBuild
();
if
(
rebuildBundle
)
{
if
(
rebuildBundle
)
{
...
@@ -376,7 +322,7 @@ class HotRunner extends ResidentRunner {
...
@@ -376,7 +322,7 @@ class HotRunner extends ResidentRunner {
if
(
result
!=
0
)
if
(
result
!=
0
)
return
UpdateFSReport
(
success:
false
);
return
UpdateFSReport
(
success:
false
);
}
}
final
List
<
String
>
invalidatedFiles
=
fileInvalidator
.
findInvalidated
();
final
UpdateFSReport
results
=
UpdateFSReport
(
success:
true
);
final
UpdateFSReport
results
=
UpdateFSReport
(
success:
true
);
for
(
FlutterDevice
device
in
flutterDevices
)
{
for
(
FlutterDevice
device
in
flutterDevices
)
{
results
.
incorporateResults
(
await
device
.
updateDevFS
(
results
.
incorporateResults
(
await
device
.
updateDevFS
(
...
@@ -386,39 +332,15 @@ class HotRunner extends ResidentRunner {
...
@@ -386,39 +332,15 @@ class HotRunner extends ResidentRunner {
firstBuildTime:
firstBuildTime
,
firstBuildTime:
firstBuildTime
,
bundleFirstUpload:
isFirstUpload
,
bundleFirstUpload:
isFirstUpload
,
bundleDirty:
isFirstUpload
==
false
&&
rebuildBundle
,
bundleDirty:
isFirstUpload
==
false
&&
rebuildBundle
,
fileFilter:
_dartDependencies
,
fullRestart:
fullRestart
,
fullRestart:
fullRestart
,
projectRootPath:
projectRootPath
,
projectRootPath:
projectRootPath
,
pathToReload:
getReloadPath
(
fullRestart:
fullRestart
),
pathToReload:
getReloadPath
(
fullRestart:
fullRestart
),
invalidatedFiles:
invalidatedFiles
,
));
));
}
}
if
(!
results
.
success
)
{
return
results
;
}
if
(!
hotRunnerConfig
.
stableDartDependencies
)
{
// Clear the set after the sync so they are recomputed next time.
_dartDependencies
=
null
;
}
return
results
;
return
results
;
}
}
Future
<
void
>
_evictDirtyAssets
()
{
final
List
<
Future
<
Map
<
String
,
dynamic
>>>
futures
=
<
Future
<
Map
<
String
,
dynamic
>>>[];
for
(
FlutterDevice
device
in
flutterDevices
)
{
if
(
device
.
devFS
.
assetPathsToEvict
.
isEmpty
)
continue
;
if
(
device
.
views
.
first
.
uiIsolate
==
null
)
{
printError
(
'Application isolate not found for
$device
'
);
continue
;
}
for
(
String
assetPath
in
device
.
devFS
.
assetPathsToEvict
)
futures
.
add
(
device
.
views
.
first
.
uiIsolate
.
flutterEvictAsset
(
assetPath
));
device
.
devFS
.
assetPathsToEvict
.
clear
();
}
return
Future
.
wait
<
Map
<
String
,
dynamic
>>(
futures
);
}
void
_resetDirtyAssets
()
{
void
_resetDirtyAssets
()
{
for
(
FlutterDevice
device
in
flutterDevices
)
for
(
FlutterDevice
device
in
flutterDevices
)
device
.
devFS
.
assetPathsToEvict
.
clear
();
device
.
devFS
.
assetPathsToEvict
.
clear
();
...
@@ -811,9 +733,9 @@ class HotRunner extends ResidentRunner {
...
@@ -811,9 +733,9 @@ class HotRunner extends ResidentRunner {
return
OperationResult
(
OperationResult
.
ok
.
code
,
reloadMessage
);
return
OperationResult
(
OperationResult
.
ok
.
code
,
reloadMessage
);
}
}
}
}
assert
(
reassembleViews
.
isNotEmpty
);
printTrace
(
'Evicting dirty assets'
);
printTrace
(
'Evicting dirty assets'
);
await
_evictDirtyAssets
();
await
_evictDirtyAssets
();
assert
(
reassembleViews
.
isNotEmpty
);
printTrace
(
'Reassembling application'
);
printTrace
(
'Reassembling application'
);
bool
failedReassemble
=
false
;
bool
failedReassemble
=
false
;
final
List
<
Future
<
void
>>
futures
=
<
Future
<
void
>>[];
final
List
<
Future
<
void
>>
futures
=
<
Future
<
void
>>[];
...
@@ -886,7 +808,6 @@ class HotRunner extends ResidentRunner {
...
@@ -886,7 +808,6 @@ class HotRunner extends ResidentRunner {
// Only report timings if we reloaded a single view without any errors.
// Only report timings if we reloaded a single view without any errors.
if
((
reassembleViews
.
length
==
1
)
&&
!
failedReassemble
&&
shouldReportReloadTime
)
if
((
reassembleViews
.
length
==
1
)
&&
!
failedReassemble
&&
shouldReportReloadTime
)
flutterUsage
.
sendTiming
(
'hot'
,
'reload'
,
reloadDuration
);
flutterUsage
.
sendTiming
(
'hot'
,
'reload'
,
reloadDuration
);
return
OperationResult
(
return
OperationResult
(
failedReassemble
?
1
:
OperationResult
.
ok
.
code
,
failedReassemble
?
1
:
OperationResult
.
ok
.
code
,
reloadMessage
,
reloadMessage
,
...
@@ -965,6 +886,23 @@ class HotRunner extends ResidentRunner {
...
@@ -965,6 +886,23 @@ class HotRunner extends ResidentRunner {
}
}
}
}
Future
<
void
>
_evictDirtyAssets
()
{
final
List
<
Future
<
Map
<
String
,
dynamic
>>>
futures
=
<
Future
<
Map
<
String
,
dynamic
>>>[];
for
(
FlutterDevice
device
in
flutterDevices
)
{
if
(
device
.
devFS
.
assetPathsToEvict
.
isEmpty
)
continue
;
if
(
device
.
views
.
first
.
uiIsolate
==
null
)
{
printError
(
'Application isolate not found for
$device
'
);
continue
;
}
for
(
String
assetPath
in
device
.
devFS
.
assetPathsToEvict
)
{
futures
.
add
(
device
.
views
.
first
.
uiIsolate
.
flutterEvictAsset
(
assetPath
));
}
device
.
devFS
.
assetPathsToEvict
.
clear
();
}
return
Future
.
wait
<
Map
<
String
,
dynamic
>>(
futures
);
}
@override
@override
Future
<
void
>
cleanupAfterSignal
()
async
{
Future
<
void
>
cleanupAfterSignal
()
async
{
await
stopEchoingDeviceLog
();
await
stopEchoingDeviceLog
();
...
@@ -988,3 +926,106 @@ class HotRunner extends ResidentRunner {
...
@@ -988,3 +926,106 @@ class HotRunner extends ResidentRunner {
await
stopEchoingDeviceLog
();
await
stopEchoingDeviceLog
();
}
}
}
}
class
ProjectFileInvalidator
{
ProjectFileInvalidator
(
this
.
_packagesPath
,
this
.
_flutterProject
)
{
final
File
packagesFile
=
fs
.
file
(
_packagesPath
);
if
(
packagesFile
.
existsSync
())
{
_packagesUpdateTime
=
packagesFile
.
statSync
().
modified
.
millisecondsSinceEpoch
;
_packageMap
=
PackageMap
(
_packagesPath
).
map
;
}
else
{
_packagesUpdateTime
=
-
1
;
_packageMap
=
const
<
String
,
Uri
>{};
}
_computePackageMap
(
_packageMap
,
_flutterProject
);
}
// Used to avoid watching pubspec directories. This will not change even with pub upgrade,
// because that actually switches the directory and requires a corresponding
// update to .packages
static
const
String
_pubCachePathLinuxAndWindows
=
'.pub-cache'
;
static
const
String
_pubCachePathWindows
=
'Pub/Cache'
;
Map
<
String
,
Uri
>
_packageMap
;
final
String
_packagesPath
;
final
FlutterProject
_flutterProject
;
final
Map
<
String
,
int
>
_updateTime
=
<
String
,
int
>{};
int
_packagesUpdateTime
;
Map
<
String
,
int
>
get
updateTime
=>
_updateTime
;
@visibleForTesting
Map
<
String
,
Uri
>
get
packageMap
=>
_packageMap
;
static
void
_computePackageMap
(
Map
<
String
,
Uri
>
packageMap
,
FlutterProject
flutterProject
)
{
if
(
flutterProject
!=
null
&&
flutterProject
.
pubspecFile
.
existsSync
())
{
try
{
final
YamlMap
pubspec
=
loadYamlDocument
(
flutterProject
.
pubspecFile
.
readAsStringSync
()).
contents
;
final
YamlMap
dependencies
=
pubspec
[
'dependencies'
];
final
Set
<
String
>
relevantDependencies
=
Set
<
String
>.
from
(
dependencies
.
keys
);
// Remove any packages which were tagged as dev dependenices,
// But don't remove the app itself!
for
(
String
packageName
in
packageMap
.
keys
.
toList
())
{
if
(!
relevantDependencies
.
contains
(
packageName
)
&&
packageName
!=
flutterProject
.
manifest
.
appName
)
{
packageMap
.
remove
(
packageName
);
continue
;
}
}
}
catch
(
err
)
{
// If we detect a pubspec formatting problem, fallback to the packages file.
}
}
// Remove any packages which are derived from the pub cache.
for
(
String
packageName
in
packageMap
.
keys
.
toList
())
{
final
String
path
=
packageMap
[
packageName
].
path
;
if
((
platform
.
isWindows
&&
path
.
contains
(
_pubCachePathWindows
))
||
path
.
contains
(
_pubCachePathLinuxAndWindows
))
{
packageMap
.
remove
(
packageName
);
}
}
}
List
<
String
>
findInvalidated
()
{
final
File
packagesFile
=
fs
.
file
(
_packagesPath
);
if
(
packagesFile
.
existsSync
())
{
final
int
newPackagesUpdateTime
=
packagesFile
.
statSync
().
modified
.
millisecondsSinceEpoch
;
// Hot reloading with an updated package will often times kill a non-trivial
// appliction. This _might_ work, given certain application size and package
// constraints, so instead of exiting we print a warning so that the user has
// some hint on what went wrong.
if
(
newPackagesUpdateTime
>
_packagesUpdateTime
)
{
printError
(
'Warning: updated dependencies detected. The Flutter application will require a restart to safely use new packages.'
);
}
_packagesUpdateTime
=
newPackagesUpdateTime
;
}
final
List
<
String
>
invalidatedFiles
=
<
String
>[];
for
(
String
packageName
in
_packageMap
.
keys
)
{
final
Uri
packageUri
=
_packageMap
[
packageName
];
_scanDirectory
(
packageUri
,
invalidatedFiles
);
}
return
invalidatedFiles
;
}
void
_scanDirectory
(
Uri
path
,
List
<
String
>
invalidatedFiles
)
{
final
Directory
directory
=
fs
.
directory
(
path
);
if
(!
directory
.
existsSync
())
{
return
;
}
for
(
FileSystemEntity
entity
in
directory
.
listSync
(
recursive:
true
))
{
if
(
entity
.
path
.
endsWith
(
'.dart'
))
{
final
int
oldUpdatedAt
=
_updateTime
[
entity
.
path
];
final
int
updatedAt
=
fs
.
statSync
(
entity
.
path
).
modified
.
millisecondsSinceEpoch
;
if
(
oldUpdatedAt
==
null
||
updatedAt
>
oldUpdatedAt
)
{
// On windows convert to file uri in expected format.
if
(
platform
.
isWindows
)
{
final
Uri
uri
=
Uri
.
file
(
entity
.
path
,
windows:
platform
.
isWindows
);
invalidatedFiles
.
add
(
uri
.
toString
());
}
else
{
invalidatedFiles
.
add
(
entity
.
path
);
}
}
_updateTime
[
entity
.
path
]
=
updatedAt
;
}
}
}
}
packages/flutter_tools/pubspec.yaml
View file @
cd803ac7
...
@@ -9,7 +9,6 @@ environment:
...
@@ -9,7 +9,6 @@ environment:
dependencies
:
dependencies
:
# To update these, use "flutter update-packages --force-upgrade".
# To update these, use "flutter update-packages --force-upgrade".
analyzer
:
0.35.3
archive
:
2.0.8
archive
:
2.0.8
args
:
1.5.1
args
:
1.5.1
bsdiff
:
0.1.0
bsdiff
:
0.1.0
...
@@ -53,6 +52,7 @@ dependencies:
...
@@ -53,6 +52,7 @@ dependencies:
build_modules
:
1.0.9
build_modules
:
1.0.9
build_daemon
:
0.4.2
build_daemon
:
0.4.2
analyzer
:
0.35.3
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
async
:
2.0.8
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
async
:
2.0.8
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
bazel_worker
:
0.1.20
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
bazel_worker
:
0.1.20
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
boolean_selector
:
1.0.4
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
boolean_selector
:
1.0.4
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
...
@@ -100,8 +100,8 @@ dev_dependencies:
...
@@ -100,8 +100,8 @@ dev_dependencies:
collection
:
1.14.11
collection
:
1.14.11
mockito
:
4.0.0
mockito
:
4.0.0
file_testing
:
2.1.0
file_testing
:
2.1.0
test
:
1.5.3
vm_service_lib
:
3.14.2
vm_service_lib
:
3.14.2
test
:
1.5.3
build_runner
:
1.2.8
build_runner
:
1.2.8
build_vm_compilers
:
0.1.1+5
build_vm_compilers
:
0.1.1+5
build_test
:
0.10.6
build_test
:
0.10.6
...
...
packages/flutter_tools/test/commands/attach_test.dart
View file @
cd803ac7
...
@@ -120,6 +120,7 @@ void main() {
...
@@ -120,6 +120,7 @@ void main() {
debuggingOptions:
anyNamed
(
'debuggingOptions'
),
debuggingOptions:
anyNamed
(
'debuggingOptions'
),
packagesFilePath:
anyNamed
(
'packagesFilePath'
),
packagesFilePath:
anyNamed
(
'packagesFilePath'
),
usesTerminalUI:
anyNamed
(
'usesTerminalUI'
),
usesTerminalUI:
anyNamed
(
'usesTerminalUI'
),
flutterProject:
anyNamed
(
'flutterProject'
),
ipv6:
false
,
ipv6:
false
,
),
),
).
thenReturn
(
mockHotRunner
);
).
thenReturn
(
mockHotRunner
);
...
@@ -151,6 +152,7 @@ void main() {
...
@@ -151,6 +152,7 @@ void main() {
debuggingOptions:
anyNamed
(
'debuggingOptions'
),
debuggingOptions:
anyNamed
(
'debuggingOptions'
),
packagesFilePath:
anyNamed
(
'packagesFilePath'
),
packagesFilePath:
anyNamed
(
'packagesFilePath'
),
usesTerminalUI:
anyNamed
(
'usesTerminalUI'
),
usesTerminalUI:
anyNamed
(
'usesTerminalUI'
),
flutterProject:
anyNamed
(
'flutterProject'
),
ipv6:
false
,
ipv6:
false
,
),
),
)..
called
(
1
);
)..
called
(
1
);
...
@@ -225,6 +227,7 @@ void main() {
...
@@ -225,6 +227,7 @@ void main() {
debuggingOptions:
anyNamed
(
'debuggingOptions'
),
debuggingOptions:
anyNamed
(
'debuggingOptions'
),
packagesFilePath:
anyNamed
(
'packagesFilePath'
),
packagesFilePath:
anyNamed
(
'packagesFilePath'
),
usesTerminalUI:
anyNamed
(
'usesTerminalUI'
),
usesTerminalUI:
anyNamed
(
'usesTerminalUI'
),
flutterProject:
anyNamed
(
'flutterProject'
),
ipv6:
false
,
ipv6:
false
,
)).
thenReturn
(
mockHotRunner
);
)).
thenReturn
(
mockHotRunner
);
...
@@ -254,6 +257,7 @@ void main() {
...
@@ -254,6 +257,7 @@ void main() {
debuggingOptions:
anyNamed
(
'debuggingOptions'
),
debuggingOptions:
anyNamed
(
'debuggingOptions'
),
packagesFilePath:
anyNamed
(
'packagesFilePath'
),
packagesFilePath:
anyNamed
(
'packagesFilePath'
),
usesTerminalUI:
anyNamed
(
'usesTerminalUI'
),
usesTerminalUI:
anyNamed
(
'usesTerminalUI'
),
flutterProject:
anyNamed
(
'flutterProject'
),
ipv6:
false
,
ipv6:
false
,
)).
called
(
1
);
)).
called
(
1
);
},
overrides:
<
Type
,
Generator
>{
},
overrides:
<
Type
,
Generator
>{
...
...
packages/flutter_tools/test/dart_dependencies_test.dart
deleted
100644 → 0
View file @
bfac6048
// Copyright 2016 The Chromium 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/dart/dependencies.dart'
;
import
'package:flutter_tools/src/base/file_system.dart'
;
import
'src/common.dart'
;
import
'src/context.dart'
;
void
main
(
)
{
group
(
'DartDependencySetBuilder'
,
()
{
final
String
dataPath
=
fs
.
path
.
join
(
getFlutterRoot
(),
'packages'
,
'flutter_tools'
,
'test'
,
'data'
,
'dart_dependencies_test'
,
);
testUsingContext
(
'good'
,
()
{
final
String
testPath
=
fs
.
path
.
join
(
dataPath
,
'good'
);
final
String
mainPath
=
fs
.
path
.
join
(
testPath
,
'main.dart'
);
final
String
packagesPath
=
fs
.
path
.
join
(
testPath
,
'.packages'
);
final
DartDependencySetBuilder
builder
=
DartDependencySetBuilder
(
mainPath
,
packagesPath
);
final
Set
<
String
>
dependencies
=
builder
.
build
();
expect
(
dependencies
.
contains
(
canonicalizePath
(
mainPath
)),
isTrue
);
expect
(
dependencies
.
contains
(
canonicalizePath
(
fs
.
path
.
join
(
testPath
,
'foo.dart'
))),
isTrue
);
});
testUsingContext
(
'syntax_error'
,
()
{
final
String
testPath
=
fs
.
path
.
join
(
dataPath
,
'syntax_error'
);
final
String
mainPath
=
fs
.
path
.
join
(
testPath
,
'main.dart'
);
final
String
packagesPath
=
fs
.
path
.
join
(
testPath
,
'.packages'
);
final
DartDependencySetBuilder
builder
=
DartDependencySetBuilder
(
mainPath
,
packagesPath
);
try
{
builder
.
build
();
fail
(
'expect an exception to be thrown.'
);
}
on
DartDependencyException
catch
(
error
)
{
expect
(
error
.
toString
(),
contains
(
'foo.dart: Expected a string literal'
));
}
});
testUsingContext
(
'bad_path'
,
()
{
final
String
testPath
=
fs
.
path
.
join
(
dataPath
,
'bad_path'
);
final
String
mainPath
=
fs
.
path
.
join
(
testPath
,
'main.dart'
);
final
String
packagesPath
=
fs
.
path
.
join
(
testPath
,
'.packages'
);
final
DartDependencySetBuilder
builder
=
DartDependencySetBuilder
(
mainPath
,
packagesPath
);
try
{
builder
.
build
();
fail
(
'expect an exception to be thrown.'
);
}
on
DartDependencyException
catch
(
error
)
{
expect
(
error
.
toString
(),
contains
(
'amaze
${fs.path.separator}
and
${fs.path.separator}
astonish.dart'
));
}
});
testUsingContext
(
'bad_package'
,
()
{
final
String
testPath
=
fs
.
path
.
join
(
dataPath
,
'bad_package'
);
final
String
mainPath
=
fs
.
path
.
join
(
testPath
,
'main.dart'
);
final
String
packagesPath
=
fs
.
path
.
join
(
testPath
,
'.packages'
);
final
DartDependencySetBuilder
builder
=
DartDependencySetBuilder
(
mainPath
,
packagesPath
);
try
{
builder
.
build
();
fail
(
'expect an exception to be thrown.'
);
}
on
DartDependencyException
catch
(
error
)
{
expect
(
error
.
toString
(),
contains
(
'rochambeau'
));
expect
(
error
.
toString
(),
contains
(
'pubspec.yaml'
));
}
});
testUsingContext
(
'does not change ASCII casing of path'
,
()
{
final
String
testPath
=
fs
.
path
.
join
(
dataPath
,
'asci_casing'
);
final
String
mainPath
=
fs
.
path
.
join
(
testPath
,
'main.dart'
);
final
String
packagesPath
=
fs
.
path
.
join
(
testPath
,
'.packages'
);
final
DartDependencySetBuilder
builder
=
DartDependencySetBuilder
(
mainPath
,
packagesPath
);
final
Set
<
String
>
deps
=
builder
.
build
();
expect
(
deps
,
contains
(
endsWith
(
'This_Import_Has_fuNNy_casING.dart'
)));
});
testUsingContext
(
'bad_import'
,
()
{
final
String
testPath
=
fs
.
path
.
join
(
dataPath
,
'bad_import'
);
final
String
mainPath
=
fs
.
path
.
join
(
testPath
,
'main.dart'
);
final
String
packagesPath
=
fs
.
path
.
join
(
testPath
,
'.packages'
);
final
DartDependencySetBuilder
builder
=
DartDependencySetBuilder
(
mainPath
,
packagesPath
);
try
{
builder
.
build
();
fail
(
'expect an exception to be thrown.'
);
}
on
DartDependencyException
catch
(
error
)
{
expect
(
error
.
toString
(),
contains
(
'Unable to parse URI'
));
}
});
});
}
packages/flutter_tools/test/data/dart_dependencies_test/.dartignore
deleted
100644 → 0
View file @
bfac6048
packages/flutter_tools/test/data/dart_dependencies_test/asci_casing/.packages
deleted
100644 → 0
View file @
bfac6048
self:lib/
packages/flutter_tools/test/data/dart_dependencies_test/asci_casing/This_Import_Has_fuNNy_casING.dart
deleted
100644 → 0
View file @
bfac6048
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
String
dummy
=
'Hello'
;
packages/flutter_tools/test/data/dart_dependencies_test/asci_casing/analysis_options.yaml
deleted
100644 → 0
View file @
bfac6048
analyzer
:
exclude
:
-
'
**'
packages/flutter_tools/test/data/dart_dependencies_test/asci_casing/main.dart
deleted
100644 → 0
View file @
bfac6048
// Copyright 2017 The Chromium 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
'This_Import_Has_fuNNy_casING.dart'
;
void
main
(
)
{
print
(
dummy
);
}
packages/flutter_tools/test/data/dart_dependencies_test/asci_casing/pubspec.yaml
deleted
100644 → 0
View file @
bfac6048
name
:
self
packages/flutter_tools/test/data/dart_dependencies_test/bad_import/analysis_options.yaml
deleted
100644 → 0
View file @
bfac6048
analyzer
:
exclude
:
-
'
**'
packages/flutter_tools/test/data/dart_dependencies_test/bad_import/main.dart
deleted
100644 → 0
View file @
bfac6048
// Copyright 2017 The Chromium 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
'data://object.dart'
;
packages/flutter_tools/test/data/dart_dependencies_test/bad_import/pubspec.yaml
deleted
100644 → 0
View file @
bfac6048
name
:
self
packages/flutter_tools/test/data/dart_dependencies_test/bad_package/.packages
deleted
100644 → 0
View file @
bfac6048
self:lib/
packages/flutter_tools/test/data/dart_dependencies_test/bad_package/analysis_options.yaml
deleted
100644 → 0
View file @
bfac6048
analyzer
:
exclude
:
-
'
**'
packages/flutter_tools/test/data/dart_dependencies_test/bad_package/main.dart
deleted
100644 → 0
View file @
bfac6048
// Copyright 2016 The Chromium 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:rochambeau/you_have_your_orders_now_go_man_go.dart'
;
packages/flutter_tools/test/data/dart_dependencies_test/bad_package/pubspec.yaml
deleted
100644 → 0
View file @
bfac6048
name
:
self
packages/flutter_tools/test/data/dart_dependencies_test/bad_path/.packages
deleted
100644 → 0
View file @
bfac6048
self:lib/
packages/flutter_tools/test/data/dart_dependencies_test/bad_path/analysis_options.yaml
deleted
100644 → 0
View file @
bfac6048
analyzer
:
exclude
:
-
'
**'
packages/flutter_tools/test/data/dart_dependencies_test/bad_path/main.dart
deleted
100644 → 0
View file @
bfac6048
// Copyright 2016 The Chromium 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
'amaze/and/astonish.dart'
;
packages/flutter_tools/test/data/dart_dependencies_test/bad_path/pubspec.yaml
deleted
100644 → 0
View file @
bfac6048
name
:
self
packages/flutter_tools/test/data/dart_dependencies_test/changed_sdk_location/.packages
deleted
100644 → 0
View file @
bfac6048
flutter:file:///a/wild/non-existent/directory/has/appeared
sdk-move-test:lib/
packages/flutter_tools/test/data/dart_dependencies_test/changed_sdk_location/lib/main.dart
deleted
100644 → 0
View file @
bfac6048
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// No content
packages/flutter_tools/test/data/dart_dependencies_test/changed_sdk_location/pubspec.yaml
deleted
100644 → 0
View file @
bfac6048
name
:
sdk-move-test
environment
:
# The pub client defaults to an <2.0.0 sdk constraint which we need to explicitly overwrite.
sdk
:
"
>=2.0.0-dev.68.0
<3.0.0"
dependencies
:
flutter
:
sdk
:
flutter
packages/flutter_tools/test/data/dart_dependencies_test/good/.packages
deleted
100644 → 0
View file @
bfac6048
self:lib/
packages/flutter_tools/test/data/dart_dependencies_test/good/analysis_options.yaml
deleted
100644 → 0
View file @
bfac6048
analyzer
:
exclude
:
-
'
**'
packages/flutter_tools/test/data/dart_dependencies_test/good/foo.dart
deleted
100644 → 0
View file @
bfac6048
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
packages/flutter_tools/test/data/dart_dependencies_test/good/lib/bar.dart
deleted
100644 → 0
View file @
bfac6048
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
packages/flutter_tools/test/data/dart_dependencies_test/good/main.dart
deleted
100644 → 0
View file @
bfac6048
// Copyright 2016 The Chromium 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
'foo.dart'
;
import
'package:self/bar.dart'
;
packages/flutter_tools/test/data/dart_dependencies_test/good/pubspec.yaml
deleted
100644 → 0
View file @
bfac6048
name
:
self
packages/flutter_tools/test/data/dart_dependencies_test/syntax_error/.packages
deleted
100644 → 0
View file @
bfac6048
self:lib/
packages/flutter_tools/test/data/dart_dependencies_test/syntax_error/analysis_options.yaml
deleted
100644 → 0
View file @
bfac6048
analyzer
:
exclude
:
-
'
**'
packages/flutter_tools/test/data/dart_dependencies_test/syntax_error/foo.dart
deleted
100644 → 0
View file @
bfac6048
// Copyright 2016 The Chromium 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
bad
programmer
!
packages/flutter_tools/test/data/dart_dependencies_test/syntax_error/main.dart
deleted
100644 → 0
View file @
bfac6048
// Copyright 2016 The Chromium 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
'foo.dart'
;
packages/flutter_tools/test/data/dart_dependencies_test/syntax_error/pubspec.yaml
deleted
100644 → 0
View file @
bfac6048
name
:
self
packages/flutter_tools/test/dependency_checker_test.dart
deleted
100644 → 0
View file @
bfac6048
// Copyright 2016 The Chromium 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/file_system.dart'
;
import
'package:flutter_tools/src/cache.dart'
;
import
'package:flutter_tools/src/commands/devices.dart'
;
import
'package:flutter_tools/src/dart/dependencies.dart'
;
import
'package:flutter_tools/src/dependency_checker.dart'
;
import
'src/common.dart'
;
import
'src/context.dart'
;
void
main
(
)
{
group
(
'DependencyChecker'
,
()
{
final
String
dataPath
=
fs
.
path
.
join
(
getFlutterRoot
(),
'packages'
,
'flutter_tools'
,
'test'
,
'data'
,
'dart_dependencies_test'
,
);
FileSystem
testFileSystem
;
setUpAll
(()
{
Cache
.
disableLocking
();
});
setUp
(()
{
testFileSystem
=
MemoryFileSystem
();
});
testUsingContext
(
'good'
,
()
{
final
String
testPath
=
fs
.
path
.
join
(
dataPath
,
'good'
);
final
String
mainPath
=
fs
.
path
.
join
(
testPath
,
'main.dart'
);
final
String
fooPath
=
fs
.
path
.
join
(
testPath
,
'foo.dart'
);
final
String
barPath
=
fs
.
path
.
join
(
testPath
,
'lib'
,
'bar.dart'
);
final
String
packagesPath
=
fs
.
path
.
join
(
testPath
,
'.packages'
);
final
DartDependencySetBuilder
builder
=
DartDependencySetBuilder
(
mainPath
,
packagesPath
);
final
DependencyChecker
dependencyChecker
=
DependencyChecker
(
builder
,
null
);
// Set file modification time on all dependencies to be in the past.
final
DateTime
baseTime
=
DateTime
.
now
();
updateFileModificationTime
(
packagesPath
,
baseTime
,
-
10
);
updateFileModificationTime
(
mainPath
,
baseTime
,
-
10
);
updateFileModificationTime
(
fooPath
,
baseTime
,
-
10
);
updateFileModificationTime
(
barPath
,
baseTime
,
-
10
);
expect
(
dependencyChecker
.
check
(
baseTime
),
isFalse
);
// Set .packages file modification time to be in the future.
updateFileModificationTime
(
packagesPath
,
baseTime
,
20
);
expect
(
dependencyChecker
.
check
(
baseTime
),
isTrue
);
// Reset .packages file modification time.
updateFileModificationTime
(
packagesPath
,
baseTime
,
0
);
expect
(
dependencyChecker
.
check
(
baseTime
),
isFalse
);
// Set 'package:self/bar.dart' file modification time to be in the future.
updateFileModificationTime
(
barPath
,
baseTime
,
10
);
expect
(
dependencyChecker
.
check
(
baseTime
),
isTrue
);
});
testUsingContext
(
'syntax error'
,
()
{
final
String
testPath
=
fs
.
path
.
join
(
dataPath
,
'syntax_error'
);
final
String
mainPath
=
fs
.
path
.
join
(
testPath
,
'main.dart'
);
final
String
fooPath
=
fs
.
path
.
join
(
testPath
,
'foo.dart'
);
final
String
packagesPath
=
fs
.
path
.
join
(
testPath
,
'.packages'
);
final
DartDependencySetBuilder
builder
=
DartDependencySetBuilder
(
mainPath
,
packagesPath
);
final
DependencyChecker
dependencyChecker
=
DependencyChecker
(
builder
,
null
);
final
DateTime
baseTime
=
DateTime
.
now
();
// Set file modification time on all dependencies to be in the past.
updateFileModificationTime
(
packagesPath
,
baseTime
,
-
10
);
updateFileModificationTime
(
mainPath
,
baseTime
,
-
10
);
updateFileModificationTime
(
fooPath
,
baseTime
,
-
10
);
// Dependencies are considered dirty because there is a syntax error in
// the .dart file.
expect
(
dependencyChecker
.
check
(
baseTime
),
isTrue
);
});
/// Test a flutter tool move.
///
/// Tests that the flutter tool doesn't crash and displays a warning when its own location
/// changed since it was last referenced to in a package's .packages file.
testUsingContext
(
'moved flutter sdk'
,
()
async
{
final
Directory
tempDir
=
fs
.
systemTempDirectory
.
createTempSync
(
'flutter_dependency_checker_test.'
);
// Copy the golden input and let the test run in an isolated temporary in-memory file system.
const
LocalFileSystem
localFileSystem
=
LocalFileSystem
();
final
Directory
sourcePath
=
localFileSystem
.
directory
(
localFileSystem
.
path
.
join
(
dataPath
,
'changed_sdk_location'
));
copyDirectorySync
(
sourcePath
,
tempDir
);
fs
.
currentDirectory
=
tempDir
;
// Doesn't matter what commands we run. Arbitrarily list devices here.
await
createTestCommandRunner
(
DevicesCommand
()).
run
(<
String
>[
'devices'
]);
expect
(
testLogger
.
errorText
,
contains
(
'.packages'
));
tryToDelete
(
tempDir
);
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
testFileSystem
,
});
});
}
packages/flutter_tools/test/devfs_test.dart
View file @
cd803ac7
...
@@ -7,10 +7,8 @@ import 'dart:convert';
...
@@ -7,10 +7,8 @@ import 'dart:convert';
import
'package:file/file.dart'
;
import
'package:file/file.dart'
;
import
'package:file/memory.dart'
;
import
'package:file/memory.dart'
;
import
'package:flutter_tools/src/asset.dart'
;
import
'package:flutter_tools/src/base/io.dart'
;
import
'package:flutter_tools/src/base/io.dart'
;
import
'package:flutter_tools/src/base/file_system.dart'
;
import
'package:flutter_tools/src/base/file_system.dart'
;
import
'package:flutter_tools/src/build_info.dart'
;
import
'package:flutter_tools/src/devfs.dart'
;
import
'package:flutter_tools/src/devfs.dart'
;
import
'package:flutter_tools/src/vmservice.dart'
;
import
'package:flutter_tools/src/vmservice.dart'
;
import
'package:json_rpc_2/json_rpc_2.dart'
as
rpc
;
import
'package:json_rpc_2/json_rpc_2.dart'
as
rpc
;
...
@@ -22,16 +20,13 @@ import 'src/mocks.dart';
...
@@ -22,16 +20,13 @@ import 'src/mocks.dart';
void
main
(
)
{
void
main
(
)
{
FileSystem
fs
;
FileSystem
fs
;
String
filePath
;
String
filePath
;
String
filePath2
;
Directory
tempDir
;
Directory
tempDir
;
String
basePath
;
String
basePath
;
DevFS
devFS
;
DevFS
devFS
;
final
AssetBundle
assetBundle
=
AssetBundleFactory
.
defaultInstance
.
createBundle
();
setUpAll
(()
{
setUpAll
(()
{
fs
=
MemoryFileSystem
();
fs
=
MemoryFileSystem
();
filePath
=
fs
.
path
.
join
(
'lib'
,
'foo.txt'
);
filePath
=
fs
.
path
.
join
(
'lib'
,
'foo.txt'
);
filePath2
=
fs
.
path
.
join
(
'foo'
,
'bar.txt'
);
});
});
group
(
'DevFSContent'
,
()
{
group
(
'DevFSContent'
,
()
{
...
@@ -94,362 +89,6 @@ void main() {
...
@@ -94,362 +89,6 @@ void main() {
});
});
});
});
group
(
'devfs local'
,
()
{
final
MockDevFSOperations
devFSOperations
=
MockDevFSOperations
();
final
MockResidentCompiler
residentCompiler
=
MockResidentCompiler
();
setUpAll
(()
{
tempDir
=
_newTempDir
(
fs
);
basePath
=
tempDir
.
path
;
});
tearDownAll
(
_cleanupTempDirs
);
testUsingContext
(
'create dev file system'
,
()
async
{
// simulate workspace
final
File
file
=
fs
.
file
(
fs
.
path
.
join
(
basePath
,
filePath
));
await
file
.
parent
.
create
(
recursive:
true
);
file
.
writeAsBytesSync
(<
int
>[
1
,
2
,
3
]);
_packages
[
'my_project'
]
=
fs
.
path
.
toUri
(
'lib'
);
// simulate package
await
_createPackage
(
fs
,
'somepkg'
,
'somefile.txt'
);
devFS
=
DevFS
.
operations
(
devFSOperations
,
'test'
,
tempDir
);
await
devFS
.
create
();
devFSOperations
.
expectMessages
(<
String
>[
'create test'
]);
expect
(
devFS
.
assetPathsToEvict
,
isEmpty
);
UpdateFSReport
report
=
await
devFS
.
update
(
mainPath:
'lib/foo.txt'
,
generator:
residentCompiler
,
pathToReload:
'lib/foo.txt.dill'
,
trackWidgetCreation:
false
,
);
devFSOperations
.
expectMessages
(<
String
>[
'writeFile test lib/foo.txt.dill build/app.dill'
,
]);
expect
(
devFS
.
assetPathsToEvict
,
isEmpty
);
report
=
await
devFS
.
update
(
mainPath:
'lib/foo.txt'
,
generator:
residentCompiler
,
pathToReload:
'lib/foo.txt.dill'
,
trackWidgetCreation:
true
,
);
devFSOperations
.
expectMessages
(<
String
>[
'writeFile test lib/foo.txt.dill build/app.dill.track.dill'
,
]);
expect
(
devFS
.
assetPathsToEvict
,
isEmpty
);
expect
(
report
.
syncedBytes
,
22
);
expect
(
report
.
success
,
true
);
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
fs
,
});
testUsingContext
(
'add new file to local file system'
,
()
async
{
final
File
file
=
fs
.
file
(
fs
.
path
.
join
(
basePath
,
filePath2
));
await
file
.
parent
.
create
(
recursive:
true
);
file
.
writeAsBytesSync
(<
int
>[
1
,
2
,
3
,
4
,
5
,
6
,
7
]);
final
UpdateFSReport
report
=
await
devFS
.
update
(
mainPath:
'lib/foo.txt'
,
generator:
residentCompiler
,
pathToReload:
'lib/foo.txt.dill'
,
trackWidgetCreation:
false
,
);
devFSOperations
.
expectMessages
(<
String
>[
'writeFile test lib/foo.txt.dill build/app.dill'
,
]);
expect
(
devFS
.
assetPathsToEvict
,
isEmpty
);
expect
(
report
.
syncedBytes
,
22
);
expect
(
report
.
success
,
true
);
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
fs
,
});
testUsingContext
(
'modify existing file on local file system'
,
()
async
{
UpdateFSReport
report
=
await
devFS
.
update
(
mainPath:
'lib/foo.txt'
,
generator:
residentCompiler
,
pathToReload:
'lib/foo.txt.dill'
,
trackWidgetCreation:
false
,
);
devFSOperations
.
expectMessages
(<
String
>[
'writeFile test lib/foo.txt.dill build/app.dill'
,
]);
expect
(
devFS
.
assetPathsToEvict
,
isEmpty
);
expect
(
report
.
syncedBytes
,
22
);
expect
(
report
.
success
,
true
);
final
File
file
=
fs
.
file
(
fs
.
path
.
join
(
basePath
,
filePath
));
// Set the last modified time to 5 seconds in the past.
updateFileModificationTime
(
file
.
path
,
DateTime
.
now
(),
-
5
);
report
=
await
devFS
.
update
(
mainPath:
'lib/foo.txt'
,
generator:
residentCompiler
,
pathToReload:
'lib/foo.txt.dill'
,
trackWidgetCreation:
false
,
);
devFSOperations
.
expectMessages
(<
String
>[
'writeFile test lib/foo.txt.dill build/app.dill'
,
]);
expect
(
devFS
.
assetPathsToEvict
,
isEmpty
);
expect
(
report
.
syncedBytes
,
22
);
expect
(
report
.
success
,
true
);
await
file
.
writeAsBytes
(<
int
>[
1
,
2
,
3
,
4
,
5
,
6
]);
report
=
await
devFS
.
update
(
mainPath:
'lib/foo.txt'
,
generator:
residentCompiler
,
pathToReload:
'lib/foo.txt.dill'
,
trackWidgetCreation:
false
,
);
devFSOperations
.
expectMessages
(<
String
>[
'writeFile test lib/foo.txt.dill build/app.dill'
,
]);
expect
(
devFS
.
assetPathsToEvict
,
isEmpty
);
expect
(
report
.
syncedBytes
,
22
);
expect
(
report
.
success
,
true
);
// Set the last modified time to 5 seconds in the past.
updateFileModificationTime
(
file
.
path
,
DateTime
.
now
(),
-
5
);
report
=
await
devFS
.
update
(
mainPath:
'lib/foo.txt'
,
generator:
residentCompiler
,
pathToReload:
'lib/foo.txt.dill'
,
trackWidgetCreation:
true
,
);
devFSOperations
.
expectMessages
(<
String
>[
'writeFile test lib/foo.txt.dill build/app.dill.track.dill'
,
]);
expect
(
devFS
.
assetPathsToEvict
,
isEmpty
);
expect
(
report
.
syncedBytes
,
22
);
expect
(
report
.
success
,
true
);
await
file
.
writeAsBytes
(<
int
>[
1
,
2
,
3
,
4
,
5
,
6
]);
report
=
await
devFS
.
update
(
mainPath:
'lib/foo.txt'
,
generator:
residentCompiler
,
pathToReload:
'lib/foo.txt.dill'
,
trackWidgetCreation:
true
,
);
devFSOperations
.
expectMessages
(<
String
>[
'writeFile test lib/foo.txt.dill build/app.dill.track.dill'
,
]);
expect
(
devFS
.
assetPathsToEvict
,
isEmpty
);
expect
(
report
.
syncedBytes
,
22
);
expect
(
report
.
success
,
true
);
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
fs
,
});
testUsingContext
(
'delete a file from the local file system'
,
()
async
{
final
File
file
=
fs
.
file
(
fs
.
path
.
join
(
basePath
,
filePath
));
await
file
.
delete
();
final
UpdateFSReport
report
=
await
devFS
.
update
(
mainPath:
'lib/foo.txt'
,
generator:
residentCompiler
,
pathToReload:
'lib/foo.txt.dill'
,
trackWidgetCreation:
false
,
);
devFSOperations
.
expectMessages
(<
String
>[
'deleteFile test lib/foo.txt'
,
'writeFile test lib/foo.txt.dill build/app.dill'
,
]);
expect
(
devFS
.
assetPathsToEvict
,
isEmpty
);
expect
(
report
.
syncedBytes
,
22
);
expect
(
report
.
success
,
true
);
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
fs
,
});
testUsingContext
(
'add new package'
,
()
async
{
await
_createPackage
(
fs
,
'newpkg'
,
'anotherfile.txt'
);
UpdateFSReport
report
=
await
devFS
.
update
(
mainPath:
'lib/foo.txt'
,
generator:
residentCompiler
,
pathToReload:
'lib/foo.txt.dill'
,
trackWidgetCreation:
false
,
);
devFSOperations
.
expectMessages
(<
String
>[
'writeFile test lib/foo.txt.dill build/app.dill'
,
]);
expect
(
devFS
.
assetPathsToEvict
,
isEmpty
);
expect
(
report
.
syncedBytes
,
22
);
expect
(
report
.
success
,
true
);
report
=
await
devFS
.
update
(
mainPath:
'lib/foo.txt'
,
generator:
residentCompiler
,
pathToReload:
'lib/foo.txt.dill'
,
trackWidgetCreation:
true
,
);
devFSOperations
.
expectMessages
(<
String
>[
'writeFile test lib/foo.txt.dill build/app.dill.track.dill'
,
]);
expect
(
devFS
.
assetPathsToEvict
,
isEmpty
);
expect
(
report
.
syncedBytes
,
22
);
expect
(
report
.
success
,
true
);
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
fs
,
});
testUsingContext
(
'add new package with double slashes in URI'
,
()
async
{
const
String
packageName
=
'doubleslashpkg'
;
await
_createPackage
(
fs
,
packageName
,
'somefile.txt'
,
doubleSlash:
true
);
final
Set
<
String
>
fileFilter
=
<
String
>{};
final
List
<
Uri
>
pkgUris
=
<
Uri
>[
fs
.
path
.
toUri
(
basePath
)]..
addAll
(
_packages
.
values
);
for
(
Uri
pkgUri
in
pkgUris
)
{
if
(!
pkgUri
.
isAbsolute
)
{
pkgUri
=
fs
.
path
.
toUri
(
fs
.
path
.
join
(
basePath
,
pkgUri
.
path
));
}
fileFilter
.
addAll
(
fs
.
directory
(
pkgUri
)
.
listSync
(
recursive:
true
)
.
whereType
<
File
>()
.
map
<
String
>((
File
file
)
=>
canonicalizePath
(
file
.
path
))
.
toList
());
}
final
UpdateFSReport
report
=
await
devFS
.
update
(
mainPath:
'lib/foo.txt'
,
fileFilter:
fileFilter
,
generator:
residentCompiler
,
pathToReload:
'lib/foo.txt.dill'
,
trackWidgetCreation:
false
,
);
devFSOperations
.
expectMessages
(<
String
>[
'writeFile test lib/foo.txt.dill build/app.dill'
,
]);
expect
(
devFS
.
assetPathsToEvict
,
isEmpty
);
expect
(
report
.
syncedBytes
,
22
);
expect
(
report
.
success
,
true
);
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
fs
,
});
testUsingContext
(
'add an asset bundle'
,
()
async
{
assetBundle
.
entries
[
'a.txt'
]
=
DevFSStringContent
(
'abc'
);
final
UpdateFSReport
report
=
await
devFS
.
update
(
mainPath:
'lib/foo.txt'
,
bundle:
assetBundle
,
bundleDirty:
true
,
generator:
residentCompiler
,
pathToReload:
'lib/foo.txt.dill'
,
trackWidgetCreation:
false
,
);
devFSOperations
.
expectMessages
(<
String
>[
'writeFile test
${_inAssetBuildDirectory(fs, 'a.txt')}
'
,
'writeFile test lib/foo.txt.dill build/app.dill'
,
]);
expect
(
devFS
.
assetPathsToEvict
,
unorderedMatches
(<
String
>[
'a.txt'
]));
devFS
.
assetPathsToEvict
.
clear
();
expect
(
report
.
syncedBytes
,
25
);
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
fs
,
});
testUsingContext
(
'add a file to the asset bundle - bundleDirty'
,
()
async
{
assetBundle
.
entries
[
'b.txt'
]
=
DevFSStringContent
(
'abcd'
);
final
UpdateFSReport
report
=
await
devFS
.
update
(
mainPath:
'lib/foo.txt'
,
bundle:
assetBundle
,
bundleDirty:
true
,
generator:
residentCompiler
,
pathToReload:
'lib/foo.txt.dill'
,
trackWidgetCreation:
false
,
);
// Expect entire asset bundle written because bundleDirty is true
devFSOperations
.
expectMessages
(<
String
>[
'writeFile test
${_inAssetBuildDirectory(fs, 'a.txt')}
'
,
'writeFile test
${_inAssetBuildDirectory(fs, 'b.txt')}
'
,
'writeFile test lib/foo.txt.dill build/app.dill'
,
]);
expect
(
devFS
.
assetPathsToEvict
,
unorderedMatches
(<
String
>[
'a.txt'
,
'b.txt'
]));
devFS
.
assetPathsToEvict
.
clear
();
expect
(
report
.
syncedBytes
,
29
);
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
fs
,
});
testUsingContext
(
'add a file to the asset bundle'
,
()
async
{
assetBundle
.
entries
[
'c.txt'
]
=
DevFSStringContent
(
'12'
);
final
UpdateFSReport
report
=
await
devFS
.
update
(
mainPath:
'lib/foo.txt'
,
bundle:
assetBundle
,
generator:
residentCompiler
,
pathToReload:
'lib/foo.txt.dill'
,
trackWidgetCreation:
false
,
);
devFSOperations
.
expectMessages
(<
String
>[
'writeFile test
${_inAssetBuildDirectory(fs, 'c.txt')}
'
,
'writeFile test lib/foo.txt.dill build/app.dill'
,
]);
expect
(
devFS
.
assetPathsToEvict
,
unorderedMatches
(<
String
>[
'c.txt'
]));
devFS
.
assetPathsToEvict
.
clear
();
expect
(
report
.
syncedBytes
,
24
);
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
fs
,
});
testUsingContext
(
'delete a file from the asset bundle'
,
()
async
{
assetBundle
.
entries
.
remove
(
'c.txt'
);
final
UpdateFSReport
report
=
await
devFS
.
update
(
mainPath:
'lib/foo.txt'
,
bundle:
assetBundle
,
generator:
residentCompiler
,
pathToReload:
'lib/foo.txt.dill'
,
trackWidgetCreation:
false
,
);
devFSOperations
.
expectMessages
(<
String
>[
'deleteFile test
${_inAssetBuildDirectory(fs, 'c.txt')}
'
,
'writeFile test lib/foo.txt.dill build/app.dill'
,
]);
expect
(
devFS
.
assetPathsToEvict
,
unorderedMatches
(<
String
>[
'c.txt'
]));
devFS
.
assetPathsToEvict
.
clear
();
expect
(
report
.
syncedBytes
,
22
);
expect
(
report
.
success
,
true
);
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
fs
,
});
testUsingContext
(
'delete all files from the asset bundle'
,
()
async
{
assetBundle
.
entries
.
clear
();
final
UpdateFSReport
report
=
await
devFS
.
update
(
mainPath:
'lib/foo.txt'
,
bundle:
assetBundle
,
bundleDirty:
true
,
generator:
residentCompiler
,
pathToReload:
'lib/foo.txt.dill'
,
trackWidgetCreation:
false
,
);
devFSOperations
.
expectMessages
(<
String
>[
'deleteFile test
${_inAssetBuildDirectory(fs, 'a.txt')}
'
,
'deleteFile test
${_inAssetBuildDirectory(fs, 'b.txt')}
'
,
'writeFile test lib/foo.txt.dill build/app.dill'
,
]);
expect
(
devFS
.
assetPathsToEvict
,
unorderedMatches
(<
String
>[
'a.txt'
,
'b.txt'
,
]));
devFS
.
assetPathsToEvict
.
clear
();
expect
(
report
.
syncedBytes
,
22
);
expect
(
report
.
success
,
true
);
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
fs
,
});
testUsingContext
(
'delete dev file system'
,
()
async
{
await
devFS
.
destroy
();
devFSOperations
.
expectMessages
(<
String
>[
'destroy test'
]);
expect
(
devFS
.
assetPathsToEvict
,
isEmpty
);
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
fs
,
});
});
group
(
'devfs remote'
,
()
{
group
(
'devfs remote'
,
()
{
MockVMService
vmService
;
MockVMService
vmService
;
final
MockResidentCompiler
residentCompiler
=
MockResidentCompiler
();
final
MockResidentCompiler
residentCompiler
=
MockResidentCompiler
();
...
@@ -484,6 +123,7 @@ void main() {
...
@@ -484,6 +123,7 @@ void main() {
generator:
residentCompiler
,
generator:
residentCompiler
,
pathToReload:
'lib/foo.txt.dill'
,
pathToReload:
'lib/foo.txt.dill'
,
trackWidgetCreation:
false
,
trackWidgetCreation:
false
,
invalidatedFiles:
<
String
>[],
);
);
vmService
.
expectMessages
(<
String
>[
vmService
.
expectMessages
(<
String
>[
'writeFile test lib/foo.txt.dill'
,
'writeFile test lib/foo.txt.dill'
,
...
@@ -652,6 +292,3 @@ Future<void> _createPackage(FileSystem fs, String pkgName, String pkgFileName, {
...
@@ -652,6 +292,3 @@ Future<void> _createPackage(FileSystem fs, String pkgName, String pkgFileName, {
fs
.
file
(
fs
.
path
.
join
(
_tempDirs
[
0
].
path
,
'.packages'
)).
writeAsStringSync
(
sb
.
toString
());
fs
.
file
(
fs
.
path
.
join
(
_tempDirs
[
0
].
path
,
'.packages'
)).
writeAsStringSync
(
sb
.
toString
());
}
}
String
_inAssetBuildDirectory
(
FileSystem
fs
,
String
filename
)
{
return
'
${fs.path.toUri(getAssetBuildDirectory()).path}
/
$filename
'
;
}
packages/flutter_tools/test/hot_test.dart
View file @
cd803ac7
...
@@ -105,13 +105,13 @@ void main() {
...
@@ -105,13 +105,13 @@ void main() {
firstBuildTime:
anyNamed
(
'firstBuildTime'
),
firstBuildTime:
anyNamed
(
'firstBuildTime'
),
bundleFirstUpload:
anyNamed
(
'bundleFirstUpload'
),
bundleFirstUpload:
anyNamed
(
'bundleFirstUpload'
),
bundleDirty:
anyNamed
(
'bundleDirty'
),
bundleDirty:
anyNamed
(
'bundleDirty'
),
fileFilter:
anyNamed
(
'fileFilter'
),
generator:
anyNamed
(
'generator'
),
generator:
anyNamed
(
'generator'
),
fullRestart:
anyNamed
(
'fullRestart'
),
fullRestart:
anyNamed
(
'fullRestart'
),
dillOutputPath:
anyNamed
(
'dillOutputPath'
),
dillOutputPath:
anyNamed
(
'dillOutputPath'
),
trackWidgetCreation:
anyNamed
(
'trackWidgetCreation'
),
trackWidgetCreation:
anyNamed
(
'trackWidgetCreation'
),
projectRootPath:
anyNamed
(
'projectRootPath'
),
projectRootPath:
anyNamed
(
'projectRootPath'
),
pathToReload:
anyNamed
(
'pathToReload'
),
pathToReload:
anyNamed
(
'pathToReload'
),
invalidatedFiles:
anyNamed
(
'invalidatedFiles'
),
)).
thenAnswer
((
Invocation
_
)
=>
Future
<
UpdateFSReport
>.
value
(
)).
thenAnswer
((
Invocation
_
)
=>
Future
<
UpdateFSReport
>.
value
(
UpdateFSReport
(
success:
true
,
syncedBytes:
1000
,
invalidatedSourcesCount:
1
)));
UpdateFSReport
(
success:
true
,
syncedBytes:
1000
,
invalidatedSourcesCount:
1
)));
when
(
mockDevFs
.
assetPathsToEvict
).
thenReturn
(<
String
>{});
when
(
mockDevFs
.
assetPathsToEvict
).
thenReturn
(<
String
>{});
...
@@ -122,18 +122,6 @@ void main() {
...
@@ -122,18 +122,6 @@ void main() {
when
(
mockArtifacts
.
getArtifactPath
(
Artifact
.
flutterPatchedSdkPath
)).
thenReturn
(
'some/path'
);
when
(
mockArtifacts
.
getArtifactPath
(
Artifact
.
flutterPatchedSdkPath
)).
thenReturn
(
'some/path'
);
});
});
testUsingContext
(
'no setup'
,
()
async
{
final
MockDevice
mockDevice
=
MockDevice
();
when
(
mockDevice
.
supportsHotReload
).
thenReturn
(
true
);
when
(
mockDevice
.
supportsHotRestart
).
thenReturn
(
true
);
final
List
<
FlutterDevice
>
devices
=
<
FlutterDevice
>[
FlutterDevice
(
mockDevice
,
generator:
residentCompiler
,
trackWidgetCreation:
false
),
];
expect
((
await
HotRunner
(
devices
).
restart
(
fullRestart:
true
)).
isOk
,
false
);
},
overrides:
<
Type
,
Generator
>{
Artifacts:
()
=>
mockArtifacts
,
});
testUsingContext
(
'Does not hot restart when device does not support it'
,
()
async
{
testUsingContext
(
'Does not hot restart when device does not support it'
,
()
async
{
// Setup mocks
// Setup mocks
final
MockDevice
mockDevice
=
MockDevice
();
final
MockDevice
mockDevice
=
MockDevice
();
...
@@ -149,7 +137,7 @@ void main() {
...
@@ -149,7 +137,7 @@ void main() {
expect
(
result
.
message
,
'hotRestart not supported'
);
expect
(
result
.
message
,
'hotRestart not supported'
);
},
overrides:
<
Type
,
Generator
>{
},
overrides:
<
Type
,
Generator
>{
Artifacts:
()
=>
mockArtifacts
,
Artifacts:
()
=>
mockArtifacts
,
HotRunnerConfig:
()
=>
TestHotRunnerConfig
(
successfulSetup:
true
,
computeDartDependencies:
false
),
HotRunnerConfig:
()
=>
TestHotRunnerConfig
(
successfulSetup:
true
),
});
});
testUsingContext
(
'Does not hot restart when one of many devices does not support it'
,
()
async
{
testUsingContext
(
'Does not hot restart when one of many devices does not support it'
,
()
async
{
...
@@ -171,7 +159,7 @@ void main() {
...
@@ -171,7 +159,7 @@ void main() {
expect
(
result
.
message
,
'hotRestart not supported'
);
expect
(
result
.
message
,
'hotRestart not supported'
);
},
overrides:
<
Type
,
Generator
>{
},
overrides:
<
Type
,
Generator
>{
Artifacts:
()
=>
mockArtifacts
,
Artifacts:
()
=>
mockArtifacts
,
HotRunnerConfig:
()
=>
TestHotRunnerConfig
(
successfulSetup:
true
,
computeDartDependencies:
false
),
HotRunnerConfig:
()
=>
TestHotRunnerConfig
(
successfulSetup:
true
),
});
});
testUsingContext
(
'Does hot restarts when all devices support it'
,
()
async
{
testUsingContext
(
'Does hot restarts when all devices support it'
,
()
async
{
...
@@ -193,7 +181,7 @@ void main() {
...
@@ -193,7 +181,7 @@ void main() {
expect
(
result
.
message
,
isNot
(
'hotRestart not supported'
));
expect
(
result
.
message
,
isNot
(
'hotRestart not supported'
));
},
overrides:
<
Type
,
Generator
>{
},
overrides:
<
Type
,
Generator
>{
Artifacts:
()
=>
mockArtifacts
,
Artifacts:
()
=>
mockArtifacts
,
HotRunnerConfig:
()
=>
TestHotRunnerConfig
(
successfulSetup:
true
,
computeDartDependencies:
false
),
HotRunnerConfig:
()
=>
TestHotRunnerConfig
(
successfulSetup:
true
),
});
});
testUsingContext
(
'setup function fails'
,
()
async
{
testUsingContext
(
'setup function fails'
,
()
async
{
...
@@ -226,7 +214,7 @@ void main() {
...
@@ -226,7 +214,7 @@ void main() {
expect
(
result
.
message
,
isNot
(
'setupHotRestart failed'
));
expect
(
result
.
message
,
isNot
(
'setupHotRestart failed'
));
},
overrides:
<
Type
,
Generator
>{
},
overrides:
<
Type
,
Generator
>{
Artifacts:
()
=>
mockArtifacts
,
Artifacts:
()
=>
mockArtifacts
,
HotRunnerConfig:
()
=>
TestHotRunnerConfig
(
successfulSetup:
true
,
computeDartDependencies:
false
),
HotRunnerConfig:
()
=>
TestHotRunnerConfig
(
successfulSetup:
true
),
});
});
group
(
'shutdown hook tests'
,
()
{
group
(
'shutdown hook tests'
,
()
{
...
@@ -235,7 +223,6 @@ void main() {
...
@@ -235,7 +223,6 @@ void main() {
setUp
(()
{
setUp
(()
{
shutdownTestingConfig
=
TestHotRunnerConfig
(
shutdownTestingConfig
=
TestHotRunnerConfig
(
successfulSetup:
true
,
successfulSetup:
true
,
computeDartDependencies:
false
,
);
);
});
});
...
@@ -283,10 +270,7 @@ class MockDevice extends Mock implements Device {
...
@@ -283,10 +270,7 @@ class MockDevice extends Mock implements Device {
}
}
class
TestHotRunnerConfig
extends
HotRunnerConfig
{
class
TestHotRunnerConfig
extends
HotRunnerConfig
{
TestHotRunnerConfig
({
@required
this
.
successfulSetup
,
bool
computeDartDependencies
=
true
})
{
TestHotRunnerConfig
({
@required
this
.
successfulSetup
});
this
.
computeDartDependencies
=
computeDartDependencies
;
}
bool
successfulSetup
;
bool
successfulSetup
;
bool
shutdownHookCalled
=
false
;
bool
shutdownHookCalled
=
false
;
...
...
packages/flutter_tools/test/project_file_invalidator_test.dart
0 → 100644
View file @
cd803ac7
// Copyright 2019 The Chromium 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/file_system.dart'
;
import
'package:flutter_tools/src/base/logger.dart'
;
import
'package:flutter_tools/src/base/platform.dart'
;
import
'package:flutter_tools/src/project.dart'
;
import
'package:flutter_tools/src/run_hot.dart'
;
import
'package:mockito/mockito.dart'
;
import
'src/common.dart'
;
import
'src/context.dart'
;
void
main
(
)
{
final
Platform
windowsPlatform
=
MockPlatform
();
final
Platform
notWindowsPlatform
=
MockPlatform
();
final
BufferLogger
bufferLogger
=
BufferLogger
();
when
(
windowsPlatform
.
isWindows
).
thenReturn
(
true
);
when
(
notWindowsPlatform
.
isWindows
).
thenReturn
(
false
);
group
(
'ProjectFileInvalidator linux/mac'
,
()
{
final
MemoryFileSystem
memoryFileSystem
=
MemoryFileSystem
();
final
File
packagesFile
=
memoryFileSystem
.
file
(
'.packages'
)
..
createSync
()
..
writeAsStringSync
(
r''
'
foo:file:///foo/lib/
bar:file:///.pub-cache/bar/lib/
baz:file:///baz/lib/
test_package:file:///lib/
'''
);
final
File
pubspecFile
=
memoryFileSystem
.
file
(
'pubspec.yaml'
)
..
createSync
()
..
writeAsStringSync
(
r''
'
name: test_package
dependencies:
foo: any
bar:
dev_dependencies:
baz: any
'''
);
final
File
mainFile
=
memoryFileSystem
.
file
(
'lib/main.dart'
)
..
createSync
(
recursive:
true
)
..
writeAsStringSync
(
r''
'
void main() {}
'''
);
final
File
fooFile
=
memoryFileSystem
.
file
(
'foo/lib/foo.dart'
)
..
createSync
(
recursive:
true
)
..
writeAsStringSync
(
''
);
memoryFileSystem
.
file
(
'bar/lib/bar.dart'
)
..
createSync
(
recursive:
true
)
..
writeAsStringSync
(
''
);
final
File
bazFile
=
memoryFileSystem
.
file
(
'baz/lib/baz.dart'
)
..
createSync
(
recursive:
true
)
..
writeAsStringSync
(
''
);
testUsingContext
(
'No .packages, no pubspec'
,
()
async
{
// Instead of setting up multiple filesystems, passing a .packages file which does not exist.
final
ProjectFileInvalidator
invalidator
=
ProjectFileInvalidator
(
'.packages-wrong'
,
null
);
invalidator
.
findInvalidated
();
expect
(
invalidator
.
packageMap
,
isEmpty
);
expect
(
invalidator
.
updateTime
,
isEmpty
);
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
memoryFileSystem
,
Platform:
()
=>
notWindowsPlatform
,
});
testUsingContext
(
'.packages only'
,
()
async
{
final
ProjectFileInvalidator
invalidator
=
ProjectFileInvalidator
(
packagesFile
.
path
,
null
);
invalidator
.
findInvalidated
();
expect
(
invalidator
.
packageMap
,
<
String
,
Uri
>{
'foo'
:
Uri
.
parse
(
'file:///foo/lib/'
),
// Excluded because it is in pub cache.
// 'bar': Uri.parse('file:///.pub-cache/bar/lib/'),
'baz'
:
Uri
.
parse
(
'file:///baz/lib/'
),
'test_package'
:
Uri
.
parse
(
'file:///lib/'
),
});
expect
(
invalidator
.
updateTime
,
<
String
,
int
>{
'/baz/lib/baz.dart'
:
bazFile
.
statSync
().
modified
.
millisecondsSinceEpoch
,
'/lib/main.dart'
:
mainFile
.
statSync
().
modified
.
millisecondsSinceEpoch
,
'/foo/lib/foo.dart'
:
fooFile
.
statSync
().
modified
.
millisecondsSinceEpoch
,
});
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
memoryFileSystem
,
Platform:
()
=>
notWindowsPlatform
,
});
testUsingContext
(
'.packages and pubspec'
,
()
async
{
final
FlutterProject
flutterProject
=
await
FlutterProject
.
fromDirectory
(
pubspecFile
.
parent
);
final
ProjectFileInvalidator
invalidator
=
ProjectFileInvalidator
(
packagesFile
.
path
,
flutterProject
);
invalidator
.
findInvalidated
();
expect
(
invalidator
.
packageMap
,
<
String
,
Uri
>{
'foo'
:
Uri
.
parse
(
'file:///foo/lib/'
),
// Excluded because it is in pub cache.
// 'bar': Uri.parse('file:///.pub-cache/bar/lib/'),
// Excluded because it is a dev dependency/
// 'baz': Uri.parse('file:///baz/lib/'),
'test_package'
:
Uri
.
parse
(
'file:///lib/'
),
});
expect
(
invalidator
.
updateTime
,
<
String
,
int
>{
'/foo/lib/foo.dart'
:
fooFile
.
statSync
().
modified
.
millisecondsSinceEpoch
,
'/lib/main.dart'
:
mainFile
.
statSync
().
modified
.
millisecondsSinceEpoch
,
});
expect
(
invalidator
.
findInvalidated
(),
isEmpty
);
// Invalidate main.dart.
mainFile
.
writeAsStringSync
(
'void main() { }'
);
expect
(
invalidator
.
findInvalidated
(),
<
String
>[
'/lib/main.dart'
]);
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
memoryFileSystem
,
Platform:
()
=>
notWindowsPlatform
,
});
testUsingContext
(
'update to .packages triggers warning'
,
()
async
{
final
FlutterProject
flutterProject
=
await
FlutterProject
.
fromDirectory
(
pubspecFile
.
parent
);
final
ProjectFileInvalidator
invalidator
=
ProjectFileInvalidator
(
packagesFile
.
path
,
flutterProject
);
invalidator
.
findInvalidated
();
packagesFile
.
writeAsStringSync
(
r''
'
foo:file:///foo/lib/
bar:file:///.pub-cache/bar/lib/
baz:file:///baz/lib/
new_dep:file:///new_dep/lib/
test_package:file:///lib/
'''
);
invalidator
.
findInvalidated
();
expect
(
bufferLogger
.
errorText
,
'Warning: updated dependencies detected. The Flutter application will require a restart to safely use new packages.
\n
'
);
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
memoryFileSystem
,
Platform:
()
=>
notWindowsPlatform
,
Logger:
()
=>
bufferLogger
,
});
});
group
(
'ProjectFileInvalidator windows'
,
()
{
final
MemoryFileSystem
memoryFileSystem
=
MemoryFileSystem
(
style:
FileSystemStyle
.
windows
);
// On windows .packages still contains file Uris, albeit ones with the Drive prefix.
final
File
packagesFile
=
memoryFileSystem
.
file
(
r'C:\.packages'
)
..
createSync
()
..
writeAsStringSync
(
r''
'
foo:file:///C:/foo/lib/
bar:file:///C:/Pub/Cache/bar/lib/
baz:file:///C:/baz/lib/
test_package:file:///C:/lib/
'''
);
memoryFileSystem
.
file
(
r'C:\pubspec.yaml'
)
..
createSync
()
..
writeAsStringSync
(
r''
'
name: test_package
dependencies:
foo: any
bar:
dev_dependencies:
baz: any
'''
);
final
File
mainFile
=
memoryFileSystem
.
file
(
r'C:\lib\main.dart'
)
..
createSync
(
recursive:
true
)
..
writeAsStringSync
(
r''
'
void main() {}
'''
);
final
File
fooFile
=
memoryFileSystem
.
file
(
r'C:\foo\lib\foo.dart'
)
..
createSync
(
recursive:
true
)
..
writeAsStringSync
(
''
);
memoryFileSystem
.
file
(
r'C:\bar\lib\bar.dart'
)
..
createSync
(
recursive:
true
)
..
writeAsStringSync
(
''
);
final
File
bazFile
=
memoryFileSystem
.
file
(
r'C:\baz\lib\baz.dart'
)
..
createSync
(
recursive:
true
)
..
writeAsStringSync
(
''
);
testUsingContext
(
'No .packages, no pubspec'
,
()
async
{
// Instead of setting up multiple filesystems, passing a .packages file which does not exist.
final
ProjectFileInvalidator
invalidator
=
ProjectFileInvalidator
(
'.packages-wrong'
,
null
);
invalidator
.
findInvalidated
();
expect
(
invalidator
.
packageMap
,
isEmpty
);
expect
(
invalidator
.
updateTime
,
isEmpty
);
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
memoryFileSystem
,
Platform:
()
=>
windowsPlatform
,
});
testUsingContext
(
'.packages only'
,
()
async
{
final
ProjectFileInvalidator
invalidator
=
ProjectFileInvalidator
(
packagesFile
.
path
,
null
);
invalidator
.
findInvalidated
();
expect
(
invalidator
.
packageMap
,
<
String
,
Uri
>{
'foo'
:
Uri
.
file
(
r'C:\foo\lib\'
,
windows:
true
),
// Excluded because it is in pub cache.
// 'bar': Uri.parse('file:///Pub/Cache/bar/lib/'),
'baz'
:
Uri
.
file
(
r'C:\baz\lib\'
,
windows:
true
),
'test_package'
:
Uri
.
file
(
r'C:\lib\'
,
windows:
true
),
});
expect
(
invalidator
.
updateTime
,
<
String
,
int
>{
r'C:\baz\lib\baz.dart'
:
bazFile
.
statSync
().
modified
.
millisecondsSinceEpoch
,
r'C:\lib\main.dart'
:
mainFile
.
statSync
().
modified
.
millisecondsSinceEpoch
,
r'C:\foo\lib\foo.dart'
:
fooFile
.
statSync
().
modified
.
millisecondsSinceEpoch
,
});
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
memoryFileSystem
,
Platform:
()
=>
windowsPlatform
,
});
testUsingContext
(
'.packages and pubspec'
,
()
async
{
final
FlutterProject
flutterProject
=
await
FlutterProject
.
fromDirectory
(
fs
.
directory
(
r'C:\'
));
final
ProjectFileInvalidator
invalidator
=
ProjectFileInvalidator
(
packagesFile
.
path
,
flutterProject
);
invalidator
.
findInvalidated
();
expect
(
invalidator
.
packageMap
,
<
String
,
Uri
>{
'foo'
:
Uri
.
file
(
r'C:\foo\lib\'
,
windows:
true
),
// Excluded because it is in pub cache.
// 'bar': Uri.parse('file:///C:/Pub/Cache/bar/lib/'),
// Excluded because it is a dev dependency/
// 'baz': Uri.parse('file:///baz/lib/'),
'test_package'
:
Uri
.
file
(
r'C:\lib\'
,
windows:
true
),
});
expect
(
invalidator
.
updateTime
,
<
String
,
int
>{
r'C:\lib\main.dart'
:
mainFile
.
statSync
().
modified
.
millisecondsSinceEpoch
,
r'C:\foo\lib\foo.dart'
:
fooFile
.
statSync
().
modified
.
millisecondsSinceEpoch
,
});
expect
(
invalidator
.
findInvalidated
(),
isEmpty
);
// Invalidate main.dart.
mainFile
.
writeAsStringSync
(
'void main() { }'
);
expect
(
invalidator
.
findInvalidated
(),
<
String
>[
'file:///C:/lib/main.dart'
]);
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
memoryFileSystem
,
Platform:
()
=>
windowsPlatform
,
});
});
}
class
MockPlatform
extends
Mock
implements
Platform
{}
packages/flutter_tools/test/src/mocks.dart
View file @
cd803ac7
...
@@ -460,12 +460,6 @@ class MockDevFSOperations extends BasicMock implements DevFSOperations {
...
@@ -460,12 +460,6 @@ class MockDevFSOperations extends BasicMock implements DevFSOperations {
messages
.
add
(
message
);
messages
.
add
(
message
);
devicePathToContent
[
deviceUri
]
=
content
;
devicePathToContent
[
deviceUri
]
=
content
;
}
}
@override
Future
<
dynamic
>
deleteFile
(
String
fsName
,
Uri
deviceUri
)
async
{
messages
.
add
(
'deleteFile
$fsName
$deviceUri
'
);
devicePathToContent
.
remove
(
deviceUri
);
}
}
}
class
MockResidentCompiler
extends
BasicMock
implements
ResidentCompiler
{
class
MockResidentCompiler
extends
BasicMock
implements
ResidentCompiler
{
...
...
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