(rootDir: string, opts: CheckOptions = {})
| 39 | * --hook pre-push: only committed bump files count. |
| 40 | */ |
| 41 | export async function checkCommand(rootDir: string, opts: CheckOptions = {}): Promise<void> { |
| 42 | const config = await loadConfig(rootDir); |
| 43 | const { packages } = await discoverWorkspace(rootDir, config); |
| 44 | |
| 45 | // Channel branches and release PR branches move/consume bump files by design — |
| 46 | // checking them against baseBranch would produce false failures. |
| 47 | const { resolveChannels, detectReleaseBranch } = await import('../core/channels.ts'); |
| 48 | const currentBranch = detectReleaseBranch(rootDir); |
| 49 | if (currentBranch) { |
| 50 | const skipBranches = new Set([config.versionPr.branch]); |
| 51 | for (const channel of resolveChannels(config).values()) { |
| 52 | skipBranches.add(channel.branch); |
| 53 | skipBranches.add(channel.versionPr.branch); |
| 54 | } |
| 55 | if (skipBranches.has(currentBranch)) { |
| 56 | log.dim(` Skipping check — "${currentBranch}" is a channel or release PR branch.`); |
| 57 | return; |
| 58 | } |
| 59 | } |
| 60 | |
| 61 | // Find which files have changed on this branch vs base |
| 62 | const baseBranch = opts.base || config.baseBranch; |
| 63 | const changedFiles = getChangedFiles(rootDir, baseBranch); |
| 64 | |
| 65 | if (changedFiles.length === 0) { |
| 66 | log.info('No changed files detected.'); |
| 67 | return; |
| 68 | } |
| 69 | |
| 70 | // Filter to only bump files added/modified on this branch |
| 71 | const { bumpFiles: allBumpFiles, errors: parseErrors } = await readBumpFiles(rootDir); |
| 72 | if (parseErrors.length > 0) { |
| 73 | for (const err of parseErrors) { |
| 74 | log.error(err); |
| 75 | } |
| 76 | process.exit(1); |
| 77 | } |
| 78 | |
| 79 | // Get git status of bump files to detect untracked/staged files |
| 80 | const bumpyDir = getBumpyDir(rootDir); |
| 81 | const bumpyRelDir = relative(rootDir, bumpyDir); |
| 82 | const fileStatuses = getFileStatuses(bumpyRelDir, { cwd: rootDir }); |
| 83 | |
| 84 | // Augment changedFiles with untracked/staged bump files that aren't already in the list |
| 85 | const augmentedChangedFiles = [...changedFiles]; |
| 86 | for (const [file] of fileStatuses) { |
| 87 | if (file.endsWith('.md') && !file.endsWith('README.md') && !augmentedChangedFiles.includes(file)) { |
| 88 | augmentedChangedFiles.push(file); |
| 89 | } |
| 90 | } |
| 91 | |
| 92 | const { branchBumpFiles, emptyBumpFileIds } = filterBranchBumpFiles(allBumpFiles, augmentedChangedFiles, rootDir); |
| 93 | |
| 94 | // Determine which bump files count based on hook context |
| 95 | const bumpFileStatuses = new Map<string, 'committed' | 'staged' | 'untracked'>(); |
| 96 | for (const bf of branchBumpFiles) { |
| 97 | const filePath = `${bumpyRelDir}/${bf.id}.md`; |
| 98 | const status = fileStatuses.get(filePath); |
no test coverage detected
searching dependent graphs…