// Copyright 2019-2023 Tauri Programme within The Commons Conservancy // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT import fs from 'fs' import path from 'path' import readline from 'readline' const header = `Copyright 2019-2023 Tauri Programme within The Commons Conservancy SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: MIT` const ignoredLicenses = [ '// Copyright 2021 Flavio Oliveira', '// Copyright 2021 Jonas Kruckenberg', '// Copyright 2018-2023 the Deno authors.' ] const extensions = ['.rs', '.js', '.ts', '.yml', '.swift', '.kt'] const ignore = [ 'target', 'templates', 'node_modules', 'gen', 'dist', 'dist-js', '.svelte-kit', 'api-iife.js', 'init-iife.js', '.build', 'notify_rust' ] async function checkFile(file) { if ( extensions.some((e) => file.endsWith(e)) && !ignore.some((i) => file.includes(`${path.sep}${i}`)) ) { const fileStream = fs.createReadStream(file) const rl = readline.createInterface({ input: fileStream, crlfDelay: Infinity }) let contents = `` let i = 0 for await (let line of rl) { // ignore empty lines, allow shebang, swift-tools-version and bundler license if ( line.length === 0 || line.startsWith('#!') || line.startsWith('// swift-tools-version:') || ignoredLicenses.includes(line) ) { continue } // strip comment marker if (line.startsWith('// ')) { line = line.substring(3) } else if (line.startsWith('# ')) { line = line.substring(2) } contents += line if (++i === 3) { break } contents += '\n' } if (contents !== header) { return true } } return false } async function check(src) { const missingHeader = [] for (const entry of fs.readdirSync(src, { withFileTypes: true })) { const p = path.join(src, entry.name) if (entry.isSymbolicLink() || ignore.includes(entry.name)) { continue } if (entry.isDirectory()) { const missing = await check(p) missingHeader.push(...missing) } else { const isMissing = await checkFile(p) if (isMissing) { missingHeader.push(p) } } } return missingHeader } const [_bin, _script, ...files] = process.argv if (files.length > 0) { async function run() { const missing = [] for (const f of files) { const isMissing = await checkFile(f) if (isMissing) { missing.push(f) } } if (missing.length > 0) { console.log(missing.join('\n')) process.exit(1) } } run() } else { check(path.resolve(new URL(import.meta.url).pathname, '../../..')).then( (missing) => { if (missing.length > 0) { console.log(missing.join('\n')) process.exit(1) } } ) }