88 lines
2.6 KiB
JavaScript
88 lines
2.6 KiB
JavaScript
import fs from 'node:fs/promises'
|
|
import path from 'node:path'
|
|
import { pathToFileURL } from 'node:url'
|
|
import process from 'node:process'
|
|
|
|
import { reportUnstyledScrollbars } from './styled-scrollbars/styled-scrollbar-jsx-check.mjs'
|
|
export {
|
|
plainClassName,
|
|
reportUnstyledScrollbars
|
|
} from './styled-scrollbars/styled-scrollbar-jsx-check.mjs'
|
|
|
|
const SOURCE_EXTENSIONS = new Set(['.ts', '.tsx', '.js', '.jsx', '.mts', '.cts'])
|
|
const SKIP_PATH_PARTS = new Set(['node_modules', 'dist', 'out', '.git', '__snapshots__'])
|
|
|
|
export function normalizePath(root, filePath) {
|
|
return path.relative(root, filePath).split(path.sep).join('/')
|
|
}
|
|
|
|
function isSkippedFile(root, filePath) {
|
|
const relative = normalizePath(root, filePath)
|
|
if (relative.includes('.test.') || relative.includes('.spec.')) {
|
|
return true
|
|
}
|
|
return relative.split('/').some((part) => SKIP_PATH_PARTS.has(part))
|
|
}
|
|
|
|
async function collectSourceFiles(root, dir) {
|
|
const entries = await fs.readdir(dir, { withFileTypes: true })
|
|
const files = []
|
|
|
|
for (const entry of entries) {
|
|
const fullPath = path.join(dir, entry.name)
|
|
if (entry.isDirectory()) {
|
|
if (!SKIP_PATH_PARTS.has(entry.name)) {
|
|
files.push(...(await collectSourceFiles(root, fullPath)))
|
|
}
|
|
} else if (
|
|
entry.isFile() &&
|
|
SOURCE_EXTENSIONS.has(path.extname(entry.name)) &&
|
|
!isSkippedFile(root, fullPath)
|
|
) {
|
|
files.push(fullPath)
|
|
}
|
|
}
|
|
|
|
return files
|
|
}
|
|
|
|
async function collectUnstyledScrollbarReports(root) {
|
|
const sourceRoot = path.join(root, 'src', 'renderer', 'src')
|
|
const files = await collectSourceFiles(root, sourceRoot)
|
|
const reports = []
|
|
|
|
for (const filePath of files) {
|
|
const sourceText = await fs.readFile(filePath, 'utf8')
|
|
reports.push(...reportUnstyledScrollbars(filePath, sourceText))
|
|
}
|
|
|
|
return reports
|
|
}
|
|
|
|
function formatReports(root, reports) {
|
|
return reports
|
|
.map(
|
|
(report) =>
|
|
`${normalizePath(root, report.filePath)}:${report.line}:${report.column} ${report.text.replace(/\s+/g, ' ')}`
|
|
)
|
|
.join('\n')
|
|
}
|
|
|
|
export async function main(root = process.cwd()) {
|
|
const reports = await collectUnstyledScrollbarReports(root)
|
|
if (reports.length === 0) {
|
|
return 0
|
|
}
|
|
|
|
console.error('Renderer vertical scroll containers must use an Orca scrollbar style.')
|
|
console.error('Put the scrollbar class in the same class literal as the vertical overflow class.')
|
|
console.error('Use scrollbar-sleek, scrollbar-editor, or worktree-sidebar-scrollbar.')
|
|
console.error('')
|
|
console.error(formatReports(root, reports))
|
|
return 1
|
|
}
|
|
|
|
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
process.exit(await main())
|
|
}
|