1import chalk from 'chalk';
2import fs from 'fs-extra';
3import path from 'path';
4
5import { findFiles } from '../utils';
6import { Task } from './Task';
7
8export type FileContentTransformStepSettings = {
9  source?: string;
10  filePattern: string;
11  find: string;
12  replace: string;
13};
14
15/**
16 * A task which will transformed files content.
17 * Firstly, it's searching for all files which matched the `filePattern` in the working directory.
18 * Then it'll find the provided pattern and replace it with a new value.
19 */
20export class TransformFilesContent extends Task {
21  protected readonly source?: string;
22  protected readonly filePattern: string;
23  protected readonly find: RegExp;
24  protected readonly replace: string;
25
26  constructor({ source, filePattern, find, replace }: FileContentTransformStepSettings) {
27    super();
28    this.source = source;
29    this.filePattern = filePattern;
30    this.find = new RegExp(find, 'gm');
31    this.replace = replace;
32  }
33
34  protected overrideWorkingDirectory(): string {
35    return this.source || '<workingDirectory>';
36  }
37
38  async execute() {
39    const workDirectory = this.getWorkingDirectory();
40
41    this.logSubStep(
42      `�� find ${chalk.yellow(this.find.toString())} in ${chalk.green(
43        this.overrideWorkingDirectory()
44      )}/${chalk.yellow(this.filePattern)} and replace with ${chalk.magenta(this.replace)}`
45    );
46
47    const files = await findFiles(workDirectory, this.filePattern);
48    await Promise.all(
49      files.map(async (file) => {
50        const content = await fs.readFile(file, 'utf8');
51        const transformedContent = content.replace(this.find, this.replace);
52        return await fs.writeFile(file, transformedContent, 'utf8');
53      })
54    );
55  }
56}
57
58export const prefixPackage = ({
59  packageName,
60  prefix,
61}: {
62  source?: string;
63  packageName: string;
64  prefix: string;
65}): TransformFilesContent => {
66  return new TransformFilesContent({
67    filePattern: path.join('android', '**', '*.@(java|kt)'),
68    find: packageName,
69    replace: `${prefix}.${packageName}`,
70  });
71};
72
73export const renameIOSSymbols = (settings: {
74  find: string;
75  replace: string;
76}): TransformFilesContent => {
77  return new TransformFilesContent({
78    ...settings,
79    filePattern: path.join('ios', '**', '*.@(h|m)'),
80  });
81};
82