0bd6410d9f
We had a few issues with lazy race conditions failing CI. This came from scripts configured to invoke lazy again, rather than through expressing dependencies between scripts. This diff reconfigures lazy to articulate these sorts of things as dependencies instead of through self-invocation. Instead of having lots of separate `build-package`, `build-docs`, etc commands, we now just have a build command with package overrides to express more specific options ### Change Type - [x] `internal` — Any other changes that don't affect the published package (will not publish a new version) ### Release Notes [internal only]
145 lines
3.7 KiB
TypeScript
145 lines
3.7 KiB
TypeScript
import kleur from 'kleur'
|
|
import path from 'path'
|
|
import { REPO_ROOT, writeJsonFile } from './lib/file'
|
|
import { getAllWorkspacePackages } from './lib/workspace'
|
|
|
|
function scriptPath(packageDir: string, scriptName: string) {
|
|
return path.relative(packageDir, path.join(__dirname, scriptName))
|
|
}
|
|
|
|
function tsScript(scriptName: string) {
|
|
return (packageDir: string) => `yarn run -T tsx ${scriptPath(packageDir, scriptName)}`
|
|
}
|
|
|
|
// all packages should have these scripts
|
|
const expectedScripts = {
|
|
lint: tsScript('lint.ts'),
|
|
}
|
|
|
|
// packages (in packages/) should have these scripts
|
|
const expectedPackageScripts = {
|
|
...expectedScripts,
|
|
test: () => 'lazy inherit',
|
|
}
|
|
|
|
// published packages should have these scripts
|
|
const expectedPublishedPackageScripts = {
|
|
...expectedPackageScripts,
|
|
build: tsScript('build-package.ts'),
|
|
'build-api': tsScript('build-api.ts'),
|
|
prepack: tsScript('prepack.ts'),
|
|
postpack: (packageDir: string) => scriptPath(packageDir, 'postpack.sh'),
|
|
'pack-tarball': () => 'yarn pack',
|
|
}
|
|
|
|
// individual packages can have different scripts than the above if needed
|
|
const perPackageExceptions: Record<string, Record<string, () => string | undefined>> = {
|
|
config: {
|
|
lint: () => undefined,
|
|
},
|
|
tsconfig: {
|
|
lint: () => undefined,
|
|
},
|
|
'@tldraw/monorepo': {
|
|
lint: () => 'lazy lint',
|
|
},
|
|
'@tldraw/polyfills': {
|
|
test: () => undefined,
|
|
},
|
|
'@tldraw/tlsync-sockets': {
|
|
test: () => 'lazy inherit --passWithNoTests',
|
|
},
|
|
'@tldraw/tlsync-worker': {
|
|
test: () => 'lazy inherit --passWithNoTests',
|
|
},
|
|
'@tldraw/ui': {
|
|
test: () => 'lazy inherit --passWithNoTests',
|
|
},
|
|
'@tldraw/assets': {
|
|
test: () => undefined,
|
|
build: () => undefined,
|
|
'build-api': () => undefined,
|
|
prepack: () => undefined,
|
|
postpack: () => undefined,
|
|
},
|
|
}
|
|
|
|
async function main({ fix }: { fix?: boolean }) {
|
|
const packages = await getAllWorkspacePackages()
|
|
const needsFix = new Set()
|
|
|
|
let errorCount = 0
|
|
for (const { path: packageDir, relativePath, packageJson, name } of packages) {
|
|
if (!packageJson.scripts) {
|
|
packageJson.scripts = {}
|
|
}
|
|
const packageScripts = packageJson.scripts
|
|
|
|
let expected =
|
|
name.startsWith('@tldraw/') &&
|
|
(relativePath.startsWith('bublic/packages/') || relativePath.startsWith('packages/'))
|
|
? packageJson.private
|
|
? expectedPackageScripts
|
|
: expectedPublishedPackageScripts
|
|
: expectedScripts
|
|
|
|
if (perPackageExceptions[name]) {
|
|
expected = {
|
|
...expected,
|
|
...perPackageExceptions[name],
|
|
}
|
|
}
|
|
|
|
for (const [scriptName, getExpectedScript] of Object.entries(expected)) {
|
|
const actualScript = packageScripts[scriptName]
|
|
const expectedScript = getExpectedScript(packageDir)
|
|
if (actualScript !== expectedScript) {
|
|
console.log(
|
|
[
|
|
'❌ ',
|
|
kleur.red(`${name}: `),
|
|
kleur.blue(`$ yarn ${scriptName}`),
|
|
kleur.grey(' -> '),
|
|
kleur.red(actualScript ?? '<missing>'),
|
|
kleur.gray(' (expected: '),
|
|
kleur.green(expectedScript),
|
|
kleur.gray(')'),
|
|
].join('')
|
|
)
|
|
packageScripts[scriptName] = expectedScript
|
|
needsFix.add(name)
|
|
errorCount++
|
|
} else {
|
|
console.log(
|
|
[
|
|
'✅ ',
|
|
kleur.green(`${name}: `),
|
|
kleur.blue(`$ yarn ${scriptName}`),
|
|
kleur.grey(' -> '),
|
|
kleur.green(actualScript ?? '<missing>'),
|
|
].join('')
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
if (errorCount) {
|
|
if (fix) {
|
|
for (const { packageJson, name, relativePath } of packages) {
|
|
if (needsFix.has(name)) {
|
|
console.log(kleur.yellow(`Fixing ${name}...`))
|
|
await writeJsonFile(path.join(REPO_ROOT, relativePath, 'package.json'), packageJson)
|
|
}
|
|
}
|
|
console.log(kleur.yellow(`Fixed ${errorCount} errors`))
|
|
process.exit(0)
|
|
} else {
|
|
console.log(kleur.red(`Found ${errorCount} errors`))
|
|
process.exit(1)
|
|
}
|
|
}
|
|
}
|
|
|
|
main({
|
|
fix: process.argv.includes('--fix'),
|
|
})
|