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…
	
	Add table
		Add a link
		
	
		Reference in a new issue