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
f53b32eb
Unverified
Commit
f53b32eb
authored
Oct 18, 2019
by
Jonah Williams
Committed by
GitHub
Oct 18, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
refactor depfile usage and update linux rule (#42487)
parent
315471bf
Changes
11
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
308 additions
and
197 deletions
+308
-197
build_system.dart
...ages/flutter_tools/lib/src/build_system/build_system.dart
+20
-11
depfile.dart
packages/flutter_tools/lib/src/build_system/depfile.dart
+78
-0
linux.dart
...ges/flutter_tools/lib/src/build_system/targets/linux.dart
+61
-21
bundle.dart
packages/flutter_tools/lib/src/bundle.dart
+22
-115
build_bundle.dart
packages/flutter_tools/lib/src/commands/build_bundle.dart
+0
-1
flutter_tester.dart
packages/flutter_tools/lib/src/tester/flutter_tester.dart
+2
-1
build_system_test.dart
...ls/test/general.shard/build_system/build_system_test.dart
+2
-3
depfile_test.dart
...r_tools/test/general.shard/build_system/depfile_test.dart
+106
-0
linux_test.dart
...s/test/general.shard/build_system/targets/linux_test.dart
+3
-1
bundle_shim_test.dart
...es/flutter_tools/test/general.shard/bundle_shim_test.dart
+1
-1
flutter_tester_test.dart
..._tools/test/general.shard/tester/flutter_tester_test.dart
+13
-43
No files found.
packages/flutter_tools/lib/src/build_system/build_system.dart
View file @
f53b32eb
...
...
@@ -502,7 +502,7 @@ class _BuildInstance {
outputFiles
[
output
.
path
]
=
output
;
}
for
(
File
input
in
node
.
inputs
)
{
final
String
resolvedPath
=
input
.
resolveSymbolicLinksSync
()
;
final
String
resolvedPath
=
input
.
absolute
.
path
;
if
(
outputFiles
.
containsKey
(
resolvedPath
))
{
continue
;
}
...
...
@@ -704,7 +704,7 @@ class Node {
/// One or more reasons why a task was invalidated.
///
/// May be empty if the task was skipped.
final
Set
<
Invalid
edReason
>
invalidatedReasons
=
<
Invalid
edReason
>{};
final
Set
<
Invalid
atedReason
>
invalidatedReasons
=
<
Invalidat
edReason
>{};
/// Whether this node needs an action performed.
bool
get
dirty
=>
_dirty
;
...
...
@@ -735,7 +735,7 @@ class Node {
if
(
fileHashStore
.
currentHashes
.
containsKey
(
absolutePath
))
{
final
String
currentHash
=
fileHashStore
.
currentHashes
[
absolutePath
];
if
(
currentHash
!=
previousHash
)
{
invalidatedReasons
.
add
(
InvalidedReason
.
inputChanged
);
invalidatedReasons
.
add
(
Invalid
at
edReason
.
inputChanged
);
_dirty
=
true
;
}
}
else
{
...
...
@@ -749,13 +749,13 @@ class Node {
// output paths changed.
if
(!
currentOutputPaths
.
contains
(
previousOutput
))
{
_dirty
=
true
;
invalidatedReasons
.
add
(
InvalidedReason
.
outputSetChanged
);
invalidatedReasons
.
add
(
Invalid
at
edReason
.
outputSetChanged
);
// if this isn't a current output file there is no reason to compute the hash.
continue
;
}
final
File
file
=
fs
.
file
(
previousOutput
);
if
(!
file
.
existsSync
())
{
invalidatedReasons
.
add
(
InvalidedReason
.
outputMissing
);
invalidatedReasons
.
add
(
Invalid
at
edReason
.
outputMissing
);
_dirty
=
true
;
continue
;
}
...
...
@@ -764,7 +764,7 @@ class Node {
if
(
fileHashStore
.
currentHashes
.
containsKey
(
absolutePath
))
{
final
String
currentHash
=
fileHashStore
.
currentHashes
[
absolutePath
];
if
(
currentHash
!=
previousHash
)
{
invalidatedReasons
.
add
(
InvalidedReason
.
outputChanged
);
invalidatedReasons
.
add
(
Invalid
at
edReason
.
outputChanged
);
_dirty
=
true
;
}
}
else
{
...
...
@@ -772,9 +772,14 @@ class Node {
}
}
// If we depend on a file that doesnt exist on disk, kill the build.
// If we depend on a file that doesnt exist on disk, mark the build as
// dirty. if the rule is not correctly specified, this will result in it
// always being rerun.
if
(
missingInputs
.
isNotEmpty
)
{
throw
MissingInputException
(
missingInputs
,
target
.
name
);
_dirty
=
true
;
final
String
missingMessage
=
missingInputs
.
map
((
File
file
)
=>
file
.
path
).
join
(
', '
);
printTrace
(
'invalidated build due to missing files:
$missingMessage
'
);
invalidatedReasons
.
add
(
InvalidatedReason
.
inputMissing
);
}
// If we have files to hash, compute them asynchronously and then
...
...
@@ -782,7 +787,7 @@ class Node {
if
(
sourcesToHash
.
isNotEmpty
)
{
final
List
<
File
>
dirty
=
await
fileHashStore
.
hashFiles
(
sourcesToHash
);
if
(
dirty
.
isNotEmpty
)
{
invalidatedReasons
.
add
(
InvalidedReason
.
inputChanged
);
invalidatedReasons
.
add
(
Invalid
at
edReason
.
inputChanged
);
_dirty
=
true
;
}
}
...
...
@@ -790,8 +795,12 @@ class Node {
}
}
/// A description of why a task was rerun.
enum
InvalidedReason
{
/// A description of why a target was rerun.
enum
InvalidatedReason
{
/// An input file that was expected is missing. This can occur when using
/// depfile dependencies, or if a target is incorrectly specified.
inputMissing
,
/// An input file has an updated hash.
inputChanged
,
...
...
packages/flutter_tools/lib/src/build_system/depfile.dart
0 → 100644
View file @
f53b32eb
// 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
'../base/file_system.dart'
;
import
'../base/platform.dart'
;
import
'../globals.dart'
;
/// A class for representing depfile formats.
class
Depfile
{
/// Create a [Depfile] from a list of [input] files and [output] files.
const
Depfile
(
this
.
inputs
,
this
.
outputs
);
/// Parse the depfile contents from [file].
///
/// If the syntax is invalid, returns an empty [Depfile].
factory
Depfile
.
parse
(
File
file
)
{
final
String
contents
=
file
.
readAsStringSync
();
final
List
<
String
>
colonSeparated
=
contents
.
split
(
': '
);
if
(
colonSeparated
.
length
!=
2
)
{
printError
(
'Invalid depfile:
${file.path}
'
);
return
const
Depfile
(<
File
>[],
<
File
>[]);
}
final
List
<
File
>
inputs
=
_processList
(
colonSeparated
[
1
].
trim
());
final
List
<
File
>
outputs
=
_processList
(
colonSeparated
[
0
].
trim
());
return
Depfile
(
inputs
,
outputs
);
}
/// The input files for this depfile.
final
List
<
File
>
inputs
;
/// The output files for this depfile.
final
List
<
File
>
outputs
;
/// Given an [depfile] File, write the depfile contents.
///
/// If either [inputs] or [outputs] is empty, does not write to the file.
void
writeToFile
(
File
depfile
)
{
if
(
inputs
.
isEmpty
||
outputs
.
isEmpty
)
{
return
;
}
final
StringBuffer
buffer
=
StringBuffer
();
_writeFilesToBuffer
(
outputs
,
buffer
);
buffer
.
write
(
': '
);
_writeFilesToBuffer
(
inputs
,
buffer
);
depfile
.
writeAsStringSync
(
buffer
.
toString
());
}
void
_writeFilesToBuffer
(
List
<
File
>
files
,
StringBuffer
buffer
)
{
for
(
File
outputFile
in
files
)
{
if
(
platform
.
isWindows
)
{
// Paths in a depfile have to be escaped on windows.
final
String
escapedPath
=
outputFile
.
path
.
replaceAll
(
r'\'
,
r'\\'
);
buffer
.
write
(
'
$escapedPath
'
);
}
else
{
buffer
.
write
(
'
${outputFile.path}
'
);
}
}
}
static
final
RegExp
_separatorExpr
=
RegExp
(
r'([^\\]) '
);
static
final
RegExp
_escapeExpr
=
RegExp
(
r'\\(.)'
);
static
List
<
File
>
_processList
(
String
rawText
)
{
return
rawText
// Put every file on right-hand side on the separate line
.
replaceAllMapped
(
_separatorExpr
,
(
Match
match
)
=>
'
${match.group(1)}
\n
'
)
.
split
(
'
\n
'
)
// Expand escape sequences, so that '\ ', for example,ß becomes ' '
.
map
<
String
>((
String
path
)
=>
path
.
replaceAllMapped
(
_escapeExpr
,
(
Match
match
)
=>
match
.
group
(
1
)).
trim
())
.
where
((
String
path
)
=>
path
.
isNotEmpty
)
// The tool doesn't write duplicates to these lists. This call is an attempt to
// be resillient to the outputs of other tools which write or user edits to depfiles.
.
toSet
()
.
map
((
String
path
)
=>
fs
.
file
(
path
))
.
toList
();
}
}
packages/flutter_tools/lib/src/build_system/targets/linux.dart
View file @
f53b32eb
...
...
@@ -11,10 +11,22 @@ import '../../build_info.dart';
import
'../../devfs.dart'
;
import
'../../globals.dart'
;
import
'../build_system.dart'
;
import
'../depfile.dart'
;
import
'../exceptions.dart'
;
import
'assets.dart'
;
import
'dart.dart'
;
/// The only files/subdirectories we care out.
const
List
<
String
>
_kLinuxArtifacts
=
<
String
>[
'libflutter_linux_glfw.so'
,
'flutter_export.h'
,
'flutter_messenger.h'
,
'flutter_plugin_registrar.h'
,
'flutter_glfw.h'
,
'icudtl.dat'
,
'cpp_client_wrapper_glfw/'
,
];
/// Copies the Linux desktop embedding files to the copy directory.
class
UnpackLinuxDebug
extends
Target
{
const
UnpackLinuxDebug
();
...
...
@@ -25,17 +37,12 @@ class UnpackLinuxDebug extends Target {
@override
List
<
Source
>
get
inputs
=>
const
<
Source
>[
Source
.
pattern
(
'{FLUTTER_ROOT}/packages/flutter_tools/lib/src/build_system/targets/linux.dart'
),
Source
.
artifact
(
Artifact
.
linuxDesktopPath
,
mode:
BuildMode
.
debug
),
Source
.
depfile
(
'linux_engine_sources.d'
),
];
@override
List
<
Source
>
get
outputs
=>
const
<
Source
>[
Source
.
pattern
(
'{PROJECT_DIR}/linux/flutter/ephemeral/libflutter_linux_glfw.so'
),
Source
.
pattern
(
'{PROJECT_DIR}/linux/flutter/ephemeral/flutter_export.h'
),
Source
.
pattern
(
'{PROJECT_DIR}/linux/flutter/ephemeral/flutter_messenger.h'
),
Source
.
pattern
(
'{PROJECT_DIR}/linux/flutter/ephemeral/flutter_plugin_registrar.h'
),
Source
.
pattern
(
'{PROJECT_DIR}/linux/flutter/ephemeral/flutter_glfw.h'
),
Source
.
pattern
(
'{PROJECT_DIR}/linux/flutter/ephemeral/icudtl.dat'
),
Source
.
depfile
(
'linux_engine_sources.d'
),
];
@override
...
...
@@ -44,22 +51,55 @@ class UnpackLinuxDebug extends Target {
@override
Future
<
void
>
build
(
Environment
environment
)
async
{
final
String
basePath
=
artifacts
.
getArtifactPath
(
Artifact
.
linuxDesktopPath
);
for
(
File
input
in
fs
.
directory
(
basePath
)
.
listSync
(
recursive:
true
)
.
whereType
<
File
>())
{
final
String
outputPath
=
fs
.
path
.
join
(
final
List
<
File
>
inputs
=
<
File
>[];
final
List
<
File
>
outputs
=
<
File
>[];
final
String
outputPrefix
=
fs
.
path
.
join
(
environment
.
projectDir
.
path
,
'linux'
,
'flutter'
,
'ephemeral'
,
);
// The native linux artifacts are composed of 6 files and a directory (listed above)
// which need to be copied to the target directory.
for
(
String
artifact
in
_kLinuxArtifacts
)
{
final
String
entityPath
=
fs
.
path
.
join
(
basePath
,
artifact
);
// If this artifact is a file, just copy the source over.
if
(
fs
.
isFileSync
(
entityPath
))
{
final
String
outputPath
=
fs
.
path
.
join
(
outputPrefix
,
fs
.
path
.
relative
(
entityPath
,
from:
basePath
),
);
final
File
destinationFile
=
fs
.
file
(
outputPath
);
if
(!
destinationFile
.
parent
.
existsSync
())
{
destinationFile
.
parent
.
createSync
(
recursive:
true
);
}
final
File
inputFile
=
fs
.
file
(
entityPath
);
inputFile
.
copySync
(
destinationFile
.
path
);
inputs
.
add
(
inputFile
);
outputs
.
add
(
destinationFile
);
continue
;
}
// If the artifact is the directory cpp_client_wrapper, recursively
// copy every file from it.
for
(
File
input
in
fs
.
directory
(
entityPath
)
.
listSync
(
recursive:
true
)
.
whereType
<
File
>())
{
final
String
outputPath
=
fs
.
path
.
join
(
outputPrefix
,
fs
.
path
.
relative
(
input
.
path
,
from:
basePath
),
);
final
File
destinationFile
=
fs
.
file
(
outputPath
);
if
(!
destinationFile
.
parent
.
existsSync
())
{
destinationFile
.
parent
.
createSync
(
recursive:
true
);
}
fs
.
file
(
input
).
copySync
(
destinationFile
.
path
);
final
File
inputFile
=
fs
.
file
(
input
);
inputFile
.
copySync
(
destinationFile
.
path
);
inputs
.
add
(
inputFile
);
outputs
.
add
(
destinationFile
);
}
}
final
Depfile
depfile
=
Depfile
(
inputs
,
outputs
);
depfile
.
writeToFile
(
environment
.
buildDir
.
childFile
(
'linux_engine_sources.d'
));
}
}
...
...
packages/flutter_tools/lib/src/bundle.dart
View file @
f53b32eb
...
...
@@ -7,15 +7,13 @@ import 'dart:async';
import
'package:meta/meta.dart'
;
import
'package:pool/pool.dart'
;
import
'artifacts.dart'
;
import
'asset.dart'
;
import
'base/common.dart'
;
import
'base/file_system.dart'
;
import
'base/platform.dart'
;
import
'build_info.dart'
;
import
'build_system/build_system.dart'
;
import
'build_system/depfile.dart'
;
import
'build_system/targets/dart.dart'
;
import
'compile.dart'
;
import
'dart/package_map.dart'
;
import
'devfs.dart'
;
import
'globals.dart'
;
...
...
@@ -45,10 +43,6 @@ String getKernelPathForTransformerOptions(
const
String
defaultPrivateKeyPath
=
'privatekey.der'
;
const
String
_kKernelKey
=
'kernel_blob.bin'
;
const
String
_kVMSnapshotData
=
'vm_snapshot_data'
;
const
String
_kIsolateSnapshotData
=
'isolate_snapshot_data'
;
/// Provides a `build` method that builds the bundle.
class
BundleBuilder
{
/// Builds the bundle for the given target platform.
...
...
@@ -72,16 +66,12 @@ class BundleBuilder {
List
<
String
>
extraGenSnapshotOptions
=
const
<
String
>[],
List
<
String
>
fileSystemRoots
,
String
fileSystemScheme
,
bool
shouldBuildWithAssemble
=
false
,
})
async
{
mainPath
??=
defaultMainPath
;
depfilePath
??=
defaultDepfilePath
;
assetDirPath
??=
getAssetBuildDirectory
();
packagesPath
??=
fs
.
path
.
absolute
(
PackageMap
.
globalPackagesPath
);
applicationKernelFilePath
??=
getDefaultApplicationKernelPath
(
trackWidgetCreation:
trackWidgetCreation
);
final
FlutterProject
flutterProject
=
FlutterProject
.
current
();
if
(
shouldBuildWithAssemble
)
{
await
buildWithAssemble
(
buildMode:
buildMode
??
BuildMode
.
debug
,
targetPlatform:
platform
,
...
...
@@ -91,54 +81,14 @@ class BundleBuilder {
depfilePath:
depfilePath
,
precompiled:
precompiledSnapshot
,
);
return
;
}
DevFSContent
kernelContent
;
if
(!
precompiledSnapshot
)
{
if
((
extraFrontEndOptions
!=
null
)
&&
extraFrontEndOptions
.
isNotEmpty
)
{
printTrace
(
'Extra front-end options:
$extraFrontEndOptions
'
);
}
ensureDirectoryExists
(
applicationKernelFilePath
);
final
KernelCompiler
kernelCompiler
=
await
kernelCompilerFactory
.
create
(
flutterProject
);
final
CompilerOutput
compilerOutput
=
await
kernelCompiler
.
compile
(
sdkRoot:
artifacts
.
getArtifactPath
(
Artifact
.
flutterPatchedSdkPath
,
mode:
buildMode
),
mainPath:
fs
.
file
(
mainPath
).
absolute
.
path
,
outputFilePath:
applicationKernelFilePath
,
depFilePath:
depfilePath
,
buildMode:
buildMode
,
trackWidgetCreation:
trackWidgetCreation
,
extraFrontEndOptions:
extraFrontEndOptions
,
fileSystemRoots:
fileSystemRoots
,
fileSystemScheme:
fileSystemScheme
,
packagesPath:
packagesPath
,
);
if
(
compilerOutput
?.
outputFilename
==
null
)
{
throwToolExit
(
'Compiler failed on
$mainPath
'
);
// Work around for flutter_tester placing kernel artifacts in odd places.
if
(
applicationKernelFilePath
!=
null
)
{
final
File
outputDill
=
fs
.
directory
(
assetDirPath
).
childFile
(
'kernel_blob.bin'
);
if
(
outputDill
.
existsSync
())
{
outputDill
.
copySync
(
applicationKernelFilePath
);
}
kernelContent
=
DevFSFileContent
(
fs
.
file
(
compilerOutput
.
outputFilename
));
fs
.
directory
(
getBuildDirectory
()).
childFile
(
'frontend_server.d'
)
.
writeAsStringSync
(
'frontend_server.d:
${artifacts.getArtifactPath(Artifact.frontendServerSnapshotForEngineDartSdk)}
\n
'
);
}
final
AssetBundle
assets
=
await
buildAssets
(
manifestPath:
manifestPath
,
assetDirPath:
assetDirPath
,
packagesPath:
packagesPath
,
reportLicensedPackages:
reportLicensedPackages
,
);
if
(
assets
==
null
)
{
throwToolExit
(
'Error building assets'
,
exitCode:
1
);
}
await
assemble
(
buildMode:
buildMode
,
assetBundle:
assets
,
kernelContent:
kernelContent
,
privateKeyPath:
privateKeyPath
,
assetDirPath:
assetDirPath
,
);
return
;
}
}
...
...
@@ -178,30 +128,13 @@ Future<void> buildWithAssemble({
}
throwToolExit
(
'Failed to build bundle.'
);
}
// Output depfile format:
final
StringBuffer
buffer
=
StringBuffer
();
buffer
.
write
(
'flutter_bundle'
);
_writeFilesToBuffer
(
result
.
outputFiles
,
buffer
);
buffer
.
write
(
': '
);
_writeFilesToBuffer
(
result
.
inputFiles
,
buffer
);
final
File
depfile
=
fs
.
file
(
depfilePath
);
if
(!
depfile
.
parent
.
existsSync
())
{
depfile
.
parent
.
createSync
(
recursive:
true
);
}
depfile
.
writeAsStringSync
(
buffer
.
toString
());
}
void
_writeFilesToBuffer
(
List
<
File
>
files
,
StringBuffer
buffer
)
{
for
(
File
outputFile
in
files
)
{
if
(
platform
.
isWindows
)
{
// Paths in a depfile have to be escaped on windows.
final
String
escapedPath
=
outputFile
.
path
.
replaceAll
(
r'\'
,
r'\\'
);
buffer
.
write
(
'
$escapedPath
'
);
}
else
{
buffer
.
write
(
'
${outputFile.path}
'
);
if
(
depfilePath
!=
null
)
{
final
Depfile
depfile
=
Depfile
(
result
.
inputFiles
,
result
.
outputFiles
);
final
File
outputDepfile
=
fs
.
file
(
depfilePath
);
if
(!
outputDepfile
.
parent
.
existsSync
())
{
outputDepfile
.
parent
.
createSync
(
recursive:
true
);
}
depfile
.
writeToFile
(
outputDepfile
);
}
}
...
...
@@ -231,32 +164,6 @@ Future<AssetBundle> buildAssets({
return
assetBundle
;
}
Future
<
void
>
assemble
({
BuildMode
buildMode
,
AssetBundle
assetBundle
,
DevFSContent
kernelContent
,
String
privateKeyPath
=
defaultPrivateKeyPath
,
String
assetDirPath
,
})
async
{
assetDirPath
??=
getAssetBuildDirectory
();
printTrace
(
'Building bundle'
);
final
Map
<
String
,
DevFSContent
>
assetEntries
=
Map
<
String
,
DevFSContent
>.
from
(
assetBundle
.
entries
);
if
(
kernelContent
!=
null
)
{
final
String
vmSnapshotData
=
artifacts
.
getArtifactPath
(
Artifact
.
vmSnapshotData
,
mode:
buildMode
);
final
String
isolateSnapshotData
=
artifacts
.
getArtifactPath
(
Artifact
.
isolateSnapshotData
,
mode:
buildMode
);
assetEntries
[
_kKernelKey
]
=
kernelContent
;
assetEntries
[
_kVMSnapshotData
]
=
DevFSFileContent
(
fs
.
file
(
vmSnapshotData
));
assetEntries
[
_kIsolateSnapshotData
]
=
DevFSFileContent
(
fs
.
file
(
isolateSnapshotData
));
}
printTrace
(
'Writing asset files to
$assetDirPath
'
);
ensureDirectoryExists
(
assetDirPath
);
await
writeBundle
(
fs
.
directory
(
assetDirPath
),
assetEntries
);
printTrace
(
'Wrote
$assetDirPath
'
);
}
Future
<
void
>
writeBundle
(
Directory
bundleDir
,
Map
<
String
,
DevFSContent
>
assetEntries
,
...
...
packages/flutter_tools/lib/src/commands/build_bundle.dart
View file @
f53b32eb
...
...
@@ -138,7 +138,6 @@ class BuildBundleCommand extends BuildSubCommand {
extraGenSnapshotOptions:
argResults
[
FlutterOptions
.
kExtraGenSnapshotOptions
],
fileSystemScheme:
argResults
[
'filesystem-scheme'
],
fileSystemRoots:
argResults
[
'filesystem-root'
],
shouldBuildWithAssemble:
true
,
);
return
null
;
}
...
...
packages/flutter_tools/lib/src/tester/flutter_tester.dart
View file @
f53b32eb
...
...
@@ -145,12 +145,13 @@ class FlutterTesterDevice extends Device {
trackWidgetCreation:
buildInfo
.
trackWidgetCreation
,
);
await
BundleBuilder
().
build
(
buildMode:
buildInfo
.
mode
,
mainPath:
mainPath
,
assetDirPath:
assetDirPath
,
applicationKernelFilePath:
applicationKernelFilePath
,
precompiledSnapshot:
false
,
buildMode:
buildInfo
.
mode
,
trackWidgetCreation:
buildInfo
.
trackWidgetCreation
,
platform:
getTargetPlatformForName
(
getNameForHostPlatform
(
getCurrentHostPlatform
())),
);
command
.
add
(
'--flutter-assets-dir=
$assetDirPath
'
);
...
...
packages/flutter_tools/test/general.shard/build_system/build_system_test.dart
View file @
f53b32eb
...
...
@@ -106,13 +106,12 @@ void main() {
);
});
test
(
'
Throws
exception if asked to build with missing inputs'
,
()
=>
testbed
.
run
(()
async
{
test
(
'
Does not throw
exception if asked to build with missing inputs'
,
()
=>
testbed
.
run
(()
async
{
// Delete required input file.
fs
.
file
(
'foo.dart'
).
deleteSync
();
final
BuildResult
buildResult
=
await
buildSystem
.
build
(
fooTarget
,
environment
);
expect
(
buildResult
.
hasException
,
true
);
expect
(
buildResult
.
exceptions
.
values
.
single
.
exception
,
isInstanceOf
<
MissingInputException
>());
expect
(
buildResult
.
hasException
,
false
);
}));
test
(
'Throws exception if it does not produce a specified output'
,
()
=>
testbed
.
run
(()
async
{
...
...
packages/flutter_tools/test/general.shard/build_system/depfile_test.dart
0 → 100644
View file @
f53b32eb
// 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/build_system/depfile.dart'
;
import
'../../src/common.dart'
;
import
'../../src/testbed.dart'
;
void
main
(
)
{
Testbed
testbed
;
setUp
(()
{
testbed
=
Testbed
();
});
test
(
'Can parse depfile from file'
,
()
=>
testbed
.
run
(()
{
final
File
depfileSource
=
fs
.
file
(
'example.d'
)..
writeAsStringSync
(
'''
a.txt: b.txt
'''
);
final
Depfile
depfile
=
Depfile
.
parse
(
depfileSource
);
expect
(
depfile
.
inputs
.
single
.
path
,
'b.txt'
);
expect
(
depfile
.
outputs
.
single
.
path
,
'a.txt'
);
}));
test
(
'Can parse depfile with multiple inputs'
,
()
=>
testbed
.
run
(()
{
final
FileSystem
fs
=
MemoryFileSystem
();
final
File
depfileSource
=
fs
.
file
(
'example.d'
)..
writeAsStringSync
(
'''
a.txt: b.txt c.txt d.txt
'''
);
final
Depfile
depfile
=
Depfile
.
parse
(
depfileSource
);
expect
(
depfile
.
inputs
.
map
((
File
file
)
=>
file
.
path
),
<
String
>[
'b.txt'
,
'c.txt'
,
'd.txt'
,
]);
expect
(
depfile
.
outputs
.
single
.
path
,
'a.txt'
);
}));
test
(
'Can parse depfile with multiple outputs'
,
()
=>
testbed
.
run
(()
{
final
FileSystem
fs
=
MemoryFileSystem
();
final
File
depfileSource
=
fs
.
file
(
'example.d'
)..
writeAsStringSync
(
'''
a.txt c.txt d.txt: b.txt
'''
);
final
Depfile
depfile
=
Depfile
.
parse
(
depfileSource
);
expect
(
depfile
.
inputs
.
single
.
path
,
'b.txt'
);
expect
(
depfile
.
outputs
.
map
((
File
file
)
=>
file
.
path
),
<
String
>[
'a.txt'
,
'c.txt'
,
'd.txt'
,
]);
}));
test
(
'Can parse depfile with windows file paths'
,
()
=>
testbed
.
run
(()
{
final
FileSystem
fs
=
MemoryFileSystem
();
final
File
depfileSource
=
fs
.
file
(
'example.d'
)..
writeAsStringSync
(
r''
'
C:
\\
a.txt: C:
\\
b.txt
'''
);
final
Depfile
depfile
=
Depfile
.
parse
(
depfileSource
);
expect
(
depfile
.
inputs
.
single
.
path
,
r'C:\b.txt'
);
expect
(
depfile
.
outputs
.
single
.
path
,
r'C:\a.txt'
);
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
MemoryFileSystem
(
style:
FileSystemStyle
.
windows
),
}));
test
(
'Resillient to weird whitespace'
,
()
=>
testbed
.
run
(()
{
final
FileSystem
fs
=
MemoryFileSystem
();
final
File
depfileSource
=
fs
.
file
(
'example.d'
)..
writeAsStringSync
(
r''
'
a.txt
: b.txt c.txt
'''
);
final
Depfile
depfile
=
Depfile
.
parse
(
depfileSource
);
expect
(
depfile
.
inputs
,
hasLength
(
2
));
expect
(
depfile
.
outputs
.
single
.
path
,
'a.txt'
);
}));
test
(
'Resillient to duplicate files'
,
()
=>
testbed
.
run
(()
{
final
FileSystem
fs
=
MemoryFileSystem
();
final
File
depfileSource
=
fs
.
file
(
'example.d'
)..
writeAsStringSync
(
r''
'
a.txt: b.txt b.txt
'''
);
final
Depfile
depfile
=
Depfile
.
parse
(
depfileSource
);
expect
(
depfile
.
inputs
.
single
.
path
,
'b.txt'
);
expect
(
depfile
.
outputs
.
single
.
path
,
'a.txt'
);
}));
test
(
'Resillient to malformed file, missing :'
,
()
=>
testbed
.
run
(()
{
final
FileSystem
fs
=
MemoryFileSystem
();
final
File
depfileSource
=
fs
.
file
(
'example.d'
)..
writeAsStringSync
(
r''
'
a.text b.txt
'''
);
final
Depfile
depfile
=
Depfile
.
parse
(
depfileSource
);
expect
(
depfile
.
inputs
,
isEmpty
);
expect
(
depfile
.
outputs
,
isEmpty
);
}));
}
packages/flutter_tools/test/general.shard/build_system/targets/linux_test.dart
View file @
f53b32eb
...
...
@@ -39,6 +39,7 @@ void main() {
kBuildMode:
'debug'
,
}
);
fs
.
file
(
'bin/cache/artifacts/engine/linux-x64/unrelated-stuff'
).
createSync
(
recursive:
true
);
fs
.
file
(
'bin/cache/artifacts/engine/linux-x64/libflutter_linux_glfw.so'
).
createSync
(
recursive:
true
);
fs
.
file
(
'bin/cache/artifacts/engine/linux-x64/flutter_export.h'
).
createSync
();
fs
.
file
(
'bin/cache/artifacts/engine/linux-x64/flutter_messenger.h'
).
createSync
();
...
...
@@ -53,7 +54,7 @@ void main() {
});
});
test
(
'Copies files to correct cache directory'
,
()
=>
testbed
.
run
(()
async
{
test
(
'Copies files to correct cache directory
, excluding unrelated code
'
,
()
=>
testbed
.
run
(()
async
{
final
BuildResult
result
=
await
buildSystem
.
build
(
const
UnpackLinuxDebug
(),
environment
);
expect
(
result
.
hasException
,
false
);
...
...
@@ -64,6 +65,7 @@ void main() {
expect
(
fs
.
file
(
'linux/flutter/ephemeral/flutter_glfw.h'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'linux/flutter/ephemeral/icudtl.dat'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'linux/flutter/ephemeral/cpp_client_wrapper_glfw/foo'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'linux/flutter/ephemeral/unrelated-stuff'
).
existsSync
(),
false
);
}));
test
(
'Does not re-copy files unecessarily'
,
()
=>
testbed
.
run
(()
async
{
...
...
packages/flutter_tools/test/general.shard/bundle_shim_test.dart
View file @
f53b32eb
...
...
@@ -43,7 +43,7 @@ void main() {
);
expect
(
fs
.
file
(
fs
.
path
.
join
(
'example'
,
'kernel_blob.bin'
)).
existsSync
(),
true
);
expect
(
fs
.
file
(
fs
.
path
.
join
(
'example'
,
'LICENSE'
)).
existsSync
(),
true
);
expect
(
fs
.
file
(
fs
.
path
.
join
(
'example.d'
)).
existsSync
(),
tru
e
);
expect
(
fs
.
file
(
fs
.
path
.
join
(
'example.d'
)).
existsSync
(),
fals
e
);
}));
test
(
'Handles build system failure'
,
()
=>
testbed
.
run
(()
{
...
...
packages/flutter_tools/test/general.shard/tester/flutter_tester_test.dart
View file @
f53b32eb
...
...
@@ -9,10 +9,8 @@ import 'package:file/memory.dart';
import
'package:flutter_tools/src/artifacts.dart'
;
import
'package:flutter_tools/src/base/platform.dart'
;
import
'package:flutter_tools/src/build_info.dart'
;
import
'package:flutter_tools/src/cache.dart'
;
import
'package:flutter_tools/src/compile.dart'
;
import
'package:flutter_tools/src/build_system/build_system.dart'
;
import
'package:flutter_tools/src/device.dart'
;
import
'package:flutter_tools/src/project.dart'
;
import
'package:flutter_tools/src/tester/flutter_tester.dart'
;
import
'package:mockito/mockito.dart'
;
import
'package:process/process.dart'
;
...
...
@@ -102,24 +100,23 @@ void main() {
String
mainPath
;
MockArtifacts
mockArtifacts
;
MockKernelCompiler
mockKernelCompiler
;
MockProcessManager
mockProcessManager
;
MockProcess
mockProcess
;
MockBuildSystem
mockBuildSystem
;
final
Map
<
Type
,
Generator
>
startOverrides
=
<
Type
,
Generator
>{
Platform:
()
=>
FakePlatform
(
operatingSystem:
'linux'
),
FileSystem:
()
=>
fs
,
ProcessManager:
()
=>
mockProcessManager
,
Cache:
()
=>
Cache
(
rootOverride:
fs
.
directory
(
flutterRoot
)),
KernelCompilerFactory:
()
=>
FakeKernelCompilerFactory
(
mockKernelCompiler
),
Artifacts:
()
=>
mockArtifacts
,
BuildSystem:
()
=>
mockBuildSystem
,
};
setUp
(()
{
mockBuildSystem
=
MockBuildSystem
();
flutterRoot
=
fs
.
path
.
join
(
'home'
,
'me'
,
'flutter'
);
flutterTesterPath
=
fs
.
path
.
join
(
flutterRoot
,
'bin'
,
'cache'
,
'artifacts'
,
'engine'
,
'linux-x64'
,
'flutter_tester'
);
final
File
flutterTesterFile
=
fs
.
file
(
flutterTesterPath
);
flutterTesterFile
.
parent
.
createSync
(
recursive:
true
);
flutterTesterFile
.
writeAsBytesSync
(
const
<
int
>[]);
...
...
@@ -139,24 +136,23 @@ void main() {
mode:
anyNamed
(
'mode'
)
)).
thenReturn
(
artifactPath
);
mockKernelCompiler
=
MockKernelCompiler
();
when
(
mockBuildSystem
.
build
(
any
,
any
,
)).
thenAnswer
((
_
)
async
{
fs
.
file
(
'
$mainPath
.dill'
).
createSync
(
recursive:
true
);
return
BuildResult
(
success:
true
);
});
});
testUsingContext
(
'not debug'
,
()
async
{
final
LaunchResult
result
=
await
device
.
startApp
(
null
,
mainPath:
mainPath
,
debuggingOptions:
DebuggingOptions
.
disabled
(
const
BuildInfo
(
BuildMode
.
release
,
null
)));
expect
(
result
.
started
,
isFalse
);
},
overrides:
startOverrides
);
testUsingContext
(
'no flutter_tester'
,
()
async
{
fs
.
file
(
flutterTesterPath
).
deleteSync
();
expect
(()
async
{
await
device
.
startApp
(
null
,
mainPath:
mainPath
,
debuggingOptions:
DebuggingOptions
.
disabled
(
const
BuildInfo
(
BuildMode
.
debug
,
null
)));
},
throwsToolExit
());
},
overrides:
startOverrides
);
testUsingContext
(
'start'
,
()
async
{
final
Uri
observatoryUri
=
Uri
.
parse
(
'http://127.0.0.1:6666/'
);
...
...
@@ -168,22 +164,6 @@ Hello!
.
codeUnits
,
]));
when
(
mockKernelCompiler
.
compile
(
sdkRoot:
anyNamed
(
'sdkRoot'
),
mainPath:
anyNamed
(
'mainPath'
),
outputFilePath:
anyNamed
(
'outputFilePath'
),
depFilePath:
anyNamed
(
'depFilePath'
),
buildMode:
BuildMode
.
debug
,
trackWidgetCreation:
anyNamed
(
'trackWidgetCreation'
),
extraFrontEndOptions:
anyNamed
(
'extraFrontEndOptions'
),
fileSystemRoots:
anyNamed
(
'fileSystemRoots'
),
fileSystemScheme:
anyNamed
(
'fileSystemScheme'
),
packagesPath:
anyNamed
(
'packagesPath'
),
)).
thenAnswer
((
_
)
async
{
fs
.
file
(
'
$mainPath
.dill'
).
createSync
(
recursive:
true
);
return
CompilerOutput
(
'
$mainPath
.dill'
,
0
,
<
Uri
>[]);
});
final
LaunchResult
result
=
await
device
.
startApp
(
null
,
mainPath:
mainPath
,
debuggingOptions:
DebuggingOptions
.
enabled
(
const
BuildInfo
(
BuildMode
.
debug
,
null
)));
...
...
@@ -195,15 +175,5 @@ Hello!
});
}
class
MockBuildSystem
extends
Mock
implements
BuildSystem
{}
class
MockArtifacts
extends
Mock
implements
Artifacts
{}
class
MockKernelCompiler
extends
Mock
implements
KernelCompiler
{}
class
FakeKernelCompilerFactory
implements
KernelCompilerFactory
{
FakeKernelCompilerFactory
(
this
.
kernelCompiler
);
final
KernelCompiler
kernelCompiler
;
@override
Future
<
KernelCompiler
>
create
(
FlutterProject
flutterProject
)
async
{
return
kernelCompiler
;
}
}
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