1*53c12298Saleqsioimport chalk from 'chalk'; 2*53c12298Saleqsioimport { readFile, writeFile } from 'fs-extra'; 3*53c12298Saleqsioimport * as path from 'path'; 4*53c12298Saleqsioimport terminalLink from 'terminal-link'; 5*53c12298Saleqsio 6*53c12298Saleqsioimport { EXPO_DIR } from '../Constants'; 7*53c12298Saleqsioimport logger from '../Logger'; 8*53c12298Saleqsioimport { AndroidProjectDependenciesUpdates } from './types'; 9*53c12298Saleqsioimport { addColorBasedOnSemverDiff, calculateSemverDiff } from './utils'; 10*53c12298Saleqsio 11*53c12298Saleqsiofunction replaceVersionInGradleFile( 12*53c12298Saleqsio body: string, 13*53c12298Saleqsio { 14*53c12298Saleqsio oldVersion, 15*53c12298Saleqsio newVersion, 16*53c12298Saleqsio fullName, 17*53c12298Saleqsio group, 18*53c12298Saleqsio name, 19*53c12298Saleqsio }: { 20*53c12298Saleqsio oldVersion: string; 21*53c12298Saleqsio newVersion: string; 22*53c12298Saleqsio fullName: string; 23*53c12298Saleqsio name: string; 24*53c12298Saleqsio group: string; 25*53c12298Saleqsio } 26*53c12298Saleqsio): string { 27*53c12298Saleqsio let modifiedBody = body; 28*53c12298Saleqsio 29*53c12298Saleqsio const regexVersionVariable = new RegExp(`${fullName}:\\\${?(\\w+)}?`, 'ig'); 30*53c12298Saleqsio 31*53c12298Saleqsio // 'de.kevcodez:pubg-api-wrapper:$myVar' 32*53c12298Saleqsio // 'de.kevcodez:pubg-api-wrapper:${myVar}' 33*53c12298Saleqsio const versionWithVariableMatches = regexVersionVariable.exec(modifiedBody); 34*53c12298Saleqsio if (versionWithVariableMatches?.length === 2) { 35*53c12298Saleqsio const variableName = versionWithVariableMatches[1]; 36*53c12298Saleqsio 37*53c12298Saleqsio const regexVariableDefinition = new RegExp( 38*53c12298Saleqsio `(${variableName}(\\s+)?=(\\s+)?('|")${oldVersion}('|"))`, 39*53c12298Saleqsio 'ig' 40*53c12298Saleqsio ); 41*53c12298Saleqsio 42*53c12298Saleqsio regexVariableDefinition 43*53c12298Saleqsio .exec(modifiedBody) 44*53c12298Saleqsio ?.filter((it) => it.includes(oldVersion)) 45*53c12298Saleqsio .forEach((match) => { 46*53c12298Saleqsio modifiedBody = modifiedBody.replace(match, match.replace(oldVersion, newVersion)); 47*53c12298Saleqsio }); 48*53c12298Saleqsio 49*53c12298Saleqsio // val PUBG_API_WRAPPER by extra("0.8.1") 50*53c12298Saleqsio // eslint-disable-next-line no-useless-escape 51*53c12298Saleqsio const regexKotlinValExtra = new RegExp(`${variableName}.+\(("|')${oldVersion}("|')\)`); 52*53c12298Saleqsio regexKotlinValExtra 53*53c12298Saleqsio .exec(modifiedBody) 54*53c12298Saleqsio ?.filter((it) => it.includes(oldVersion)) 55*53c12298Saleqsio .forEach((match) => { 56*53c12298Saleqsio modifiedBody = modifiedBody.replace(match, match.replace(oldVersion, newVersion)); 57*53c12298Saleqsio }); 58*53c12298Saleqsio } 59*53c12298Saleqsio 60*53c12298Saleqsio // compile 'de.kevcodez:pubg-api-wrapper:1.0.0' 61*53c12298Saleqsio const regexVersionInline = new RegExp(`${fullName}:${oldVersion}`, 'g'); 62*53c12298Saleqsio regexVersionInline 63*53c12298Saleqsio .exec(modifiedBody) 64*53c12298Saleqsio ?.filter((it) => it.includes(`${fullName}:${oldVersion}`)) 65*53c12298Saleqsio .forEach((match) => { 66*53c12298Saleqsio modifiedBody = modifiedBody.replace(match, `${fullName}:${newVersion}`); 67*53c12298Saleqsio }); 68*53c12298Saleqsio 69*53c12298Saleqsio // id 'com.github.ben-manes.versions' version "0.21.0" 70*53c12298Saleqsio // id("com.github.ben-manes.versions") version "0.22.0" 71*53c12298Saleqsio const regexPluginVersionWithPrefix = new RegExp( 72*53c12298Saleqsio `${group}("|')\\)?(\\s+)?version(\\s+)?("|')${oldVersion}("|')` 73*53c12298Saleqsio ); 74*53c12298Saleqsio regexPluginVersionWithPrefix 75*53c12298Saleqsio .exec(modifiedBody) 76*53c12298Saleqsio ?.filter((it) => it.includes(oldVersion)) // filter out all groups not containing version 77*53c12298Saleqsio .forEach((match) => { 78*53c12298Saleqsio modifiedBody = modifiedBody.replace(match, match.replace(oldVersion, newVersion)); 79*53c12298Saleqsio }); 80*53c12298Saleqsio 81*53c12298Saleqsio // compile group: 'de.kevcodez.pubg', name: 'pubg-api-wrapper', version: '0.8.1' 82*53c12298Saleqsio const regexDependencyWithVersionPrefix = new RegExp( 83*53c12298Saleqsio `${name}('|"),(\\s+)?version:(\\s+)('|")${oldVersion}('|")` 84*53c12298Saleqsio ); 85*53c12298Saleqsio regexDependencyWithVersionPrefix 86*53c12298Saleqsio .exec(modifiedBody) 87*53c12298Saleqsio ?.filter((it) => it.includes(oldVersion)) 88*53c12298Saleqsio .forEach((match) => { 89*53c12298Saleqsio modifiedBody = modifiedBody.replace(match, match.replace(oldVersion, newVersion)); 90*53c12298Saleqsio }); 91*53c12298Saleqsio 92*53c12298Saleqsio return modifiedBody; 93*53c12298Saleqsio} 94*53c12298Saleqsio 95*53c12298Saleqsioasync function readGradleFiles( 96*53c12298Saleqsio updates: AndroidProjectDependenciesUpdates[] 97*53c12298Saleqsio): Promise<Record<string, string>> { 98*53c12298Saleqsio const buildFiles = ( 99*53c12298Saleqsio await Promise.all( 100*53c12298Saleqsio updates.map(async ({ report: { gradleFilePath } }) => [ 101*53c12298Saleqsio gradleFilePath, 102*53c12298Saleqsio await readFile(gradleFilePath, 'utf-8'), 103*53c12298Saleqsio ]) 104*53c12298Saleqsio ) 105*53c12298Saleqsio ).reduce<Record<string, string>>((acc, [filePath, content]) => { 106*53c12298Saleqsio acc[filePath] = content; 107*53c12298Saleqsio return acc; 108*53c12298Saleqsio }, {}); 109*53c12298Saleqsio 110*53c12298Saleqsio return buildFiles; 111*53c12298Saleqsio} 112*53c12298Saleqsio 113*53c12298Saleqsioasync function writeGradleFiles(gradleFiles: Record<string, string>) { 114*53c12298Saleqsio await Promise.all( 115*53c12298Saleqsio Object.entries(gradleFiles).map( 116*53c12298Saleqsio async ([filePath, content]) => await writeFile(filePath, content) 117*53c12298Saleqsio ) 118*53c12298Saleqsio ); 119*53c12298Saleqsio} 120*53c12298Saleqsio 121*53c12298Saleqsioexport async function updateGradleDependencies( 122*53c12298Saleqsio updatesList: AndroidProjectDependenciesUpdates[] 123*53c12298Saleqsio): Promise<void> { 124*53c12298Saleqsio logger.log(chalk.white.bold(`\nUpdating gradle files.`)); 125*53c12298Saleqsio const buildFiles = await readGradleFiles(updatesList); 126*53c12298Saleqsio for (const updates of updatesList) { 127*53c12298Saleqsio if (updates.updates.length === 0) { 128*53c12298Saleqsio continue; 129*53c12298Saleqsio } 130*53c12298Saleqsio 131*53c12298Saleqsio logger.log( 132*53c12298Saleqsio `\n Updating %s native dependencies in file: %s`, 133*53c12298Saleqsio chalk.blue(updates.report.projectName), 134*53c12298Saleqsio terminalLink( 135*53c12298Saleqsio chalk.italic.grey(path.relative(EXPO_DIR, updates.report.gradleFilePath)), 136*53c12298Saleqsio updates.report.gradleFilePath 137*53c12298Saleqsio ) 138*53c12298Saleqsio ); 139*53c12298Saleqsio 140*53c12298Saleqsio let buildFile = buildFiles[updates.report.gradleFilePath]; 141*53c12298Saleqsio for (const singleUpdate of updates.updates) { 142*53c12298Saleqsio logger.log( 143*53c12298Saleqsio ` ▶︎ ${chalk.blueBright(singleUpdate.fullName)}:${ 144*53c12298Saleqsio singleUpdate.oldVersion 145*53c12298Saleqsio } ➡️ ${addColorBasedOnSemverDiff( 146*53c12298Saleqsio singleUpdate.newVersion, 147*53c12298Saleqsio calculateSemverDiff(singleUpdate.oldVersion, singleUpdate.newVersion) 148*53c12298Saleqsio )}` 149*53c12298Saleqsio ); 150*53c12298Saleqsio buildFile = replaceVersionInGradleFile(buildFile, singleUpdate); 151*53c12298Saleqsio } 152*53c12298Saleqsio buildFiles[updates.report.gradleFilePath] = buildFile; 153*53c12298Saleqsio } 154*53c12298Saleqsio 155*53c12298Saleqsio await writeGradleFiles(buildFiles); 156*53c12298Saleqsio} 157