mirror of
https://github.com/langgenius/dify.git
synced 2026-06-03 08:16:37 +08:00
122 lines
3.4 KiB
TypeScript
122 lines
3.4 KiB
TypeScript
import type { CommandTree } from './registry'
|
|
import { BaseError } from '@/errors/base'
|
|
import { formatErrorForCli } from '@/errors/format'
|
|
import { formatHelp } from './help'
|
|
import { stringifyOutput } from './output'
|
|
import { findSuggestions, resolveCommand } from './registry'
|
|
|
|
export async function run(tree: CommandTree, argv: string[]): Promise<void> {
|
|
if (argv.length === 0 || argv[0] === 'help' || argv.includes('--help') || argv.includes('-h')) {
|
|
const helpArgv = argv.filter(a => a !== '--help' && a !== '-h' && a !== 'help')
|
|
|
|
if (helpArgv.length > 0) {
|
|
const resolved = resolveCommand(tree, helpArgv)
|
|
|
|
if (resolved) {
|
|
process.stdout.write(`${formatHelp(resolved.command, resolved.path.join(' '))}\n`)
|
|
|
|
return
|
|
}
|
|
}
|
|
|
|
printTopLevelHelp(tree)
|
|
|
|
return
|
|
}
|
|
|
|
const resolved = resolveCommand(tree, argv)
|
|
|
|
if (!resolved) {
|
|
process.stderr.write(`unknown command: ${argv.join(' ')}\n`)
|
|
const suggestions = findSuggestions(tree, argv)
|
|
|
|
if (suggestions.length > 0) {
|
|
process.stderr.write('\nDid you mean:\n')
|
|
|
|
for (const s of suggestions.slice(0, 5))
|
|
process.stderr.write(` ${s}\n`)
|
|
}
|
|
|
|
process.exit(1)
|
|
}
|
|
|
|
try {
|
|
const Ctor = resolved.command
|
|
if (typeof Ctor.deprecated === 'string' && Ctor.deprecated.length > 0)
|
|
process.stderr.write(`deprecated: ${Ctor.deprecated}\n`)
|
|
const cmd = new Ctor()
|
|
const commandArgv = argv.slice(resolved.path.length)
|
|
cmd.processGlobalFlags(commandArgv)
|
|
|
|
const output = await cmd.run(commandArgv)
|
|
if (output !== undefined)
|
|
process.stdout.write(stringifyOutput(output))
|
|
}
|
|
catch (err) {
|
|
if ((err as NodeJS.ErrnoException).code === 'EPIPE')
|
|
process.exit(0)
|
|
if (err instanceof BaseError) {
|
|
const format = sniffOutputFormat(argv)
|
|
process.stderr.write(`${formatErrorForCli(err, { format, isErrTTY: process.stderr.isTTY })}\n`)
|
|
process.exit(err.exit())
|
|
return
|
|
}
|
|
if (err instanceof Error) {
|
|
process.stderr.write(`${err.message}\n`)
|
|
process.exit(1)
|
|
return
|
|
}
|
|
process.stderr.write(`${String(err)}\n`)
|
|
process.exit(1)
|
|
}
|
|
}
|
|
|
|
export function sniffOutputFormat(argv: readonly string[]): string {
|
|
for (let i = 0; i < argv.length; i++) {
|
|
const t = argv[i]
|
|
if (t === undefined)
|
|
continue
|
|
if (t === '--')
|
|
return ''
|
|
|
|
if (t === '--output' || t === '-o') {
|
|
const next = argv[i + 1]
|
|
if (next !== undefined && !next.startsWith('-'))
|
|
return next
|
|
continue
|
|
}
|
|
if (t.startsWith('--output='))
|
|
return t.slice('--output='.length)
|
|
if (t.startsWith('-o='))
|
|
return t.slice('-o='.length)
|
|
}
|
|
return ''
|
|
}
|
|
|
|
function printTopLevelHelp(tree: CommandTree): void {
|
|
process.stdout.write('difyctl — Dify command-line interface\n\n')
|
|
process.stdout.write('COMMANDS\n')
|
|
|
|
for (const [topic, node] of Object.entries(tree)) {
|
|
if (node.command?.hidden === true)
|
|
continue
|
|
|
|
if (node.command) {
|
|
const desc = node.command.description ?? ''
|
|
process.stdout.write(` ${topic} ${desc}\n`)
|
|
}
|
|
else {
|
|
process.stdout.write(` ${topic}\n`)
|
|
}
|
|
|
|
for (const [verb, sub] of Object.entries(node.subcommands)) {
|
|
if (sub.command?.hidden === true)
|
|
continue
|
|
const desc = sub.command?.description ?? ''
|
|
process.stdout.write(` ${verb} ${desc}\n`)
|
|
}
|
|
}
|
|
|
|
process.stdout.write('\n')
|
|
}
|