gen-libc++-filenames.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. const chalk = require('chalk');
  2. const fs = require('node:fs');
  3. const path = require('node:path');
  4. const check = process.argv.includes('--check');
  5. function findAllHeaders (basePath) {
  6. const allFiles = fs.readdirSync(basePath);
  7. const toReturn = [];
  8. for (const file of allFiles) {
  9. const absPath = path.resolve(basePath, file);
  10. if (fs.statSync(absPath).isDirectory()) {
  11. toReturn.push(...findAllHeaders(absPath));
  12. } else {
  13. toReturn.push(absPath);
  14. }
  15. }
  16. return toReturn;
  17. }
  18. const diff = (array1, array2) => {
  19. const set1 = new Set(array1);
  20. const set2 = new Set(array2);
  21. const added = array1.filter(item => !set2.has(item));
  22. const removed = array2.filter(item => !set1.has(item));
  23. console.log(chalk.white.bgGreen.bold('Files Added:'));
  24. added.forEach(item => console.log(chalk.green.bold(`+ ${item}`)));
  25. console.log(chalk.white.bgRed.bold('Files Removed:'));
  26. removed.forEach(item => console.log(chalk.red.bold(`- ${item}`)));
  27. };
  28. const parseHeaders = (name, content) => {
  29. const pattern = new RegExp(`${name}_headers\\s*=\\s*\\[(.*?)\\]`, 's');
  30. const headers = content.match(pattern);
  31. if (!headers) return [];
  32. return headers[1].split(',')
  33. .map(item => item.trim().replace(/"/g, ''))
  34. .filter(item => item.length > 0);
  35. };
  36. for (const folder of ['libc++', 'libc++abi']) {
  37. const prettyName = folder.replace(/\+/g, 'x');
  38. const libcxxIncludeDir = path.resolve(__dirname, '..', '..', 'third_party', folder, 'src', 'include');
  39. const gclientPath = `third_party/${folder}/src/include`;
  40. const headers = findAllHeaders(libcxxIncludeDir).map(absPath => path.relative(path.resolve(__dirname, '../..', gclientPath), absPath));
  41. const newHeaders = headers.map(f => `//${path.posix.join(gclientPath, f)}`);
  42. const content = `${prettyName}_headers = [
  43. ${newHeaders.map(h => `"${h}"`).join(',\n ')},
  44. ]
  45. ${prettyName}_licenses = [ "//third_party/${folder}/src/LICENSE.TXT" ]
  46. `;
  47. const file = `filenames.${prettyName}.gni`;
  48. const filenamesPath = path.resolve(__dirname, '..', file);
  49. if (check) {
  50. const currentContent = fs.readFileSync(filenamesPath, 'utf8');
  51. if (currentContent !== content) {
  52. const currentHeaders = parseHeaders(prettyName, currentContent);
  53. console.error(chalk.bold(`${file} contents are not up to date:\n`));
  54. diff(currentHeaders, newHeaders);
  55. console.error(chalk.bold(`\nRun node gen-libc++-filenames.js to regenerate ${file}`));
  56. process.exit(1);
  57. }
  58. } else {
  59. console.log(filenamesPath);
  60. fs.writeFileSync(filenamesPath, content);
  61. }
  62. }