-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Expand file tree
/
Copy pathcodegen-utils.js
More file actions
145 lines (124 loc) · 5.3 KB
/
codegen-utils.js
File metadata and controls
145 lines (124 loc) · 5.3 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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
const packageJSON = require('../packages/react-native-gesture-handler/package.json');
const ERROR_PREFIX = 'react-native-gesture-handler';
const ROOT_DIR = path.resolve(
__dirname,
'../packages/react-native-gesture-handler'
);
const ANDROID_DIR = path.resolve(ROOT_DIR, 'android');
const GENERATED_DIR = path.resolve(ANDROID_DIR, 'build/generated');
const OLD_ARCH_DIR = path.resolve(ANDROID_DIR, 'paper/src/main');
const SPECS_DIR = path.resolve(ROOT_DIR, packageJSON.codegenConfig.jsSrcsDir);
const PACKAGE_NAME = packageJSON.codegenConfig.android.javaPackageName;
const RN_DIR = path.resolve(__dirname, '../node_modules/react-native');
const RN_CODEGEN_DIR = path.resolve(
__dirname,
'../node_modules/@react-native/codegen'
);
const SOURCE_FOLDER = 'java/com/facebook/react/viewmanagers';
const GH_SOURCE_FOLDER = 'java/com/swmansion/gesturehandler';
const SOURCE_FOLDERS = [
{
codegenPath: `${GENERATED_DIR}/source/codegen/${SOURCE_FOLDER}`,
oldArchPath: `${OLD_ARCH_DIR}/${SOURCE_FOLDER}`,
},
{
codegenPath: `${GENERATED_DIR}/source/codegen/${GH_SOURCE_FOLDER}`,
oldArchPath: `${OLD_ARCH_DIR}/${GH_SOURCE_FOLDER}`,
},
];
const BLACKLISTED_FILES = new Set(['ReactContextExtensions.kt']);
function exec(command) {
console.log(`[${ERROR_PREFIX}]> ` + command);
execSync(command);
}
function readdirSync(dir) {
return fs.readdirSync(dir).filter((file) => !BLACKLISTED_FILES.has(file));
}
function fixOldArchJavaForRN72Compat(dir) {
// see https://github.com/rnmapbox/maps/issues/3193
const files = readdirSync(dir);
files.forEach((file) => {
const filePath = path.join(dir, file);
const fileExtension = path.extname(file);
if (fileExtension === '.java') {
let fileContent = fs.readFileSync(filePath, 'utf-8');
let newFileContent = fileContent.replace(
/extends ReactContextBaseJavaModule implements TurboModule/g,
'extends ReactContextBaseJavaModule implements ReactModuleWithSpec, TurboModule'
);
if (fileContent !== newFileContent) {
// also insert an import line with `import com.facebook.react.bridge.ReactModuleWithSpec;`
newFileContent = newFileContent.replace(
/import com.facebook.react.bridge.ReactMethod;/,
'import com.facebook.react.bridge.ReactMethod;\nimport com.facebook.react.bridge.ReactModuleWithSpec;'
);
console.log(' => fixOldArchJava applied to:', filePath);
fs.writeFileSync(filePath, newFileContent, 'utf-8');
}
} else if (fs.lstatSync(filePath).isDirectory()) {
fixOldArchJavaForRN72Compat(filePath);
}
});
}
async function generateCodegen() {
exec(`rm -rf ${GENERATED_DIR}`);
exec(`mkdir -p ${GENERATED_DIR}/source/codegen/`);
exec(
`node ${RN_CODEGEN_DIR}/lib/cli/combine/combine-js-to-schema-cli.js --platform android ${GENERATED_DIR}/source/codegen/schema.json ${SPECS_DIR}`
);
exec(
`node ${RN_DIR}/scripts/generate-specs-cli.js --platform android --schemaPath ${GENERATED_DIR}/source/codegen/schema.json --outputDir ${GENERATED_DIR}/source/codegen --javaPackageName ${PACKAGE_NAME}`
);
fixOldArchJavaForRN72Compat(`${GENERATED_DIR}/source/codegen/java/`);
}
async function generateCodegenJavaOldArch() {
await generateCodegen();
SOURCE_FOLDERS.forEach(({ codegenPath, oldArchPath }) => {
const generatedFiles = readdirSync(codegenPath);
const oldArchFiles = readdirSync(oldArchPath);
const existingFilesSet = new Set(oldArchFiles.map((fileName) => fileName));
generatedFiles.forEach((generatedFile) => {
if (!existingFilesSet.has(generatedFile)) {
console.warn(
`[${ERROR_PREFIX}] ${generatedFile} not found in paper dir, if it's used on Android you need to copy it manually and implement yourself before using auto-copy feature.`
);
}
});
if (oldArchFiles.length === 0) {
console.warn(
`[${ERROR_PREFIX}] Paper destination with codegen interfaces is empty. This might be okay if you don't have any interfaces/delegates used on Android, otherwise please check if OLD_ARCH_DIR and SOURCE_FOLDERS are set properly.`
);
}
oldArchFiles.forEach((file) => {
if (!fs.existsSync(`${codegenPath}/${file}`)) {
console.warn(
`[${ERROR_PREFIX}] ${file} file does not exist in codegen artifacts source destination. Please check if you still need this interface/delagete.`
);
} else {
exec(`cp -rf ${codegenPath}/${file} ${oldArchPath}/${file}`);
}
});
});
}
function compareFileAtTwoPaths(filename, firstPath, secondPath) {
const fileA = fs.readFileSync(`${firstPath}/${filename}`, 'utf-8');
const fileB = fs.readFileSync(`${secondPath}/${filename}`, 'utf-8');
if (fileA !== fileB) {
throw new Error(
`[${ERROR_PREFIX}] File ${filename} is different at ${firstPath} and ${secondPath}. Make sure you committed codegen autogenerated files.`
);
}
}
async function checkCodegenIntegrity() {
await generateCodegen();
SOURCE_FOLDERS.forEach(({ codegenPath, oldArchPath }) => {
const oldArchFiles = readdirSync(oldArchPath);
oldArchFiles.forEach((file) => {
compareFileAtTwoPaths(file, codegenPath, oldArchPath);
});
});
}
module.exports = { generateCodegenJavaOldArch, checkCodegenIntegrity };