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