1*082815dcSEvan Baconimport { ExpoConfig } from '@expo/config-types';
2*082815dcSEvan Bacon
3*082815dcSEvan Baconimport { ConfigPlugin } from '../Plugin.types';
4*082815dcSEvan Baconimport { withAppBuildGradle, withProjectBuildGradle } from '../plugins/android-plugins';
5*082815dcSEvan Baconimport { addWarningAndroid } from '../utils/warnings';
6*082815dcSEvan Bacon
7*082815dcSEvan Baconexport const withVersion: ConfigPlugin = (config) => {
8*082815dcSEvan Bacon  return withAppBuildGradle(config, (config) => {
9*082815dcSEvan Bacon    if (config.modResults.language === 'groovy') {
10*082815dcSEvan Bacon      config.modResults.contents = setVersionCode(config, config.modResults.contents);
11*082815dcSEvan Bacon      config.modResults.contents = setVersionName(config, config.modResults.contents);
12*082815dcSEvan Bacon    } else {
13*082815dcSEvan Bacon      addWarningAndroid(
14*082815dcSEvan Bacon        'android.versionCode',
15*082815dcSEvan Bacon        `Cannot automatically configure app build.gradle if it's not groovy`
16*082815dcSEvan Bacon      );
17*082815dcSEvan Bacon    }
18*082815dcSEvan Bacon    return config;
19*082815dcSEvan Bacon  });
20*082815dcSEvan Bacon};
21*082815dcSEvan Bacon
22*082815dcSEvan Bacon/** Sets a numeric version for a value in the project.gradle buildscript.ext object to be at least the provided props.minVersion, if the existing value is greater then no change will be made. */
23*082815dcSEvan Baconexport const withBuildScriptExtMinimumVersion: ConfigPlugin<{
24*082815dcSEvan Bacon  name: string;
25*082815dcSEvan Bacon  minVersion: number;
26*082815dcSEvan Bacon}> = (config, props) => {
27*082815dcSEvan Bacon  return withProjectBuildGradle(config, (config) => {
28*082815dcSEvan Bacon    if (config.modResults.language === 'groovy') {
29*082815dcSEvan Bacon      config.modResults.contents = setMinBuildScriptExtVersion(config.modResults.contents, props);
30*082815dcSEvan Bacon    } else {
31*082815dcSEvan Bacon      addWarningAndroid(
32*082815dcSEvan Bacon        'withBuildScriptExtVersion',
33*082815dcSEvan Bacon        `Cannot automatically configure project build.gradle if it's not groovy`
34*082815dcSEvan Bacon      );
35*082815dcSEvan Bacon    }
36*082815dcSEvan Bacon    return config;
37*082815dcSEvan Bacon  });
38*082815dcSEvan Bacon};
39*082815dcSEvan Bacon
40*082815dcSEvan Baconexport function setMinBuildScriptExtVersion(
41*082815dcSEvan Bacon  buildGradle: string,
42*082815dcSEvan Bacon  { name, minVersion }: { name: string; minVersion: number }
43*082815dcSEvan Bacon) {
44*082815dcSEvan Bacon  const regex = new RegExp(`(${name}\\s?=\\s?)(\\d+(?:\\.\\d+)?)`);
45*082815dcSEvan Bacon  const currentVersion = buildGradle.match(regex)?.[2];
46*082815dcSEvan Bacon  if (!currentVersion) {
47*082815dcSEvan Bacon    addWarningAndroid(
48*082815dcSEvan Bacon      'withBuildScriptExtVersion',
49*082815dcSEvan Bacon      `Cannot set minimum buildscript.ext.${name} version because the property "${name}" cannot be found or does not have a numeric value.`
50*082815dcSEvan Bacon    );
51*082815dcSEvan Bacon    // TODO: Maybe just add the property...
52*082815dcSEvan Bacon    return buildGradle;
53*082815dcSEvan Bacon  }
54*082815dcSEvan Bacon
55*082815dcSEvan Bacon  const currentVersionNum = Number(currentVersion);
56*082815dcSEvan Bacon  return buildGradle.replace(regex, `$1${Math.max(minVersion, currentVersionNum)}`);
57*082815dcSEvan Bacon}
58*082815dcSEvan Bacon
59*082815dcSEvan Baconexport function getVersionName(config: Pick<ExpoConfig, 'version'>) {
60*082815dcSEvan Bacon  return config.version ?? null;
61*082815dcSEvan Bacon}
62*082815dcSEvan Bacon
63*082815dcSEvan Baconexport function setVersionName(config: Pick<ExpoConfig, 'version'>, buildGradle: string) {
64*082815dcSEvan Bacon  const versionName = getVersionName(config);
65*082815dcSEvan Bacon  if (versionName === null) {
66*082815dcSEvan Bacon    return buildGradle;
67*082815dcSEvan Bacon  }
68*082815dcSEvan Bacon
69*082815dcSEvan Bacon  const pattern = new RegExp(`versionName ".*"`);
70*082815dcSEvan Bacon  return buildGradle.replace(pattern, `versionName "${versionName}"`);
71*082815dcSEvan Bacon}
72*082815dcSEvan Bacon
73*082815dcSEvan Baconexport function getVersionCode(config: Pick<ExpoConfig, 'android'>) {
74*082815dcSEvan Bacon  return config.android?.versionCode ?? 1;
75*082815dcSEvan Bacon}
76*082815dcSEvan Bacon
77*082815dcSEvan Baconexport function setVersionCode(config: Pick<ExpoConfig, 'android'>, buildGradle: string) {
78*082815dcSEvan Bacon  const versionCode = getVersionCode(config);
79*082815dcSEvan Bacon  if (versionCode === null) {
80*082815dcSEvan Bacon    return buildGradle;
81*082815dcSEvan Bacon  }
82*082815dcSEvan Bacon
83*082815dcSEvan Bacon  const pattern = new RegExp(`versionCode.*`);
84*082815dcSEvan Bacon  return buildGradle.replace(pattern, `versionCode ${versionCode}`);
85*082815dcSEvan Bacon}
86