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