refactor(chart): enforce 400-line source limit
Some checks failed
Package component / package (push) Failing after 4m19s
Some checks failed
Package component / package (push) Failing after 4m19s
This commit is contained in:
45
scripts/check-file-length.mjs
Normal file
45
scripts/check-file-length.mjs
Normal file
@@ -0,0 +1,45 @@
|
||||
import { readdirSync, readFileSync } from 'node:fs'
|
||||
import { relative, resolve } from 'node:path'
|
||||
import { pathToFileURL } from 'node:url'
|
||||
|
||||
export const maximumLines = 400
|
||||
|
||||
export function physicalLineCount(contents) {
|
||||
if (contents.length === 0) return 0
|
||||
return contents.split('\n').length - Number(contents.endsWith('\n'))
|
||||
}
|
||||
|
||||
export function isTextFile(contents) {
|
||||
return !contents.includes(0)
|
||||
}
|
||||
|
||||
export function collectTextFiles(directory) {
|
||||
return readdirSync(directory, { withFileTypes: true }).flatMap((entry) => {
|
||||
const path = resolve(directory, entry.name)
|
||||
if (entry.isDirectory()) return collectTextFiles(path)
|
||||
if (!entry.isFile()) return []
|
||||
const contents = readFileSync(path)
|
||||
return isTextFile(contents) ? [{ path, contents: contents.toString('utf8') }] : []
|
||||
})
|
||||
}
|
||||
|
||||
export function findFileLengthViolations(sourceRoot, limit = maximumLines) {
|
||||
return collectTextFiles(sourceRoot).flatMap(({ path, contents }) => {
|
||||
const lineCount = physicalLineCount(contents)
|
||||
if (lineCount <= limit) return []
|
||||
return [{ path: relative(process.cwd(), path), lineCount, limit }]
|
||||
})
|
||||
}
|
||||
|
||||
function run() {
|
||||
const violations = findFileLengthViolations(resolve('src'))
|
||||
if (!violations.length) return
|
||||
console.error('Files exceed the source file length limit:')
|
||||
violations.forEach(({ path, lineCount, limit }) => {
|
||||
console.error(` ${path}: ${lineCount} lines (maximum ${limit})`)
|
||||
})
|
||||
process.exitCode = 1
|
||||
}
|
||||
|
||||
const entryPath = process.argv[1] ? pathToFileURL(resolve(process.argv[1])).href : ''
|
||||
if (import.meta.url === entryPath) run()
|
||||
56
scripts/check-file-length.test.ts
Normal file
56
scripts/check-file-length.test.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import { mkdtempSync, rmSync, writeFileSync } from 'node:fs'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { join } from 'node:path'
|
||||
import { afterEach, describe, expect, it } from 'vitest'
|
||||
|
||||
import {
|
||||
collectTextFiles,
|
||||
findFileLengthViolations,
|
||||
physicalLineCount,
|
||||
} from './check-file-length.mjs'
|
||||
|
||||
const temporaryDirectories: string[] = []
|
||||
|
||||
function makeTemporaryDirectory() {
|
||||
const directory = mkdtempSync(join(tmpdir(), 'waveform-file-length-'))
|
||||
temporaryDirectories.push(directory)
|
||||
return directory
|
||||
}
|
||||
|
||||
afterEach(() => {
|
||||
temporaryDirectories.splice(0).forEach((directory) => {
|
||||
rmSync(directory, { recursive: true, force: true })
|
||||
})
|
||||
})
|
||||
|
||||
describe('file length check', () => {
|
||||
it('counts physical lines with and without a trailing newline', () => {
|
||||
expect(physicalLineCount('')).toBe(0)
|
||||
expect(physicalLineCount('first')).toBe(1)
|
||||
expect(physicalLineCount('first\nsecond')).toBe(2)
|
||||
expect(physicalLineCount('first\nsecond\n')).toBe(2)
|
||||
})
|
||||
|
||||
it('checks text files regardless of extension and skips binary files', () => {
|
||||
const directory = makeTemporaryDirectory()
|
||||
writeFileSync(join(directory, 'source.custom'), 'first\nsecond')
|
||||
writeFileSync(join(directory, 'binary.data'), Buffer.from([0, 1, 2, 3]))
|
||||
|
||||
expect(collectTextFiles(directory).map(({ path }) => path)).toEqual([
|
||||
join(directory, 'source.custom'),
|
||||
])
|
||||
})
|
||||
|
||||
it('reports the file, actual line count, and configured limit', () => {
|
||||
const directory = makeTemporaryDirectory()
|
||||
writeFileSync(join(directory, 'too-long.unknown'), 'first\nsecond\nthird')
|
||||
|
||||
expect(findFileLengthViolations(directory, 2)).toEqual([
|
||||
{
|
||||
path: expect.stringContaining('too-long.unknown'),
|
||||
lineCount: 3,
|
||||
limit: 2,
|
||||
},
|
||||
])
|
||||
})
|
||||
})
|
||||
4
scripts/clean-types.mjs
Normal file
4
scripts/clean-types.mjs
Normal file
@@ -0,0 +1,4 @@
|
||||
import { rmSync } from 'node:fs'
|
||||
import { resolve } from 'node:path'
|
||||
|
||||
rmSync(resolve('dist/types'), { recursive: true, force: true })
|
||||
Reference in New Issue
Block a user