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
e110ca72
Unverified
Commit
e110ca72
authored
Jul 09, 2020
by
Jenn Magder
Committed by
GitHub
Jul 09, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Case insensitive check flavor names against Xcode schemes (#61140)
parent
39f93d18
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
176 additions
and
137 deletions
+176
-137
free.xcscheme
...ios/Runner.xcodeproj/xcshareddata/xcschemes/free.xcscheme
+1
-10
paid.xcscheme
...ios/Runner.xcodeproj/xcshareddata/xcschemes/paid.xcscheme
+1
-10
mac.dart
packages/flutter_tools/lib/src/ios/mac.dart
+2
-10
xcodeproj.dart
packages/flutter_tools/lib/src/ios/xcodeproj.dart
+22
-5
build_macos.dart
packages/flutter_tools/lib/src/macos/build_macos.dart
+1
-1
project.dart
packages/flutter_tools/lib/src/project.dart
+44
-50
build_macos_test.dart
..._tools/test/commands.shard/hermetic/build_macos_test.dart
+2
-0
clean_test.dart
...lutter_tools/test/commands.shard/hermetic/clean_test.dart
+2
-1
ios_device_start_nonprebuilt_test.dart
.../general.shard/ios/ios_device_start_nonprebuilt_test.dart
+1
-0
xcodeproj_test.dart
.../flutter_tools/test/general.shard/ios/xcodeproj_test.dart
+39
-4
project_test.dart
packages/flutter_tools/test/general.shard/project_test.dart
+60
-46
context.dart
packages/flutter_tools/test/src/context.dart
+1
-0
No files found.
dev/integration_tests/flavors/ios/Runner.xcodeproj/xcshareddata/xcschemes/
F
ree.xcscheme
→
dev/integration_tests/flavors/ios/Runner.xcodeproj/xcshareddata/xcschemes/
f
ree.xcscheme
View file @
e110ca72
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion =
"
083
0"
LastUpgradeVersion =
"
120
0"
version =
"1.3"
>
<BuildAction
parallelizeBuildables =
"YES"
...
...
@@ -27,15 +27,6 @@
selectedDebuggerIdentifier =
"Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier =
"Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv =
"YES"
>
<MacroExpansion>
<BuildableReference
BuildableIdentifier =
"primary"
BlueprintIdentifier =
"97C146ED1CF9000F007C117D"
BuildableName =
"Free App.app"
BlueprintName =
"Free App"
ReferencedContainer =
"container:Runner.xcodeproj"
>
</BuildableReference>
</MacroExpansion>
<Testables>
</Testables>
</TestAction>
...
...
dev/integration_tests/flavors/ios/Runner.xcodeproj/xcshareddata/xcschemes/
P
aid.xcscheme
→
dev/integration_tests/flavors/ios/Runner.xcodeproj/xcshareddata/xcschemes/
p
aid.xcscheme
View file @
e110ca72
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion =
"
083
0"
LastUpgradeVersion =
"
120
0"
version =
"1.3"
>
<BuildAction
parallelizeBuildables =
"YES"
...
...
@@ -27,15 +27,6 @@
selectedDebuggerIdentifier =
"Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier =
"Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv =
"YES"
>
<MacroExpansion>
<BuildableReference
BuildableIdentifier =
"primary"
BlueprintIdentifier =
"97C146ED1CF9000F007C117D"
BuildableName =
"Free App.app"
BlueprintName =
"Free App"
ReferencedContainer =
"container:Runner.xcodeproj"
>
</BuildableReference>
</MacroExpansion>
<Testables>
</Testables>
</TestAction>
...
...
packages/flutter_tools/lib/src/ios/mac.dart
View file @
e110ca72
...
...
@@ -119,18 +119,10 @@ Future<XcodeBuildResult> buildXcodeProject({
await
removeFinderExtendedAttributes
(
app
.
project
.
hostAppRoot
,
processUtils
,
globals
.
logger
);
final
XcodeProjectInfo
projectInfo
=
await
globals
.
xcodeProjectInterpreter
.
getInfo
(
app
.
project
.
hostAppRoot
.
path
);
final
XcodeProjectInfo
projectInfo
=
await
app
.
project
.
projectInfo
(
);
final
String
scheme
=
projectInfo
.
schemeFor
(
buildInfo
);
if
(
scheme
==
null
)
{
globals
.
printError
(
''
);
if
(
projectInfo
.
definesCustomSchemes
)
{
globals
.
printError
(
'The Xcode project defines schemes:
${projectInfo.schemes.join(', ')}
'
);
globals
.
printError
(
'You must specify a --flavor option to select one of them.'
);
}
else
{
globals
.
printError
(
'The Xcode project does not define custom schemes.'
);
globals
.
printError
(
'You cannot use the --flavor option.'
);
}
return
XcodeBuildResult
(
success:
false
);
projectInfo
.
reportFlavorNotFoundAndExit
();
}
final
String
configuration
=
projectInfo
.
buildConfigurationFor
(
buildInfo
,
scheme
);
if
(
configuration
==
null
)
{
...
...
packages/flutter_tools/lib/src/ios/xcodeproj.dart
View file @
e110ca72
...
...
@@ -391,7 +391,7 @@ class XcodeProjectInterpreter {
if
(
result
.
exitCode
==
missingProjectExitCode
)
{
throwToolExit
(
'Unable to get Xcode project information:
\n
${result.stderr}
'
);
}
return
XcodeProjectInfo
.
fromXcodeBuildOutput
(
result
.
toString
());
return
XcodeProjectInfo
.
fromXcodeBuildOutput
(
result
.
toString
()
,
_logger
);
}
}
...
...
@@ -435,9 +435,14 @@ String substituteXcodeVariables(String str, Map<String, String> xcodeBuildSettin
///
/// Represents the output of `xcodebuild -list`.
class
XcodeProjectInfo
{
XcodeProjectInfo
(
this
.
targets
,
this
.
buildConfigurations
,
this
.
schemes
);
factory
XcodeProjectInfo
.
fromXcodeBuildOutput
(
String
output
)
{
XcodeProjectInfo
(
this
.
targets
,
this
.
buildConfigurations
,
this
.
schemes
,
Logger
logger
)
:
_logger
=
logger
;
factory
XcodeProjectInfo
.
fromXcodeBuildOutput
(
String
output
,
Logger
logger
)
{
final
List
<
String
>
targets
=
<
String
>[];
final
List
<
String
>
buildConfigurations
=
<
String
>[];
final
List
<
String
>
schemes
=
<
String
>[];
...
...
@@ -461,16 +466,18 @@ class XcodeProjectInfo {
if
(
schemes
.
isEmpty
)
{
schemes
.
add
(
'Runner'
);
}
return
XcodeProjectInfo
(
targets
,
buildConfigurations
,
schemes
);
return
XcodeProjectInfo
(
targets
,
buildConfigurations
,
schemes
,
logger
);
}
final
List
<
String
>
targets
;
final
List
<
String
>
buildConfigurations
;
final
List
<
String
>
schemes
;
final
Logger
_logger
;
bool
get
definesCustomSchemes
=>
!(
schemes
.
contains
(
'Runner'
)
&&
schemes
.
length
==
1
);
/// The expected scheme for [buildInfo].
@visibleForTesting
static
String
expectedSchemeFor
(
BuildInfo
buildInfo
)
{
return
toTitleCase
(
buildInfo
?.
flavor
??
'runner'
);
}
...
...
@@ -507,6 +514,16 @@ class XcodeProjectInfo {
});
}
void
reportFlavorNotFoundAndExit
()
{
_logger
.
printError
(
''
);
if
(
definesCustomSchemes
)
{
_logger
.
printError
(
'The Xcode project defines schemes:
${schemes.join(', ')}
'
);
throwToolExit
(
'You must specify a --flavor option to select one of the available schemes.'
);
}
else
{
throwToolExit
(
'The Xcode project does not define custom schemes. You cannot use the --flavor option.'
);
}
}
/// Returns unique build configuration matching [buildInfo] and [scheme], or
/// null, if there is no unique best match.
String
buildConfigurationFor
(
BuildInfo
buildInfo
,
String
scheme
)
{
...
...
packages/flutter_tools/lib/src/macos/build_macos.dart
View file @
e110ca72
...
...
@@ -61,7 +61,7 @@ Future<void> buildMacOS({
);
final
String
scheme
=
projectInfo
.
schemeFor
(
buildInfo
);
if
(
scheme
==
null
)
{
throwToolExit
(
'Unable to find expected scheme in Xcode project.'
);
projectInfo
.
reportFlavorNotFoundAndExit
(
);
}
final
String
configuration
=
projectInfo
.
buildConfigurationFor
(
buildInfo
,
scheme
);
if
(
configuration
==
null
)
{
...
...
packages/flutter_tools/lib/src/project.dart
View file @
e110ca72
...
...
@@ -20,6 +20,7 @@ import 'flutter_manifest.dart';
import
'globals.dart'
as
globals
;
import
'ios/plist_parser.dart'
;
import
'ios/xcodeproj.dart'
as
xcode
;
import
'ios/xcodeproj.dart'
;
import
'platform_plugins.dart'
;
import
'plugins.dart'
;
import
'template.dart'
;
...
...
@@ -105,11 +106,16 @@ class FlutterProject {
// Don't require iOS build info, this method is only
// used during create as best-effort, use the
// default target bundle identifier.
await
ios
.
productBundleIdentifier
(
null
),
android
.
applicationId
,
android
.
group
,
example
.
android
.
applicationId
,
await
example
.
ios
.
productBundleIdentifier
(
null
),
if
(
ios
.
existsSync
())
await
ios
.
productBundleIdentifier
(
null
),
if
(
android
.
existsSync
())
...<
String
>[
android
.
applicationId
,
android
.
group
,
],
if
(
example
.
android
.
existsSync
())
example
.
android
.
applicationId
,
if
(
example
.
ios
.
existsSync
())
await
example
.
ios
.
productBundleIdentifier
(
null
),
];
return
Set
<
String
>.
of
(
candidates
.
map
<
String
>(
_organizationNameFromPackageName
)
...
...
@@ -434,8 +440,12 @@ class IosProject extends FlutterProjectPlatform implements XcodeBasedProject {
/// The product bundle identifier of the host app, or null if not set or if
/// iOS tooling needed to read it is not installed.
Future<String> productBundleIdentifier(BuildInfo buildInfo) async =>
_productBundleIdentifier ??= await _parseProductBundleIdentifier(buildInfo);
Future<String> productBundleIdentifier(BuildInfo buildInfo) async {
if (!existsSync()) {
return null;
}
return _productBundleIdentifier ??= await _parseProductBundleIdentifier(buildInfo);
}
String _productBundleIdentifier;
Future<String> _parseProductBundleIdentifier(BuildInfo buildInfo) async {
...
...
@@ -481,8 +491,12 @@ class IosProject extends FlutterProjectPlatform implements XcodeBasedProject {
}
/// The bundle name of the host app, `My App.app`.
Future<String> hostAppBundleName(BuildInfo buildInfo) async =>
_hostAppBundleName ??= await _parseHostAppBundleName(buildInfo);
Future<String> hostAppBundleName(BuildInfo buildInfo) async {
if (!existsSync()) {
return null;
}
return _hostAppBundleName ??= await _parseHostAppBundleName(buildInfo);
}
String _hostAppBundleName;
Future<String> _parseHostAppBundleName(BuildInfo buildInfo) async {
...
...
@@ -507,12 +521,32 @@ class IosProject extends FlutterProjectPlatform implements XcodeBasedProject {
///
/// Returns null, if iOS tooling is unavailable.
Future
<
Map
<
String
,
String
>>
buildSettingsForBuildInfo
(
BuildInfo
buildInfo
)
async
{
if
(!
existsSync
())
{
return
null
;
}
_buildSettingsByScheme
??=
<
String
,
Map
<
String
,
String
>>{};
final
String
scheme
=
xcode
.
XcodeProjectInfo
.
expectedSchemeFor
(
buildInfo
);
final
XcodeProjectInfo
info
=
await
projectInfo
();
if
(
info
==
null
)
{
return
null
;
}
final
String
scheme
=
info
.
schemeFor
(
buildInfo
);
if
(
scheme
==
null
)
{
info
.
reportFlavorNotFoundAndExit
();
}
return
_buildSettingsByScheme
[
scheme
]
??=
await
_xcodeProjectBuildSettings
(
scheme
);
}
Map
<
String
,
Map
<
String
,
String
>>
_buildSettingsByScheme
;
Future
<
XcodeProjectInfo
>
projectInfo
()
async
{
if
(!
existsSync
()
||
!
globals
.
xcodeProjectInterpreter
.
isInstalled
)
{
return
null
;
}
return
_projectInfo
??=
await
globals
.
xcodeProjectInterpreter
.
getInfo
(
hostAppRoot
.
path
);
}
XcodeProjectInfo
_projectInfo
;
Future
<
Map
<
String
,
String
>>
_xcodeProjectBuildSettings
(
String
scheme
)
async
{
if
(!
globals
.
xcodeProjectInterpreter
.
isInstalled
)
{
return
null
;
...
...
@@ -624,32 +658,6 @@ class IosProject extends FlutterProjectPlatform implements XcodeBasedProject {
}
}
Future
<
void
>
makeHostAppEditable
()
async
{
assert
(
isModule
);
if
(
_editableDirectory
.
existsSync
())
{
throwToolExit
(
'iOS host app is already editable. To start fresh, delete the ios/ folder.'
);
}
_deleteIfExistsSync
(
ephemeralDirectory
);
await
_overwriteFromTemplate
(
globals
.
fs
.
path
.
join
(
'module'
,
'ios'
,
'library'
),
ephemeralDirectory
,
);
await
_overwriteFromTemplate
(
globals
.
fs
.
path
.
join
(
'module'
,
'ios'
,
'host_app_ephemeral'
),
_editableDirectory
,
);
await
_overwriteFromTemplate
(
globals
.
fs
.
path
.
join
(
'module'
,
'ios'
,
'host_app_ephemeral_cocoapods'
),
_editableDirectory
,
);
await
_overwriteFromTemplate
(
globals
.
fs
.
path
.
join
(
'module'
,
'ios'
,
'host_app_editable_cocoapods'
),
_editableDirectory
,
);
await
_updateGeneratedXcodeConfigIfNeeded
();
await
injectPlugins
(
parent
);
}
@override
File
get
generatedXcodePropertiesFile
=>
_flutterLibRoot
.
childDirectory
(
'Flutter'
)
...
...
@@ -788,20 +796,6 @@ class AndroidProject extends FlutterProjectPlatform {
)
||
globals
.
cache
.
isOlderThanToolsStamp
(
ephemeralDirectory
);
}
Future
<
void
>
makeHostAppEditable
()
async
{
assert
(
isModule
);
if
(
_editableHostAppDirectory
.
existsSync
())
{
throwToolExit
(
'Android host app is already editable. To start fresh, delete the android/ folder.'
);
}
await
_regenerateLibrary
();
await
_overwriteFromTemplate
(
globals
.
fs
.
path
.
join
(
'module'
,
'android'
,
'host_app_common'
),
_editableHostAppDirectory
);
await
_overwriteFromTemplate
(
globals
.
fs
.
path
.
join
(
'module'
,
'android'
,
'host_app_editable'
),
_editableHostAppDirectory
);
await
_overwriteFromTemplate
(
globals
.
fs
.
path
.
join
(
'module'
,
'android'
,
'gradle'
),
_editableHostAppDirectory
);
gradle
.
gradleUtils
.
injectGradleWrapperIfNeeded
(
_editableHostAppDirectory
);
gradle
.
writeLocalProperties
(
_editableHostAppDirectory
.
childFile
(
'local.properties'
));
await
injectPlugins
(
parent
);
}
File
get
localPropertiesFile
=>
_flutterLibGradleRoot
.
childFile
(
'local.properties'
);
Directory
get
pluginRegistrantHost
=>
_flutterLibGradleRoot
.
childDirectory
(
isModule
?
'Flutter'
:
'app'
);
...
...
packages/flutter_tools/test/commands.shard/hermetic/build_macos_test.dart
View file @
e110ca72
...
...
@@ -5,6 +5,7 @@
import
'package:args/command_runner.dart'
;
import
'package:file/memory.dart'
;
import
'package:flutter_tools/src/base/file_system.dart'
;
import
'package:flutter_tools/src/base/logger.dart'
;
import
'package:flutter_tools/src/base/platform.dart'
;
import
'package:flutter_tools/src/build_info.dart'
;
import
'package:flutter_tools/src/cache.dart'
;
...
...
@@ -26,6 +27,7 @@ class FakeXcodeProjectInterpreterWithProfile extends FakeXcodeProjectInterpreter
<
String
>[
'Runner'
],
<
String
>[
'Debug'
,
'Profile'
,
'Release'
],
<
String
>[
'Runner'
],
BufferLogger
.
test
(),
);
}
}
...
...
packages/flutter_tools/test/commands.shard/hermetic/clean_test.dart
View file @
e110ca72
...
...
@@ -5,6 +5,7 @@
import
'package:file/memory.dart'
;
import
'package:flutter_tools/src/base/context.dart'
;
import
'package:flutter_tools/src/base/file_system.dart'
;
import
'package:flutter_tools/src/base/logger.dart'
;
import
'package:flutter_tools/src/base/platform.dart'
;
import
'package:flutter_tools/src/commands/clean.dart'
;
import
'package:flutter_tools/src/ios/xcodeproj.dart'
;
...
...
@@ -140,6 +141,6 @@ class MockXcode extends Mock implements Xcode {}
class
MockXcodeProjectInterpreter
extends
Mock
implements
XcodeProjectInterpreter
{
@override
Future
<
XcodeProjectInfo
>
getInfo
(
String
projectPath
,
{
String
projectFilename
})
async
{
return
XcodeProjectInfo
(
null
,
null
,
<
String
>[
'Runner'
]);
return
XcodeProjectInfo
(
null
,
null
,
<
String
>[
'Runner'
]
,
BufferLogger
.
test
()
);
}
}
packages/flutter_tools/test/general.shard/ios/ios_device_start_nonprebuilt_test.dart
View file @
e110ca72
...
...
@@ -87,6 +87,7 @@ void main() {
<
String
>[
'Runner'
],
<
String
>[
'Debug'
,
'Release'
],
<
String
>[
'Runner'
],
logger
,
));
}
);
...
...
packages/flutter_tools/test/general.shard/ios/xcodeproj_test.dart
View file @
e110ca72
...
...
@@ -379,7 +379,7 @@ Information about project "Runner":
Runner
'''
;
final
XcodeProjectInfo
info
=
XcodeProjectInfo
.
fromXcodeBuildOutput
(
output
);
final
XcodeProjectInfo
info
=
XcodeProjectInfo
.
fromXcodeBuildOutput
(
output
,
logger
);
expect
(
info
.
targets
,
<
String
>[
'Runner'
]);
expect
(
info
.
schemes
,
<
String
>[
'Runner'
]);
expect
(
info
.
buildConfigurations
,
<
String
>[
'Debug'
,
'Release'
]);
...
...
@@ -404,7 +404,7 @@ Information about project "Runner":
Paid
'''
;
final
XcodeProjectInfo
info
=
XcodeProjectInfo
.
fromXcodeBuildOutput
(
output
);
final
XcodeProjectInfo
info
=
XcodeProjectInfo
.
fromXcodeBuildOutput
(
output
,
logger
);
expect
(
info
.
targets
,
<
String
>[
'Runner'
]);
expect
(
info
.
schemes
,
<
String
>[
'Free'
,
'Paid'
]);
expect
(
info
.
buildConfigurations
,
<
String
>[
'Debug (Free)'
,
'Debug (Paid)'
,
'Release (Free)'
,
'Release (Paid)'
]);
...
...
@@ -434,7 +434,7 @@ Information about project "Runner":
});
testWithoutContext
(
'scheme for default project is Runner'
,
()
{
final
XcodeProjectInfo
info
=
XcodeProjectInfo
(<
String
>[
'Runner'
],
<
String
>[
'Debug'
,
'Release'
],
<
String
>[
'Runner'
]);
final
XcodeProjectInfo
info
=
XcodeProjectInfo
(<
String
>[
'Runner'
],
<
String
>[
'Debug'
,
'Release'
],
<
String
>[
'Runner'
]
,
logger
);
expect
(
info
.
schemeFor
(
BuildInfo
.
debug
),
'Runner'
);
expect
(
info
.
schemeFor
(
BuildInfo
.
profile
),
'Runner'
);
...
...
@@ -443,7 +443,7 @@ Information about project "Runner":
});
testWithoutContext
(
'build configuration for default project is matched against BuildMode'
,
()
{
final
XcodeProjectInfo
info
=
XcodeProjectInfo
(<
String
>[
'Runner'
],
<
String
>[
'Debug'
,
'Profile'
,
'Release'
],
<
String
>[
'Runner'
]);
final
XcodeProjectInfo
info
=
XcodeProjectInfo
(<
String
>[
'Runner'
],
<
String
>[
'Debug'
,
'Profile'
,
'Release'
],
<
String
>[
'Runner'
]
,
logger
);
expect
(
info
.
buildConfigurationFor
(
BuildInfo
.
debug
,
'Runner'
),
'Debug'
);
expect
(
info
.
buildConfigurationFor
(
BuildInfo
.
profile
,
'Runner'
),
'Profile'
);
...
...
@@ -455,6 +455,7 @@ Information about project "Runner":
<
String
>[
'Runner'
],
<
String
>[
'Debug (Free)'
,
'Debug (Paid)'
,
'Release (Free)'
,
'Release (Paid)'
],
<
String
>[
'Free'
,
'Paid'
],
logger
,
);
expect
(
info
.
schemeFor
(
const
BuildInfo
(
BuildMode
.
debug
,
'free'
,
treeShakeIcons:
false
)),
'Free'
);
...
...
@@ -464,11 +465,44 @@ Information about project "Runner":
expect
(
info
.
schemeFor
(
const
BuildInfo
(
BuildMode
.
debug
,
'unknown'
,
treeShakeIcons:
false
)),
isNull
);
});
testWithoutContext
(
'reports default scheme error and exit'
,
()
{
final
XcodeProjectInfo
defaultInfo
=
XcodeProjectInfo
(
<
String
>[],
<
String
>[],
<
String
>[
'Runner'
],
logger
,
);
expect
(
()
=>
defaultInfo
.
reportFlavorNotFoundAndExit
(),
throwsToolExit
(
message:
'The Xcode project does not define custom schemes. You cannot use the --flavor option.'
),
);
});
testWithoutContext
(
'reports custom scheme error and exit'
,
()
{
final
XcodeProjectInfo
info
=
XcodeProjectInfo
(
<
String
>[],
<
String
>[],
<
String
>[
'Free'
,
'Paid'
],
logger
,
);
expect
(
()
=>
info
.
reportFlavorNotFoundAndExit
(),
throwsToolExit
(
message:
'You must specify a --flavor option to select one of the available schemes.'
),
);
});
testWithoutContext
(
'build configuration for project with custom schemes is matched against BuildMode and flavor'
,
()
{
final
XcodeProjectInfo
info
=
XcodeProjectInfo
(
<
String
>[
'Runner'
],
<
String
>[
'debug (free)'
,
'Debug paid'
,
'profile - Free'
,
'Profile-Paid'
,
'release - Free'
,
'Release-Paid'
],
<
String
>[
'Free'
,
'Paid'
],
logger
,
);
expect
(
info
.
buildConfigurationFor
(
const
BuildInfo
(
BuildMode
.
debug
,
'free'
,
treeShakeIcons:
false
),
'Free'
),
'debug (free)'
);
...
...
@@ -482,6 +516,7 @@ Information about project "Runner":
<
String
>[
'Runner'
],
<
String
>[
'Debug-F'
,
'Dbg Paid'
,
'Rel Free'
,
'Release Full'
],
<
String
>[
'Free'
,
'Paid'
],
logger
,
);
expect
(
info
.
buildConfigurationFor
(
const
BuildInfo
(
BuildMode
.
debug
,
'Free'
,
treeShakeIcons:
false
),
'Free'
),
null
);
expect
(
info
.
buildConfigurationFor
(
const
BuildInfo
(
BuildMode
.
profile
,
'Free'
,
treeShakeIcons:
false
),
'Free'
),
null
);
...
...
packages/flutter_tools/test/general.shard/project_test.dart
View file @
e110ca72
...
...
@@ -9,6 +9,7 @@ import 'package:file/memory.dart';
import
'package:flutter_tools/src/base/context.dart'
;
import
'package:flutter_tools/src/base/file_system.dart'
;
import
'package:flutter_tools/src/base/logger.dart'
;
import
'package:flutter_tools/src/build_info.dart'
;
import
'package:flutter_tools/src/cache.dart'
;
import
'package:flutter_tools/src/features.dart'
;
import
'package:flutter_tools/src/flutter_manifest.dart'
;
...
...
@@ -109,52 +110,6 @@ void main() {
});
});
group
(
'editable Android host app'
,
()
{
_testInMemory
(
'fails on non-module'
,
()
async
{
final
FlutterProject
project
=
await
someProject
();
await
expectLater
(
project
.
android
.
makeHostAppEditable
(),
throwsAssertionError
,
);
});
_testInMemory
(
'exits on already editable module'
,
()
async
{
final
FlutterProject
project
=
await
aModuleProject
();
await
project
.
android
.
makeHostAppEditable
();
return
expectToolExitLater
(
project
.
android
.
makeHostAppEditable
(),
contains
(
'already editable'
));
});
_testInMemory
(
'creates android/app folder in place of .android/app'
,
()
async
{
final
FlutterProject
project
=
await
aModuleProject
();
await
project
.
android
.
makeHostAppEditable
();
expectNotExists
(
project
.
directory
.
childDirectory
(
'.android'
).
childDirectory
(
'app'
));
expect
(
project
.
directory
.
childDirectory
(
'.android'
).
childFile
(
'settings.gradle'
).
readAsStringSync
(),
isNot
(
contains
(
"include ':app'"
)),
);
expectExists
(
project
.
directory
.
childDirectory
(
'android'
).
childDirectory
(
'app'
));
expectExists
(
project
.
directory
.
childDirectory
(
'android'
).
childFile
(
'local.properties'
));
expect
(
project
.
directory
.
childDirectory
(
'android'
).
childFile
(
'settings.gradle'
).
readAsStringSync
(),
contains
(
"include ':app'"
),
);
});
_testInMemory
(
'retains .android/Flutter folder and references it'
,
()
async
{
final
FlutterProject
project
=
await
aModuleProject
();
await
project
.
android
.
makeHostAppEditable
();
expectExists
(
project
.
directory
.
childDirectory
(
'.android'
).
childDirectory
(
'Flutter'
));
expect
(
project
.
directory
.
childDirectory
(
'android'
).
childFile
(
'settings.gradle'
).
readAsStringSync
(),
contains
(
"new File(settingsDir.parentFile, '.android/include_flutter.groovy')"
),
);
});
_testInMemory
(
'can be redone after deletion'
,
()
async
{
final
FlutterProject
project
=
await
aModuleProject
();
await
project
.
android
.
makeHostAppEditable
();
project
.
directory
.
childDirectory
(
'android'
).
deleteSync
(
recursive:
true
);
await
project
.
android
.
makeHostAppEditable
();
expectExists
(
project
.
directory
.
childDirectory
(
'android'
).
childDirectory
(
'app'
));
});
});
group
(
'ensure ready for platform-specific tooling'
,
()
{
_testInMemory
(
'does nothing, if project is not created'
,
()
async
{
final
FlutterProject
project
=
FlutterProject
(
...
...
@@ -384,6 +339,9 @@ apply plugin: 'kotlin-android'
});
}
);
when
(
mockXcodeProjectInterpreter
.
getInfo
(
any
,
projectFilename:
anyNamed
(
'projectFilename'
))).
thenAnswer
(
(
_
)
{
return
Future
<
XcodeProjectInfo
>.
value
(
XcodeProjectInfo
(<
String
>[],
<
String
>[],
<
String
>[
'Runner'
],
logger
));
});
expect
(
await
project
.
ios
.
productBundleIdentifier
(
null
),
'io.flutter.someProject'
);
});
...
...
@@ -411,6 +369,10 @@ apply plugin: 'kotlin-android'
});
}
);
when
(
mockXcodeProjectInterpreter
.
getInfo
(
any
,
projectFilename:
anyNamed
(
'projectFilename'
))).
thenAnswer
(
(
_
)
{
return
Future
<
XcodeProjectInfo
>.
value
(
XcodeProjectInfo
(<
String
>[],
<
String
>[],
<
String
>[
'Runner'
],
logger
));
});
when
(
mockPlistUtils
.
getValueFromFile
(
any
,
any
)).
thenReturn
(
r'$(PRODUCT_BUNDLE_IDENTIFIER)'
);
expect
(
await
project
.
ios
.
productBundleIdentifier
(
null
),
'io.flutter.someProject'
);
});
...
...
@@ -426,9 +388,55 @@ apply plugin: 'kotlin-android'
});
}
);
when
(
mockXcodeProjectInterpreter
.
getInfo
(
any
,
projectFilename:
anyNamed
(
'projectFilename'
))).
thenAnswer
(
(
_
)
{
return
Future
<
XcodeProjectInfo
>.
value
(
XcodeProjectInfo
(<
String
>[],
<
String
>[],
<
String
>[
'Runner'
],
logger
));
});
when
(
mockPlistUtils
.
getValueFromFile
(
any
,
any
)).
thenReturn
(
r'$(PRODUCT_BUNDLE_IDENTIFIER).$(SUFFIX)'
);
expect
(
await
project
.
ios
.
productBundleIdentifier
(
null
),
'io.flutter.someProject.suffix'
);
});
testWithMocks
(
'fails with no flavor and defined schemes'
,
()
async
{
final
FlutterProject
project
=
await
someProject
();
when
(
mockXcodeProjectInterpreter
.
getInfo
(
any
,
projectFilename:
anyNamed
(
'projectFilename'
))).
thenAnswer
(
(
_
)
{
return
Future
<
XcodeProjectInfo
>.
value
(
XcodeProjectInfo
(<
String
>[],
<
String
>[],
<
String
>[
'free'
,
'paid'
],
logger
));
});
await
expectToolExitLater
(
project
.
ios
.
productBundleIdentifier
(
null
),
contains
(
'You must specify a --flavor option to select one of the available schemes.'
)
);
});
testWithMocks
(
'handles case insensitive flavor'
,
()
async
{
final
FlutterProject
project
=
await
someProject
();
when
(
mockXcodeProjectInterpreter
.
getBuildSettings
(
any
,
scheme:
anyNamed
(
'scheme'
))).
thenAnswer
(
(
_
)
{
return
Future
<
Map
<
String
,
String
>>.
value
(<
String
,
String
>{
'PRODUCT_BUNDLE_IDENTIFIER'
:
'io.flutter.someProject'
,
});
}
);
when
(
mockXcodeProjectInterpreter
.
getInfo
(
any
,
projectFilename:
anyNamed
(
'projectFilename'
))).
thenAnswer
(
(
_
)
{
return
Future
<
XcodeProjectInfo
>.
value
(
XcodeProjectInfo
(<
String
>[],
<
String
>[],
<
String
>[
'Free'
],
logger
));
});
const
BuildInfo
buildInfo
=
BuildInfo
(
BuildMode
.
debug
,
'free'
,
treeShakeIcons:
false
);
expect
(
await
project
.
ios
.
productBundleIdentifier
(
buildInfo
),
'io.flutter.someProject'
);
});
testWithMocks
(
'fails with flavor and default schemes'
,
()
async
{
final
FlutterProject
project
=
await
someProject
();
when
(
mockXcodeProjectInterpreter
.
getInfo
(
any
,
projectFilename:
anyNamed
(
'projectFilename'
))).
thenAnswer
(
(
_
)
{
return
Future
<
XcodeProjectInfo
>.
value
(
XcodeProjectInfo
(<
String
>[],
<
String
>[],
<
String
>[
'Runner'
],
logger
));
});
const
BuildInfo
buildInfo
=
BuildInfo
(
BuildMode
.
debug
,
'free'
,
treeShakeIcons:
false
);
await
expectToolExitLater
(
project
.
ios
.
productBundleIdentifier
(
buildInfo
),
contains
(
'The Xcode project does not define custom schemes. You cannot use the --flavor option.'
)
);
});
testWithMocks
(
'empty surrounded by quotes'
,
()
async
{
final
FlutterProject
project
=
await
someProject
();
addIosProjectFile
(
project
.
directory
,
projectFileContent:
()
{
...
...
@@ -476,6 +484,9 @@ apply plugin: 'kotlin-android'
'FULL_PRODUCT_NAME'
:
'My App.app'
});
});
when
(
mockXcodeProjectInterpreter
.
getInfo
(
any
,
projectFilename:
anyNamed
(
'projectFilename'
))).
thenAnswer
(
(
_
)
{
return
Future
<
XcodeProjectInfo
>.
value
(
XcodeProjectInfo
(<
String
>[],
<
String
>[],
<
String
>[
'Runner'
],
logger
));
});
expect
(
await
project
.
ios
.
hostAppBundleName
(
null
),
'My App.app'
);
},
overrides:
<
Type
,
Generator
>{
...
...
@@ -634,6 +645,9 @@ name: foo_bar
});
}
);
when
(
mockXcodeProjectInterpreter
.
getInfo
(
any
,
projectFilename:
anyNamed
(
'projectFilename'
))).
thenAnswer
(
(
_
)
{
return
Future
<
XcodeProjectInfo
>.
value
(
XcodeProjectInfo
(<
String
>[],
<
String
>[],
<
String
>[
'Runner'
],
logger
));
});
});
testUsingContext
(
'no Info.plist in target'
,
()
async
{
...
...
packages/flutter_tools/test/src/context.dart
View file @
e110ca72
...
...
@@ -414,6 +414,7 @@ class FakeXcodeProjectInterpreter implements XcodeProjectInterpreter {
<
String
>[
'Runner'
],
<
String
>[
'Debug'
,
'Release'
],
<
String
>[
'Runner'
],
BufferLogger
.
test
(),
);
}
}
...
...
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