From 5fee5b0e223aa73ddb118646431b6f4330135208 Mon Sep 17 00:00:00 2001 From: David Sanders Date: Wed, 22 Jun 2022 03:23:11 -0700 Subject: [PATCH] chore: chunk filenames when linting C++ files (#34237) * chore: chunk filenames when linting C++ files * chore: refactor code for better readability Co-authored-by: Charles Kerr * chore: further tweak * chore: limit all platforms to 4095 characters on command line * chore: use python3 * Revert "chore: use python3" Co-authored-by: Charles Kerr Co-authored-by: Cheng Zhao --- script/lib/utils.js | 29 +++++++++++++++++++++++++++++ script/lint.js | 11 ++++++----- script/run-clang-tidy.ts | 29 ++--------------------------- 3 files changed, 37 insertions(+), 32 deletions(-) diff --git a/script/lib/utils.js b/script/lib/utils.js index 55f678b43e..44c81dc86a 100644 --- a/script/lib/utils.js +++ b/script/lib/utils.js @@ -1,5 +1,6 @@ const { GitProcess } = require('dugite'); const fs = require('fs'); +const os = require('os'); const path = require('path'); const ELECTRON_DIR = path.resolve(__dirname, '..', '..'); @@ -95,7 +96,35 @@ async function getCurrentBranch (gitDir) { return branch.trim(); } +function chunkFilenames (filenames, offset = 0) { + // Windows has a max command line length of 2047 characters, so we can't + // provide too many filenames without going over that. To work around that, + // chunk up a list of filenames such that it won't go over that limit when + // used as args. Other platforms may have higher limits, but 4095 might be + // the limit on Linux systems according to `termios(3)`, so cap it there. + const MAX_FILENAME_ARGS_LENGTH = + (os.platform() === 'win32' ? 2047 : 4095) - offset; + + return filenames.reduce( + (chunkedFilenames, filename) => { + const currChunk = chunkedFilenames[chunkedFilenames.length - 1]; + const currChunkLength = currChunk.reduce( + (totalLength, _filename) => totalLength + _filename.length + 1, + 0 + ); + if (currChunkLength + filename.length + 1 > MAX_FILENAME_ARGS_LENGTH) { + chunkedFilenames.push([filename]); + } else { + currChunk.push(filename); + } + return chunkedFilenames; + }, + [[]] + ); +} + module.exports = { + chunkFilenames, getCurrentBranch, getElectronExec, getOutDir, diff --git a/script/lint.js b/script/lint.js index 42b1abf1f0..839215ee35 100755 --- a/script/lint.js +++ b/script/lint.js @@ -9,6 +9,8 @@ const klaw = require('klaw'); const minimist = require('minimist'); const path = require('path'); +const { chunkFilenames } = require('./lib/utils'); + const ELECTRON_ROOT = path.normalize(path.dirname(__dirname)); const SOURCE_ROOT = path.resolve(ELECTRON_ROOT, '..'); const DEPOT_TOOLS = path.resolve(SOURCE_ROOT, 'third_party', 'depot_tools'); @@ -69,12 +71,11 @@ const LINTERS = [{ roots: ['shell'], test: filename => filename.endsWith('.cc') || (filename.endsWith('.h') && !isObjCHeader(filename)), run: (opts, filenames) => { - if (opts.fix) { - spawnAndCheckExitCode('python3', ['script/run-clang-format.py', '-r', '--fix', ...filenames]); - } else { - spawnAndCheckExitCode('python3', ['script/run-clang-format.py', '-r', ...filenames]); + const clangFormatFlags = opts.fix ? ['--fix'] : []; + for (const chunk of chunkFilenames(filenames)) { + spawnAndCheckExitCode('python3', ['script/run-clang-format.py', ...clangFormatFlags, ...chunk]); + cpplint(chunk); } - cpplint(filenames); } }, { key: 'objc', diff --git a/script/run-clang-tidy.ts b/script/run-clang-tidy.ts index 93d1a13f72..86dba04f2e 100644 --- a/script/run-clang-tidy.ts +++ b/script/run-clang-tidy.ts @@ -9,6 +9,8 @@ import * as streamJson from 'stream-json'; import { ignore as streamJsonIgnore } from 'stream-json/filters/Ignore'; import { streamArray as streamJsonStreamArray } from 'stream-json/streamers/StreamArray'; +import { chunkFilenames } from './lib/utils'; + const SOURCE_ROOT = path.normalize(path.dirname(__dirname)); const LLVM_BIN = path.resolve( SOURCE_ROOT, @@ -108,33 +110,6 @@ function getDepotToolsEnv (): NodeJS.ProcessEnv { return depotToolsEnv; } -function chunkFilenames (filenames: string[], offset: number = 0): string[][] { - // Windows has a max command line length of 2047 characters, so we can't - // provide too many filenames without going over that. To work around that, - // chunk up a list of filenames such that it won't go over that limit when - // used as args. Use a much higher limit on other platforms which will - // effectively be a no-op. - const MAX_FILENAME_ARGS_LENGTH = - PLATFORM === 'win32' ? 2047 - offset : 100 * 1024; - - return filenames.reduce( - (chunkedFilenames: string[][], filename) => { - const currChunk = chunkedFilenames[chunkedFilenames.length - 1]; - const currChunkLength = currChunk.reduce( - (totalLength, _filename) => totalLength + _filename.length + 1, - 0 - ); - if (currChunkLength + filename.length + 1 > MAX_FILENAME_ARGS_LENGTH) { - chunkedFilenames.push([filename]); - } else { - currChunk.push(filename); - } - return chunkedFilenames; - }, - [[]] - ); -} - async function runClangTidy ( outDir: string, filenames: string[],