mirror of
https://github.com/iflytek/skillhub.git
synced 2026-10-15 04:18:20 +00:00
test(cli): prove lifecycle warning outputs
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
This commit is contained in:
parent
b9be415d34
commit
8444313fdf
5 changed files with 56 additions and 4 deletions
|
|
@ -135,7 +135,7 @@ async function resolveSyncContext(options: SyncCommonOptions): Promise<{
|
|||
return { client: new SkillHubClient(registry, token), registry, token, namespace, rootDir }
|
||||
}
|
||||
|
||||
function renderPullResult(result: PullResult, json: boolean, check: boolean): string {
|
||||
export function renderPullResult(result: PullResult, json: boolean, check: boolean): string {
|
||||
if (json) {
|
||||
return JSON.stringify({ ok: result.failures.length === 0, check, ...result })
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ function renderUpgradePlan(
|
|||
].join('\n')
|
||||
}
|
||||
|
||||
function renderUpgradeResult(plan: UpgradePlan, result: UpgradeExecutionResult, json: boolean): string {
|
||||
export function renderUpgradeResult(plan: UpgradePlan, result: UpgradeExecutionResult, json: boolean): string {
|
||||
const executionByCoordinate = new Map(result.items.map(item => [item.coordinate, item]))
|
||||
const items = plan.items.map(item => ({
|
||||
coordinate: item.coordinate,
|
||||
|
|
|
|||
|
|
@ -64,6 +64,10 @@ export interface UpgradeExecutionResult {
|
|||
notAttempted: number
|
||||
}
|
||||
|
||||
type UpgradeExecutionOptions = Pick<UpgradeSelectionOptions, 'home' | 'tokenForRegistry'> & {
|
||||
installSkillFn?: typeof installSkill
|
||||
}
|
||||
|
||||
export async function planSkillUpgrades(options: UpgradeSelectionOptions): Promise<UpgradePlan> {
|
||||
if (options.coordinates.length === 0) {
|
||||
throw new CliError('provide at least one installed skill coordinate', EXIT.usage)
|
||||
|
|
@ -223,7 +227,7 @@ export async function planSkillUpgrades(options: UpgradeSelectionOptions): Promi
|
|||
|
||||
export async function executeSkillUpgradePlan(
|
||||
plan: UpgradePlan,
|
||||
options: Pick<UpgradeSelectionOptions, 'home' | 'tokenForRegistry'>
|
||||
options: UpgradeExecutionOptions
|
||||
): Promise<UpgradeExecutionResult> {
|
||||
if (plan.blocked > 0) {
|
||||
throw new CliError('upgrade plan contains blocked skills', EXIT.validation)
|
||||
|
|
@ -244,7 +248,7 @@ export async function executeSkillUpgradePlan(
|
|||
|
||||
try {
|
||||
const token = await options.tokenForRegistry(item.registry)
|
||||
const installed = await installSkill({
|
||||
const installed = await (options.installSkillFn ?? installSkill)({
|
||||
registry: item.registry,
|
||||
token,
|
||||
namespace: item.inventoryItem.namespace,
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import { runCli } from '../helpers/run-cli'
|
|||
import { createTempHome } from '../helpers/temp-env'
|
||||
import { SkillHubClient } from '../../src/clients/skillhub-client'
|
||||
import { pullNamespace } from '../../src/services/sync-service'
|
||||
import { renderPullResult } from '../../src/commands/sync'
|
||||
|
||||
function makeSkill(body: string): { zipBytes: Uint8Array; fingerprint: string } {
|
||||
const content = strToU8(body)
|
||||
|
|
@ -47,6 +48,8 @@ describe('sync command', () => {
|
|||
slug: 'demo',
|
||||
message: 'target lock cleanup failed: simulated release failure'
|
||||
}])
|
||||
expect(JSON.parse(renderPullResult(result, true, false)).warnings).toEqual(result.warnings)
|
||||
expect(renderPullResult(result, false, false)).toContain('warning demo: target lock cleanup failed')
|
||||
} finally {
|
||||
registry.stop()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ import { createTempHome } from '../helpers/temp-env'
|
|||
import { startFakeRegistry } from '../helpers/fake-registry'
|
||||
import { runCli } from '../helpers/run-cli'
|
||||
import { executeSkillUpgradePlan, planSkillUpgrades } from '../../src/services/upgrade-service'
|
||||
import { installSkill } from '../../src/services/install-service'
|
||||
import { renderUpgradeResult } from '../../src/commands/upgrade'
|
||||
|
||||
let registries: Array<Awaited<ReturnType<typeof startFakeRegistry>>> = []
|
||||
|
||||
|
|
@ -575,6 +577,49 @@ describe('upgrade command', () => {
|
|||
expect(registry.received.downloads).toBe(5)
|
||||
})
|
||||
|
||||
test('a committed upgrade keeps success and renders a post-commit warning', async () => {
|
||||
const env = await createTempHome()
|
||||
const skill = { namespace: 'global', slug: 'warned', version: '1.0.0', fingerprint: 'v1', zipBytes: makeSkillZip('# v1') }
|
||||
const registry = await startFakeRegistry({ skills: [skill] })
|
||||
registries.push(registry)
|
||||
const rootDir = join(env.cwd, 'skills')
|
||||
await mkdir(rootDir, { recursive: true })
|
||||
await runCli(['install', '@global/warned', '--dir', rootDir, '--registry', registry.url], {
|
||||
HOME: env.home,
|
||||
USERPROFILE: env.home
|
||||
})
|
||||
skill.version = '1.1.0'
|
||||
skill.fingerprint = 'v2'
|
||||
skill.zipBytes = makeSkillZip('# v2')
|
||||
const tokenForRegistry = async () => undefined
|
||||
const plan = await planSkillUpgrades({
|
||||
coordinates: ['@global/warned'],
|
||||
registry: registry.url,
|
||||
force: false,
|
||||
home: env.home,
|
||||
tokenForRegistry
|
||||
})
|
||||
|
||||
const result = await executeSkillUpgradePlan(plan, {
|
||||
home: env.home,
|
||||
tokenForRegistry,
|
||||
installSkillFn: options => installSkill({
|
||||
...options,
|
||||
acquireTargetLock: async () => async () => { throw new Error('simulated release failure') }
|
||||
})
|
||||
})
|
||||
|
||||
expect(result).toMatchObject({ upgraded: 1, failed: 0 })
|
||||
expect(result.items[0]).toMatchObject({ action: 'upgraded' })
|
||||
expect(result.items[0]?.warnings).toEqual(['target lock cleanup failed: simulated release failure'])
|
||||
expect(JSON.parse(renderUpgradeResult(plan, result, true)).items[0].warnings).toHaveLength(1)
|
||||
expect(renderUpgradeResult(plan, result, false)).toContain('upgraded')
|
||||
expect(renderUpgradeResult(plan, result, false)).toContain('[warning: target lock cleanup failed')
|
||||
expect(await readFile(join(rootDir, 'warned', 'SKILL.md'), 'utf-8')).toBe('# v2')
|
||||
const inventory = JSON.parse(await readFile(join(env.home, '.skillhub', 'inventory.json'), 'utf-8'))
|
||||
expect(inventory.items[0]).toMatchObject({ version: '1.1.0', fingerprint: 'v2' })
|
||||
})
|
||||
|
||||
test('legacy metadata without a file baseline requires explicit force migration', async () => {
|
||||
const env = await createTempHome()
|
||||
const skill = { namespace: 'global', slug: 'legacy', version: '1.0.0', fingerprint: 'v1', zipBytes: makeSkillZip('# v1') }
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue