fix(ci): preserve recorded npm resolution during vendor rescoping
This commit is contained in:
1 parent
c2a68638b2
commit
55fc8b91e4
2 files changed
+27
-9
No files matched your search
@@ -1,15 +1,27 @@
|
|||||||
/**
|
/** Recorded npm evidence stays intact while authored files and exact edits remain checked. */
|
||||||
* Acceptance-path coverage for the rescope codemod's exact-edit classifier: a
|
|
||||||
* duplicated insertion — what a non-idempotent apply produces — must be
|
|
||||||
* rejected rather than applied again.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { describe, expect, it } from 'vitest'
|
import { describe, expect, it } from 'vitest'
|
||||||
import { exactEditState } from './rescope-vendor.ts'
|
import { exactEditState, isRescopeExcluded } from './rescope-vendor.ts'
|
||||||
|
|
||||||
const ANCHOR = '\n## Sync procedure'
|
const ANCHOR = '\n## Sync procedure'
|
||||||
const INSERTED = `\n15. **rescope**: one log entry.\n${ANCHOR}`
|
const INSERTED = `\n15. **rescope**: one log entry.\n${ANCHOR}`
|
||||||
|
|
||||||
|
describe('rescope file selection', () => {
|
||||||
|
it('preserves the recorded npm resolution', () => {
|
||||||
|
expect(isRescopeExcluded('scripts/dependency-catalog/package-lock.json')).toBe(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
it.each([
|
||||||
|
'scripts/dependency-catalog/package.json',
|
||||||
|
'scripts/dependency-catalog/source.ts',
|
||||||
|
'scripts/other/package-lock.json',
|
||||||
|
'packages/example/src/index.ts',
|
||||||
|
'packages/example/package.json',
|
||||||
|
])('keeps %s subject to upstream package-name checks', (file) => {
|
||||||
|
expect(isRescopeExcluded(file)).toBe(false)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe('exactEditState', () => {
|
describe('exactEditState', () => {
|
||||||
it('classifies an insertion by its target form, so a duplicate is invalid', () => {
|
it('classifies an insertion by its target form, so a duplicate is invalid', () => {
|
||||||
expect(exactEditState(`log\n${ANCHOR}\n`, ANCHOR, INSERTED, 1)).toBe('pending')
|
expect(exactEditState(`log\n${ANCHOR}\n`, ANCHOR, INSERTED, 1)).toBe('pending')
|
||||||
|
|||||||
@@ -419,8 +419,12 @@ const VENDORED_LIBRARY = /^@deepseek-ai\\/(cosmokit|schemastery)(\\/|$)/
|
|||||||
})),
|
})),
|
||||||
]
|
]
|
||||||
|
|
||||||
/** Files the rescope must never rewrite. */
|
/**
|
||||||
function excluded(file: string): boolean {
|
* Identify files whose recorded content must remain outside the rescope pass.
|
||||||
|
* @param file - Repository-relative path with forward slash separators.
|
||||||
|
* @returns Whether the codemod must preserve the file without scanning its tokens.
|
||||||
|
*/
|
||||||
|
export function isRescopeExcluded(file: string): boolean {
|
||||||
if (file === 'scripts/rescope-vendor.ts') return true // the mapping itself
|
if (file === 'scripts/rescope-vendor.ts') return true // the mapping itself
|
||||||
if (file.startsWith('.agents/notes/')) return true // notes record what was true when written
|
if (file.startsWith('.agents/notes/')) return true // notes record what was true when written
|
||||||
// Recorded model payloads quote documentation verbatim, so they must mirror the
|
// Recorded model payloads quote documentation verbatim, so they must mirror the
|
||||||
@@ -430,6 +434,8 @@ function excluded(file: string): boolean {
|
|||||||
if (file === 'docs/rescope.md' || file === 'docs/rescope.zh.md') return true
|
if (file === 'docs/rescope.md' || file === 'docs/rescope.zh.md') return true
|
||||||
if (file.endsWith('.i18n.yaml')) return true // blob-hash records, re-recorded by the pairing gate
|
if (file.endsWith('.i18n.yaml')) return true // blob-hash records, re-recorded by the pairing gate
|
||||||
if (file === 'pnpm-lock.yaml') return true // regenerated by pnpm install
|
if (file === 'pnpm-lock.yaml') return true // regenerated by pnpm install
|
||||||
|
// Raw npm registry resolution; only gen-dependency-catalog --refresh replaces this evidence.
|
||||||
|
if (file === 'scripts/dependency-catalog/package-lock.json') return true
|
||||||
if (/^vendor\/[^/]+\/(README\.md|LICENSE)$/.test(file)) return true // upstream files kept verbatim
|
if (/^vendor\/[^/]+\/(README\.md|LICENSE)$/.test(file)) return true // upstream files kept verbatim
|
||||||
return !EXTENSIONS.some(extension => file.endsWith(extension))
|
return !EXTENSIONS.some(extension => file.endsWith(extension))
|
||||||
}
|
}
|
||||||
@@ -558,7 +564,7 @@ function main(): void {
|
|||||||
const all = patterns(reverse)
|
const all = patterns(reverse)
|
||||||
const files = execFileSync('git', ['ls-files', '-z'], { cwd: root, encoding: 'utf8' })
|
const files = execFileSync('git', ['ls-files', '-z'], { cwd: root, encoding: 'utf8' })
|
||||||
.split('\0')
|
.split('\0')
|
||||||
.filter(file => file !== '' && !excluded(file))
|
.filter(file => file !== '' && !isRescopeExcluded(file))
|
||||||
|
|
||||||
const counts = new Map<string, { files: number; lines: number }>()
|
const counts = new Map<string, { files: number; lines: number }>()
|
||||||
const failures: string[] = []
|
const failures: string[] = []
|
||||||
|
|||||||
Reference in new issue
Block a user