Unverified Commit 91d1e3ed authored by Jenn Magder's avatar Jenn Magder Committed by GitHub

Default new project to the ios-signing-cert development team (#90021)

parent 4ef6fc18
...@@ -16,6 +16,7 @@ import '../features.dart'; ...@@ -16,6 +16,7 @@ import '../features.dart';
import '../flutter_manifest.dart'; import '../flutter_manifest.dart';
import '../flutter_project_metadata.dart'; import '../flutter_project_metadata.dart';
import '../globals_null_migrated.dart' as globals; import '../globals_null_migrated.dart' as globals;
import '../ios/code_signing.dart';
import '../project.dart'; import '../project.dart';
import '../reporting/reporting.dart'; import '../reporting/reporting.dart';
import '../runner/flutter_command.dart'; import '../runner/flutter_command.dart';
...@@ -234,6 +235,17 @@ class CreateCommand extends CreateBase { ...@@ -234,6 +235,17 @@ class CreateCommand extends CreateBase {
} }
final String dartSdk = globals.cache.dartSdkBuild; final String dartSdk = globals.cache.dartSdkBuild;
final bool includeIos = featureFlags.isIOSEnabled && platforms.contains('ios');
String developmentTeam;
if (includeIos) {
developmentTeam = await getCodeSigningIdentityDevelopmentTeam(
processManager: globals.processManager,
platform: globals.platform,
logger: globals.logger,
config: globals.config,
terminal: globals.terminal,
);
}
final Map<String, Object> templateContext = createTemplateContext( final Map<String, Object> templateContext = createTemplateContext(
organization: organization, organization: organization,
...@@ -243,7 +255,8 @@ class CreateCommand extends CreateBase { ...@@ -243,7 +255,8 @@ class CreateCommand extends CreateBase {
withPluginHook: generatePlugin, withPluginHook: generatePlugin,
androidLanguage: stringArg('android-language'), androidLanguage: stringArg('android-language'),
iosLanguage: stringArg('ios-language'), iosLanguage: stringArg('ios-language'),
ios: featureFlags.isIOSEnabled && platforms.contains('ios'), iosDevelopmentTeam: developmentTeam,
ios: includeIos,
android: featureFlags.isAndroidEnabled && platforms.contains('android'), android: featureFlags.isAndroidEnabled && platforms.contains('android'),
web: featureFlags.isWebEnabled && platforms.contains('web'), web: featureFlags.isWebEnabled && platforms.contains('web'),
linux: featureFlags.isLinuxEnabled && platforms.contains('linux'), linux: featureFlags.isLinuxEnabled && platforms.contains('linux'),
......
...@@ -325,6 +325,7 @@ abstract class CreateBase extends FlutterCommand { ...@@ -325,6 +325,7 @@ abstract class CreateBase extends FlutterCommand {
String projectName, String projectName,
String projectDescription, String projectDescription,
String androidLanguage, String androidLanguage,
String iosDevelopmentTeam,
String iosLanguage, String iosLanguage,
String flutterRoot, String flutterRoot,
String dartSdkVersionBounds, String dartSdkVersionBounds,
...@@ -375,6 +376,8 @@ abstract class CreateBase extends FlutterCommand { ...@@ -375,6 +376,8 @@ abstract class CreateBase extends FlutterCommand {
'withPluginHook': withPluginHook, 'withPluginHook': withPluginHook,
'androidLanguage': androidLanguage, 'androidLanguage': androidLanguage,
'iosLanguage': iosLanguage, 'iosLanguage': iosLanguage,
'hasIosDevelopmentTeam': iosDevelopmentTeam != null && iosDevelopmentTeam.isNotEmpty,
'iosDevelopmentTeam': iosDevelopmentTeam ?? '',
'flutterRevision': globals.flutterVersion.frameworkRevision, 'flutterRevision': globals.flutterVersion.frameworkRevision,
'flutterChannel': globals.flutterVersion.channel, 'flutterChannel': globals.flutterVersion.channel,
'ios': ios, 'ios': ios,
......
...@@ -8,10 +8,13 @@ import '../base/common.dart'; ...@@ -8,10 +8,13 @@ import '../base/common.dart';
import '../base/config.dart'; import '../base/config.dart';
import '../base/io.dart'; import '../base/io.dart';
import '../base/logger.dart'; import '../base/logger.dart';
import '../base/platform.dart';
import '../base/process.dart'; import '../base/process.dart';
import '../base/terminal.dart'; import '../base/terminal.dart';
import '../convert.dart' show utf8; import '../convert.dart' show utf8;
const String _developmentTeamBuildSettingName = 'DEVELOPMENT_TEAM';
/// User message when no development certificates are found in the keychain. /// User message when no development certificates are found in the keychain.
/// ///
/// The user likely never did any iOS development. /// The user likely never did any iOS development.
...@@ -91,9 +94,10 @@ final RegExp _certificateOrganizationalUnitExtractionPattern = RegExp(r'OU=([a-z ...@@ -91,9 +94,10 @@ final RegExp _certificateOrganizationalUnitExtractionPattern = RegExp(r'OU=([a-z
/// ///
/// Will return null if none are found, if the user cancels or if the Xcode /// Will return null if none are found, if the user cancels or if the Xcode
/// project has a development team set in the project's build settings. /// project has a development team set in the project's build settings.
Future<Map<String, String>?> getCodeSigningIdentityDevelopmentTeam({ Future<Map<String, String>?> getCodeSigningIdentityDevelopmentTeamBuildSetting({
required Map<String, String>? buildSettings, required Map<String, String>? buildSettings,
required ProcessManager processManager, required ProcessManager processManager,
required Platform platform,
required Logger logger, required Logger logger,
required Config config, required Config config,
required Terminal terminal, required Terminal terminal,
...@@ -104,10 +108,10 @@ Future<Map<String, String>?> getCodeSigningIdentityDevelopmentTeam({ ...@@ -104,10 +108,10 @@ Future<Map<String, String>?> getCodeSigningIdentityDevelopmentTeam({
// If the user already has it set in the project build settings itself, // If the user already has it set in the project build settings itself,
// continue with that. // continue with that.
if (_isNotEmpty(buildSettings['DEVELOPMENT_TEAM'])) { if (_isNotEmpty(buildSettings[_developmentTeamBuildSettingName])) {
logger.printStatus( logger.printStatus(
'Automatically signing iOS for device deployment using specified development ' 'Automatically signing iOS for device deployment using specified development '
'team in Xcode project: ${buildSettings['DEVELOPMENT_TEAM']}' 'team in Xcode project: ${buildSettings[_developmentTeamBuildSettingName]}'
); );
return null; return null;
} }
...@@ -116,6 +120,53 @@ Future<Map<String, String>?> getCodeSigningIdentityDevelopmentTeam({ ...@@ -116,6 +120,53 @@ Future<Map<String, String>?> getCodeSigningIdentityDevelopmentTeam({
return null; return null;
} }
final String? developmentTeam = await _getCodeSigningIdentityDevelopmentTeam(
processManager: processManager,
platform: platform,
logger: logger,
config: config,
terminal: terminal,
shouldExitOnNoCerts: true,
);
if (developmentTeam == null) {
return null;
}
return <String, String>{
_developmentTeamBuildSettingName: developmentTeam,
};
}
Future<String?> getCodeSigningIdentityDevelopmentTeam({
required ProcessManager processManager,
required Platform platform,
required Logger logger,
required Config config,
required Terminal terminal,
}) async =>
_getCodeSigningIdentityDevelopmentTeam(
processManager: processManager,
platform: platform,
logger: logger,
config: config,
terminal: terminal,
shouldExitOnNoCerts: false,
);
/// Set [shouldExitOnNoCerts] to show instructions for how to add a cert when none are found, then [toolExit].
Future<String?> _getCodeSigningIdentityDevelopmentTeam({
required ProcessManager processManager,
required Platform platform,
required Logger logger,
required Config config,
required Terminal terminal,
bool shouldExitOnNoCerts = false,
}) async {
if (!platform.isMacOS) {
return null;
}
// If the user's environment is missing the tools needed to find and read // If the user's environment is missing the tools needed to find and read
// certificates, abandon. Tools should be pre-equipped on macOS. // certificates, abandon. Tools should be pre-equipped on macOS.
final ProcessUtils processUtils = ProcessUtils(processManager: processManager, logger: logger); final ProcessUtils processUtils = ProcessUtils(processManager: processManager, logger: logger);
...@@ -150,7 +201,8 @@ Future<Map<String, String>?> getCodeSigningIdentityDevelopmentTeam({ ...@@ -150,7 +201,8 @@ Future<Map<String, String>?> getCodeSigningIdentityDevelopmentTeam({
.toSet() // Unique. .toSet() // Unique.
.toList(); .toList();
final String? signingIdentity = await _chooseSigningIdentity(validCodeSigningIdentities, logger, config, terminal); final String? signingIdentity =
await _chooseSigningIdentity(validCodeSigningIdentities, logger, config, terminal, shouldExitOnNoCerts);
// If none are chosen, return null. // If none are chosen, return null.
if (signingIdentity == null) { if (signingIdentity == null) {
...@@ -193,28 +245,25 @@ Future<Map<String, String>?> getCodeSigningIdentityDevelopmentTeam({ ...@@ -193,28 +245,25 @@ Future<Map<String, String>?> getCodeSigningIdentityDevelopmentTeam({
return null; return null;
} }
final String? developmentTeam = _certificateOrganizationalUnitExtractionPattern return _certificateOrganizationalUnitExtractionPattern.firstMatch(opensslOutput)?.group(1);
.firstMatch(opensslOutput)
?.group(1);
if (developmentTeam == null) {
return null;
}
return <String, String>{
'DEVELOPMENT_TEAM': developmentTeam,
};
} }
/// Set [shouldExitOnNoCerts] to show instructions for how to add a cert when none are found, then [toolExit].
Future<String?> _chooseSigningIdentity( Future<String?> _chooseSigningIdentity(
List<String> validCodeSigningIdentities, List<String> validCodeSigningIdentities,
Logger logger, Logger logger,
Config config, Config config,
Terminal terminal, Terminal terminal,
bool shouldExitOnNoCerts,
) async { ) async {
// The user has no valid code signing identities. // The user has no valid code signing identities.
if (validCodeSigningIdentities.isEmpty) { if (validCodeSigningIdentities.isEmpty) {
if (shouldExitOnNoCerts) {
logger.printError(noCertificatesInstruction, emphasis: true); logger.printError(noCertificatesInstruction, emphasis: true);
throwToolExit('No development certificates available to code sign app for device deployment'); throwToolExit('No development certificates available to code sign app for device deployment');
} else {
return null;
}
} }
if (validCodeSigningIdentities.length == 1) { if (validCodeSigningIdentities.length == 1) {
......
...@@ -189,8 +189,9 @@ Future<XcodeBuildResult> buildXcodeProject({ ...@@ -189,8 +189,9 @@ Future<XcodeBuildResult> buildXcodeProject({
) ?? <String, String>{}; ) ?? <String, String>{};
if (codesign && environmentType == EnvironmentType.physical) { if (codesign && environmentType == EnvironmentType.physical) {
autoSigningConfigs = await getCodeSigningIdentityDevelopmentTeam( autoSigningConfigs = await getCodeSigningIdentityDevelopmentTeamBuildSetting(
buildSettings: buildSettings, buildSettings: buildSettings,
platform: globals.platform,
processManager: globals.processManager, processManager: globals.processManager,
logger: globals.logger, logger: globals.logger,
config: globals.config, config: globals.config,
......
...@@ -10,6 +10,7 @@ import 'build_info.dart'; ...@@ -10,6 +10,7 @@ import 'build_info.dart';
import 'bundle.dart' as bundle; import 'bundle.dart' as bundle;
import 'flutter_plugins.dart'; import 'flutter_plugins.dart';
import 'globals_null_migrated.dart' as globals; import 'globals_null_migrated.dart' as globals;
import 'ios/code_signing.dart';
import 'ios/plist_parser.dart'; import 'ios/plist_parser.dart';
import 'ios/xcode_build_settings.dart' as xcode; import 'ios/xcode_build_settings.dart' as xcode;
import 'ios/xcodeproj.dart'; import 'ios/xcodeproj.dart';
...@@ -475,12 +476,23 @@ class IosProject extends XcodeBasedProject { ...@@ -475,12 +476,23 @@ class IosProject extends XcodeBasedProject {
templateRenderer: globals.templateRenderer, templateRenderer: globals.templateRenderer,
); );
final String iosBundleIdentifier = parent.manifest.iosBundleIdentifier ?? 'com.example.${parent.manifest.appName}'; final String iosBundleIdentifier = parent.manifest.iosBundleIdentifier ?? 'com.example.${parent.manifest.appName}';
final String? iosDevelopmentTeam = await getCodeSigningIdentityDevelopmentTeam(
processManager: globals.processManager,
platform: globals.platform,
logger: globals.logger,
config: globals.config,
terminal: globals.terminal,
);
template.render( template.render(
target, target,
<String, Object>{ <String, Object>{
'ios': true, 'ios': true,
'projectName': parent.manifest.appName, 'projectName': parent.manifest.appName,
'iosIdentifier': iosBundleIdentifier, 'iosIdentifier': iosBundleIdentifier,
'hasIosDevelopmentTeam': iosDevelopmentTeam != null && iosDevelopmentTeam.isNotEmpty,
'iosDevelopmentTeam': iosDevelopmentTeam ?? '',
}, },
printStatusWhenWriting: false, printStatusWhenWriting: false,
overwriteExisting: true, overwriteExisting: true,
......
...@@ -298,6 +298,9 @@ ...@@ -298,6 +298,9 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
{{#hasIosDevelopmentTeam}}
DEVELOPMENT_TEAM = {{iosDevelopmentTeam}};
{{/hasIosDevelopmentTeam}}
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
...@@ -421,6 +424,9 @@ ...@@ -421,6 +424,9 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
{{#hasIosDevelopmentTeam}}
DEVELOPMENT_TEAM = {{iosDevelopmentTeam}};
{{/hasIosDevelopmentTeam}}
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
...@@ -439,6 +445,9 @@ ...@@ -439,6 +445,9 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
{{#hasIosDevelopmentTeam}}
DEVELOPMENT_TEAM = {{iosDevelopmentTeam}};
{{/hasIosDevelopmentTeam}}
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
......
...@@ -288,6 +288,9 @@ ...@@ -288,6 +288,9 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
{{#hasIosDevelopmentTeam}}
DEVELOPMENT_TEAM = {{iosDevelopmentTeam}};
{{/hasIosDevelopmentTeam}}
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
...@@ -416,6 +419,9 @@ ...@@ -416,6 +419,9 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
{{#hasIosDevelopmentTeam}}
DEVELOPMENT_TEAM = {{iosDevelopmentTeam}};
{{/hasIosDevelopmentTeam}}
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
...@@ -438,6 +444,9 @@ ...@@ -438,6 +444,9 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
{{#hasIosDevelopmentTeam}}
DEVELOPMENT_TEAM = {{iosDevelopmentTeam}};
{{/hasIosDevelopmentTeam}}
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
......
...@@ -298,6 +298,9 @@ ...@@ -298,6 +298,9 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
{{#hasIosDevelopmentTeam}}
DEVELOPMENT_TEAM = {{iosDevelopmentTeam}};
{{/hasIosDevelopmentTeam}}
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
...@@ -420,6 +423,9 @@ ...@@ -420,6 +423,9 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
{{#hasIosDevelopmentTeam}}
DEVELOPMENT_TEAM = {{iosDevelopmentTeam}};
{{/hasIosDevelopmentTeam}}
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
...@@ -437,6 +443,9 @@ ...@@ -437,6 +443,9 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
{{#hasIosDevelopmentTeam}}
DEVELOPMENT_TEAM = {{iosDevelopmentTeam}};
{{/hasIosDevelopmentTeam}}
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
......
...@@ -129,7 +129,7 @@ void main() { ...@@ -129,7 +129,7 @@ void main() {
group('AndroidSdk', () { group('AndroidSdk', () {
testUsingContext('throws throwsToolExit if AndroidSdk is null', () async { testUsingContext('throws throwsToolExit if AndroidSdk is null', () async {
final String projectPath = await createProject(tempDir, arguments: <String>['--no-pub', '--template=app']); final String projectPath = await createProject(tempDir, arguments: <String>['--no-pub', '--template=app', '--platform=android']);
await expectLater( await expectLater(
() => runBuildApkCommand( () => runBuildApkCommand(
...@@ -150,7 +150,7 @@ void main() { ...@@ -150,7 +150,7 @@ void main() {
}); });
testUsingContext('shrinking is enabled by default on release mode', () async { testUsingContext('shrinking is enabled by default on release mode', () async {
final String projectPath = await createProject(tempDir, arguments: <String>['--no-pub', '--template=app']); final String projectPath = await createProject(tempDir, arguments: <String>['--no-pub', '--template=app', '--platform=android']);
processManager.addCommand(FakeCommand( processManager.addCommand(FakeCommand(
command: <String>[ command: <String>[
gradlew, gradlew,
...@@ -179,7 +179,7 @@ void main() { ...@@ -179,7 +179,7 @@ void main() {
}); });
testUsingContext('--split-debug-info is enabled when an output directory is provided', () async { testUsingContext('--split-debug-info is enabled when an output directory is provided', () async {
final String projectPath = await createProject(tempDir, arguments: <String>['--no-pub', '--template=app']); final String projectPath = await createProject(tempDir, arguments: <String>['--no-pub', '--template=app', '--platform=android']);
processManager.addCommand(FakeCommand( processManager.addCommand(FakeCommand(
command: <String>[ command: <String>[
gradlew, gradlew,
...@@ -209,7 +209,7 @@ void main() { ...@@ -209,7 +209,7 @@ void main() {
}); });
testUsingContext('--extra-front-end-options are provided to gradle project', () async { testUsingContext('--extra-front-end-options are provided to gradle project', () async {
final String projectPath = await createProject(tempDir, arguments: <String>['--no-pub', '--template=app']); final String projectPath = await createProject(tempDir, arguments: <String>['--no-pub', '--template=app', '--platform=android']);
processManager.addCommand(FakeCommand( processManager.addCommand(FakeCommand(
command: <String>[ command: <String>[
gradlew, gradlew,
...@@ -239,7 +239,7 @@ void main() { ...@@ -239,7 +239,7 @@ void main() {
}); });
testUsingContext('shrinking is disabled when --no-shrink is passed', () async { testUsingContext('shrinking is disabled when --no-shrink is passed', () async {
final String projectPath = await createProject(tempDir, arguments: <String>['--no-pub', '--template=app']); final String projectPath = await createProject(tempDir, arguments: <String>['--no-pub', '--template=app', '--platform=android']);
processManager.addCommand(FakeCommand( processManager.addCommand(FakeCommand(
command: <String>[ command: <String>[
gradlew, gradlew,
...@@ -271,7 +271,7 @@ void main() { ...@@ -271,7 +271,7 @@ void main() {
}); });
testUsingContext('guides the user when the shrinker fails', () async { testUsingContext('guides the user when the shrinker fails', () async {
final String projectPath = await createProject(tempDir, arguments: <String>['--no-pub', '--template=app']); final String projectPath = await createProject(tempDir, arguments: <String>['--no-pub', '--template=app', '--platform=android']);
const String r8StdoutWarning = const String r8StdoutWarning =
"Execution failed for task ':app:transformClassesAndResourcesWithR8ForStageInternal'.\n" "Execution failed for task ':app:transformClassesAndResourcesWithR8ForStageInternal'.\n"
'> com.android.tools.r8.CompilationFailedException: Compilation failed to complete'; '> com.android.tools.r8.CompilationFailedException: Compilation failed to complete';
...@@ -322,7 +322,7 @@ void main() { ...@@ -322,7 +322,7 @@ void main() {
}); });
testUsingContext("reports when the app isn't using AndroidX", () async { testUsingContext("reports when the app isn't using AndroidX", () async {
final String projectPath = await createProject(tempDir, arguments: <String>['--no-pub', '--template=app']); final String projectPath = await createProject(tempDir, arguments: <String>['--no-pub', '--template=app', '--platform=android']);
// Simulate a non-androidx project. // Simulate a non-androidx project.
tempDir tempDir
.childDirectory('flutter_project') .childDirectory('flutter_project')
...@@ -375,7 +375,7 @@ void main() { ...@@ -375,7 +375,7 @@ void main() {
}); });
testUsingContext('reports when the app is using AndroidX', () async { testUsingContext('reports when the app is using AndroidX', () async {
final String projectPath = await createProject(tempDir, arguments: <String>['--no-pub', '--template=app']); final String projectPath = await createProject(tempDir, arguments: <String>['--no-pub', '--template=app', '--platform=android']);
processManager.addCommand(FakeCommand( processManager.addCommand(FakeCommand(
command: <String>[ command: <String>[
gradlew, gradlew,
......
...@@ -44,6 +44,9 @@ const String _kDisabledPlatformRequestedMessage = 'currently not supported on yo ...@@ -44,6 +44,9 @@ const String _kDisabledPlatformRequestedMessage = 'currently not supported on yo
// This needs to be created from the local platform due to re-entrant flutter calls made in this test. // This needs to be created from the local platform due to re-entrant flutter calls made in this test.
FakePlatform _kNoColorTerminalPlatform() => FakePlatform.fromPlatform(const LocalPlatform())..stdoutSupportsAnsi = false; FakePlatform _kNoColorTerminalPlatform() => FakePlatform.fromPlatform(const LocalPlatform())..stdoutSupportsAnsi = false;
FakePlatform _kNoColorTerminalMacOSPlatform() => FakePlatform.fromPlatform(const LocalPlatform())
..stdoutSupportsAnsi = false
..operatingSystem = 'macos';
final Map<Type, Generator> noColorTerminalOverride = <Type, Generator>{ final Map<Type, Generator> noColorTerminalOverride = <Type, Generator>{
Platform: _kNoColorTerminalPlatform, Platform: _kNoColorTerminalPlatform,
...@@ -60,6 +63,7 @@ void main() { ...@@ -60,6 +63,7 @@ void main() {
Directory projectDir; Directory projectDir;
FakeFlutterVersion fakeFlutterVersion; FakeFlutterVersion fakeFlutterVersion;
LoggingProcessManager loggingProcessManager; LoggingProcessManager loggingProcessManager;
FakeProcessManager fakeProcessManager;
BufferLogger logger; BufferLogger logger;
setUpAll(() async { setUpAll(() async {
...@@ -76,6 +80,7 @@ void main() { ...@@ -76,6 +80,7 @@ void main() {
frameworkRevision: frameworkRevision, frameworkRevision: frameworkRevision,
channel: frameworkChannel, channel: frameworkChannel,
); );
fakeProcessManager = FakeProcessManager.empty();
}); });
tearDown(() { tearDown(() {
...@@ -1308,6 +1313,56 @@ void main() { ...@@ -1308,6 +1313,56 @@ void main() {
Platform: _kNoColorTerminalPlatform, Platform: _kNoColorTerminalPlatform,
}); });
testUsingContext('has iOS development team with app template', () async {
Cache.flutterRoot = '../..';
final Completer<void> completer = Completer<void>();
final StreamController<List<int>> controller = StreamController<List<int>>();
const String certificates = '''
1) 86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 "iPhone Developer: Profile 1 (1111AAAA11)"
1 valid identities found''';
fakeProcessManager.addCommands(<FakeCommand>[
const FakeCommand(
command: <String>['which', 'security'],
),
const FakeCommand(
command: <String>['which', 'openssl'],
),
const FakeCommand(
command: <String>['security', 'find-identity', '-p', 'codesigning', '-v'],
stdout: certificates,
),
const FakeCommand(
command: <String>['security', 'find-certificate', '-c', '1111AAAA11', '-p'],
stdout: 'This is a fake certificate',
),
FakeCommand(
command: const <String>['openssl', 'x509', '-subject'],
stdin: IOSink(controller.sink),
stdout: 'subject= /CN=iPhone Developer: Profile 1 (1111AAAA11)/OU=3333CCCC33/O=My Team/C=US',
)
]);
controller.stream.listen((List<int> chunk) {
completer.complete();
});
final CreateCommand command = CreateCommand();
final CommandRunner<void> runner = createTestCommandRunner(command);
await runner.run(<String>['create', '--template=app', '--no-pub', '--org', 'com.foo.bar', projectDir.path]);
final String xcodeProjectPath = globals.fs.path.join('ios', 'Runner.xcodeproj', 'project.pbxproj');
final File xcodeProjectFile = globals.fs.file(globals.fs.path.join(projectDir.path, xcodeProjectPath));
expect(xcodeProjectFile, exists);
final String xcodeProject = xcodeProjectFile.readAsStringSync();
expect(xcodeProject, contains('DEVELOPMENT_TEAM = 3333CCCC33;'));
}, overrides: <Type, Generator>{
FlutterVersion: () => fakeFlutterVersion,
Platform: _kNoColorTerminalMacOSPlatform,
ProcessManager: () => fakeProcessManager,
});
testUsingContext('has correct content and formatting with macOS app template', () async { testUsingContext('has correct content and formatting with macOS app template', () async {
Cache.flutterRoot = '../..'; Cache.flutterRoot = '../..';
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment