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
2ab46995
Unverified
Commit
2ab46995
authored
Jul 31, 2019
by
Jonah Williams
Committed by
GitHub
Jul 31, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Flutter assemble for macos take 2! (#36987)
parent
dd1fb3bc
Changes
28
Hide whitespace changes
Inline
Side-by-side
Showing
28 changed files
with
680 additions
and
226 deletions
+680
-226
macos_build_flutter_assets.sh
packages/flutter_tools/bin/macos_build_flutter_assets.sh
+29
-25
artifacts.dart
packages/flutter_tools/lib/src/artifacts.dart
+7
-0
build_system.dart
...ages/flutter_tools/lib/src/build_system/build_system.dart
+62
-8
source.dart
packages/flutter_tools/lib/src/build_system/source.dart
+40
-34
assets.dart
...es/flutter_tools/lib/src/build_system/targets/assets.dart
+44
-0
dart.dart
...ages/flutter_tools/lib/src/build_system/targets/dart.dart
+5
-1
macos.dart
...ges/flutter_tools/lib/src/build_system/targets/macos.dart
+117
-1
assemble.dart
packages/flutter_tools/lib/src/commands/assemble.dart
+40
-11
attach.dart
packages/flutter_tools/lib/src/commands/attach.dart
+0
-1
build_macos.dart
packages/flutter_tools/lib/src/commands/build_macos.dart
+1
-1
daemon.dart
packages/flutter_tools/lib/src/commands/daemon.dart
+0
-1
run.dart
packages/flutter_tools/lib/src/commands/run.dart
+0
-1
xcodeproj.dart
packages/flutter_tools/lib/src/ios/xcodeproj.dart
+5
-2
application_package.dart
...ages/flutter_tools/lib/src/macos/application_package.dart
+10
-49
build_macos.dart
packages/flutter_tools/lib/src/macos/build_macos.dart
+45
-20
macos_device.dart
packages/flutter_tools/lib/src/macos/macos_device.dart
+11
-10
project.dart
packages/flutter_tools/lib/src/project.dart
+8
-0
resident_runner.dart
packages/flutter_tools/lib/src/resident_runner.dart
+15
-4
run_hot.dart
packages/flutter_tools/lib/src/run_hot.dart
+3
-2
build_system_test.dart
...ls/test/general.shard/build_system/build_system_test.dart
+8
-0
source_test.dart
...er_tools/test/general.shard/build_system/source_test.dart
+8
-0
assets_test.dart
.../test/general.shard/build_system/targets/assets_test.dart
+11
-0
macos_test.dart
...s/test/general.shard/build_system/targets/macos_test.dart
+113
-19
assemble_test.dart
...tter_tools/test/general.shard/commands/assemble_test.dart
+44
-2
attach_test.dart
...lutter_tools/test/general.shard/commands/attach_test.dart
+0
-1
build_macos_test.dart
...r_tools/test/general.shard/commands/build_macos_test.dart
+22
-11
macos_device_test.dart
...ter_tools/test/general.shard/macos/macos_device_test.dart
+29
-22
resident_runner_test.dart
...lutter_tools/test/general.shard/resident_runner_test.dart
+3
-0
No files found.
packages/flutter_tools/bin/macos_build_flutter_assets.sh
View file @
2ab46995
...
...
@@ -3,8 +3,6 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# TODO(jonahwilliams): refactor this and xcode_backend.sh into one script
# once macOS supports the same configuration as iOS.
RunCommand
()
{
if
[[
-n
"
$VERBOSE_SCRIPT_LOGGING
"
]]
;
then
echo
"♦
$*
"
...
...
@@ -33,18 +31,6 @@ if [[ -n "$FLUTTER_TARGET" ]]; then
target_path
=
"
${
FLUTTER_TARGET
}
"
fi
# Set the track widget creation flag.
track_widget_creation_flag
=
""
if
[[
-n
"
$TRACK_WIDGET_CREATION
"
]]
;
then
track_widget_creation_flag
=
"--track-widget-creation"
fi
# Copy the framework and handle local engine builds.
framework_name
=
"FlutterMacOS.framework"
ephemeral_dir
=
"
${
SOURCE_ROOT
}
/Flutter/ephemeral"
framework_path
=
"
${
FLUTTER_ROOT
}
/bin/cache/artifacts/engine/darwin-x64"
flutter_framework
=
"
${
framework_path
}
/
${
framework_name
}
"
if
[[
-n
"
$FLUTTER_ENGINE
"
]]
;
then
flutter_engine_flag
=
"--local-engine-src-path=
${
FLUTTER_ENGINE
}
"
fi
...
...
@@ -63,22 +49,40 @@ if [[ -n "$LOCAL_ENGINE" ]]; then
exit
-1
fi
local_engine_flag
=
"--local-engine=
${
LOCAL_ENGINE
}
"
flutter_framework
=
"
${
FLUTTER_ENGINE
}
/out/
${
LOCAL_ENGINE
}
/
${
framework_name
}
"
fi
RunCommand
mkdir
-p
--
"
$ephemeral_dir
"
RunCommand
rm
-rf
--
"
${
ephemeral_dir
}
/
${
framework_name
}
"
RunCommand
cp
-Rp
--
"
${
flutter_framework
}
"
"
${
ephemeral_dir
}
"
# Set the build mode
build_mode
=
"
$(
echo
"
${
FLUTTER_BUILD_MODE
:-${
CONFIGURATION
}}
"
|
tr
"[:upper:]"
"[:lower:]"
)
"
case
"
$build_mode
"
in
debug
)
build_target
=
"debug_macos_application"
;;
profile
)
build_target
=
"profile_macos_application"
;;
release
)
build_target
=
"release_macos_application"
;;
*
)
EchoError
"Unknown build mode
${
build_mode
}
"
exit
-1
;;
esac
# The path where the input/output xcfilelists are stored. These are used by xcode
# to conditionally skip this script phase if neither have changed.
build_inputs_path
=
"
${
SOURCE_ROOT
}
/Flutter/ephemeral/FlutterInputs.xcfilelist"
build_outputs_path
=
"
${
SOURCE_ROOT
}
/Flutter/ephemeral/FlutterOutputs.xcfilelist"
# TODO(jonahwilliams): support flavors https://github.com/flutter/flutter/issues/32923
RunCommand
"
${
FLUTTER_ROOT
}
/bin/flutter"
--suppress-analytics
\
${
verbose_flag
}
\
build bundle
\
--target-platform
=
darwin-x64
\
--target
=
"
${
target_path
}
"
\
--
${
build_mode
}
\
${
track_widget_creation_flag
}
\
${
flutter_engine_flag
}
\
${
local_engine_flag
}
${
local_engine_flag
}
\
assemble
\
-dTargetFile
=
"
${
target_path
}
"
\
-dTargetPlatform
=
darwin-x64
\
-dBuildMode
=
"
${
build_mode
}
"
\
--build-inputs
=
"
${
build_inputs_path
}
"
\
--build-outputs
=
"
${
build_outputs_path
}
"
\
"
${
build_target
}
"
packages/flutter_tools/lib/src/artifacts.dart
View file @
2ab46995
...
...
@@ -54,6 +54,8 @@ enum Artifact {
windowsDesktopPath
,
/// The root of the sky_engine package
skyEnginePath
,
/// The location of the macOS engine podspec file.
flutterMacOSPodspec
,
}
String
_artifactToFileName
(
Artifact
artifact
,
[
TargetPlatform
platform
,
BuildMode
mode
])
{
...
...
@@ -119,6 +121,8 @@ String _artifactToFileName(Artifact artifact, [ TargetPlatform platform, BuildMo
return
''
;
case
Artifact
.
skyEnginePath
:
return
'sky_engine'
;
case
Artifact
.
flutterMacOSPodspec
:
return
'FlutterMacOS.podspec'
;
}
assert
(
false
,
'Invalid artifact
$artifact
.'
);
return
null
;
...
...
@@ -269,6 +273,7 @@ class CachedArtifacts extends Artifacts {
case
Artifact
.
flutterMacOSFramework
:
case
Artifact
.
linuxDesktopPath
:
case
Artifact
.
windowsDesktopPath
:
case
Artifact
.
flutterMacOSPodspec
:
final
String
engineArtifactsPath
=
cache
.
getArtifactDirectory
(
'engine'
).
path
;
final
String
platformDirName
=
getNameForTargetPlatform
(
platform
);
return
fs
.
path
.
join
(
engineArtifactsPath
,
platformDirName
,
_artifactToFileName
(
artifact
,
platform
,
mode
));
...
...
@@ -384,6 +389,8 @@ class LocalEngineArtifacts extends Artifacts {
return
fs
.
path
.
join
(
_hostEngineOutPath
,
artifactFileName
);
case
Artifact
.
skyEnginePath
:
return
fs
.
path
.
join
(
_hostEngineOutPath
,
'gen'
,
'dart-pkg'
,
artifactFileName
);
case
Artifact
.
flutterMacOSPodspec
:
return
fs
.
path
.
join
(
_hostEngineOutPath
,
_artifactToFileName
(
artifact
));
}
assert
(
false
,
'Invalid artifact
$artifact
.'
);
return
null
;
...
...
packages/flutter_tools/lib/src/build_system/build_system.dart
View file @
2ab46995
...
...
@@ -171,7 +171,7 @@ abstract class Target {
}
}
// For each outut, first determine if we've already computed the hash
// For each out
p
ut, first determine if we've already computed the hash
// for it. Then collect it to be sent off for hashing as a group.
for
(
String
previousOutput
in
previousOutputs
)
{
final
File
file
=
fs
.
file
(
previousOutput
);
...
...
@@ -436,11 +436,19 @@ class Environment {
/// The result information from the build system.
class
BuildResult
{
BuildResult
(
this
.
success
,
this
.
exceptions
,
this
.
performance
);
BuildResult
({
@required
this
.
success
,
this
.
exceptions
=
const
<
String
,
ExceptionMeasurement
>{},
this
.
performance
=
const
<
String
,
PerformanceMeasurement
>{},
this
.
inputFiles
=
const
<
File
>[],
this
.
outputFiles
=
const
<
File
>[],
});
final
bool
success
;
final
Map
<
String
,
ExceptionMeasurement
>
exceptions
;
final
Map
<
String
,
PerformanceMeasurement
>
performance
;
final
List
<
File
>
inputFiles
;
final
List
<
File
>
outputFiles
;
bool
get
hasException
=>
exceptions
.
isNotEmpty
;
}
...
...
@@ -472,10 +480,31 @@ class BuildSystem {
// Always persist the file cache to disk.
fileCache
.
persist
();
}
// TODO(jonahwilliams): this is a bit of a hack, due to various parts of
// the flutter tool writing these files unconditionally. Since Xcode uses
// timestamps to track files, this leads to unecessary rebuilds if they
// are included. Once all the places that write these files have been
// tracked down and moved into assemble, these checks should be removable.
{
buildInstance
.
inputFiles
.
removeWhere
((
String
path
,
File
file
)
{
return
path
.
contains
(
'pubspec.yaml'
)
||
path
.
contains
(
'.flutter-plugins'
)
||
path
.
contains
(
'xcconfig'
);
});
buildInstance
.
outputFiles
.
removeWhere
((
String
path
,
File
file
)
{
return
path
.
contains
(
'pubspec.yaml'
)
||
path
.
contains
(
'.flutter-plugins'
)
||
path
.
contains
(
'xcconfig'
);
});
}
return
BuildResult
(
passed
,
buildInstance
.
exceptionMeasurements
,
buildInstance
.
stepTimings
,
success:
passed
,
exceptions:
buildInstance
.
exceptionMeasurements
,
performance:
buildInstance
.
stepTimings
,
inputFiles:
buildInstance
.
inputFiles
.
values
.
toList
()
..
sort
((
File
a
,
File
b
)
=>
a
.
path
.
compareTo
(
b
.
path
)),
outputFiles:
buildInstance
.
outputFiles
.
values
.
toList
()
..
sort
((
File
a
,
File
b
)
=>
a
.
path
.
compareTo
(
b
.
path
)),
);
}
}
...
...
@@ -490,6 +519,8 @@ class _BuildInstance {
final
Map
<
String
,
AsyncMemoizer
<
void
>>
pending
=
<
String
,
AsyncMemoizer
<
void
>>{};
final
Environment
environment
;
final
FileHashStore
fileCache
;
final
Map
<
String
,
File
>
inputFiles
=
<
String
,
File
>{};
final
Map
<
String
,
File
>
outputFiles
=
<
String
,
File
>{};
// Timings collected during target invocation.
final
Map
<
String
,
PerformanceMeasurement
>
stepTimings
=
<
String
,
PerformanceMeasurement
>{};
...
...
@@ -514,18 +545,41 @@ class _BuildInstance {
try
{
final
List
<
File
>
inputs
=
target
.
resolveInputs
(
environment
);
final
bool
canSkip
=
await
target
.
computeChanges
(
inputs
,
environment
,
fileCache
);
for
(
File
input
in
inputs
)
{
// The build system should produce a list of aggregate input and output
// files for the overall build. The goal is to provide this to a hosting
// build system, such as Xcode, to configure logic for when to skip the
// rule/phase which contains the flutter build. When looking at the
// inputs and outputs for the individual rules, we need to be careful to
// remove inputs that were actually output from previous build steps.
// This indicates that the file is actual an output or intermediary. If
// these files are included as both inputs and outputs then it isn't
// possible to construct a DAG describing the build.
final
String
resolvedPath
=
input
.
resolveSymbolicLinksSync
();
if
(
outputFiles
.
containsKey
(
resolvedPath
))
{
continue
;
}
inputFiles
[
resolvedPath
]
=
input
;
}
if
(
canSkip
)
{
skipped
=
true
;
printStatus
(
'Skipping target:
${target.name}
'
);
final
List
<
File
>
outputs
=
target
.
resolveOutputs
(
environment
,
implicit:
true
);
for
(
File
output
in
outputs
)
{
outputFiles
[
output
.
resolveSymbolicLinksSync
()]
=
output
;
}
}
else
{
printStatus
(
'
${target.name}
: Starting'
);
await
target
.
build
(
inputs
,
environment
);
printStatus
(
'
${target.name}
: Complete'
);
final
List
<
File
>
outputs
=
target
.
resolveOutputs
(
environment
);
final
List
<
File
>
outputs
=
target
.
resolveOutputs
(
environment
,
implicit:
true
);
// Update hashes for output files.
await
fileCache
.
hashFiles
(
outputs
);
target
.
_writeStamp
(
inputs
,
outputs
,
environment
);
for
(
File
output
in
outputs
)
{
outputFiles
[
output
.
resolveSymbolicLinksSync
()]
=
output
;
}
}
}
catch
(
exception
,
stackTrace
)
{
target
.
clearStamp
(
environment
);
...
...
@@ -554,10 +608,10 @@ class ExceptionMeasurement {
/// Helper class to collect measurement data.
class
PerformanceMeasurement
{
PerformanceMeasurement
(
this
.
target
,
this
.
elapsedMilliseconds
,
this
.
skiped
,
this
.
passed
);
PerformanceMeasurement
(
this
.
target
,
this
.
elapsedMilliseconds
,
this
.
skip
p
ed
,
this
.
passed
);
final
int
elapsedMilliseconds
;
final
String
target
;
final
bool
skiped
;
final
bool
skip
p
ed
;
final
bool
passed
;
}
...
...
packages/flutter_tools/lib/src/build_system/source.dart
View file @
2ab46995
...
...
@@ -38,8 +38,10 @@ class SourceVisitor {
/// Visit a [Source] which contains a file uri.
///
/// The uri may that may include constants defined in an [Environment].
void
visitPattern
(
String
pattern
)
{
/// The uri may include constants defined in an [Environment]. If
/// [optional] is true, the file is not required to exist. In this case, it
/// is never resolved as an input.
void
visitPattern
(
String
pattern
,
bool
optional
)
{
// perform substitution of the environmental values and then
// of the local values.
final
List
<
String
>
segments
=
<
String
>[];
...
...
@@ -74,38 +76,41 @@ class SourceVisitor {
}
rawParts
.
skip
(
1
).
forEach
(
segments
.
add
);
final
String
filePath
=
fs
.
path
.
joinAll
(
segments
);
if
(
hasWildcard
)
{
// Perform a simple match by splitting the wildcard containing file one
// the `*`. For example, for `/*.dart`, we get [.dart]. We then check
// that part of the file matches. If there are values before and after
// the `*` we need to check that both match without overlapping. For
// example, `foo_*_.dart`. We want to match `foo_b_.dart` but not
// `foo_.dart`. To do so, we first subtract the first section from the
// string if the first segment matches.
final
List
<
String
>
segments
=
wildcardFile
.
split
(
'*'
);
if
(
segments
.
length
>
2
)
{
throw
InvalidPatternException
(
pattern
);
}
if
(!
fs
.
directory
(
filePath
).
existsSync
())
{
throw
Exception
(
'
$filePath
does not exist!'
);
if
(!
hasWildcard
)
{
if
(
optional
&&
!
fs
.
isFileSync
(
filePath
))
{
return
;
}
for
(
FileSystemEntity
entity
in
fs
.
directory
(
filePath
).
listSync
())
{
final
String
filename
=
fs
.
path
.
basename
(
entity
.
path
);
if
(
segments
.
isEmpty
)
{
sources
.
add
(
fs
.
file
(
entity
.
absolute
));
}
else
if
(
segments
.
length
==
1
)
{
if
(
filename
.
startsWith
(
segments
[
0
])
||
filename
.
endsWith
(
segments
[
0
]))
{
sources
.
add
(
entity
.
absolute
);
}
}
else
if
(
filename
.
startsWith
(
segments
[
0
]))
{
if
(
filename
.
substring
(
segments
[
0
].
length
).
endsWith
(
segments
[
1
]))
{
sources
.
add
(
entity
.
absolute
);
}
sources
.
add
(
fs
.
file
(
fs
.
path
.
normalize
(
filePath
)));
return
;
}
// Perform a simple match by splitting the wildcard containing file one
// the `*`. For example, for `/*.dart`, we get [.dart]. We then check
// that part of the file matches. If there are values before and after
// the `*` we need to check that both match without overlapping. For
// example, `foo_*_.dart`. We want to match `foo_b_.dart` but not
// `foo_.dart`. To do so, we first subtract the first section from the
// string if the first segment matches.
final
List
<
String
>
wildcardSegments
=
wildcardFile
.
split
(
'*'
);
if
(
wildcardSegments
.
length
>
2
)
{
throw
InvalidPatternException
(
pattern
);
}
if
(!
fs
.
directory
(
filePath
).
existsSync
())
{
throw
Exception
(
'
$filePath
does not exist!'
);
}
for
(
FileSystemEntity
entity
in
fs
.
directory
(
filePath
).
listSync
())
{
final
String
filename
=
fs
.
path
.
basename
(
entity
.
path
);
if
(
wildcardSegments
.
isEmpty
)
{
sources
.
add
(
fs
.
file
(
entity
.
absolute
));
}
else
if
(
wildcardSegments
.
length
==
1
)
{
if
(
filename
.
startsWith
(
wildcardSegments
[
0
])
||
filename
.
endsWith
(
wildcardSegments
[
0
]))
{
sources
.
add
(
entity
.
absolute
);
}
}
else
if
(
filename
.
startsWith
(
wildcardSegments
[
0
]))
{
if
(
filename
.
substring
(
wildcardSegments
[
0
].
length
).
endsWith
(
wildcardSegments
[
1
]))
{
sources
.
add
(
entity
.
absolute
);
}
}
}
else
{
sources
.
add
(
fs
.
file
(
fs
.
path
.
normalize
(
filePath
)));
}
}
...
...
@@ -139,7 +144,7 @@ class SourceVisitor {
abstract
class
Source
{
/// This source is a file-uri which contains some references to magic
/// environment variables.
const
factory
Source
.
pattern
(
String
pattern
)
=
_PatternSource
;
const
factory
Source
.
pattern
(
String
pattern
,
{
bool
optional
}
)
=
_PatternSource
;
/// This source is produced by invoking the provided function.
const
factory
Source
.
function
(
InputFunction
function
)
=
_FunctionSource
;
...
...
@@ -203,12 +208,13 @@ class _FunctionSource implements Source {
}
class
_PatternSource
implements
Source
{
const
_PatternSource
(
this
.
value
);
const
_PatternSource
(
this
.
value
,
{
this
.
optional
=
false
}
);
final
String
value
;
final
bool
optional
;
@override
void
accept
(
SourceVisitor
visitor
)
=>
visitor
.
visitPattern
(
value
);
void
accept
(
SourceVisitor
visitor
)
=>
visitor
.
visitPattern
(
value
,
optional
);
@override
bool
get
implicit
=>
value
.
contains
(
'*'
);
...
...
packages/flutter_tools/lib/src/build_system/targets/assets.dart
View file @
2ab46995
...
...
@@ -7,6 +7,8 @@ import 'package:pool/pool.dart';
import
'../../asset.dart'
;
import
'../../base/file_system.dart'
;
import
'../../devfs.dart'
;
import
'../../plugins.dart'
;
import
'../../project.dart'
;
import
'../build_system.dart'
;
/// The copying logic for flutter assets.
...
...
@@ -100,3 +102,45 @@ class CopyAssets extends Target {
}));
}
}
/// Rewrites the `.flutter-plugins` file of [project] based on the plugin
/// dependencies declared in `pubspec.yaml`.
// TODO(jonahwiliams): this should be per platform and located in build
// outputs.
class
FlutterPlugins
extends
Target
{
const
FlutterPlugins
();
@override
String
get
name
=>
'flutter_plugins'
;
@override
List
<
Target
>
get
dependencies
=>
const
<
Target
>[];
@override
List
<
Source
>
get
inputs
=>
const
<
Source
>[
Source
.
pattern
(
'{FLUTTER_ROOT}/packages/flutter_tools/lib/src/build_system/targets/assets.dart'
),
Source
.
pattern
(
'{PROJECT_DIR}/pubspec.yaml'
),
];
@override
List
<
Source
>
get
outputs
=>
const
<
Source
>[
Source
.
pattern
(
'{PROJECT_DIR}/.flutter-plugins'
)
];
@override
Future
<
void
>
build
(
List
<
File
>
inputFiles
,
Environment
environment
)
async
{
// The pubspec may change for reasons other than plugins changing, so we compare
// the manifest before writing. Some hosting build systems use timestamps
// so we need to be careful to avoid tricking them into doing more work than
// necessary.
final
FlutterProject
project
=
FlutterProject
.
fromDirectory
(
environment
.
projectDir
);
final
List
<
Plugin
>
plugins
=
findPlugins
(
project
);
final
String
pluginManifest
=
plugins
.
map
<
String
>((
Plugin
p
)
=>
'
${p.name}
=
${escapePath(p.path)}
'
)
.
join
(
'
\n
'
);
final
File
flutterPluginsFile
=
environment
.
projectDir
.
childFile
(
'.flutter-plugins'
);
if
(!
flutterPluginsFile
.
existsSync
()
||
flutterPluginsFile
.
readAsStringSync
()
!=
pluginManifest
)
{
flutterPluginsFile
.
writeAsStringSync
(
pluginManifest
);
}
}
}
packages/flutter_tools/lib/src/build_system/targets/dart.dart
View file @
2ab46995
...
...
@@ -86,6 +86,9 @@ class KernelSnapshot extends Target {
}
final
BuildMode
buildMode
=
getBuildModeForName
(
environment
.
defines
[
kBuildMode
]);
final
String
targetFile
=
environment
.
defines
[
kTargetFile
]
??
fs
.
path
.
join
(
'lib'
,
'main.dart'
);
final
String
packagesPath
=
environment
.
projectDir
.
childFile
(
'.packages'
).
path
;
final
PackageUriMapper
packageUriMapper
=
PackageUriMapper
(
targetFile
,
packagesPath
,
null
,
null
);
final
CompilerOutput
output
=
await
compiler
.
compile
(
sdkRoot:
artifacts
.
getArtifactPath
(
Artifact
.
flutterPatchedSdkPath
,
mode:
buildMode
),
...
...
@@ -95,7 +98,8 @@ class KernelSnapshot extends Target {
targetProductVm:
buildMode
==
BuildMode
.
release
,
outputFilePath:
environment
.
buildDir
.
childFile
(
'app.dill'
).
path
,
depFilePath:
null
,
mainPath:
targetFile
,
packagesPath:
packagesPath
,
mainPath:
packageUriMapper
.
map
(
targetFile
)?.
toString
()
??
targetFile
,
);
if
(
output
.
errorCount
!=
0
)
{
throw
Exception
(
'Errors during snapshot creation:
$output
'
);
...
...
packages/flutter_tools/lib/src/build_system/targets/macos.dart
View file @
2ab46995
...
...
@@ -6,10 +6,16 @@ import '../../artifacts.dart';
import
'../../base/file_system.dart'
;
import
'../../base/io.dart'
;
import
'../../base/process_manager.dart'
;
import
'../../build_info.dart'
;
import
'../../globals.dart'
;
import
'../../macos/cocoapods.dart'
;
import
'../../project.dart'
;
import
'../build_system.dart'
;
import
'../exceptions.dart'
;
import
'assets.dart'
;
import
'dart.dart'
;
const
String
_kOutputPrefix
=
'{PROJECT_DIR}/macos/Flutter/FlutterMacOS.framework'
;
const
String
_kOutputPrefix
=
'{PROJECT_DIR}/macos/Flutter/
ephemeral/
FlutterMacOS.framework'
;
/// Copy the macOS framework to the correct copy dir by invoking 'cp -R'.
///
...
...
@@ -63,6 +69,7 @@ class UnpackMacOS extends Target {
.
projectDir
.
childDirectory
(
'macos'
)
.
childDirectory
(
'Flutter'
)
.
childDirectory
(
'ephemeral'
)
.
childDirectory
(
'FlutterMacOS.framework'
);
if
(
targetDirectory
.
existsSync
())
{
targetDirectory
.
deleteSync
(
recursive:
true
);
...
...
@@ -78,3 +85,112 @@ class UnpackMacOS extends Target {
}
}
}
/// Tell cocoapods to re-fetch dependencies.
class
DebugMacOSPodInstall
extends
Target
{
const
DebugMacOSPodInstall
();
@override
String
get
name
=>
'debug_macos_pod_install'
;
@override
List
<
Source
>
get
inputs
=>
const
<
Source
>[
Source
.
artifact
(
Artifact
.
flutterMacOSPodspec
,
platform:
TargetPlatform
.
darwin_x64
,
mode:
BuildMode
.
debug
),
Source
.
pattern
(
'{PROJECT_DIR}/macos/Podfile'
,
optional:
true
),
Source
.
pattern
(
'{PROJECT_DIR}/macos/Runner.xcodeproj/project.pbxproj'
),
Source
.
pattern
(
'{PROJECT_DIR}/macos/Flutter/ephemeral/Flutter-Generated.xcconfig'
),
];
@override
List
<
Source
>
get
outputs
=>
const
<
Source
>[
// TODO(jonahwilliams): introduce configuration/planning phase to build.
// No outputs because Cocoapods is fully responsible for tracking. plus there
// is no concept of an optional output. Instead we will need a build config
// phase to conditionally add this rule so that it can be written properly.
];
@override
List
<
Target
>
get
dependencies
=>
const
<
Target
>[
UnpackMacOS
(),
FlutterPlugins
(),
];
@override
Future
<
void
>
build
(
List
<
File
>
inputFiles
,
Environment
environment
)
async
{
if
(
environment
.
defines
[
kBuildMode
]
==
null
)
{
throw
MissingDefineException
(
kBuildMode
,
'debug_macos_pod_install'
);
}
// If there is no podfile do not perform any pods actions.
if
(!
environment
.
projectDir
.
childDirectory
(
'macos'
)
.
childFile
(
'Podfile'
).
existsSync
())
{
return
;
}
final
BuildMode
buildMode
=
getBuildModeForName
(
environment
.
defines
[
kBuildMode
]);
final
FlutterProject
project
=
FlutterProject
.
fromDirectory
(
environment
.
projectDir
);
final
String
enginePath
=
artifacts
.
getArtifactPath
(
Artifact
.
flutterMacOSPodspec
,
mode:
buildMode
,
platform:
TargetPlatform
.
darwin_x64
);
await
cocoaPods
.
processPods
(
xcodeProject:
project
.
macos
,
engineDir:
enginePath
,
isSwift:
true
,
dependenciesChanged:
true
,
);
}
}
/// Build all of the artifacts for a debug macOS application.
class
DebugMacOSApplication
extends
Target
{
const
DebugMacOSApplication
();
@override
Future
<
void
>
build
(
List
<
File
>
inputFiles
,
Environment
environment
)
async
{
final
File
sourceFile
=
environment
.
buildDir
.
childFile
(
'app.dill'
);
final
File
destinationFile
=
environment
.
buildDir
.
childDirectory
(
'flutter_assets'
)
.
childFile
(
'kernel_blob.bin'
);
if
(!
destinationFile
.
parent
.
existsSync
())
{
destinationFile
.
parent
.
createSync
(
recursive:
true
);
}
sourceFile
.
copySync
(
destinationFile
.
path
);
}
@override
List
<
Target
>
get
dependencies
=>
const
<
Target
>[
FlutterPlugins
(),
UnpackMacOS
(),
KernelSnapshot
(),
CopyAssets
(),
DebugMacOSPodInstall
(),
];
@override
List
<
Source
>
get
inputs
=>
const
<
Source
>[
Source
.
pattern
(
'{BUILD_DIR}/app.dill'
)
];
@override
String
get
name
=>
'debug_macos_application'
;
@override
List
<
Source
>
get
outputs
=>
const
<
Source
>[
Source
.
pattern
(
'{BUILD_DIR}/flutter_assets/kernel_blob.bin'
),
];
}
// TODO(jonahwilliams): real AOT implementation.
class
ReleaseMacOSApplication
extends
DebugMacOSApplication
{
const
ReleaseMacOSApplication
();
@override
String
get
name
=>
'release_macos_application'
;
}
class
ProfileMacOSApplication
extends
DebugMacOSApplication
{
const
ProfileMacOSApplication
();
@override
String
get
name
=>
'profile_macos_application'
;
}
packages/flutter_tools/lib/src/commands/assemble.dart
View file @
2ab46995
...
...
@@ -2,8 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:meta/meta.dart'
;
import
'../base/common.dart'
;
import
'../base/context.dart'
;
import
'../base/file_system.dart'
;
import
'../build_system/build_system.dart'
;
import
'../build_system/targets/assets.dart'
;
import
'../build_system/targets/dart.dart'
;
...
...
@@ -29,6 +32,9 @@ const List<Target> _kDefaultTargets = <Target>[
AotElfRelease
(),
AotAssemblyProfile
(),
AotAssemblyRelease
(),
DebugMacOSApplication
(),
ProfileMacOSApplication
(),
ReleaseMacOSApplication
(),
];
/// Assemble provides a low level API to interact with the flutter tool build
...
...
@@ -40,14 +46,14 @@ class AssembleCommand extends FlutterCommand {
abbr:
'd'
,
help:
'Allows passing configuration to a target with --define=target=key=value.'
);
argParser
.
addOption
(
'build-mode'
,
allowed:
const
<
String
>[
'
debug'
,
'profile'
,
'
release'
,
],
);
argParser
.
addOption
(
'build-inputs'
,
help:
'A file path where a newline '
'separated file containing all inputs used will be written after a build.'
' This file is not included as a build input or output. This file is not'
'
written if the build fails for any reason.'
);
argParser
.
addOption
(
'build-outputs'
,
help:
'A file path where a newline '
'
separated file containing all outputs used will be written after a build.'
' This file is not included as a build input or output. This file is not'
' written if the build fails for any reason.'
);
argParser
.
addOption
(
'resource-pool-size'
,
help:
'The maximum number of concurrent tasks the build system will run.'
...
...
@@ -106,10 +112,33 @@ class AssembleCommand extends FlutterCommand {
printError
(
'Target
${data.key}
failed:
${data.value.exception}
'
);
printError
(
'
${data.value.exception}
'
);
}
throwToolExit
(
'build failed'
);
}
else
{
printStatus
(
'build succeeded'
);
throwToolExit
(
'build failed.'
);
}
printStatus
(
'build succeeded.'
);
if
(
argResults
.
wasParsed
(
'build-inputs'
))
{
writeListIfChanged
(
result
.
inputFiles
,
argResults
[
'build-inputs'
]);
}
if
(
argResults
.
wasParsed
(
'build-outputs'
))
{
writeListIfChanged
(
result
.
outputFiles
,
argResults
[
'build-outputs'
]);
}
return
null
;
}
}
@visibleForTesting
void
writeListIfChanged
(
List
<
File
>
files
,
String
path
)
{
final
File
file
=
fs
.
file
(
path
);
final
StringBuffer
buffer
=
StringBuffer
();
// These files are already sorted.
for
(
File
file
in
files
)
{
buffer
.
writeln
(
file
.
resolveSymbolicLinksSync
());
}
final
String
newContents
=
buffer
.
toString
();
if
(!
file
.
existsSync
())
{
file
.
writeAsStringSync
(
newContents
);
}
final
String
currentContents
=
file
.
readAsStringSync
();
if
(
currentContents
!=
newContents
)
{
file
.
writeAsStringSync
(
newContents
);
}
}
packages/flutter_tools/lib/src/commands/attach.dart
View file @
2ab46995
...
...
@@ -257,7 +257,6 @@ class AttachCommand extends FlutterCommand {
device
,
flutterProject:
flutterProject
,
trackWidgetCreation:
argResults
[
'track-widget-creation'
],
dillOutputPath:
argResults
[
'output-dill'
],
fileSystemRoots:
argResults
[
'filesystem-root'
],
fileSystemScheme:
argResults
[
'filesystem-scheme'
],
viewFilter:
argResults
[
'isolate-filter'
],
...
...
packages/flutter_tools/lib/src/commands/build_macos.dart
View file @
2ab46995
...
...
@@ -14,7 +14,7 @@ import '../project.dart';
import
'../runner/flutter_command.dart'
show
FlutterCommandResult
;
import
'build.dart'
;
/// A command to build a mac
os
desktop target through a build shell script.
/// A command to build a mac
OS
desktop target through a build shell script.
class
BuildMacosCommand
extends
BuildSubCommand
{
BuildMacosCommand
()
{
usesTargetOption
();
...
...
packages/flutter_tools/lib/src/commands/daemon.dart
View file @
2ab46995
...
...
@@ -406,7 +406,6 @@ class AppDomain extends Domain {
device
,
flutterProject:
flutterProject
,
trackWidgetCreation:
trackWidgetCreation
,
dillOutputPath:
dillOutputPath
,
viewFilter:
isolateFilter
,
target:
target
,
buildMode:
options
.
buildInfo
.
mode
,
...
...
packages/flutter_tools/lib/src/commands/run.dart
View file @
2ab46995
...
...
@@ -397,7 +397,6 @@ class RunCommand extends RunCommandBase {
device
,
flutterProject:
flutterProject
,
trackWidgetCreation:
argResults
[
'track-widget-creation'
],
dillOutputPath:
argResults
[
'output-dill'
],
fileSystemRoots:
argResults
[
'filesystem-root'
],
fileSystemScheme:
argResults
[
'filesystem-scheme'
],
viewFilter:
argResults
[
'isolate-filter'
],
...
...
packages/flutter_tools/lib/src/ios/xcodeproj.dart
View file @
2ab46995
...
...
@@ -48,13 +48,15 @@ Future<void> updateGeneratedXcodeProperties({
String
targetOverride
,
bool
useMacOSConfig
=
false
,
bool
setSymroot
=
true
,
String
buildDirOverride
,
})
async
{
final
List
<
String
>
xcodeBuildSettings
=
_xcodeBuildSettingsLines
(
project:
project
,
buildInfo:
buildInfo
,
targetOverride:
targetOverride
,
useMacOSConfig:
useMacOSConfig
,
setSymroot:
setSymroot
setSymroot:
setSymroot
,
buildDirOverride:
buildDirOverride
);
_updateGeneratedXcodePropertiesFile
(
...
...
@@ -121,6 +123,7 @@ List<String> _xcodeBuildSettingsLines({
String
targetOverride
,
bool
useMacOSConfig
=
false
,
bool
setSymroot
=
true
,
String
buildDirOverride
,
})
{
final
List
<
String
>
xcodeBuildSettings
=
<
String
>[];
...
...
@@ -135,7 +138,7 @@ List<String> _xcodeBuildSettingsLines({
xcodeBuildSettings
.
add
(
'FLUTTER_TARGET=
$targetOverride
'
);
// The build outputs directory, relative to FLUTTER_APPLICATION_PATH.
xcodeBuildSettings
.
add
(
'FLUTTER_BUILD_DIR=
${getBuildDirectory()}
'
);
xcodeBuildSettings
.
add
(
'FLUTTER_BUILD_DIR=
${
buildDirOverride ??
getBuildDirectory()}
'
);
if
(
setSymroot
)
{
xcodeBuildSettings
.
add
(
'SYMROOT=
\
${SOURCE_ROOT}
/../
${getIosBuildDirectory()}
'
);
...
...
packages/flutter_tools/lib/src/macos/application_package.dart
View file @
2ab46995
...
...
@@ -6,7 +6,6 @@ import 'package:meta/meta.dart';
import
'../application_package.dart'
;
import
'../base/file_system.dart'
;
import
'../build_info.dart'
;
import
'../globals.dart'
;
import
'../ios/plist_utils.dart'
as
plist
;
import
'../project.dart'
;
...
...
@@ -31,18 +30,17 @@ abstract class MacOSApp extends ApplicationPackage {
/// which is expected to start the application and send the observatory
/// port over stdout.
factory
MacOSApp
.
fromPrebuiltApp
(
FileSystemEntity
applicationBinary
)
{
final
_ExecutableAndId
executableAndId
=
_
executableFromBundle
(
applicationBinary
);
final
ExecutableAndId
executableAndId
=
executableFromBundle
(
applicationBinary
);
final
Directory
applicationBundle
=
fs
.
directory
(
applicationBinary
);
return
PrebuiltMacOSApp
(
bundleDir:
applicationBundle
,
bundleName:
applicationBundle
.
path
,
projectBundleId:
executableAndId
.
id
,
executable:
executableAndId
.
executable
,
executableAndId:
executableAndId
,
);
}
/// Look up the executable name for a macOS application bundle.
static
_ExecutableAndId
_
executableFromBundle
(
Directory
applicationBundle
)
{
static
ExecutableAndId
executableFromBundle
(
Directory
applicationBundle
)
{
final
FileSystemEntityType
entityType
=
fs
.
typeSync
(
applicationBundle
.
path
);
if
(
entityType
==
FileSystemEntityType
.
notFound
)
{
printError
(
'File "
${applicationBundle.path}
" does not exist.'
);
...
...
@@ -75,40 +73,28 @@ abstract class MacOSApp extends ApplicationPackage {
if
(!
fs
.
file
(
executable
).
existsSync
())
{
printError
(
'Could not find macOS binary at
$executable
'
);
}
return
_
ExecutableAndId
(
executable
,
id
);
return
ExecutableAndId
(
executable
,
id
);
}
@override
String
get
displayName
=>
id
;
String
applicationBundle
(
BuildMode
buildMode
);
String
executable
(
BuildMode
buildMode
);
}
class
PrebuiltMacOSApp
extends
MacOSApp
{
PrebuiltMacOSApp
({
@required
this
.
bundleDir
,
@required
this
.
bundleName
,
@required
this
.
projectBundleId
,
@required
String
executable
,
})
:
_executable
=
executable
,
super
(
projectBundleId:
projectBundleId
);
@required
this
.
executableAndId
,
});
final
Directory
bundleDir
;
final
String
bundleName
;
final
String
projectBundleId
;
final
String
_executable
;
final
ExecutableAndId
executableAndId
;
@override
String
get
name
=>
bundleName
;
@override
String
applicationBundle
(
BuildMode
buildMode
)
=>
bundleDir
.
path
;
@override
String
executable
(
BuildMode
buildMode
)
=>
_executable
;
String
get
executable
=>
executableAndId
.
executable
;
}
class
BuildableMacOSApp
extends
MacOSApp
{
...
...
@@ -118,35 +104,10 @@ class BuildableMacOSApp extends MacOSApp {
@override
String
get
name
=>
'macOS'
;
@override
String
applicationBundle
(
BuildMode
buildMode
)
{
final
File
appBundleNameFile
=
project
.
nameFile
;
if
(!
appBundleNameFile
.
existsSync
())
{
printError
(
'Unable to find app name.
${appBundleNameFile.path}
does not exist'
);
return
null
;
}
return
fs
.
path
.
join
(
getMacOSBuildDirectory
(),
'Build'
,
'Products'
,
buildMode
==
BuildMode
.
debug
?
'Debug'
:
'Release'
,
appBundleNameFile
.
readAsStringSync
().
trim
());
}
@override
String
executable
(
BuildMode
buildMode
)
{
final
String
directory
=
applicationBundle
(
buildMode
);
if
(
directory
==
null
)
{
return
null
;
}
final
_ExecutableAndId
executableAndId
=
MacOSApp
.
_executableFromBundle
(
fs
.
directory
(
directory
));
return
executableAndId
.
executable
;
}
}
class
_
ExecutableAndId
{
_
ExecutableAndId
(
this
.
executable
,
this
.
id
);
class
ExecutableAndId
{
ExecutableAndId
(
this
.
executable
,
this
.
id
);
final
String
executable
;
final
String
id
;
...
...
packages/flutter_tools/lib/src/macos/build_macos.dart
View file @
2ab46995
...
...
@@ -8,25 +8,34 @@ import '../base/io.dart';
import
'../base/logger.dart'
;
import
'../base/process_manager.dart'
;
import
'../build_info.dart'
;
import
'../build_system/build_system.dart'
;
import
'../build_system/targets/dart.dart'
;
import
'../convert.dart'
;
import
'../globals.dart'
;
import
'../ios/xcodeproj.dart'
;
import
'../project.dart'
;
import
'../reporting/reporting.dart'
;
import
'application_package.dart'
;
import
'cocoapod_utils.dart'
;
/// Builds the macOS project through xcodebuild.
// TODO(jonahwilliams): refactor to share code with the existing iOS code.
Future
<
void
>
buildMacOS
({
/// Builds the macOS project through xcodebuild and returns the app bundle.
Future
<
PrebuiltMacOSApp
>
buildMacOS
({
FlutterProject
flutterProject
,
BuildInfo
buildInfo
,
String
targetOverride
,
String
targetOverride
=
'lib/main.dart'
,
})
async
{
final
Directory
flutterBuildDir
=
fs
.
directory
(
getMacOSBuildDirectory
());
if
(!
flutterBuildDir
.
existsSync
())
{
flutterBuildDir
.
createSync
(
recursive:
true
);
}
// Create the environment used to process the build. This needs to match what
// is provided in bin/macos_build_flutter_assets.sh otherwise the directories
// will be different.
final
Environment
environment
=
Environment
(
projectDir:
flutterProject
.
directory
,
buildDir:
flutterProject
.
dartTool
.
childDirectory
(
'flutter_build'
),
defines:
<
String
,
String
>{
kBuildMode:
buildInfo
.
isDebug
==
true
?
'debug'
:
'release'
,
kTargetPlatform:
'darwin-x64'
,
kTargetFile:
fs
.
file
(
targetOverride
).
absolute
.
path
},
);
// Write configuration to an xconfig file in a standard location.
await
updateGeneratedXcodeProperties
(
project:
flutterProject
,
...
...
@@ -34,27 +43,34 @@ Future<void> buildMacOS({
targetOverride:
targetOverride
,
useMacOSConfig:
true
,
setSymroot:
false
,
buildDirOverride:
environment
.
buildDir
.
path
,
);
await
processPodsIfNeeded
(
flutterProject
.
macos
,
getMacOSBuildDirectory
(),
buildInfo
.
mode
);
// If the xcfilelists do not exist, create empty version.
if
(!
flutterProject
.
macos
.
inputFileList
.
existsSync
())
{
flutterProject
.
macos
.
inputFileList
.
createSync
(
recursive:
true
);
}
if
(!
flutterProject
.
macos
.
outputFileList
.
existsSync
())
{
flutterProject
.
macos
.
outputFileList
.
createSync
(
recursive:
true
);
}
// Set debug or release mode.
String
config
=
'Debug'
;
if
(
buildInfo
.
isRelease
)
{
if
(
buildInfo
.
isRelease
??
false
)
{
config
=
'Release'
;
}
//
Run build script provided by applic
ation.
//
Invoke Xcode with correct configur
ation.
final
Stopwatch
sw
=
Stopwatch
()..
start
();
final
Process
process
=
await
processManager
.
start
(
<
String
>[
final
List
<
String
>
command
=
<
String
>[
'/usr/bin/env'
,
'xcrun'
,
'xcodebuild'
,
'-workspace'
,
flutterProject
.
macos
.
xcodeWorkspace
.
path
,
'-configuration'
,
'
$config
'
,
'-configuration'
,
config
,
'-scheme'
,
'Runner'
,
'-derivedDataPath'
,
flutterBuildDir
.
absolute
.
path
,
'OBJROOT=
${fs.path.join(flutterBuildDir.absolute.path, 'Build', 'Intermediates.noindex')}
'
,
'SYMROOT=
${fs.path.join(flutterBuildDir.absolute.path, 'Build', 'Products')}
'
,
],
runInShell:
true
);
'-derivedDataPath'
,
environment
.
buildDir
.
path
,
'OBJROOT=
${fs.path.join(environment.buildDir.path, 'Build', 'Intermediates.noindex')}
'
,
'SYMROOT=
${fs.path.join(environment.buildDir.path, 'Build', 'Products')}
'
,
];
final
Process
process
=
await
processManager
.
start
(
command
);
final
Status
status
=
logger
.
startProgress
(
'Building macOS application...'
,
timeout:
null
,
...
...
@@ -77,4 +93,13 @@ Future<void> buildMacOS({
throwToolExit
(
'Build process failed'
);
}
flutterUsage
.
sendTiming
(
'build'
,
'xcode-macos'
,
Duration
(
milliseconds:
sw
.
elapsedMilliseconds
));
final
File
appBundleNameFile
=
flutterProject
.
macos
.
nameFile
;
final
Directory
bundleDir
=
fs
.
directory
(
fs
.
path
.
join
(
environment
.
buildDir
.
path
,
'Build'
,
'Products'
,
buildInfo
.
mode
==
BuildMode
.
debug
?
'Debug'
:
'Release'
,
appBundleNameFile
.
readAsStringSync
().
trim
(),
));
return
MacOSApp
.
fromPrebuiltApp
(
bundleDir
);
}
packages/flutter_tools/lib/src/macos/macos_device.dart
View file @
2ab46995
...
...
@@ -80,10 +80,13 @@ class MacOSDevice extends Device {
bool
usesTerminalUi
=
true
,
bool
ipv6
=
false
,
})
async
{
Cache
.
releaseLockEarly
();
// Stop any running applications with the same executable.
if
(!
prebuiltApplication
)
{
Cache
.
releaseLockEarly
();
await
buildMacOS
(
PrebuiltMacOSApp
prebuiltMacOSApp
;
if
(
prebuiltApplication
)
{
prebuiltMacOSApp
=
package
;
}
else
{
prebuiltMacOSApp
=
await
buildMacOS
(
flutterProject:
FlutterProject
.
current
(),
buildInfo:
debuggingOptions
?.
buildInfo
,
targetOverride:
mainPath
,
...
...
@@ -91,8 +94,7 @@ class MacOSDevice extends Device {
}
// Ensure that the executable is locatable.
final
String
executable
=
package
.
executable
(
debuggingOptions
?.
buildInfo
?.
mode
);
if
(
executable
==
null
)
{
if
(
prebuiltMacOSApp
==
null
)
{
printError
(
'Unable to find executable to run'
);
return
LaunchResult
.
failed
();
}
...
...
@@ -100,7 +102,7 @@ class MacOSDevice extends Device {
// Make sure to call stop app after we've built.
await
stopApp
(
package
);
final
Process
process
=
await
processManager
.
start
(<
String
>[
executable
prebuiltMacOSApp
.
executable
,
]);
if
(
debuggingOptions
?.
buildInfo
?.
isRelease
==
true
)
{
return
LaunchResult
.
succeeded
();
...
...
@@ -111,7 +113,7 @@ class MacOSDevice extends Device {
final
Uri
observatoryUri
=
await
observatoryDiscovery
.
uri
;
// Bring app to foreground.
await
processManager
.
run
(<
String
>[
'open'
,
p
ackage
.
applicationBundle
(
debuggingOptions
?.
buildInfo
?.
mode
)
,
'open'
,
p
rebuiltMacOSApp
.
bundleName
,
]);
return
LaunchResult
.
succeeded
(
observatoryUri:
observatoryUri
);
}
catch
(
error
)
{
...
...
@@ -125,9 +127,8 @@ class MacOSDevice extends Device {
// TODO(jonahwilliams): implement using process manager.
// currently we rely on killing the isolate taking down the application.
@override
Future
<
bool
>
stopApp
(
covariant
MacOSApp
app
)
async
{
// Assume debug for now.
return
killProcess
(
app
.
executable
(
BuildMode
.
debug
));
Future
<
bool
>
stopApp
(
covariant
PrebuiltMacOSApp
app
)
async
{
return
killProcess
(
app
.
executable
);
}
@override
...
...
packages/flutter_tools/lib/src/project.dart
View file @
2ab46995
...
...
@@ -664,6 +664,14 @@ class MacOSProject implements XcodeBasedProject {
/// checked in should live here.
Directory
get
ephemeralDirectory
=>
managedDirectory
.
childDirectory
(
'ephemeral'
);
/// The xcfilelist used to track the inputs for the Flutter script phase in
/// the Xcode build.
File
get
inputFileList
=>
ephemeralDirectory
.
childFile
(
'FlutterInputs.xcfilelist'
);
/// The xcfilelist used to track the outputs for the Flutter script phase in
/// the Xcode build.
File
get
outputFileList
=>
ephemeralDirectory
.
childFile
(
'FlutterOutputs.xcfilelist'
);
@override
File
get
generatedXcodePropertiesFile
=>
ephemeralDirectory
.
childFile
(
'Flutter-Generated.xcconfig'
);
...
...
packages/flutter_tools/lib/src/resident_runner.dart
View file @
2ab46995
...
...
@@ -31,7 +31,6 @@ class FlutterDevice {
FlutterDevice
(
this
.
device
,
{
@required
this
.
trackWidgetCreation
,
this
.
dillOutputPath
,
this
.
fileSystemRoots
,
this
.
fileSystemScheme
,
this
.
viewFilter
,
...
...
@@ -56,7 +55,6 @@ class FlutterDevice {
@required
bool
trackWidgetCreation
,
@required
String
target
,
@required
BuildMode
buildMode
,
String
dillOutputPath
,
List
<
String
>
fileSystemRoots
,
String
fileSystemScheme
,
String
viewFilter
,
...
...
@@ -82,7 +80,6 @@ class FlutterDevice {
return
FlutterDevice
(
device
,
trackWidgetCreation:
trackWidgetCreation
,
dillOutputPath:
dillOutputPath
,
fileSystemRoots:
fileSystemRoots
,
fileSystemScheme:
fileSystemScheme
,
viewFilter:
viewFilter
,
...
...
@@ -99,7 +96,6 @@ class FlutterDevice {
List
<
VMService
>
vmServices
;
DevFS
devFS
;
ApplicationPackage
package
;
String
dillOutputPath
;
List
<
String
>
fileSystemRoots
;
String
fileSystemScheme
;
StreamSubscription
<
String
>
_loggingSubscription
;
...
...
@@ -476,6 +472,7 @@ class FlutterDevice {
bool
fullRestart
=
false
,
String
projectRootPath
,
String
pathToReload
,
@required
String
dillOutputPath
,
@required
List
<
Uri
>
invalidatedFiles
,
})
async
{
final
Status
devFSStatus
=
logger
.
startProgress
(
...
...
@@ -527,12 +524,25 @@ abstract class ResidentRunner {
this
.
usesTerminalUi
=
true
,
this
.
stayResident
=
true
,
this
.
hotMode
=
true
,
this
.
dillOutputPath
,
})
{
_mainPath
=
findMainDartFile
(
target
);
_projectRootPath
=
projectRootPath
??
fs
.
currentDirectory
.
path
;
_packagesFilePath
=
packagesFilePath
??
fs
.
path
.
absolute
(
PackageMap
.
globalPackagesPath
);
_assetBundle
=
AssetBundleFactory
.
instance
.
createBundle
();
// TODO(jonahwilliams): this is transitionary logic to allow us to support
// platforms that are not yet using flutter assemble. In the "new world",
// builds are isolated based on a number of factors. Thus, we cannot assume
// that a debug build will create the expected `build/app.dill` file. For
// now, I'm working around this by just creating it if it is missing here.
// In the future, once build & run are more strongly separated, the build
// environment will be plumbed through so that it all comes from a single
// source of truth, the [Environment].
final
File
dillOutput
=
fs
.
file
(
dillOutputPath
??
fs
.
path
.
join
(
'build'
,
'app.dill'
));
if
(!
dillOutput
.
existsSync
())
{
dillOutput
.
createSync
(
recursive:
true
);
}
}
final
List
<
FlutterDevice
>
flutterDevices
;
...
...
@@ -542,6 +552,7 @@ abstract class ResidentRunner {
final
bool
stayResident
;
final
bool
ipv6
;
final
Completer
<
int
>
_finished
=
Completer
<
int
>();
final
String
dillOutputPath
;
bool
_exited
=
false
;
bool
hotMode
;
String
_packagesFilePath
;
...
...
packages/flutter_tools/lib/src/run_hot.dart
View file @
2ab46995
...
...
@@ -63,7 +63,7 @@ class HotRunner extends ResidentRunner {
this
.
hostIsIde
=
false
,
String
projectRootPath
,
String
packagesFilePath
,
this
.
dillOutputPath
,
String
dillOutputPath
,
bool
stayResident
=
true
,
bool
ipv6
=
false
,
})
:
super
(
devices
,
...
...
@@ -74,13 +74,13 @@ class HotRunner extends ResidentRunner {
packagesFilePath:
packagesFilePath
,
stayResident:
stayResident
,
hotMode:
true
,
dillOutputPath:
dillOutputPath
,
ipv6:
ipv6
);
final
bool
benchmarkMode
;
final
File
applicationBinary
;
final
bool
hostIsIde
;
bool
_didAttach
=
false
;
final
String
dillOutputPath
;
final
Map
<
String
,
List
<
int
>>
benchmarkData
=
<
String
,
List
<
int
>>{};
// The initial launch is from a snapshot.
...
...
@@ -304,6 +304,7 @@ class HotRunner extends ResidentRunner {
projectRootPath:
projectRootPath
,
pathToReload:
getReloadPath
(
fullRestart:
fullRestart
),
invalidatedFiles:
invalidatedFiles
,
dillOutputPath:
dillOutputPath
,
));
}
return
results
;
...
...
packages/flutter_tools/test/general.shard/build_system/build_system_test.dart
View file @
2ab46995
...
...
@@ -138,6 +138,14 @@ void main() {
expect
(
stampContents
[
'inputs'
],
<
Object
>[
'/foo.dart'
]);
}));
test
(
'Creates a BuildResult with inputs and outputs'
,
()
=>
testbed
.
run
(()
async
{
final
BuildResult
result
=
await
buildSystem
.
build
(
fooTarget
,
environment
);
expect
(
result
.
inputFiles
.
single
.
path
,
fs
.
path
.
absolute
(
'foo.dart'
));
expect
(
result
.
outputFiles
.
single
.
path
,
fs
.
path
.
absolute
(
fs
.
path
.
join
(
environment
.
buildDir
.
path
,
'out'
)));
}));
test
(
'Does not re-invoke build if stamp is valid'
,
()
=>
testbed
.
run
(()
async
{
await
buildSystem
.
build
(
fooTarget
,
environment
);
await
buildSystem
.
build
(
fooTarget
,
environment
);
...
...
packages/flutter_tools/test/general.shard/build_system/source_test.dart
View file @
2ab46995
...
...
@@ -135,6 +135,14 @@ void main() {
expect
(()
=>
invalidBase
.
accept
(
visitor
),
throwsA
(
isInstanceOf
<
InvalidPatternException
>()));
}));
test
(
'can substitute optional files'
,
()
=>
testbed
.
run
(()
{
const
Source
missingSource
=
Source
.
pattern
(
'{PROJECT_DIR}/foo'
,
optional:
true
);
expect
(
fs
.
file
(
'foo'
).
existsSync
(),
false
);
missingSource
.
accept
(
visitor
);
expect
(
visitor
.
sources
,
isEmpty
);
}));
}
class
TestBehavior
extends
SourceBehavior
{
...
...
packages/flutter_tools/test/general.shard/build_system/targets/assets_test.dart
View file @
2ab46995
...
...
@@ -65,4 +65,15 @@ flutter:
// See https://github.com/flutter/flutter/issues/35293
expect
(
fs
.
file
(
fs
.
path
.
join
(
environment
.
buildDir
.
path
,
'flutter_assets'
,
'assets/foo/bar.png'
)).
existsSync
(),
false
);
}));
test
(
'FlutterPlugins updates required files as needed'
,
()
=>
testbed
.
run
(()
async
{
fs
.
file
(
'pubspec.yaml'
)
..
writeAsStringSync
(
'name: foo
\n
dependencies:
\n
foo: any
\n
'
);
await
const
FlutterPlugins
().
build
(<
File
>[],
Environment
(
projectDir:
fs
.
currentDirectory
,
));
expect
(
fs
.
file
(
'.flutter-plugins'
).
existsSync
(),
true
);
}));
}
packages/flutter_tools/test/general.shard/build_system/targets/macos_test.dart
View file @
2ab46995
...
...
@@ -7,8 +7,11 @@ import 'package:flutter_tools/src/base/io.dart';
import
'package:flutter_tools/src/base/platform.dart'
;
import
'package:flutter_tools/src/base/process_manager.dart'
;
import
'package:flutter_tools/src/build_system/build_system.dart'
;
import
'package:flutter_tools/src/build_system/exceptions.dart'
;
import
'package:flutter_tools/src/build_system/targets/dart.dart'
;
import
'package:flutter_tools/src/build_system/targets/macos.dart'
;
import
'package:flutter_tools/src/cache.dart'
;
import
'package:flutter_tools/src/macos/cocoapods.dart'
;
import
'package:mockito/mockito.dart'
;
import
'package:process/process.dart'
;
...
...
@@ -17,7 +20,6 @@ import '../../../src/testbed.dart';
void
main
(
)
{
Testbed
testbed
;
const
BuildSystem
buildSystem
=
BuildSystem
();
Environment
environment
;
MockPlatform
mockPlatform
;
...
...
@@ -31,6 +33,7 @@ void main() {
when
(
mockPlatform
.
isWindows
).
thenReturn
(
false
);
when
(
mockPlatform
.
isMacOS
).
thenReturn
(
true
);
when
(
mockPlatform
.
isLinux
).
thenReturn
(
false
);
when
(
mockPlatform
.
environment
).
thenReturn
(
const
<
String
,
String
>{});
testbed
=
Testbed
(
setup:
()
{
environment
=
Environment
(
projectDir:
fs
.
currentDirectory
,
...
...
@@ -79,28 +82,117 @@ void main() {
});
test
(
'Copies files to correct cache directory'
,
()
=>
testbed
.
run
(()
async
{
await
buildSystem
.
build
(
const
UnpackMacOS
(),
environment
);
expect
(
fs
.
directory
(
'macos/Flutter/FlutterMacOS.framework'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'macos/Flutter/FlutterMacOS.framework/FlutterMacOS'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'macos/Flutter/FlutterMacOS.framework/Headers/FLEOpenGLContextHandling.h'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'macos/Flutter/FlutterMacOS.framework/Headers/FLEReshapeListener.h'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'macos/Flutter/FlutterMacOS.framework/Headers/FLEView.h'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'macos/Flutter/FlutterMacOS.framework/Headers/FLEViewController.h'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'macos/Flutter/FlutterMacOS.framework/Headers/FlutterBinaryMessenger.h'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'macos/Flutter/FlutterMacOS.framework/Headers/FlutterChannels.h'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'macos/Flutter/FlutterMacOS.framework/Headers/FlutterCodecs.h'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'macos/Flutter/FlutterMacOS.framework/Headers/FlutterMacOS.h'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'macos/Flutter/FlutterMacOS.framework/Headers/FlutterPluginMacOS.h'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'macos/Flutter/FlutterMacOS.framework/Headers/FlutterPluginRegisrarMacOS.h'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'macos/Flutter/FlutterMacOS.framework/Modules/module.modulemap'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'macos/Flutter/FlutterMacOS.framework/Resources/icudtl.dat'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'macos/Flutter/FlutterMacOS.framework/Resources/info.plist'
).
existsSync
(),
true
);
await
const
UnpackMacOS
().
build
(<
File
>[],
environment
);
expect
(
fs
.
directory
(
'macos/Flutter/ephemeral/FlutterMacOS.framework'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'macos/Flutter/ephemeral/FlutterMacOS.framework/FlutterMacOS'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'macos/Flutter/ephemeral/FlutterMacOS.framework/Headers/FLEOpenGLContextHandling.h'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'macos/Flutter/ephemeral/FlutterMacOS.framework/Headers/FLEReshapeListener.h'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'macos/Flutter/ephemeral/FlutterMacOS.framework/Headers/FLEView.h'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'macos/Flutter/ephemeral/FlutterMacOS.framework/Headers/FLEViewController.h'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'macos/Flutter/ephemeral/FlutterMacOS.framework/Headers/FlutterBinaryMessenger.h'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'macos/Flutter/ephemeral/FlutterMacOS.framework/Headers/FlutterChannels.h'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'macos/Flutter/ephemeral/FlutterMacOS.framework/Headers/FlutterCodecs.h'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'macos/Flutter/ephemeral/FlutterMacOS.framework/Headers/FlutterMacOS.h'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'macos/Flutter/ephemeral/FlutterMacOS.framework/Headers/FlutterPluginMacOS.h'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'macos/Flutter/ephemeral/FlutterMacOS.framework/Headers/FlutterPluginRegisrarMacOS.h'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'macos/Flutter/ephemeral/FlutterMacOS.framework/Modules/module.modulemap'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'macos/Flutter/ephemeral/FlutterMacOS.framework/Resources/icudtl.dat'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'macos/Flutter/ephemeral/FlutterMacOS.framework/Resources/info.plist'
).
existsSync
(),
true
);
}));
test
(
'debug macOS application copies kernel blob'
,
()
=>
testbed
.
run
(()
async
{
final
String
inputKernel
=
fs
.
path
.
join
(
environment
.
buildDir
.
path
,
'app.dill'
);
final
String
outputKernel
=
fs
.
path
.
join
(
environment
.
buildDir
.
path
,
'flutter_assets'
,
'kernel_blob.bin'
);
fs
.
file
(
inputKernel
)
..
createSync
(
recursive:
true
)
..
writeAsStringSync
(
'testing'
);
await
const
DebugMacOSApplication
().
build
(<
File
>[],
environment
);
expect
(
fs
.
file
(
outputKernel
).
readAsStringSync
(),
'testing'
);
}));
test
(
'profile macOS application copies kernel blob'
,
()
=>
testbed
.
run
(()
async
{
final
String
inputKernel
=
fs
.
path
.
join
(
environment
.
buildDir
.
path
,
'app.dill'
);
final
String
outputKernel
=
fs
.
path
.
join
(
environment
.
buildDir
.
path
,
'flutter_assets'
,
'kernel_blob.bin'
);
fs
.
file
(
inputKernel
)
..
createSync
(
recursive:
true
)
..
writeAsStringSync
(
'testing'
);
await
const
ProfileMacOSApplication
().
build
(<
File
>[],
environment
);
expect
(
fs
.
file
(
outputKernel
).
readAsStringSync
(),
'testing'
);
}));
test
(
'release macOS application copies kernel blob'
,
()
=>
testbed
.
run
(()
async
{
final
String
inputKernel
=
fs
.
path
.
join
(
environment
.
buildDir
.
path
,
'app.dill'
);
final
String
outputKernel
=
fs
.
path
.
join
(
environment
.
buildDir
.
path
,
'flutter_assets'
,
'kernel_blob.bin'
);
fs
.
file
(
inputKernel
)
..
createSync
(
recursive:
true
)
..
writeAsStringSync
(
'testing'
);
await
const
ReleaseMacOSApplication
().
build
(<
File
>[],
environment
);
expect
(
fs
.
file
(
outputKernel
).
readAsStringSync
(),
'testing'
);
}));
// Changing target names will require a corresponding update in flutter_tools/bin/macos_build_flutter_assets.sh.
test
(
'Target names match those expected by bin scripts'
,
()
=>
testbed
.
run
(()
async
{
expect
(
const
DebugMacOSApplication
().
name
,
'debug_macos_application'
);
expect
(
const
ProfileMacOSApplication
().
name
,
'profile_macos_application'
);
expect
(
const
ReleaseMacOSApplication
().
name
,
'release_macos_application'
);
}));
test
(
'DebugMacOSPodInstall throws if missing build mode'
,
()
=>
testbed
.
run
(()
async
{
expect
(()
=>
const
DebugMacOSPodInstall
().
build
(<
File
>[],
environment
),
throwsA
(
isInstanceOf
<
MissingDefineException
>()));
}));
test
(
'DebugMacOSPodInstall skips if podfile does not exist'
,
()
=>
testbed
.
run
(()
async
{
await
const
DebugMacOSPodInstall
().
build
(<
File
>[],
Environment
(
projectDir:
fs
.
currentDirectory
,
defines:
<
String
,
String
>{
kBuildMode:
'debug'
}
));
verifyNever
(
cocoaPods
.
processPods
(
xcodeProject:
anyNamed
(
'xcodeProject'
),
engineDir:
anyNamed
(
'engineDir'
),
isSwift:
true
,
dependenciesChanged:
true
));
},
overrides:
<
Type
,
Generator
>{
CocoaPods:
()
=>
MockCocoaPods
(),
}));
test
(
'DebugMacOSPodInstall invokes processPods with podfile'
,
()
=>
testbed
.
run
(()
async
{
fs
.
file
(
fs
.
path
.
join
(
'macos'
,
'Podfile'
)).
createSync
(
recursive:
true
);
await
const
DebugMacOSPodInstall
().
build
(<
File
>[],
Environment
(
projectDir:
fs
.
currentDirectory
,
defines:
<
String
,
String
>{
kBuildMode:
'debug'
}
));
verify
(
cocoaPods
.
processPods
(
xcodeProject:
anyNamed
(
'xcodeProject'
),
engineDir:
anyNamed
(
'engineDir'
),
isSwift:
true
,
dependenciesChanged:
true
)).
called
(
1
);
},
overrides:
<
Type
,
Generator
>{
CocoaPods:
()
=>
MockCocoaPods
(),
}));
test
(
'b'
,
()
=>
testbed
.
run
(()
async
{
}));
}
class
MockPlatform
extends
Mock
implements
Platform
{}
class
MockCocoaPods
extends
Mock
implements
CocoaPods
{}
class
MockProcessManager
extends
Mock
implements
ProcessManager
{}
class
FakeProcessResult
implements
ProcessResult
{
@override
...
...
@@ -115,3 +207,5 @@ class FakeProcessResult implements ProcessResult {
@override
String
stdout
=
''
;
}
packages/flutter_tools/test/general.shard/commands/assemble_test.dart
View file @
2ab46995
...
...
@@ -3,6 +3,7 @@
// found in the LICENSE file.
import
'package:args/command_runner.dart'
;
import
'package:flutter_tools/src/base/file_system.dart'
;
import
'package:flutter_tools/src/base/logger.dart'
;
import
'package:flutter_tools/src/build_system/build_system.dart'
;
import
'package:flutter_tools/src/cache.dart'
;
...
...
@@ -31,13 +32,54 @@ void main() {
test
(
'Can run a build'
,
()
=>
testbed
.
run
(()
async
{
when
(
mockBuildSystem
.
build
(
any
,
any
,
buildSystemConfig:
anyNamed
(
'buildSystemConfig'
)))
.
thenAnswer
((
Invocation
invocation
)
async
{
return
BuildResult
(
true
,
const
<
String
,
ExceptionMeasurement
>{},
const
<
String
,
PerformanceMeasurement
>{}
);
return
BuildResult
(
success:
true
);
});
final
CommandRunner
<
void
>
commandRunner
=
createTestCommandRunner
(
AssembleCommand
());
await
commandRunner
.
run
(<
String
>[
'assemble'
,
'unpack_macos'
]);
final
BufferLogger
bufferLogger
=
logger
;
expect
(
bufferLogger
.
statusText
.
trim
(),
'build succeeded'
);
expect
(
bufferLogger
.
statusText
.
trim
(),
'build succeeded.'
);
}));
test
(
'Only writes input and output files when the values change'
,
()
=>
testbed
.
run
(()
async
{
when
(
mockBuildSystem
.
build
(
any
,
any
,
buildSystemConfig:
anyNamed
(
'buildSystemConfig'
)))
.
thenAnswer
((
Invocation
invocation
)
async
{
return
BuildResult
(
success:
true
,
inputFiles:
<
File
>[
fs
.
file
(
'foo'
)..
createSync
()],
outputFiles:
<
File
>[
fs
.
file
(
'bar'
)..
createSync
()],
);
});
final
CommandRunner
<
void
>
commandRunner
=
createTestCommandRunner
(
AssembleCommand
());
await
commandRunner
.
run
(<
String
>[
'assemble'
,
'--build-outputs=outputs'
,
'--build-inputs=inputs'
,
'unpack_macos'
]);
final
File
inputs
=
fs
.
file
(
'inputs'
);
final
File
outputs
=
fs
.
file
(
'outputs'
);
expect
(
inputs
.
readAsStringSync
(),
contains
(
'foo'
));
expect
(
outputs
.
readAsStringSync
(),
contains
(
'bar'
));
final
DateTime
theDistantPast
=
DateTime
(
1991
,
8
,
23
);
inputs
.
setLastModifiedSync
(
theDistantPast
);
outputs
.
setLastModifiedSync
(
theDistantPast
);
await
commandRunner
.
run
(<
String
>[
'assemble'
,
'--build-outputs=outputs'
,
'--build-inputs=inputs'
,
'unpack_macos'
]);
expect
(
inputs
.
lastModifiedSync
(),
theDistantPast
);
expect
(
outputs
.
lastModifiedSync
(),
theDistantPast
);
when
(
mockBuildSystem
.
build
(
any
,
any
,
buildSystemConfig:
anyNamed
(
'buildSystemConfig'
)))
.
thenAnswer
((
Invocation
invocation
)
async
{
return
BuildResult
(
success:
true
,
inputFiles:
<
File
>[
fs
.
file
(
'foo'
),
fs
.
file
(
'fizz'
)..
createSync
()],
outputFiles:
<
File
>[
fs
.
file
(
'bar'
)]);
});
await
commandRunner
.
run
(<
String
>[
'assemble'
,
'--build-outputs=outputs'
,
'--build-inputs=inputs'
,
'unpack_macos'
]);
expect
(
inputs
.
readAsStringSync
(),
contains
(
'foo'
));
expect
(
inputs
.
readAsStringSync
(),
contains
(
'fizz'
));
expect
(
inputs
.
lastModifiedSync
(),
isNot
(
theDistantPast
));
}));
}
...
...
packages/flutter_tools/test/general.shard/commands/attach_test.dart
View file @
2ab46995
...
...
@@ -168,7 +168,6 @@ void main() {
// output dill, filesystem scheme, and filesystem root.
final
FlutterDevice
flutterDevice
=
flutterDevices
.
first
;
expect
(
flutterDevice
.
dillOutputPath
,
outputDill
);
expect
(
flutterDevice
.
fileSystemScheme
,
filesystemScheme
);
expect
(
flutterDevice
.
fileSystemRoots
,
const
<
String
>[
filesystemRoot
]);
},
overrides:
<
Type
,
Generator
>{
...
...
packages/flutter_tools/test/general.shard/commands/build_macos_test.dart
View file @
2ab46995
...
...
@@ -8,7 +8,8 @@ import 'package:flutter_tools/src/base/common.dart';
import
'package:flutter_tools/src/base/file_system.dart'
;
import
'package:flutter_tools/src/base/io.dart'
;
import
'package:flutter_tools/src/base/platform.dart'
;
import
'package:flutter_tools/src/build_info.dart'
;
import
'package:flutter_tools/src/build_system/build_system.dart'
;
import
'package:flutter_tools/src/build_system/targets/dart.dart'
;
import
'package:flutter_tools/src/cache.dart'
;
import
'package:flutter_tools/src/commands/build.dart'
;
import
'package:flutter_tools/src/features.dart'
;
...
...
@@ -86,25 +87,35 @@ void main() {
fs
.
file
(
'.packages'
).
createSync
();
fs
.
file
(
fs
.
path
.
join
(
'lib'
,
'main.dart'
)).
createSync
(
recursive:
true
);
final
FlutterProject
flutterProject
=
FlutterProject
.
fromDirectory
(
fs
.
currentDirectory
);
final
Directory
flutterBuildDir
=
fs
.
directory
(
getMacOSBuildDirectory
());
final
Environment
environment
=
Environment
(
projectDir:
flutterProject
.
directory
,
buildDir:
flutterProject
.
dartTool
.
childDirectory
(
'flutter_build'
),
defines:
<
String
,
String
>{
kBuildMode:
'release'
,
kTargetFile:
fs
.
path
.
absolute
(
fs
.
path
.
join
(
'lib'
,
'main.dart'
)),
kTargetPlatform:
'darwin-x64'
,
}
);
when
(
mockProcessManager
.
start
(<
String
>[
'/usr/bin/env'
,
'xcrun'
,
'xcodebuild'
,
'-workspace'
,
flutterProject
.
macos
.
xcodeWorkspace
.
path
,
'-configuration'
,
'
Debug
'
,
'-configuration'
,
'
Release
'
,
'-scheme'
,
'Runner'
,
'-derivedDataPath'
,
flutterBuildDir
.
absolute
.
path
,
'OBJROOT=
${fs.path.join(flutterBuildDir.absolute.path, 'Build', 'Intermediates.noindex')}
'
,
'SYMROOT=
${fs.path.join(flutterBuildDir.absolute.path, 'Build', 'Products')}
'
,
],
runInShell:
true
)).
thenAnswer
((
Invocation
invocation
)
async
{
'-derivedDataPath'
,
environment
.
buildDir
.
path
,
'OBJROOT=
${fs.path.join(environment.buildDir.path, 'Build', 'Intermediates.noindex')}
'
,
'SYMROOT=
${fs.path.join(environment.buildDir.path, 'Build', 'Products')}
'
,
])).
thenAnswer
((
Invocation
invocation
)
async
{
fs
.
file
(
fs
.
path
.
join
(
'macos'
,
'Flutter'
,
'ephemeral'
,
'.app_filename'
))
..
createSync
(
recursive:
true
)
..
writeAsStringSync
(
'example.app'
);
return
mockProcess
;
});
await
createTestCommandRunner
(
command
).
run
(
const
<
String
>[
'build'
,
'macos'
]
);
expect
(
createTestCommandRunner
(
command
).
run
(
const
<
String
>[
'build'
,
'macos'
,
'--release'
]
)
,
throwsA
(
isInstanceOf
<
AssertionError
>()))
;
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
memoryFilesystem
,
ProcessManager:
()
=>
mockProcessManager
,
...
...
packages/flutter_tools/test/general.shard/macos/macos_device_test.dart
View file @
2ab46995
...
...
@@ -36,7 +36,6 @@ void main() {
testUsingContext
(
'defaults'
,
()
async
{
final
MockMacOSApp
mockMacOSApp
=
MockMacOSApp
();
when
(
mockMacOSApp
.
executable
(
any
)).
thenReturn
(
'foo'
);
expect
(
await
device
.
targetPlatform
,
TargetPlatform
.
darwin_x64
);
expect
(
device
.
name
,
'macOS'
);
expect
(
await
device
.
installApp
(
mockMacOSApp
),
true
);
...
...
@@ -54,7 +53,7 @@ void main() {
tester 17193 0.0 0.2 4791128 37820 ?? S 2:27PM 0:00.09 /Applications/foo
'''
;
final
MockMacOSApp
mockMacOSApp
=
MockMacOSApp
();
when
(
mockMacOSApp
.
executable
(
any
)).
thenReturn
(
'/Applications/foo
'
);
when
(
mockMacOSApp
.
executable
).
thenReturn
(
'tester
'
);
when
(
mockProcessManager
.
run
(<
String
>[
'ps'
,
'aux'
])).
thenAnswer
((
Invocation
invocation
)
async
{
return
ProcessResult
(
1
,
0
,
psOut
,
''
);
});
...
...
@@ -68,27 +67,35 @@ tester 17193 0.0 0.2 4791128 37820 ?? S 2:27PM 0:00.09 /Applica
});
group
(
'startApp'
,
()
{
final
MockMacOSApp
macOSApp
=
MockMacOSApp
();
final
MockFileSystem
mockFileSystem
=
MockFileSystem
();
final
MockProcessManager
mockProcessManager
=
MockProcessManager
();
final
MockFile
mockFile
=
MockFile
();
when
(
macOSApp
.
executable
(
any
)).
thenReturn
(
'test'
);
when
(
mockFileSystem
.
file
(
'test'
)).
thenReturn
(
mockFile
);
when
(
mockFile
.
existsSync
()).
thenReturn
(
true
);
when
(
mockProcessManager
.
start
(<
String
>[
'test'
])).
thenAnswer
((
Invocation
invocation
)
async
{
return
FakeProcess
(
exitCode:
Completer
<
int
>().
future
,
stdout:
Stream
<
List
<
int
>>.
fromIterable
(<
List
<
int
>>[
utf8
.
encode
(
'Observatory listening on http://127.0.0.1/0
\n
'
),
]),
stderr:
const
Stream
<
List
<
int
>>.
empty
(),
);
});
when
(
mockProcessManager
.
run
(
any
)).
thenAnswer
((
Invocation
invocation
)
async
{
return
ProcessResult
(
0
,
1
,
''
,
''
);
MockMacOSApp
macOSApp
;
MockFileSystem
mockFileSystem
;
MockProcessManager
mockProcessManager
;
MockFile
mockFile
;
setUp
(()
{
macOSApp
=
MockMacOSApp
();
mockFileSystem
=
MockFileSystem
();
mockProcessManager
=
MockProcessManager
();
mockFile
=
MockFile
();
when
(
mockFileSystem
.
file
(
'test'
)).
thenReturn
(
mockFile
);
when
(
mockFile
.
existsSync
()).
thenReturn
(
true
);
when
(
macOSApp
.
executable
).
thenReturn
(
'test'
);
when
(
mockProcessManager
.
start
(<
String
>[
'test'
])).
thenAnswer
((
Invocation
invocation
)
async
{
return
FakeProcess
(
exitCode:
Completer
<
int
>().
future
,
stdout:
Stream
<
List
<
int
>>.
fromIterable
(<
List
<
int
>>[
utf8
.
encode
(
'Observatory listening on http://127.0.0.1/0
\n
'
),
]),
stderr:
const
Stream
<
List
<
int
>>.
empty
(),
);
});
when
(
mockProcessManager
.
run
(
any
)).
thenAnswer
((
Invocation
invocation
)
async
{
return
ProcessResult
(
0
,
1
,
''
,
''
);
});
});
testUsingContext
(
'
C
an run from prebuilt application'
,
()
async
{
testUsingContext
(
'
c
an run from prebuilt application'
,
()
async
{
final
LaunchResult
result
=
await
device
.
startApp
(
macOSApp
,
prebuiltApplication:
true
);
expect
(
result
.
started
,
true
);
expect
(
result
.
observatoryUri
,
Uri
.
parse
(
'http://127.0.0.1/0'
));
...
...
@@ -137,7 +144,7 @@ tester 17193 0.0 0.2 4791128 37820 ?? S 2:27PM 0:00.09 /Applica
class
MockPlatform
extends
Mock
implements
Platform
{}
class
MockMacOSApp
extends
Mock
implements
MacOSApp
{}
class
MockMacOSApp
extends
Mock
implements
Prebuilt
MacOSApp
{}
class
MockFileSystem
extends
Mock
implements
FileSystem
{}
...
...
packages/flutter_tools/test/general.shard/resident_runner_test.dart
View file @
2ab46995
...
...
@@ -68,6 +68,7 @@ void main() {
fullRestart:
anyNamed
(
'fullRestart'
),
projectRootPath:
anyNamed
(
'projectRootPath'
),
pathToReload:
anyNamed
(
'pathToReload'
),
dillOutputPath:
anyNamed
(
'dillOutputPath'
),
)).
thenAnswer
((
Invocation
invocation
)
async
{
return
UpdateFSReport
(
success:
true
,
...
...
@@ -175,6 +176,7 @@ void main() {
projectRootPath:
anyNamed
(
'projectRootPath'
),
pathToReload:
anyNamed
(
'pathToReload'
),
invalidatedFiles:
anyNamed
(
'invalidatedFiles'
),
dillOutputPath:
anyNamed
(
'dillOutputPath'
),
)).
thenThrow
(
RpcException
(
666
,
'something bad happened'
));
final
OperationResult
result
=
await
residentRunner
.
restart
(
fullRestart:
false
);
...
...
@@ -279,6 +281,7 @@ void main() {
projectRootPath:
anyNamed
(
'projectRootPath'
),
pathToReload:
anyNamed
(
'pathToReload'
),
invalidatedFiles:
anyNamed
(
'invalidatedFiles'
),
dillOutputPath:
anyNamed
(
'dillOutputPath'
),
)).
thenThrow
(
RpcException
(
666
,
'something bad happened'
));
final
OperationResult
result
=
await
residentRunner
.
restart
(
fullRestart:
true
);
...
...
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