1import { ExpoConfig } from '@expo/config-types'; 2 3import { ConfigPlugin } from '../Plugin.types'; 4import { createStringsXmlPlugin, withSettingsGradle } from '../plugins/android-plugins'; 5import { addWarningAndroid } from '../utils/warnings'; 6import { buildResourceItem, ResourceXML } from './Resources'; 7import { removeStringItem, setStringItem } from './Strings'; 8 9/** 10 * Sanitize a name, this should be used for files and gradle names. 11 * - `[/, \, :, <, >, ", ?, *, |]` are not allowed 12 * https://docs.gradle.org/4.2/release-notes.html#path-separator-characters-in-names-are-deprecated 13 * 14 * @param name 15 */ 16export function sanitizeNameForGradle(name: string): string { 17 // Remove escape characters which are valid in XML names but not in gradle. 18 name = name.replace(/[\n\r\t]/g, ''); 19 20 // Gradle disallows these: 21 // The project name 'My-Special Co/ol_Project' must not contain any of the following characters: [/, \, :, <, >, ", ?, *, |]. Set the 'rootProject.name' or adjust the 'include' statement (see https://docs.gradle.org/6.2/dsl/org.gradle.api.initialization.Settings.html#org.gradle.api.initialization.Settings:include(java.lang.String[]) for more details). 22 return name.replace(/(\/|\\|:|<|>|"|\?|\*|\|)/g, ''); 23} 24 25export const withName = createStringsXmlPlugin(applyNameFromConfig, 'withName'); 26 27export const withNameSettingsGradle: ConfigPlugin = (config) => { 28 return withSettingsGradle(config, (config) => { 29 if (config.modResults.language === 'groovy') { 30 config.modResults.contents = applyNameSettingsGradle(config, config.modResults.contents); 31 } else { 32 addWarningAndroid( 33 'name', 34 `Cannot automatically configure settings.gradle if it's not groovy` 35 ); 36 } 37 return config; 38 }); 39}; 40 41export function getName(config: Pick<ExpoConfig, 'name'>) { 42 return typeof config.name === 'string' ? config.name : null; 43} 44 45function applyNameFromConfig( 46 config: Pick<ExpoConfig, 'name'>, 47 stringsJSON: ResourceXML 48): ResourceXML { 49 const name = getName(config); 50 if (name) { 51 return setStringItem([buildResourceItem({ name: 'app_name', value: name })], stringsJSON); 52 } 53 return removeStringItem('app_name', stringsJSON); 54} 55 56/** 57 * Regex a name change -- fragile. 58 * 59 * @param config 60 * @param settingsGradle 61 */ 62export function applyNameSettingsGradle(config: Pick<ExpoConfig, 'name'>, settingsGradle: string) { 63 const name = sanitizeNameForGradle(getName(config) ?? ''); 64 65 // Select rootProject.name = '***' and replace the contents between the quotes. 66 return settingsGradle.replace( 67 /rootProject.name\s?=\s?(["'])(?:(?=(\\?))\2.)*?\1/g, 68 `rootProject.name = '${name.replace(/'/g, "\\'")}'` 69 ); 70} 71