Unverified Commit be81e9ea authored by hellohuanlin's avatar hellohuanlin Committed by GitHub

[tools]build ipa validate launch image using template files (#116242)

* [tools]build ipa validate launch image using template files

* reuse more code by sharing the same file key

* fix space
parent 0234b18f
......@@ -46,10 +46,13 @@ Future<void> main() async {
throw TaskResult.failure('Must validate incorrect app icon image size.');
}
// The project is still using Flutter template icon.
// The project is still using Flutter template icon and launch image.
if (!output.contains('Warning: App icon is set to the default placeholder icon. Replace with unique icons.')) {
throw TaskResult.failure('Must validate template app icon.');
}
if (!output.contains('Warning: Launch image is set to the default placeholder. Replace with unique launch images.')) {
throw TaskResult.failure('Must validate template launch image.');
}
});
final String archivePath = path.join(
......
......@@ -153,30 +153,21 @@ class BuildableIOSApp extends IOSApp {
_hostAppBundleName == null ? 'Runner.app' : _hostAppBundleName!,
'Info.plist');
// Both project icon's image assets and Contents.json are in the same directory.
String get projectAppIconDirName => globals.fs.path.join('ios', _appIconDirNameSuffix);
String get projectAppIconDirName => _projectImageAssetDirName(_appIconAsset);
// template icon's Contents.json is in flutter_tools.
String get templateAppIconDirNameForContentsJson => globals.fs.path.join(
Cache.flutterRoot!,
'packages',
'flutter_tools',
'templates',
'app_shared',
'ios.tmpl',
_appIconDirNameSuffix,
);
String get projectLaunchImageDirName => _projectImageAssetDirName(_launchImageAsset);
// template icon's image assets are in flutter_template_images package.
Future<String> get templateAppIconDirNameForImages async {
final Directory imageTemplate = await templateImageDirectory(null, globals.fs, globals.logger);
return globals.fs.path.join(
imageTemplate.path,
'app_shared',
'ios.tmpl',
_appIconDirNameSuffix,
);
}
String get templateAppIconDirNameForContentsJson
=> _templateImageAssetDirNameForContentsJson(_appIconAsset);
String get templateLaunchImageDirNameForContentsJson
=> _templateImageAssetDirNameForContentsJson(_launchImageAsset);
Future<String> get templateAppIconDirNameForImages async
=> _templateImageAssetDirNameForImages(_appIconAsset);
Future<String> get templateLaunchImageDirNameForImages async
=> _templateImageAssetDirNameForImages(_launchImageAsset);
String get ipaOutputPath =>
globals.fs.path.join(getIosBuildDirectory(), 'ipa');
......@@ -185,10 +176,35 @@ class BuildableIOSApp extends IOSApp {
return globals.fs.path.join(getIosBuildDirectory(), type, _hostAppBundleName);
}
String get _appIconDirNameSuffix => globals.fs.path.join(
String _projectImageAssetDirName(String asset)
=> globals.fs.path.join('ios', 'Runner', 'Assets.xcassets', asset);
// Template asset's Contents.json file is in flutter_tools, but the actual
String _templateImageAssetDirNameForContentsJson(String asset)
=> globals.fs.path.join(
Cache.flutterRoot!,
'packages',
'flutter_tools',
'templates',
_templateImageAssetDirNameSuffix(asset),
);
// Template asset's images are in flutter_template_images package.
Future<String> _templateImageAssetDirNameForImages(String asset) async {
final Directory imageTemplate = await templateImageDirectory(null, globals.fs, globals.logger);
return globals.fs.path.join(imageTemplate.path, _templateImageAssetDirNameSuffix(asset));
}
String _templateImageAssetDirNameSuffix(String asset) => globals.fs.path.join(
'app_shared',
'ios.tmpl',
'Runner',
'Assets.xcassets',
'AppIcon.appiconset');
asset,
);
String get _appIconAsset => 'AppIcon.appiconset';
String get _launchImageAsset => 'LaunchImage.imageset';
}
class PrebuiltIOSApp extends IOSApp implements PrebuiltApplicationPackage {
......
......@@ -1476,6 +1476,162 @@ void main() {
Platform: () => macosPlatform,
XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(),
});
testUsingContext('Validate template launch images with conflicts', () async {
const String projectLaunchImageContentsJsonPath = 'ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json';
const String projectLaunchImagePath = 'ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png';
final String templateLaunchImageContentsJsonPath = '${Cache.flutterRoot!}/packages/flutter_tools/templates/app_shared/ios.tmpl/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json';
const String templateLaunchImagePath = '/flutter_template_images/templates/app_shared/ios.tmpl/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png';
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
setUpFakeXcodeBuildHandler(onRun: () {
fileSystem.file(templateLaunchImageContentsJsonPath)
..createSync(recursive: true)
..writeAsStringSync('''
{
"images": [
{
"idiom": "iphone",
"filename": "LaunchImage@2x.png",
"scale": "2x"
}
],
"info": {
"version": 1,
"author": "xcode"
}
}
''');
fileSystem.file(templateLaunchImagePath)
..createSync(recursive: true)
..writeAsBytes(<int>[1, 2, 3]);
fileSystem.file(projectLaunchImageContentsJsonPath)
..createSync(recursive: true)
..writeAsStringSync('''
{
"images": [
{
"idiom": "iphone",
"filename": "LaunchImage@2x.png",
"scale": "2x"
}
],
"info": {
"version": 1,
"author": "xcode"
}
}
''');
fileSystem.file(projectLaunchImagePath)
..createSync(recursive: true)
..writeAsBytes(<int>[1, 2, 3]);
}),
exportArchiveCommand(exportOptionsPlist: _exportOptionsPlist),
]);
createMinimalMockProjectFiles();
final BuildCommand command = BuildCommand(
androidSdk: FakeAndroidSdk(),
buildSystem: TestBuildSystem.all(BuildResult(success: true)),
fileSystem: MemoryFileSystem.test(),
logger: BufferLogger.test(),
osUtils: FakeOperatingSystemUtils(),
);
await createTestCommandRunner(command).run(
<String>['build', 'ipa', '--no-pub']);
expect(
testLogger.statusText,
contains('Warning: Launch image is set to the default placeholder. Replace with unique launch images.'),
);
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => fakeProcessManager,
Platform: () => macosPlatform,
XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(),
});
testUsingContext('Validate template launch images without conflicts', () async {
const String projectLaunchImageContentsJsonPath = 'ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json';
const String projectLaunchImagePath = 'ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png';
final String templateLaunchImageContentsJsonPath = '${Cache.flutterRoot!}/packages/flutter_tools/templates/app_shared/ios.tmpl/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json';
const String templateLaunchImagePath = '/flutter_template_images/templates/app_shared/ios.tmpl/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png';
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
setUpFakeXcodeBuildHandler(onRun: () {
fileSystem.file(templateLaunchImageContentsJsonPath)
..createSync(recursive: true)
..writeAsStringSync('''
{
"images": [
{
"idiom": "iphone",
"filename": "LaunchImage@2x.png",
"scale": "2x"
}
],
"info": {
"version": 1,
"author": "xcode"
}
}
''');
fileSystem.file(templateLaunchImagePath)
..createSync(recursive: true)
..writeAsBytes(<int>[1, 2, 3]);
fileSystem.file(projectLaunchImageContentsJsonPath)
..createSync(recursive: true)
..writeAsStringSync('''
{
"images": [
{
"idiom": "iphone",
"filename": "LaunchImage@2x.png",
"scale": "2x"
}
],
"info": {
"version": 1,
"author": "xcode"
}
}
''');
fileSystem.file(projectLaunchImagePath)
..createSync(recursive: true)
..writeAsBytes(<int>[4, 5, 6]);
}),
exportArchiveCommand(exportOptionsPlist: _exportOptionsPlist),
]);
createMinimalMockProjectFiles();
final BuildCommand command = BuildCommand(
androidSdk: FakeAndroidSdk(),
buildSystem: TestBuildSystem.all(BuildResult(success: true)),
fileSystem: MemoryFileSystem.test(),
logger: BufferLogger.test(),
osUtils: FakeOperatingSystemUtils(),
);
await createTestCommandRunner(command).run(
<String>['build', 'ipa', '--no-pub']);
expect(
testLogger.statusText,
isNot(contains('Warning: Launch image is set to the default placeholder. Replace with unique launch images.')),
);
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => fakeProcessManager,
Platform: () => macosPlatform,
XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(),
});
}
......
......@@ -476,6 +476,92 @@ void main() {
),
);
}, overrides: overrides);
testUsingContext('returns project launch image dirname', () async {
final BuildableIOSApp iosApp = BuildableIOSApp(
IosProject.fromFlutter(FlutterProject.fromDirectory(globals.fs.currentDirectory)),
'com.foo.bar',
'Runner',
);
final String launchImageDirSuffix = globals.fs.path.join(
'Runner',
'Assets.xcassets',
'LaunchImage.imageset',
);
expect(iosApp.projectLaunchImageDirName, globals.fs.path.join('ios', launchImageDirSuffix));
}, overrides: overrides);
testUsingContext('returns template launch image dirname for Contents.json', () async {
final BuildableIOSApp iosApp = BuildableIOSApp(
IosProject.fromFlutter(FlutterProject.fromDirectory(globals.fs.currentDirectory)),
'com.foo.bar',
'Runner',
);
final String launchImageDirSuffix = globals.fs.path.join(
'Runner',
'Assets.xcassets',
'LaunchImage.imageset',
);
expect(
iosApp.templateLaunchImageDirNameForContentsJson,
globals.fs.path.join(
Cache.flutterRoot!,
'packages',
'flutter_tools',
'templates',
'app_shared',
'ios.tmpl',
launchImageDirSuffix,
),
);
}, overrides: overrides);
testUsingContext('returns template launch image dirname for images', () async {
final String toolsDir = globals.fs.path.join(
Cache.flutterRoot!,
'packages',
'flutter_tools',
);
final String packageConfigPath = globals.fs.path.join(
toolsDir,
'.dart_tool',
'package_config.json'
);
globals.fs.file(packageConfigPath)
..createSync(recursive: true)
..writeAsStringSync('''
{
"configVersion": 2,
"packages": [
{
"name": "flutter_template_images",
"rootUri": "/flutter_template_images",
"packageUri": "lib/",
"languageVersion": "2.12"
}
]
}
''');
final BuildableIOSApp iosApp = BuildableIOSApp(
IosProject.fromFlutter(FlutterProject.fromDirectory(globals.fs.currentDirectory)),
'com.foo.bar',
'Runner');
final String launchImageDirSuffix = globals.fs.path.join(
'Runner',
'Assets.xcassets',
'LaunchImage.imageset',
);
expect(
await iosApp.templateLaunchImageDirNameForImages,
globals.fs.path.absolute(
'flutter_template_images',
'templates',
'app_shared',
'ios.tmpl',
launchImageDirSuffix,
),
);
}, overrides: overrides);
});
group('FuchsiaApp', () {
......
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