1082815dcSEvan Baconimport { ExpoConfig } from '@expo/config-types'; 2082815dcSEvan Bacon 3*8a424bebSJames Ideimport { buildResourceItem, ResourceXML } from './Resources'; 4*8a424bebSJames Ideimport { removeStringItem, setStringItem } from './Strings'; 5082815dcSEvan Baconimport { ConfigPlugin } from '../Plugin.types'; 6082815dcSEvan Baconimport { createStringsXmlPlugin, withSettingsGradle } from '../plugins/android-plugins'; 7082815dcSEvan Baconimport { addWarningAndroid } from '../utils/warnings'; 8082815dcSEvan Bacon 9082815dcSEvan Bacon/** 10082815dcSEvan Bacon * Sanitize a name, this should be used for files and gradle names. 11082815dcSEvan Bacon * - `[/, \, :, <, >, ", ?, *, |]` are not allowed 12082815dcSEvan Bacon * https://docs.gradle.org/4.2/release-notes.html#path-separator-characters-in-names-are-deprecated 13082815dcSEvan Bacon * 14082815dcSEvan Bacon * @param name 15082815dcSEvan Bacon */ 16082815dcSEvan Baconexport function sanitizeNameForGradle(name: string): string { 17082815dcSEvan Bacon // Remove escape characters which are valid in XML names but not in gradle. 18082815dcSEvan Bacon name = name.replace(/[\n\r\t]/g, ''); 19082815dcSEvan Bacon 20082815dcSEvan Bacon // Gradle disallows these: 21082815dcSEvan Bacon // 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). 22082815dcSEvan Bacon return name.replace(/(\/|\\|:|<|>|"|\?|\*|\|)/g, ''); 23082815dcSEvan Bacon} 24082815dcSEvan Bacon 25082815dcSEvan Baconexport const withName = createStringsXmlPlugin(applyNameFromConfig, 'withName'); 26082815dcSEvan Bacon 27082815dcSEvan Baconexport const withNameSettingsGradle: ConfigPlugin = (config) => { 28082815dcSEvan Bacon return withSettingsGradle(config, (config) => { 29082815dcSEvan Bacon if (config.modResults.language === 'groovy') { 30082815dcSEvan Bacon config.modResults.contents = applyNameSettingsGradle(config, config.modResults.contents); 31082815dcSEvan Bacon } else { 32082815dcSEvan Bacon addWarningAndroid( 33082815dcSEvan Bacon 'name', 34082815dcSEvan Bacon `Cannot automatically configure settings.gradle if it's not groovy` 35082815dcSEvan Bacon ); 36082815dcSEvan Bacon } 37082815dcSEvan Bacon return config; 38082815dcSEvan Bacon }); 39082815dcSEvan Bacon}; 40082815dcSEvan Bacon 41082815dcSEvan Baconexport function getName(config: Pick<ExpoConfig, 'name'>) { 42082815dcSEvan Bacon return typeof config.name === 'string' ? config.name : null; 43082815dcSEvan Bacon} 44082815dcSEvan Bacon 45082815dcSEvan Baconfunction applyNameFromConfig( 46082815dcSEvan Bacon config: Pick<ExpoConfig, 'name'>, 47082815dcSEvan Bacon stringsJSON: ResourceXML 48082815dcSEvan Bacon): ResourceXML { 49082815dcSEvan Bacon const name = getName(config); 50082815dcSEvan Bacon if (name) { 51082815dcSEvan Bacon return setStringItem([buildResourceItem({ name: 'app_name', value: name })], stringsJSON); 52082815dcSEvan Bacon } 53082815dcSEvan Bacon return removeStringItem('app_name', stringsJSON); 54082815dcSEvan Bacon} 55082815dcSEvan Bacon 56082815dcSEvan Bacon/** 57082815dcSEvan Bacon * Regex a name change -- fragile. 58082815dcSEvan Bacon * 59082815dcSEvan Bacon * @param config 60082815dcSEvan Bacon * @param settingsGradle 61082815dcSEvan Bacon */ 62082815dcSEvan Baconexport function applyNameSettingsGradle(config: Pick<ExpoConfig, 'name'>, settingsGradle: string) { 63082815dcSEvan Bacon const name = sanitizeNameForGradle(getName(config) ?? ''); 64082815dcSEvan Bacon 65082815dcSEvan Bacon // Select rootProject.name = '***' and replace the contents between the quotes. 66082815dcSEvan Bacon return settingsGradle.replace( 67082815dcSEvan Bacon /rootProject.name\s?=\s?(["'])(?:(?=(\\?))\2.)*?\1/g, 68082815dcSEvan Bacon `rootProject.name = '${name.replace(/'/g, "\\'")}'` 69082815dcSEvan Bacon ); 70082815dcSEvan Bacon} 71