diff --git a/packages/flutter_tools/lib/src/ios/xcodeproj.dart b/packages/flutter_tools/lib/src/ios/xcodeproj.dart index 7234890361e..af9630890e2 100644 --- a/packages/flutter_tools/lib/src/ios/xcodeproj.dart +++ b/packages/flutter_tools/lib/src/ios/xcodeproj.dart @@ -152,12 +152,17 @@ List _xcodeBuildSettingsLines({ xcodeBuildSettings.add('FLUTTER_FRAMEWORK_DIR=$frameworkDir'); } - final String buildName = validatedBuildNameForPlatform(TargetPlatform.ios, buildInfo?.buildName ?? project.manifest.buildName); + final String buildNameToParse = buildInfo?.buildName ?? project.manifest.buildName; + final String buildName = validatedBuildNameForPlatform(TargetPlatform.ios, buildNameToParse); if (buildName != null) { xcodeBuildSettings.add('FLUTTER_BUILD_NAME=$buildName'); } - final String buildNumber = validatedBuildNumberForPlatform(TargetPlatform.ios, buildInfo?.buildNumber ?? project.manifest.buildNumber); + String buildNumber = validatedBuildNumberForPlatform(TargetPlatform.ios, buildInfo?.buildNumber ?? project.manifest.buildNumber); + // Drop back to parsing build name if build number is not present. Build number is optional in the manifest, but + // FLUTTER_BUILD_NUMBER is required as the backing value for the required CFBundleVersion. + buildNumber ??= validatedBuildNumberForPlatform(TargetPlatform.ios, buildNameToParse); + if (buildNumber != null) { xcodeBuildSettings.add('FLUTTER_BUILD_NUMBER=$buildNumber'); } diff --git a/packages/flutter_tools/test/general.shard/build_info_test.dart b/packages/flutter_tools/test/general.shard/build_info_test.dart index e4bc22af9d0..1f12d081802 100644 --- a/packages/flutter_tools/test/general.shard/build_info_test.dart +++ b/packages/flutter_tools/test/general.shard/build_info_test.dart @@ -17,6 +17,8 @@ void main() { testUsingContext('CFBundleVersion for iOS', () async { String buildName = validatedBuildNumberForPlatform(TargetPlatform.ios, 'xyz'); expect(buildName, '0'); + buildName = validatedBuildNumberForPlatform(TargetPlatform.ios, '0.0.1'); + expect(buildName, '0.0.1'); buildName = validatedBuildNumberForPlatform(TargetPlatform.ios, '123.xyz'); expect(buildName, '123'); buildName = validatedBuildNumberForPlatform(TargetPlatform.ios, '123.456.xyz'); @@ -37,6 +39,8 @@ void main() { testUsingContext('CFBundleShortVersionString for iOS', () async { String buildName = validatedBuildNameForPlatform(TargetPlatform.ios, 'xyz'); expect(buildName, '0.0.0'); + buildName = validatedBuildNameForPlatform(TargetPlatform.ios, '0.0.1'); + expect(buildName, '0.0.1'); buildName = validatedBuildNameForPlatform(TargetPlatform.ios, '123.456.xyz'); expect(buildName, '123.456.0'); buildName = validatedBuildNameForPlatform(TargetPlatform.ios, '123.xyz'); diff --git a/packages/flutter_tools/test/general.shard/flutter_manifest_test.dart b/packages/flutter_tools/test/general.shard/flutter_manifest_test.dart index d3bb8704992..231a2b8872e 100644 --- a/packages/flutter_tools/test/general.shard/flutter_manifest_test.dart +++ b/packages/flutter_tools/test/general.shard/flutter_manifest_test.dart @@ -415,6 +415,23 @@ flutter: ); }); + test('parses major.minor.patch with no build version', () async { + const String manifest = ''' +name: test +version: 0.0.1 +dependencies: + flutter: + sdk: flutter +flutter: +'''; + await checkManifestVersion( + manifest: manifest, + expectedAppVersion: '0.0.1', + expectedBuildName: '0.0.1', + expectedBuildNumber: null, + ); + }); + test('parses major.minor.patch+build version clause 2', () async { const String manifest = ''' name: test diff --git a/packages/flutter_tools/test/general.shard/ios/xcodeproj_test.dart b/packages/flutter_tools/test/general.shard/ios/xcodeproj_test.dart index ec81949d4ae..ef36055a3e8 100644 --- a/packages/flutter_tools/test/general.shard/ios/xcodeproj_test.dart +++ b/packages/flutter_tools/test/general.shard/ios/xcodeproj_test.dart @@ -413,6 +413,7 @@ Information about project "Runner": final File localPropertiesFile = fs.file('path/to/project/ios/Flutter/Generated.xcconfig'); expect(propertyFor('FLUTTER_BUILD_NAME', localPropertiesFile), expectedBuildName); expect(propertyFor('FLUTTER_BUILD_NUMBER', localPropertiesFile), expectedBuildNumber); + expect(propertyFor('FLUTTER_BUILD_NUMBER', localPropertiesFile), isNotNull); } testUsingOsxContext('extract build name and number from pubspec.yaml', () async { @@ -448,7 +449,7 @@ flutter: manifestString: manifest, buildInfo: buildInfo, expectedBuildName: '1.0.0', - expectedBuildNumber: null, + expectedBuildNumber: '1.0.0', ); }); @@ -470,6 +471,24 @@ flutter: ); }); + testUsingOsxContext('allow build info to override build name with build number fallback', () async { + const String manifest = ''' +name: test +version: 1.0.0 +dependencies: + flutter: + sdk: flutter +flutter: +'''; + const BuildInfo buildInfo = BuildInfo(BuildMode.release, null, buildName: '1.0.2'); + await checkBuildVersion( + manifestString: manifest, + buildInfo: buildInfo, + expectedBuildName: '1.0.2', + expectedBuildNumber: '1.0.2', + ); + }); + testUsingOsxContext('allow build info to override build number', () async { const String manifest = ''' name: test