Skip to content

Commit 00d1891

Browse files
build: add basic linting for the patches folder to ensure that .patches match the state on disk (electron#18615)
1 parent ae49aa4 commit 00d1891

File tree

1 file changed

+51
-3
lines changed

1 file changed

+51
-3
lines changed

script/lint.js

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,12 +133,60 @@ const LINTERS = [ {
133133
process.exit(1)
134134
}
135135
}
136+
}, {
137+
key: 'patches',
138+
roots: ['patches'],
139+
test: () => true,
140+
run: () => {
141+
const patchesDir = path.resolve(__dirname, '../patches')
142+
for (const patchTarget of fs.readdirSync(patchesDir)) {
143+
const targetDir = path.resolve(patchesDir, patchTarget)
144+
// If the config does not exist that is OK, we just skip this dir
145+
const targetConfig = path.resolve(targetDir, 'config.json')
146+
if (!fs.existsSync(targetConfig)) continue
147+
148+
const config = JSON.parse(fs.readFileSync(targetConfig, 'utf8'))
149+
for (const key of Object.keys(config)) {
150+
// The directory the config points to should exist
151+
const targetPatchesDir = path.resolve(__dirname, '../../..', key)
152+
if (!fs.existsSync(targetPatchesDir)) throw new Error(`target patch directory: "${targetPatchesDir}" does not exist`)
153+
// We need a .patches file
154+
const dotPatchesPath = path.resolve(targetPatchesDir, '.patches')
155+
if (!fs.existsSync(dotPatchesPath)) throw new Error(`.patches file: "${dotPatchesPath}" does not exist`)
156+
157+
// Read the patch list
158+
const patchFileList = fs.readFileSync(dotPatchesPath, 'utf8').trim().split('\n')
159+
const patchFileSet = new Set(patchFileList)
160+
patchFileList.reduce((seen, file) => {
161+
if (seen.has(file)) {
162+
throw new Error(`'${file}' is listed in ${dotPatchesPath} more than once`)
163+
}
164+
return seen.add(file)
165+
}, new Set())
166+
if (patchFileList.length !== patchFileSet.size) throw new Error('each patch file should only be in the .patches file once')
167+
for (const file of fs.readdirSync(targetPatchesDir)) {
168+
// Ignore the .patches file and READMEs
169+
if (file === '.patches' || file === 'README.md') continue
170+
171+
if (!patchFileSet.has(file)) {
172+
throw new Error(`Expected the .patches file at "${dotPatchesPath}" to contain a patch file ("${file}") present in the directory but it did not`)
173+
}
174+
patchFileSet.delete(file)
175+
}
176+
177+
// If anything is left in this set, it means it did not exist on disk
178+
if (patchFileSet.size > 0) {
179+
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)}`)
180+
}
181+
}
182+
}
183+
}
136184
}]
137185

138186
function parseCommandLine () {
139187
let help
140188
const opts = minimist(process.argv.slice(2), {
141-
boolean: [ 'c++', 'objc', 'javascript', 'python', 'gn', 'help', 'changed', 'fix', 'verbose', 'only' ],
189+
boolean: [ 'c++', 'objc', 'javascript', 'python', 'gn', 'patches', 'help', 'changed', 'fix', 'verbose', 'only' ],
142190
alias: { 'c++': ['cc', 'cpp', 'cxx'], javascript: ['js', 'es'], python: 'py', changed: 'c', help: 'h', verbose: 'v' },
143191
unknown: arg => { help = true }
144192
})
@@ -221,8 +269,8 @@ async function main () {
221269
const opts = parseCommandLine()
222270

223271
// no mode specified? run 'em all
224-
if (!opts['c++'] && !opts.javascript && !opts.python && !opts.gn) {
225-
opts['c++'] = opts.javascript = opts.python = opts.gn = true
272+
if (!opts['c++'] && !opts.javascript && !opts.python && !opts.gn && !opts.patches) {
273+
opts['c++'] = opts.javascript = opts.python = opts.gn = opts.patches = true
226274
}
227275

228276
const linters = LINTERS.filter(x => opts[x.key])

0 commit comments

Comments
 (0)