-
Notifications
You must be signed in to change notification settings - Fork 225
Expand file tree
/
Copy pathpatchCodegenAndroidPackage.ts
More file actions
110 lines (95 loc) · 3.57 KB
/
patchCodegenAndroidPackage.ts
File metadata and controls
110 lines (95 loc) · 3.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import fs from 'fs-extra';
import path from 'path';
import type { Report } from '../../../types';
import kleur from 'kleur';
export const CODEGEN_DOCS =
'https://reactnative.dev/docs/the-new-architecture/using-codegen#configuring-codegen';
/**
* Currently, running react-native codegen generates java files with package name `com.facebook.fbreact.specs`.
* This is a known issue in react-native itself.
* You can find the relevant line here: https://github.com/facebook/react-native/blob/dc460147bb00d6f912cc0a829f8040d85faeeb13/packages/react-native/scripts/codegen/generate-artifacts-executor.js#L459.
* To workaround, this function renames the package name to the one provided in the codegenConfig.
* @throws if codegenConfig.outputDir.android or codegenConfig.android.javaPackageName is not defined in package.json
* @throws if the codegenAndroidPath does not exist
*/
export async function patchCodegenAndroidPackage(
projectPath: string,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
packageJson: any,
report: Report
) {
let codegenAndroidPath: string | undefined =
packageJson.codegenConfig?.outputDir?.android;
if (!codegenAndroidPath) {
throw new Error(
`Your package.json doesn't contain codegenConfig.outputDir.android. Please see ${CODEGEN_DOCS}`
);
}
codegenAndroidPath = path.resolve(projectPath, codegenAndroidPath);
if (!(await fs.pathExists(codegenAndroidPath))) {
throw new Error(
`The codegen android path defined in your package.json: ${codegenAndroidPath} doesn't exist.`
);
}
const codegenJavaPackageName: string | undefined =
packageJson.codegenConfig.android.javaPackageName;
if (!codegenJavaPackageName) {
throw new Error(
`Your package.json doesn't contain codegenConfig.android.javaPackageName. Please see ${CODEGEN_DOCS}`
);
}
const codegenJavaPath = path.resolve(
codegenAndroidPath,
`java/com/facebook/fbreact/specs`
);
// If this issue is ever fixed in react-native, this check will prevent the patching from running.
if (!(await fs.pathExists(codegenJavaPath))) {
report.info(
`Could not find ${kleur.blue(
path.relative(projectPath, codegenJavaPath)
)}. Skipping patching codegen java files.`
);
return;
}
const javaFiles = await fs.readdir(codegenJavaPath);
await Promise.all(
javaFiles.map(async (file) => {
const filePath = path.resolve(codegenJavaPath, file);
const fileContent = await fs.readFile(filePath, 'utf8');
const newFileContent = fileContent.replace(
'package com.facebook.fbreact.specs',
`package ${codegenJavaPackageName}`
);
await fs.writeFile(filePath, newFileContent);
})
);
const newPackagePath = path.resolve(
codegenAndroidPath,
`java/${codegenJavaPackageName.replace(/\./g, '/')}`
);
if (!(await fs.pathExists(newPackagePath))) {
await fs.mkdir(newPackagePath, { recursive: true });
}
await Promise.all(
javaFiles.map(async (file) => {
const filePath = path.resolve(codegenJavaPath, file);
const newFilePath = path.resolve(newPackagePath, file);
await fs.rename(filePath, newFilePath);
})
);
if (
await fs.pathExists(
path.resolve(codegenAndroidPath, 'java/com/facebook/react/viewmanagers')
)
) {
// Keep the view managers
await fs.rm(path.resolve(codegenAndroidPath, 'java/com/facebook/fbreact'), {
recursive: true,
});
} else {
// Delete the entire facebook namespace
await fs.rm(path.resolve(codegenAndroidPath, 'java/com/facebook'), {
recursive: true,
});
}
}