build: add basic linting for the patches folder to ensure that .patches match the state on disk (#18615)
This commit is contained in:
parent
ae49aa4a03
commit
00d18917d0
1 changed files with 51 additions and 3 deletions
|
@ -133,12 +133,60 @@ const LINTERS = [ {
|
|||
process.exit(1)
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: 'patches',
|
||||
roots: ['patches'],
|
||||
test: () => true,
|
||||
run: () => {
|
||||
const patchesDir = path.resolve(__dirname, '../patches')
|
||||
for (const patchTarget of fs.readdirSync(patchesDir)) {
|
||||
const targetDir = path.resolve(patchesDir, patchTarget)
|
||||
// If the config does not exist that is OK, we just skip this dir
|
||||
const targetConfig = path.resolve(targetDir, 'config.json')
|
||||
if (!fs.existsSync(targetConfig)) continue
|
||||
|
||||
const config = JSON.parse(fs.readFileSync(targetConfig, 'utf8'))
|
||||
for (const key of Object.keys(config)) {
|
||||
// The directory the config points to should exist
|
||||
const targetPatchesDir = path.resolve(__dirname, '../../..', key)
|
||||
if (!fs.existsSync(targetPatchesDir)) throw new Error(`target patch directory: "${targetPatchesDir}" does not exist`)
|
||||
// We need a .patches file
|
||||
const dotPatchesPath = path.resolve(targetPatchesDir, '.patches')
|
||||
if (!fs.existsSync(dotPatchesPath)) throw new Error(`.patches file: "${dotPatchesPath}" does not exist`)
|
||||
|
||||
// Read the patch list
|
||||
const patchFileList = fs.readFileSync(dotPatchesPath, 'utf8').trim().split('\n')
|
||||
const patchFileSet = new Set(patchFileList)
|
||||
patchFileList.reduce((seen, file) => {
|
||||
if (seen.has(file)) {
|
||||
throw new Error(`'${file}' is listed in ${dotPatchesPath} more than once`)
|
||||
}
|
||||
return seen.add(file)
|
||||
}, new Set())
|
||||
if (patchFileList.length !== patchFileSet.size) throw new Error('each patch file should only be in the .patches file once')
|
||||
for (const file of fs.readdirSync(targetPatchesDir)) {
|
||||
// Ignore the .patches file and READMEs
|
||||
if (file === '.patches' || file === 'README.md') continue
|
||||
|
||||
if (!patchFileSet.has(file)) {
|
||||
throw new Error(`Expected the .patches file at "${dotPatchesPath}" to contain a patch file ("${file}") present in the directory but it did not`)
|
||||
}
|
||||
patchFileSet.delete(file)
|
||||
}
|
||||
|
||||
// If anything is left in this set, it means it did not exist on disk
|
||||
if (patchFileSet.size > 0) {
|
||||
throw new Error(`Expected all the patch files listed in the .patches file at "${dotPatchesPath}" to exist but some did not:\n${JSON.stringify([...patchFileSet.values()], null, 2)}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}]
|
||||
|
||||
function parseCommandLine () {
|
||||
let help
|
||||
const opts = minimist(process.argv.slice(2), {
|
||||
boolean: [ 'c++', 'objc', 'javascript', 'python', 'gn', 'help', 'changed', 'fix', 'verbose', 'only' ],
|
||||
boolean: [ 'c++', 'objc', 'javascript', 'python', 'gn', 'patches', 'help', 'changed', 'fix', 'verbose', 'only' ],
|
||||
alias: { 'c++': ['cc', 'cpp', 'cxx'], javascript: ['js', 'es'], python: 'py', changed: 'c', help: 'h', verbose: 'v' },
|
||||
unknown: arg => { help = true }
|
||||
})
|
||||
|
@ -221,8 +269,8 @@ async function main () {
|
|||
const opts = parseCommandLine()
|
||||
|
||||
// no mode specified? run 'em all
|
||||
if (!opts['c++'] && !opts.javascript && !opts.python && !opts.gn) {
|
||||
opts['c++'] = opts.javascript = opts.python = opts.gn = true
|
||||
if (!opts['c++'] && !opts.javascript && !opts.python && !opts.gn && !opts.patches) {
|
||||
opts['c++'] = opts.javascript = opts.python = opts.gn = opts.patches = true
|
||||
}
|
||||
|
||||
const linters = LINTERS.filter(x => opts[x.key])
|
||||
|
|
Loading…
Reference in a new issue