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
db3f49b1
Unverified
Commit
db3f49b1
authored
Apr 28, 2021
by
Jenn Magder
Committed by
GitHub
Apr 28, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use cached Xcode build settings during iOS build (#80904)
parent
2d5ee03c
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
172 additions
and
188 deletions
+172
-188
mac.dart
packages/flutter_tools/lib/src/ios/mac.dart
+7
-40
xcodeproj.dart
packages/flutter_tools/lib/src/ios/xcodeproj.dart
+37
-4
cocoapods.dart
packages/flutter_tools/lib/src/macos/cocoapods.dart
+1
-0
project.dart
packages/flutter_tools/lib/src/project.dart
+12
-6
build_ios_test.dart
...er_tools/test/commands.shard/hermetic/build_ios_test.dart
+34
-9
build_ipa_test.dart
...er_tools/test/commands.shard/hermetic/build_ipa_test.dart
+2
-8
ios_device_start_nonprebuilt_test.dart
.../general.shard/ios/ios_device_start_nonprebuilt_test.dart
+7
-99
xcodeproj_test.dart
.../flutter_tools/test/general.shard/ios/xcodeproj_test.dart
+64
-14
cocoapods_test.dart
...lutter_tools/test/general.shard/macos/cocoapods_test.dart
+1
-1
project_test.dart
packages/flutter_tools/test/general.shard/project_test.dart
+6
-6
context.dart
packages/flutter_tools/test/src/context.dart
+1
-1
No files found.
packages/flutter_tools/lib/src/ios/mac.dart
View file @
db3f49b1
...
...
@@ -176,9 +176,15 @@ Future<XcodeBuildResult> buildXcodeProject({
}
Map
<
String
,
String
>
autoSigningConfigs
;
final
Map
<
String
,
String
>
buildSettings
=
await
app
.
project
.
buildSettingsForBuildInfo
(
buildInfo
,
environmentType:
buildForDevice
?
EnvironmentType
.
physical
:
EnvironmentType
.
simulator
,
)
??
<
String
,
String
>{};
if
(
codesign
&&
buildForDevice
)
{
autoSigningConfigs
=
await
getCodeSigningIdentityDevelopmentTeam
(
buildSettings:
await
app
.
project
.
buildSettingsForBuildInfo
(
buildInfo
)
,
buildSettings:
buildSettings
,
processManager:
globals
.
processManager
,
logger:
globals
.
logger
,
config:
globals
.
config
,
...
...
@@ -353,45 +359,6 @@ Future<XcodeBuildResult> buildXcodeProject({
);
globals
.
flutterUsage
.
sendTiming
(
xcodeBuildActionToString
(
buildAction
),
'xcode-ios'
,
Duration
(
milliseconds:
sw
.
elapsedMilliseconds
));
// Run -showBuildSettings again but with the exact same parameters as the
// build. showBuildSettings is reported to occasionally timeout. Here, we give
// it a lot of wiggle room (locally on Flutter Gallery, this takes ~1s).
// When there is a timeout, we retry once. See issue #35988.
final
List
<
String
>
showBuildSettingsCommand
=
(
List
<
String
>
.
of
(
buildCommands
)
..
add
(
'-showBuildSettings'
))
// Undocumented behavior: xcodebuild craps out if -showBuildSettings
// is used together with -allowProvisioningUpdates or
// -allowProvisioningDeviceRegistration and freezes forever.
.
where
((
String
buildCommand
)
{
return
!
const
<
String
>[
'-allowProvisioningUpdates'
,
'-allowProvisioningDeviceRegistration'
,
].
contains
(
buildCommand
);
}).
toList
();
const
Duration
showBuildSettingsTimeout
=
Duration
(
minutes:
1
);
Map
<
String
,
String
>
buildSettings
;
try
{
final
RunResult
showBuildSettingsResult
=
await
globals
.
processUtils
.
run
(
showBuildSettingsCommand
,
throwOnError:
true
,
workingDirectory:
app
.
project
.
hostAppRoot
.
path
,
timeout:
showBuildSettingsTimeout
,
timeoutRetries:
1
,
);
final
String
showBuildSettings
=
showBuildSettingsResult
.
stdout
.
trim
();
buildSettings
=
parseXcodeBuildSettings
(
showBuildSettings
);
}
on
ProcessException
catch
(
e
)
{
if
(
e
.
toString
().
contains
(
'timed out'
))
{
BuildEvent
(
'xcode-show-build-settings-timeout'
,
type:
'ios'
,
command:
showBuildSettingsCommand
.
join
(
' '
),
flutterUsage:
globals
.
flutterUsage
,
).
send
();
}
rethrow
;
}
if
(
buildResult
.
exitCode
!=
0
)
{
globals
.
printStatus
(
'Failed to build iOS app'
);
if
(
buildResult
.
stderr
.
isNotEmpty
)
{
...
...
packages/flutter_tools/lib/src/ios/xcodeproj.dart
View file @
db3f49b1
...
...
@@ -166,10 +166,12 @@ class XcodeProjectInterpreter {
/// target (by default this is Runner).
Future
<
Map
<
String
,
String
>>
getBuildSettings
(
String
projectPath
,
{
String
?
scheme
,
required
XcodeProjectBuildContext
buildContext
,
Duration
timeout
=
const
Duration
(
minutes:
1
),
})
async
{
final
Status
status
=
_logger
.
startSpinner
();
final
String
?
scheme
=
buildContext
.
scheme
;
final
String
?
configuration
=
buildContext
.
configuration
;
final
List
<
String
>
showBuildSettingsCommand
=
<
String
>[
...
xcrunCommand
(),
'xcodebuild'
,
...
...
@@ -177,7 +179,12 @@ class XcodeProjectInterpreter {
_fileSystem
.
path
.
absolute
(
projectPath
),
if
(
scheme
!=
null
)
...<
String
>[
'-scheme'
,
scheme
],
if
(
configuration
!=
null
)
...<
String
>[
'-configuration'
,
configuration
],
if
(
buildContext
.
environmentType
==
EnvironmentType
.
simulator
)
...<
String
>[
'-sdk'
,
'iphonesimulator'
],
'-showBuildSettings'
,
'BUILD_DIR=
${_fileSystem.path.absolute(getIosBuildDirectory())}
'
,
...
environmentVariablesAsXcodeBuildSettings
(
_platform
)
];
try
{
...
...
@@ -201,7 +208,7 @@ class XcodeProjectInterpreter {
flutterUsage:
_usage
,
).
send
();
}
_logger
.
printTrace
(
'Unexpected failure to get
th
e build settings:
$error
.'
);
_logger
.
printTrace
(
'Unexpected failure to get
Xcod
e build settings:
$error
.'
);
return
const
<
String
,
String
>{};
}
finally
{
status
.
stop
();
...
...
@@ -282,6 +289,29 @@ String substituteXcodeVariables(String str, Map<String, String> xcodeBuildSettin
return
str
.
replaceAllMapped
(
_varExpr
,
(
Match
m
)
=>
xcodeBuildSettings
[
m
[
1
]!]
??
m
[
0
]!);
}
@immutable
class
XcodeProjectBuildContext
{
const
XcodeProjectBuildContext
({
this
.
scheme
,
this
.
configuration
,
this
.
environmentType
=
EnvironmentType
.
physical
});
final
String
?
scheme
;
final
String
?
configuration
;
final
EnvironmentType
environmentType
;
@override
int
get
hashCode
=>
scheme
.
hashCode
^
configuration
.
hashCode
^
environmentType
.
hashCode
;
@override
bool
operator
==(
Object
other
)
{
if
(
identical
(
other
,
this
))
{
return
true
;
}
return
other
is
XcodeProjectBuildContext
&&
other
.
scheme
==
scheme
&&
other
.
configuration
==
configuration
&&
other
.
environmentType
==
environmentType
;
}
}
/// Information about an Xcode project.
///
/// Represents the output of `xcodebuild -list`.
...
...
@@ -365,7 +395,7 @@ class XcodeProjectInfo {
});
}
void
reportFlavorNotFoundAndExit
()
{
Never
reportFlavorNotFoundAndExit
()
{
_logger
.
printError
(
''
);
if
(
definesCustomSchemes
)
{
_logger
.
printError
(
'The Xcode project defines schemes:
${schemes.join(', ')}
'
);
...
...
@@ -377,7 +407,10 @@ class XcodeProjectInfo {
/// Returns unique build configuration matching [buildInfo] and [scheme], or
/// null, if there is no unique best match.
String
?
buildConfigurationFor
(
BuildInfo
buildInfo
,
String
scheme
)
{
String
?
buildConfigurationFor
(
BuildInfo
?
buildInfo
,
String
scheme
)
{
if
(
buildInfo
==
null
)
{
return
null
;
}
final
String
expectedConfiguration
=
expectedBuildConfigurationFor
(
buildInfo
,
scheme
);
if
(
hasBuildConfigurationForBuildMode
(
expectedConfiguration
))
{
return
expectedConfiguration
;
...
...
packages/flutter_tools/lib/src/macos/cocoapods.dart
View file @
db3f49b1
...
...
@@ -248,6 +248,7 @@ class CocoaPods {
}
else
{
final
bool
isSwift
=
(
await
_xcodeProjectInterpreter
.
getBuildSettings
(
runnerProject
.
path
,
buildContext:
const
XcodeProjectBuildContext
(),
)).
containsKey
(
'SWIFT_VERSION'
);
podfileTemplateName
=
isSwift
?
'Podfile-ios-swift'
:
'Podfile-ios-objc'
;
}
...
...
packages/flutter_tools/lib/src/project.dart
View file @
db3f49b1
...
...
@@ -593,11 +593,10 @@ class IosProject extends FlutterProjectPlatform implements XcodeBasedProject {
/// The build settings for the host app of this project, as a detached map.
///
/// Returns null, if iOS tooling is unavailable.
Future
<
Map
<
String
,
String
>>
buildSettingsForBuildInfo
(
BuildInfo
buildInfo
)
async
{
Future
<
Map
<
String
,
String
>>
buildSettingsForBuildInfo
(
BuildInfo
buildInfo
,
{
EnvironmentType
environmentType
=
EnvironmentType
.
physical
}
)
async
{
if
(!
existsSync
())
{
return
null
;
}
_buildSettingsByScheme
??=
<
String
,
Map
<
String
,
String
>>{};
final
XcodeProjectInfo
info
=
await
projectInfo
();
if
(
info
==
null
)
{
return
null
;
...
...
@@ -608,9 +607,15 @@ class IosProject extends FlutterProjectPlatform implements XcodeBasedProject {
info
.
reportFlavorNotFoundAndExit
();
}
return
_buildSettingsByScheme
[
scheme
]
??=
await
_xcodeProjectBuildSettings
(
scheme
);
final
String
configuration
=
(
await
projectInfo
()).
buildConfigurationFor
(
buildInfo
,
scheme
,
);
final
XcodeProjectBuildContext
buildContext
=
XcodeProjectBuildContext
(
environmentType:
environmentType
,
scheme:
scheme
,
configuration:
configuration
);
return
_buildSettingsByBuildContext
[
buildContext
]
??=
await
_xcodeProjectBuildSettings
(
buildContext
);
}
Map
<
String
,
Map
<
String
,
String
>>
_buildSettingsByScheme
;
final
Map
<
XcodeProjectBuildContext
,
Map
<
String
,
String
>>
_buildSettingsByBuildContext
=
<
XcodeProjectBuildContext
,
Map
<
String
,
String
>>{};
Future
<
XcodeProjectInfo
>
projectInfo
()
async
{
if
(!
xcodeProject
.
existsSync
()
||
!
globals
.
xcodeProjectInterpreter
.
isInstalled
)
{
...
...
@@ -620,13 +625,14 @@ class IosProject extends FlutterProjectPlatform implements XcodeBasedProject {
}
XcodeProjectInfo
_projectInfo
;
Future
<
Map
<
String
,
String
>>
_xcodeProjectBuildSettings
(
String
scheme
)
async
{
Future
<
Map
<
String
,
String
>>
_xcodeProjectBuildSettings
(
XcodeProjectBuildContext
buildContext
)
async
{
if
(!
globals
.
xcodeProjectInterpreter
.
isInstalled
)
{
return
null
;
}
final
Map
<
String
,
String
>
buildSettings
=
await
globals
.
xcodeProjectInterpreter
.
getBuildSettings
(
xcodeProject
.
path
,
scheme:
scheme
,
buildContext:
buildContext
,
);
if
(
buildSettings
!=
null
&&
buildSettings
.
isNotEmpty
)
{
// No timeouts, flakes, or errors.
...
...
packages/flutter_tools/test/commands.shard/hermetic/build_ios_test.dart
View file @
db3f49b1
...
...
@@ -22,12 +22,14 @@ class FakeXcodeProjectInterpreterWithBuildSettings extends FakeXcodeProjectInter
@override
Future
<
Map
<
String
,
String
>>
getBuildSettings
(
String
projectPath
,
{
String
scheme
,
XcodeProjectBuildContext
buildContext
,
Duration
timeout
=
const
Duration
(
minutes:
1
),
})
async
{
return
<
String
,
String
>{
'PRODUCT_BUNDLE_IDENTIFIER'
:
'io.flutter.someProject'
,
'DEVELOPMENT_TEAM'
:
'abc'
,
'TARGET_BUILD_DIR'
:
'build/ios/Release-iphoneos'
,
'WRAPPER_NAME'
:
'Runner.app'
,
};
}
}
...
...
@@ -92,12 +94,16 @@ void main() {
// Creates a FakeCommand for the xcodebuild call to build the app
// in the given configuration.
FakeCommand
_setUpFakeXcodeBuildHandler
({
bool
verbose
=
false
,
bool
s
howBuildSettings
=
false
,
void
Function
()
onRun
})
{
FakeCommand
_setUpFakeXcodeBuildHandler
({
bool
verbose
=
false
,
bool
s
imulator
=
false
,
void
Function
()
onRun
})
{
return
FakeCommand
(
command:
<
String
>[
'xcrun'
,
'xcodebuild'
,
'-configuration'
,
'Release'
,
'-configuration'
,
if
(
simulator
)
'Debug'
else
'Release'
,
if
(
verbose
)
'VERBOSE_SCRIPT_LOGGING=YES'
else
...
...
@@ -105,11 +111,13 @@ void main() {
'-workspace'
,
'Runner.xcworkspace'
,
'-scheme'
,
'Runner'
,
'BUILD_DIR=/build/ios'
,
'-sdk'
,
'iphoneos'
,
'-sdk'
,
if
(
simulator
)
'iphonesimulator'
else
'iphoneos'
,
'FLUTTER_SUPPRESS_ANALYTICS=true'
,
'COMPILER_INDEX_STORE_ENABLE=NO'
,
if
(
showBuildSettings
)
'-showBuildSettings'
,
],
stdout:
'''
TARGET_BUILD_DIR=build/ios/Release-iphoneos
...
...
@@ -179,7 +187,26 @@ void main() {
_setUpFakeXcodeBuildHandler
(
onRun:
()
{
fileSystem
.
directory
(
'build/ios/Release-iphoneos/Runner.app'
).
createSync
(
recursive:
true
);
}),
_setUpFakeXcodeBuildHandler
(
showBuildSettings:
true
),
_setUpRsyncCommand
(),
]),
Platform:
()
=>
macosPlatform
,
XcodeProjectInterpreter:
()
=>
FakeXcodeProjectInterpreterWithBuildSettings
(),
});
testUsingContext
(
'ios simulator build invokes xcode build'
,
()
async
{
final
BuildCommand
command
=
BuildCommand
();
_createMinimalMockProjectFiles
();
await
createTestCommandRunner
(
command
).
run
(
const
<
String
>[
'build'
,
'ios'
,
'--simulator'
,
'--no-pub'
]
);
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
fileSystem
,
ProcessManager:
()
=>
FakeProcessManager
.
list
(<
FakeCommand
>[
xattrCommand
,
_setUpFakeXcodeBuildHandler
(
simulator:
true
,
onRun:
()
{
fileSystem
.
directory
(
'build/ios/Debug-iphonesimulator/Runner.app'
).
createSync
(
recursive:
true
);
}),
_setUpRsyncCommand
(),
]),
Platform:
()
=>
macosPlatform
,
...
...
@@ -200,7 +227,6 @@ void main() {
_setUpFakeXcodeBuildHandler
(
verbose:
true
,
onRun:
()
{
fileSystem
.
directory
(
'build/ios/Release-iphoneos/Runner.app'
).
createSync
(
recursive:
true
);
}),
_setUpFakeXcodeBuildHandler
(
verbose:
true
,
showBuildSettings:
true
),
_setUpRsyncCommand
(),
]),
Platform:
()
=>
macosPlatform
,
...
...
@@ -241,7 +267,6 @@ void main() {
..
createSync
(
recursive:
true
)
..
writeAsStringSync
(
'{}'
);
}),
_setUpFakeXcodeBuildHandler
(
showBuildSettings:
true
),
_setUpRsyncCommand
(
onRun:
()
=>
fileSystem
.
file
(
'build/ios/iphoneos/Runner.app/Frameworks/App.framework/App'
)
..
createSync
(
recursive:
true
)
..
writeAsBytesSync
(
List
<
int
>.
generate
(
10000
,
(
int
index
)
=>
0
))),
...
...
packages/flutter_tools/test/commands.shard/hermetic/build_ipa_test.dart
View file @
db3f49b1
...
...
@@ -21,7 +21,7 @@ class FakeXcodeProjectInterpreterWithBuildSettings extends FakeXcodeProjectInter
@override
Future
<
Map
<
String
,
String
>>
getBuildSettings
(
String
projectPath
,
{
String
scheme
,
XcodeProjectBuildContext
buildContext
,
Duration
timeout
=
const
Duration
(
minutes:
1
),
})
async
{
return
<
String
,
String
>{
...
...
@@ -81,7 +81,7 @@ void main() {
// Creates a FakeCommand for the xcodebuild call to build the app
// in the given configuration.
FakeCommand
setUpFakeXcodeBuildHandler
({
bool
verbose
=
false
,
bool
showBuildSettings
=
false
,
void
Function
()
onRun
})
{
FakeCommand
setUpFakeXcodeBuildHandler
({
bool
verbose
=
false
,
void
Function
()
onRun
})
{
return
FakeCommand
(
command:
<
String
>[
'xcrun'
,
...
...
@@ -98,8 +98,6 @@ void main() {
'COMPILER_INDEX_STORE_ENABLE=NO'
,
'-archivePath'
,
'/build/ios/archive/Runner'
,
'archive'
,
if
(
showBuildSettings
)
'-showBuildSettings'
,
],
stdout:
'STDOUT STUFF'
,
onRun:
onRun
,
...
...
@@ -224,7 +222,6 @@ void main() {
ProcessManager:
()
=>
FakeProcessManager
.
list
(<
FakeCommand
>[
xattrCommand
,
setUpFakeXcodeBuildHandler
(),
setUpFakeXcodeBuildHandler
(
showBuildSettings:
true
),
]),
Platform:
()
=>
macosPlatform
,
XcodeProjectInterpreter:
()
=>
FakeXcodeProjectInterpreterWithBuildSettings
(),
...
...
@@ -242,7 +239,6 @@ void main() {
ProcessManager:
()
=>
FakeProcessManager
.
list
(<
FakeCommand
>[
xattrCommand
,
setUpFakeXcodeBuildHandler
(
verbose:
true
),
setUpFakeXcodeBuildHandler
(
verbose:
true
,
showBuildSettings:
true
),
]),
Platform:
()
=>
macosPlatform
,
XcodeProjectInterpreter:
()
=>
FakeXcodeProjectInterpreterWithBuildSettings
(),
...
...
@@ -303,7 +299,6 @@ void main() {
..
createSync
(
recursive:
true
)
..
writeAsStringSync
(
'{}'
);
}),
setUpFakeXcodeBuildHandler
(
showBuildSettings:
true
),
]),
Platform:
()
=>
macosPlatform
,
FileSystemUtils:
()
=>
FileSystemUtils
(
fileSystem:
fileSystem
,
platform:
macosPlatform
),
...
...
@@ -335,7 +330,6 @@ void main() {
ProcessManager:
()
=>
FakeProcessManager
.
list
(<
FakeCommand
>[
xattrCommand
,
setUpFakeXcodeBuildHandler
(),
setUpFakeXcodeBuildHandler
(
showBuildSettings:
true
),
exportArchiveCommand
,
]),
Platform:
()
=>
macosPlatform
,
...
...
packages/flutter_tools/test/general.shard/ios/ios_device_start_nonprebuilt_test.dart
View file @
db3f49b1
...
...
@@ -105,6 +105,13 @@ void main() {
));
}
);
when
(
mockXcodeProjectInterpreter
.
getBuildSettings
(
any
,
buildContext:
anyNamed
(
'buildContext'
)))
.
thenAnswer
((
_
)
async
=>
<
String
,
String
>{
'TARGET_BUILD_DIR'
:
'build/ios/Release-iphoneos'
,
'WRAPPER_NAME'
:
'My Super Awesome App.app'
,
'DEVELOPMENT_TEAM'
:
'3333CCCC33'
,
});
xcode
=
Xcode
.
test
(
processManager:
FakeProcessManager
.
any
(),
xcodeProjectInterpreter:
mockXcodeProjectInterpreter
);
fileSystem
.
file
(
'foo/.packages'
)
..
createSync
(
recursive:
true
)
...
...
@@ -125,11 +132,6 @@ void main() {
processManager
.
addCommand
(
FakeCommand
(
command:
_xattrArgs
(
flutterProject
)));
processManager
.
addCommand
(
const
FakeCommand
(
command:
kRunReleaseArgs
));
processManager
.
addCommand
(
const
FakeCommand
(
command:
<
String
>[...
kRunReleaseArgs
,
'-showBuildSettings'
],
stdout:
r''
'
TARGET_BUILD_DIR=build/ios/Release-iphoneos
WRAPPER_NAME=My Super Awesome App.app
'''
));
processManager
.
addCommand
(
const
FakeCommand
(
command:
<
String
>[
'rsync'
,
'-av'
,
...
...
@@ -174,95 +176,6 @@ void main() {
Xcode:
()
=>
xcode
,
});
testUsingContext
(
'with flaky buildSettings call'
,
()
async
{
LaunchResult
launchResult
;
FakeAsync
().
run
((
FakeAsync
time
)
{
final
IOSDevice
iosDevice
=
setUpIOSDevice
(
fileSystem:
fileSystem
,
processManager:
processManager
,
logger:
logger
,
artifacts:
artifacts
,
);
setUpIOSProject
(
fileSystem
);
final
FlutterProject
flutterProject
=
FlutterProject
.
fromDirectory
(
fileSystem
.
currentDirectory
);
final
BuildableIOSApp
buildableIOSApp
=
BuildableIOSApp
(
flutterProject
.
ios
,
'flutter'
,
'My Super Awesome App.app'
);
fileSystem
.
directory
(
'build/ios/Release-iphoneos/My Super Awesome App.app'
).
createSync
(
recursive:
true
);
processManager
.
addCommand
(
FakeCommand
(
command:
_xattrArgs
(
flutterProject
)));
processManager
.
addCommand
(
const
FakeCommand
(
command:
kRunReleaseArgs
));
// The first showBuildSettings call should timeout.
processManager
.
addCommand
(
const
FakeCommand
(
command:
<
String
>[...
kRunReleaseArgs
,
'-showBuildSettings'
],
duration:
Duration
(
minutes:
5
),
// this is longer than the timeout of 1 minute.
));
// The second call succeeds and is made after the first times out.
processManager
.
addCommand
(
const
FakeCommand
(
command:
<
String
>[...
kRunReleaseArgs
,
'-showBuildSettings'
],
exitCode:
0
,
stdout:
r''
'
TARGET_BUILD_DIR=build/ios/Release-iphoneos
WRAPPER_NAME=My Super Awesome App.app
'''
));
processManager
.
addCommand
(
const
FakeCommand
(
command:
<
String
>[
'rsync'
,
'-av'
,
'--delete'
,
'build/ios/Release-iphoneos/My Super Awesome App.app'
,
'build/ios/iphoneos'
,
]));
processManager
.
addCommand
(
FakeCommand
(
command:
<
String
>[
iosDeployPath
,
'--id'
,
'123'
,
'--bundle'
,
'build/ios/iphoneos/My Super Awesome App.app'
,
'--app_deltas'
,
'build/ios/app-delta'
,
'--no-wifi'
,
'--justlaunch'
,
'--args'
,
const
<
String
>[
'--enable-dart-profiling'
,
'--disable-service-auth-codes'
,
].
join
(
' '
)
])
);
iosDevice
.
startApp
(
buildableIOSApp
,
debuggingOptions:
DebuggingOptions
.
disabled
(
BuildInfo
.
release
),
platformArgs:
<
String
,
Object
>{},
).
then
((
LaunchResult
result
)
{
launchResult
=
result
;
});
// Elapse duration for process timeout.
time
.
flushMicrotasks
();
time
.
elapse
(
const
Duration
(
minutes:
1
));
// Elapse duration for overall process timer.
time
.
flushMicrotasks
();
time
.
elapse
(
const
Duration
(
minutes:
5
));
time
.
flushTimers
();
});
expect
(
launchResult
?.
started
,
true
);
expect
(
fileSystem
.
directory
(
'build/ios/iphoneos'
),
exists
);
expect
(
processManager
,
hasNoRemainingExpectations
);
},
overrides:
<
Type
,
Generator
>{
ProcessManager:
()
=>
processManager
,
FileSystem:
()
=>
fileSystem
,
Logger:
()
=>
logger
,
Platform:
()
=>
macPlatform
,
XcodeProjectInterpreter:
()
=>
mockXcodeProjectInterpreter
,
Xcode:
()
=>
xcode
,
});
testUsingContext
(
'with concurrent build failures'
,
()
async
{
final
IOSDevice
iosDevice
=
setUpIOSDevice
(
fileSystem:
fileSystem
,
...
...
@@ -284,11 +197,6 @@ void main() {
stdout:
kConcurrentBuildErrorMessage
,
));
processManager
.
addCommand
(
const
FakeCommand
(
command:
kRunReleaseArgs
));
processManager
.
addCommand
(
const
FakeCommand
(
command:
<
String
>[...
kRunReleaseArgs
,
'-showBuildSettings'
],
exitCode:
0
,
));
processManager
.
addCommand
(
FakeCommand
(
command:
<
String
>[
iosDeployPath
,
...
...
packages/flutter_tools/test/general.shard/ios/xcodeproj_test.dart
View file @
db3f49b1
...
...
@@ -46,7 +46,7 @@ void main() {
);
});
test
Without
Context
(
'xcodebuild build settings flakes'
,
()
async
{
test
Using
Context
(
'xcodebuild build settings flakes'
,
()
async
{
const
Duration
delay
=
Duration
(
seconds:
1
);
processManager
.
processFactory
=
mocks
.
flakyProcessFactory
(
flakes:
1
,
...
...
@@ -59,8 +59,7 @@ void main() {
when
(
processManager
.
runSync
(<
String
>[
'sysctl'
,
'hw.optional.arm64'
]))
.
thenReturn
(
ProcessResult
(
0
,
1
,
''
,
''
));
expect
(
await
xcodeProjectInterpreter
.
getBuildSettings
(
''
,
scheme:
'Runner'
,
timeout:
delay
),
expect
(
await
xcodeProjectInterpreter
.
getBuildSettings
(
''
,
buildContext:
const
XcodeProjectBuildContext
(
scheme:
'Runner'
),
timeout:
delay
),
const
<
String
,
String
>{});
// build settings times out and is killed once, then succeeds.
verify
(
processManager
.
killPid
(
any
)).
called
(
1
);
...
...
@@ -292,12 +291,12 @@ void main() {
expect
(
fakeProcessManager
.
hasRemainingExpectations
,
isFalse
);
});
test
Without
Context
(
'xcodebuild build settings is empty when xcodebuild failed to get the build settings'
,
()
async
{
test
Using
Context
(
'xcodebuild build settings is empty when xcodebuild failed to get the build settings'
,
()
async
{
platform
.
environment
=
const
<
String
,
String
>{};
fakeProcessManager
.
addCommands
(
const
<
FakeCommand
>[
fakeProcessManager
.
addCommands
(<
FakeCommand
>[
kWhichSysctlCommand
,
FakeCommand
(
const
FakeCommand
(
command:
<
String
>[
'sysctl'
,
'hw.optional.arm64'
,
...
...
@@ -312,20 +311,26 @@ void main() {
'/'
,
'-scheme'
,
'Free'
,
'-showBuildSettings'
'-showBuildSettings'
,
'BUILD_DIR=
${fileSystem.path.absolute('build', 'ios')}
'
,
],
exitCode:
1
,
),
]);
expect
(
await
xcodeProjectInterpreter
.
getBuildSettings
(
''
,
scheme:
'Free'
),
const
<
String
,
String
>{});
expect
(
await
xcodeProjectInterpreter
.
getBuildSettings
(
''
,
buildContext:
const
XcodeProjectBuildContext
(
scheme:
'Free'
)),
const
<
String
,
String
>{});
expect
(
fakeProcessManager
.
hasRemainingExpectations
,
isFalse
);
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
fileSystem
,
ProcessManager:
()
=>
FakeProcessManager
.
any
(),
});
test
WithoutContext
(
'build settings accepts an empty scheme
'
,
()
async
{
test
UsingContext
(
'build settings passes in the simulator SDK
'
,
()
async
{
platform
.
environment
=
const
<
String
,
String
>{};
fakeProcessManager
.
addCommands
(
const
<
FakeCommand
>[
fakeProcessManager
.
addCommands
(<
FakeCommand
>[
kWhichSysctlCommand
,
kARMCheckCommand
,
FakeCommand
(
...
...
@@ -334,17 +339,56 @@ void main() {
'xcodebuild'
,
'-project'
,
'/'
,
'-showBuildSettings'
'-sdk'
,
'iphonesimulator'
,
'-showBuildSettings'
,
'BUILD_DIR=
${fileSystem.path.absolute('build', 'ios')}
'
,
],
exitCode:
1
,
),
]);
expect
(
await
xcodeProjectInterpreter
.
getBuildSettings
(
''
),
const
<
String
,
String
>{});
expect
(
await
xcodeProjectInterpreter
.
getBuildSettings
(
''
,
buildContext:
const
XcodeProjectBuildContext
(
environmentType:
EnvironmentType
.
simulator
),
),
const
<
String
,
String
>{},
);
expect
(
fakeProcessManager
.
hasRemainingExpectations
,
isFalse
);
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
fileSystem
,
ProcessManager:
()
=>
FakeProcessManager
.
any
(),
});
testWithoutContext
(
'xcodebuild build settings contains Flutter Xcode environment variables'
,
()
async
{
testUsingContext
(
'build settings accepts an empty scheme'
,
()
async
{
platform
.
environment
=
const
<
String
,
String
>{};
fakeProcessManager
.
addCommands
(<
FakeCommand
>[
kWhichSysctlCommand
,
kARMCheckCommand
,
FakeCommand
(
command:
<
String
>[
'xcrun'
,
'xcodebuild'
,
'-project'
,
'/'
,
'-showBuildSettings'
,
'BUILD_DIR=
${fileSystem.path.absolute('build', 'ios')}
'
,
],
exitCode:
1
,
),
]);
expect
(
await
xcodeProjectInterpreter
.
getBuildSettings
(
''
,
buildContext:
const
XcodeProjectBuildContext
()),
const
<
String
,
String
>{});
expect
(
fakeProcessManager
.
hasRemainingExpectations
,
isFalse
);
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
fileSystem
,
ProcessManager:
()
=>
FakeProcessManager
.
any
(),
});
testUsingContext
(
'xcodebuild build settings contains Flutter Xcode environment variables'
,
()
async
{
platform
.
environment
=
const
<
String
,
String
>{
'FLUTTER_XCODE_CODE_SIGN_STYLE'
:
'Manual'
,
'FLUTTER_XCODE_ARCHS'
:
'arm64'
...
...
@@ -361,13 +405,19 @@ void main() {
'-scheme'
,
'Free'
,
'-showBuildSettings'
,
'BUILD_DIR=
${fileSystem.path.absolute('build', 'ios')}
'
,
'CODE_SIGN_STYLE=Manual'
,
'ARCHS=arm64'
],
),
]);
expect
(
await
xcodeProjectInterpreter
.
getBuildSettings
(
''
,
scheme:
'Free'
),
const
<
String
,
String
>{});
expect
(
await
xcodeProjectInterpreter
.
getBuildSettings
(
''
,
buildContext:
const
XcodeProjectBuildContext
(
scheme:
'Free'
)),
const
<
String
,
String
>{});
expect
(
fakeProcessManager
.
hasRemainingExpectations
,
isFalse
);
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
fileSystem
,
ProcessManager:
()
=>
FakeProcessManager
.
any
(),
});
testWithoutContext
(
'xcodebuild clean contains Flutter Xcode environment variables'
,
()
async
{
...
...
packages/flutter_tools/test/general.shard/macos/cocoapods_test.dart
View file @
db3f49b1
...
...
@@ -794,7 +794,7 @@ class FakeXcodeProjectInterpreter extends Fake implements XcodeProjectInterprete
@override
Future
<
Map
<
String
,
String
>>
getBuildSettings
(
String
projectPath
,
{
String
scheme
,
XcodeProjectBuildContext
buildContext
,
Duration
timeout
=
const
Duration
(
minutes:
1
),
})
async
=>
buildSettings
;
...
...
packages/flutter_tools/test/general.shard/project_test.dart
View file @
db3f49b1
...
...
@@ -397,7 +397,7 @@ apply plugin: 'kotlin-android'
testWithMocks
(
'from build settings, if no plist'
,
()
async
{
final
FlutterProject
project
=
await
someProject
();
project
.
ios
.
xcodeProject
.
createSync
();
when
(
mockXcodeProjectInterpreter
.
getBuildSettings
(
any
,
scheme:
anyNamed
(
'scheme
'
))).
thenAnswer
(
when
(
mockXcodeProjectInterpreter
.
getBuildSettings
(
any
,
buildContext:
anyNamed
(
'buildContext
'
))).
thenAnswer
(
(
_
)
{
return
Future
<
Map
<
String
,
String
>>.
value
(<
String
,
String
>{
'PRODUCT_BUNDLE_IDENTIFIER'
:
'io.flutter.someProject'
,
...
...
@@ -428,7 +428,7 @@ apply plugin: 'kotlin-android'
testWithMocks
(
'from build settings and plist, if default variable'
,
()
async
{
final
FlutterProject
project
=
await
someProject
();
project
.
ios
.
xcodeProject
.
createSync
();
when
(
mockXcodeProjectInterpreter
.
getBuildSettings
(
any
,
scheme:
anyNamed
(
'scheme
'
))).
thenAnswer
(
when
(
mockXcodeProjectInterpreter
.
getBuildSettings
(
any
,
buildContext:
anyNamed
(
'buildContext
'
))).
thenAnswer
(
(
_
)
{
return
Future
<
Map
<
String
,
String
>>.
value
(<
String
,
String
>{
'PRODUCT_BUNDLE_IDENTIFIER'
:
'io.flutter.someProject'
,
...
...
@@ -447,7 +447,7 @@ apply plugin: 'kotlin-android'
final
FlutterProject
project
=
await
someProject
();
project
.
ios
.
xcodeProject
.
createSync
();
project
.
ios
.
defaultHostInfoPlist
.
createSync
(
recursive:
true
);
when
(
mockXcodeProjectInterpreter
.
getBuildSettings
(
any
,
scheme:
anyNamed
(
'scheme
'
))).
thenAnswer
(
when
(
mockXcodeProjectInterpreter
.
getBuildSettings
(
any
,
buildContext:
anyNamed
(
'buildContext
'
))).
thenAnswer
(
(
_
)
{
return
Future
<
Map
<
String
,
String
>>.
value
(<
String
,
String
>{
'PRODUCT_BUNDLE_IDENTIFIER'
:
'io.flutter.someProject'
,
...
...
@@ -478,7 +478,7 @@ apply plugin: 'kotlin-android'
testWithMocks
(
'handles case insensitive flavor'
,
()
async
{
final
FlutterProject
project
=
await
someProject
();
project
.
ios
.
xcodeProject
.
createSync
();
when
(
mockXcodeProjectInterpreter
.
getBuildSettings
(
any
,
scheme:
anyNamed
(
'scheme
'
))).
thenAnswer
(
when
(
mockXcodeProjectInterpreter
.
getBuildSettings
(
any
,
buildContext:
anyNamed
(
'buildContext
'
))).
thenAnswer
(
(
_
)
{
return
Future
<
Map
<
String
,
String
>>.
value
(<
String
,
String
>{
'PRODUCT_BUNDLE_IDENTIFIER'
:
'io.flutter.someProject'
,
...
...
@@ -550,7 +550,7 @@ apply plugin: 'kotlin-android'
testUsingContext
(
'app product name xcodebuild settings'
,
()
async
{
final
FlutterProject
project
=
await
someProject
();
project
.
ios
.
xcodeProject
.
createSync
();
when
(
mockXcodeProjectInterpreter
.
getBuildSettings
(
any
,
scheme:
anyNamed
(
'scheme
'
))).
thenAnswer
((
_
)
{
when
(
mockXcodeProjectInterpreter
.
getBuildSettings
(
any
,
buildContext:
anyNamed
(
'buildContext
'
))).
thenAnswer
((
_
)
{
return
Future
<
Map
<
String
,
String
>>.
value
(<
String
,
String
>{
'FULL_PRODUCT_NAME'
:
'My App.app'
});
...
...
@@ -667,7 +667,7 @@ apply plugin: 'kotlin-android'
group
(
'with bundle identifier'
,
()
{
setUp
(()
{
when
(
mockXcodeProjectInterpreter
.
getBuildSettings
(
any
,
scheme:
anyNamed
(
'scheme
'
))).
thenAnswer
(
when
(
mockXcodeProjectInterpreter
.
getBuildSettings
(
any
,
buildContext:
anyNamed
(
'buildContext
'
))).
thenAnswer
(
(
_
)
{
return
Future
<
Map
<
String
,
String
>>.
value
(<
String
,
String
>{
'PRODUCT_BUNDLE_IDENTIFIER'
:
'io.flutter.someProject'
,
...
...
packages/flutter_tools/test/src/context.dart
View file @
db3f49b1
...
...
@@ -307,7 +307,7 @@ class FakeXcodeProjectInterpreter implements XcodeProjectInterpreter {
@override
Future
<
Map
<
String
,
String
>>
getBuildSettings
(
String
projectPath
,
{
String
scheme
,
XcodeProjectBuildContext
buildContext
,
Duration
timeout
=
const
Duration
(
minutes:
1
),
})
async
{
return
<
String
,
String
>{};
...
...
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