diff --git a/packages/cli-link-assets/src/__tests__/linkAssets.test.ts b/packages/cli-link-assets/src/__tests__/linkAssets.test.ts index a6b6642fa..c1bbcf9d8 100644 --- a/packages/cli-link-assets/src/__tests__/linkAssets.test.ts +++ b/packages/cli-link-assets/src/__tests__/linkAssets.test.ts @@ -585,4 +585,59 @@ describe('linkAssets', () => { ), ).toMatchSnapshot(); }); + it('should link a font asset whose extension is upper-cased', async () => { + writeFiles(DIR, { + ...baseProjectKotlin, + 'assets/shared/fonts/Montserrat-Regular.TTF': + fixtureFiles.montserratRegularFont, + }); + + await linkAssets([], configMock as CLIConfig); + + // Android: it is linked as a font resource, not as a custom asset. + expect(readMontserratXMLFontFile()).toContain('@font/montserrat_regular'); + expect( + fs.existsSync( + path.resolve( + DIR, + 'android/app/src/main/res/font/montserrat_regular.ttf', + ), + ), + ).toBe(true); + expect( + fs.existsSync( + path.resolve( + DIR, + 'android/app/src/main/assets/custom/Montserrat-Regular.TTF', + ), + ), + ).toBe(false); + expect(readMainApplicationKotlinFile()).toContain( + 'addCustomFont(this, "Montserrat", R.font.montserrat)', + ); + + // iOS: it is registered in `UIAppFonts`, otherwise the font ships in the + // bundle but cannot be used at runtime. + expect(readInfoPlistFile()).toContain('Montserrat-Regular.TTF'); + }); + + it('should link an image asset whose extension is upper-cased', async () => { + writeFiles(DIR, { + ...baseProjectKotlin, + 'assets/shared/Upper Image.PNG': fixtureFiles.imagePng, + }); + + await linkAssets([], configMock as CLIConfig); + + expect( + fs.existsSync( + path.resolve(DIR, 'android/app/src/main/res/drawable/upper_image.png'), + ), + ).toBe(true); + expect( + fs.existsSync( + path.resolve(DIR, 'android/app/src/main/assets/custom/Upper Image.PNG'), + ), + ).toBe(false); + }); }); diff --git a/packages/cli-link-assets/src/fileTypes.ts b/packages/cli-link-assets/src/fileTypes.ts index ce2ccee8c..c27e0257d 100644 --- a/packages/cli-link-assets/src/fileTypes.ts +++ b/packages/cli-link-assets/src/fileTypes.ts @@ -1,7 +1,20 @@ +import path from 'path'; + const fontTypes = ['otf', 'ttf'] as const; const imageTypes = ['png', 'jpg', 'gif'] as const; const audioTypes = ['mp3'] as const; -export {fontTypes, imageTypes, audioTypes}; +/** + * Returns the extension of an asset, without the leading dot and lower-cased. + * + * The known asset types above are all spelled in lower case, while the + * extension on disk can be cased in any way (`Lato-Regular.TTF`), so it has to + * be normalized before it is matched against them. + */ +function getAssetExtension(filePath: string) { + return path.extname(filePath).substring(1).toLowerCase(); +} + +export {fontTypes, imageTypes, audioTypes, getAssetExtension}; diff --git a/packages/cli-link-assets/src/tools/linkPlatform/index.ts b/packages/cli-link-assets/src/tools/linkPlatform/index.ts index 3479bb06b..f30b8bb30 100644 --- a/packages/cli-link-assets/src/tools/linkPlatform/index.ts +++ b/packages/cli-link-assets/src/tools/linkPlatform/index.ts @@ -1,6 +1,7 @@ import {CLIError, logger} from '@react-native-community/cli-tools'; import fs from 'fs'; import path from 'path'; +import {getAssetExtension} from '../../fileTypes'; import sha1File from '../../sha1File'; import {CleanAssets} from '../cleanAssets/types'; import {CopyAssets} from '../copyAssets/types'; @@ -173,7 +174,7 @@ function linkPlatform({ .map((fileExt): FileFilter => { return { name: fileExt, - filter: (asset) => path.extname(asset.path) === `.${fileExt}`, + filter: (asset) => getAssetExtension(asset.path) === fileExt, options: linkOptionsPerExt[fileExt as Extension], }; }) @@ -181,7 +182,7 @@ function linkPlatform({ name: 'custom', filter: (asset) => Object.keys(linkOptionsPerExt).indexOf( - path.extname(asset.path).substring(1), + getAssetExtension(asset.path), ) === -1, options: otherLinkOptions, }); diff --git a/packages/cli-link-assets/src/tools/manifest/migrations/migration2.ts b/packages/cli-link-assets/src/tools/manifest/migrations/migration2.ts index 8a7f65f3f..de8a4350d 100644 --- a/packages/cli-link-assets/src/tools/manifest/migrations/migration2.ts +++ b/packages/cli-link-assets/src/tools/manifest/migrations/migration2.ts @@ -1,6 +1,5 @@ -import path from 'path'; import {AssetPathAndSHA1} from '..'; -import {fontTypes} from '../../../fileTypes'; +import {fontTypes, getAssetExtension} from '../../../fileTypes'; import {Platform} from '../../linkPlatform'; function migration2( @@ -12,7 +11,7 @@ function migration2( shouldRelinkAndroidFonts: platform === 'android' && fontTypes.includes( - path.extname(asset.path).substring(1) as (typeof fontTypes)[number], + getAssetExtension(asset.path) as (typeof fontTypes)[number], ), })); }