mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-10-14 21:20:48 +08:00
* refactor(ipc): generate bindings with Specta * fix(profile): project IPC inputs to consumed fields * fix(events): remove unused refresh payloads * fix(webdav): return only consumed backup metadata * fix(network): trim unused interface metadata * fix(sysinfo): return only displayed system fields * chore(knip): check generated runtime exports * fix(proxy): confirm runtime chain updates before UI changes * fix(clipboard): propagate proxy environment copy failures * refactor(dns): remove ignored runtime patch * refactor(core): trim unused upgrade response fields * refactor(ipc): avoid redundant response copies * refactor(proxy): clarify automatic proxy query naming * chore(tests): remove added IPC regression tests * refactor(ipc): enforce typed command boundaries * chore(contract): check generated bindings before push * refactor(ipc): remove unused proxy liveness payloads
70 lines
2.1 KiB
JavaScript
70 lines
2.1 KiB
JavaScript
import { execFileSync } from 'node:child_process'
|
|
import fs from 'node:fs'
|
|
import path from 'node:path'
|
|
|
|
const ROOT = path.resolve(import.meta.dirname, '..')
|
|
const git = (...args) =>
|
|
execFileSync('git', args, { cwd: ROOT, encoding: 'utf8' }).trim()
|
|
const { contract } = JSON.parse(
|
|
fs.readFileSync(path.join(ROOT, 'scripts/contract-inputs.json'), 'utf8'),
|
|
)
|
|
const inputs = contract.map((pattern) => `:(glob)${pattern}`)
|
|
const args = process.argv.slice(2)
|
|
if (args.length !== 2 || args[0] !== '--push') {
|
|
console.error('usage: check-contract-changes.mjs --push <remote>')
|
|
process.exit(2)
|
|
}
|
|
const hasChanges = (...range) =>
|
|
git('diff', '--name-only', ...range, '--', ...inputs) !== ''
|
|
const assertCleanInputs = (...range) => {
|
|
if (
|
|
hasChanges(...range) ||
|
|
git('ls-files', '--others', '--exclude-standard', '--', ...inputs)
|
|
) {
|
|
throw new Error(
|
|
'Contract inputs differ from the pushed commit. Commit those changes before pushing.',
|
|
)
|
|
}
|
|
}
|
|
let relevant = false
|
|
const head = git('rev-parse', 'HEAD')
|
|
for (const line of fs
|
|
.readFileSync(0, 'utf8')
|
|
.trim()
|
|
.split('\n')
|
|
.filter(Boolean)) {
|
|
const fields = line.trim().split(/\s+/)
|
|
if (
|
|
fields.length !== 4 ||
|
|
![fields[1], fields[3]].every((sha) => /^[a-f0-9]{40,64}$/.test(sha))
|
|
) {
|
|
throw new Error('Invalid pre-push ref update')
|
|
}
|
|
const [, local, , remote] = fields
|
|
if (/^0+$/.test(local) || local === remote) continue
|
|
// A new remote branch has no upstream; use its fork point with the remote default branch.
|
|
const base = /^0+$/.test(remote)
|
|
? git('merge-base', local, `refs/remotes/${args[1]}/HEAD`)
|
|
: remote
|
|
if (!hasChanges(base, local)) continue
|
|
const commit = git('rev-parse', `${local}^{commit}`)
|
|
if (commit !== head)
|
|
throw new Error(
|
|
'Check out the pushed commit before validating its changed IPC contract.',
|
|
)
|
|
assertCleanInputs('HEAD')
|
|
relevant = true
|
|
}
|
|
if (relevant) {
|
|
execFileSync(
|
|
process.execPath,
|
|
[path.join(ROOT, 'scripts/gen-contract.mjs'), '--check'],
|
|
{
|
|
cwd: ROOT,
|
|
stdio: 'inherit',
|
|
},
|
|
)
|
|
} else {
|
|
console.log('[contract] inputs unchanged; skipping Rust generation')
|
|
}
|