Browse Source

build: improve `gen-libc++-filenames` output (#44444)

build: improve gen-libc++-filenames output

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <[email protected]>
trop[bot] 5 months ago
parent
commit
cab11e6de0

+ 4 - 0
.github/workflows/pipeline-segment-electron-gn-check.yml

@@ -132,6 +132,10 @@ jobs:
       with:
         path: src/electron
         fetch-depth: 0
+    - name: Install Dependencies
+      run: |
+        cd src/electron
+        node script/yarn install --frozen-lockfile
     - name: Default GN gen
       run: |
         cd src/electron

+ 35 - 5
script/gen-libc++-filenames.js

@@ -1,3 +1,5 @@
+const chalk = require('chalk');
+
 const fs = require('node:fs');
 const path = require('node:path');
 
@@ -17,6 +19,29 @@ function findAllHeaders (basePath) {
   return toReturn;
 }
 
+const diff = (array1, array2) => {
+  const set1 = new Set(array1);
+  const set2 = new Set(array2);
+
+  const added = array1.filter(item => !set2.has(item));
+  const removed = array2.filter(item => !set1.has(item));
+
+  console.log(chalk.white.bgGreen.bold('Files Added:'));
+  added.forEach(item => console.log(chalk.green.bold(`+ ${item}`)));
+
+  console.log(chalk.white.bgRed.bold('Files Removed:'));
+  removed.forEach(item => console.log(chalk.red.bold(`- ${item}`)));
+};
+
+const parseHeaders = (name, content) => {
+  const pattern = new RegExp(`${name}_headers\\s*=\\s*\\[(.*?)\\]`, 's');
+  const headers = content.match(pattern);
+  if (!headers) return [];
+  return headers[1].split(',')
+    .map(item => item.trim().replace(/"/g, ''))
+    .filter(item => item.length > 0);
+};
+
 for (const folder of ['libc++', 'libc++abi']) {
   const prettyName = folder.replace(/\+/g, 'x');
 
@@ -25,21 +50,26 @@ for (const folder of ['libc++', 'libc++abi']) {
 
   const headers = findAllHeaders(libcxxIncludeDir).map(absPath => path.relative(path.resolve(__dirname, '../..', gclientPath), absPath));
 
+  const newHeaders = headers.map(f => `//${path.posix.join(gclientPath, f)}`);
   const content = `${prettyName}_headers = [
-  ${headers.map(f => `"//${path.posix.join(gclientPath, f)}"`).join(',\n  ')},
+  ${newHeaders.map(h => `"${h}"`).join(',\n  ')},
 ]
 
 ${prettyName}_licenses = [ "//third_party/${folder}/src/LICENSE.TXT" ]
 `;
 
-  const filenamesPath = path.resolve(__dirname, '..', `filenames.${prettyName}.gni`);
+  const file = `filenames.${prettyName}.gni`;
+  const filenamesPath = path.resolve(__dirname, '..', file);
 
   if (check) {
     const currentContent = fs.readFileSync(filenamesPath, 'utf8');
     if (currentContent !== content) {
-      console.log('currentContent: ', currentContent);
-      console.log('content: ', content);
-      throw new Error(`${prettyName} filenames need to be regenerated, latest generation does not match current file.  Please run node gen-libc++-filenames.js`);
+      const currentHeaders = parseHeaders(prettyName, currentContent);
+
+      console.error(chalk.bold(`${file} contents are not up to date:\n`));
+      diff(currentHeaders, newHeaders);
+      console.error(chalk.bold(`\nRun node gen-libc++-filenames.js to regenerate ${file}`));
+      process.exit(1);
     }
   } else {
     console.log(filenamesPath);