mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-19 09:33:53 +00:00
fix: remove unused cli finding code
This commit is contained in:
@@ -2,19 +2,10 @@
|
|||||||
* CLI path auto-detection and subprocess spawning utilities
|
* CLI path auto-detection and subprocess spawning utilities
|
||||||
*
|
*
|
||||||
* Supports multiple execution modes:
|
* Supports multiple execution modes:
|
||||||
* 1. Native binary: 'qwen' (production)
|
* 1. Bundled CLI: Node.js bundle included in the SDK package (default)
|
||||||
* 2. Node.js bundle: 'node /path/to/cli.js' (production validation)
|
* 2. Node.js bundle: 'node /path/to/cli.js' (custom path)
|
||||||
* 3. Bun bundle: 'bun /path/to/cli.js' (alternative runtime)
|
* 3. Bun bundle: 'bun /path/to/cli.js' (alternative runtime)
|
||||||
* 4. TypeScript source: 'tsx /path/to/index.ts' (development)
|
* 4. TypeScript source: 'tsx /path/to/index.ts' (development)
|
||||||
*
|
|
||||||
* Auto-detection locations for native binary:
|
|
||||||
* 1. QWEN_CODE_CLI_PATH environment variable
|
|
||||||
* 2. ~/.volta/bin/qwen
|
|
||||||
* 3. ~/.npm-global/bin/qwen
|
|
||||||
* 4. /usr/local/bin/qwen
|
|
||||||
* 5. ~/.local/bin/qwen
|
|
||||||
* 6. ~/node_modules/.bin/qwen
|
|
||||||
* 7. ~/.yarn/bin/qwen
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import * as fs from 'node:fs';
|
import * as fs from 'node:fs';
|
||||||
@@ -68,48 +59,11 @@ export function findNativeCliPath(): string {
|
|||||||
return bundledCli;
|
return bundledCli;
|
||||||
}
|
}
|
||||||
|
|
||||||
const homeDir = process.env['HOME'] || process.env['USERPROFILE'] || '';
|
|
||||||
|
|
||||||
const candidates: Array<string | undefined> = [
|
|
||||||
// 1. Environment variable
|
|
||||||
process.env['QWEN_CODE_CLI_PATH'],
|
|
||||||
|
|
||||||
// 2. Volta bin
|
|
||||||
path.join(homeDir, '.volta', 'bin', 'qwen'),
|
|
||||||
|
|
||||||
// 3. Global npm installations
|
|
||||||
path.join(homeDir, '.npm-global', 'bin', 'qwen'),
|
|
||||||
|
|
||||||
// 4. Common Unix binary locations
|
|
||||||
'/usr/local/bin/qwen',
|
|
||||||
|
|
||||||
// 5. User local bin
|
|
||||||
path.join(homeDir, '.local', 'bin', 'qwen'),
|
|
||||||
|
|
||||||
// 6. Node modules bin in home directory
|
|
||||||
path.join(homeDir, 'node_modules', '.bin', 'qwen'),
|
|
||||||
|
|
||||||
// 7. Yarn global bin
|
|
||||||
path.join(homeDir, '.yarn', 'bin', 'qwen'),
|
|
||||||
];
|
|
||||||
|
|
||||||
// Find first existing candidate
|
|
||||||
for (const candidate of candidates) {
|
|
||||||
if (candidate && fs.existsSync(candidate)) {
|
|
||||||
return path.resolve(candidate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Not found - throw helpful error
|
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'qwen CLI not found. Please:\n' +
|
'Bundled qwen CLI not found. The CLI should be included in the SDK package.\n' +
|
||||||
' 1. Install qwen globally: npm install -g qwen\n' +
|
'If you need to use a custom CLI, provide explicit executable:\n' +
|
||||||
' 2. Or provide explicit executable: query({ pathToQwenExecutable: "/path/to/qwen" })\n' +
|
' • query({ pathToQwenExecutable: "/path/to/cli.js" })\n' +
|
||||||
' 3. Or set environment variable: QWEN_CODE_CLI_PATH="/path/to/qwen"\n' +
|
|
||||||
'\n' +
|
|
||||||
'For development/testing, you can also use:\n' +
|
|
||||||
' • TypeScript source: query({ pathToQwenExecutable: "/path/to/index.ts" })\n' +
|
' • TypeScript source: query({ pathToQwenExecutable: "/path/to/index.ts" })\n' +
|
||||||
' • Node.js bundle: query({ pathToQwenExecutable: "/path/to/cli.js" })\n' +
|
|
||||||
' • Force specific runtime: query({ pathToQwenExecutable: "bun:/path/to/cli.js" })',
|
' • Force specific runtime: query({ pathToQwenExecutable: "bun:/path/to/cli.js" })',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,38 +52,26 @@ describe('CLI Path Utilities', () => {
|
|||||||
|
|
||||||
describe('parseExecutableSpec', () => {
|
describe('parseExecutableSpec', () => {
|
||||||
describe('auto-detection (no spec provided)', () => {
|
describe('auto-detection (no spec provided)', () => {
|
||||||
it('should auto-detect native CLI when no spec provided', () => {
|
it('should auto-detect bundled CLI when no spec provided', () => {
|
||||||
// Mock environment variable
|
// Mock existsSync to return true for bundled CLI
|
||||||
const originalEnv = process.env['QWEN_CODE_CLI_PATH'];
|
|
||||||
process.env['QWEN_CODE_CLI_PATH'] = '/usr/local/bin/qwen';
|
|
||||||
// Mock existsSync to return false for bundled CLI, true for env var path
|
|
||||||
mockFs.existsSync.mockImplementation((p) => {
|
mockFs.existsSync.mockImplementation((p) => {
|
||||||
const pathStr = p.toString();
|
const pathStr = p.toString();
|
||||||
if (
|
return (
|
||||||
pathStr.includes('cli/cli.js') ||
|
pathStr.includes('cli/cli.js') || pathStr.includes('cli\\cli.js')
|
||||||
pathStr.includes('cli\\cli.js')
|
);
|
||||||
) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return pathStr.includes('/usr/local/bin/qwen');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const result = parseExecutableSpec();
|
const result = parseExecutableSpec();
|
||||||
|
|
||||||
expect(result).toEqual({
|
expect(result.executablePath).toContain('cli.js');
|
||||||
executablePath: path.resolve('/usr/local/bin/qwen'),
|
expect(result.isExplicitRuntime).toBe(false);
|
||||||
isExplicitRuntime: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Restore env
|
|
||||||
process.env['QWEN_CODE_CLI_PATH'] = originalEnv;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw when auto-detection fails', () => {
|
it('should throw when bundled CLI not found', () => {
|
||||||
mockFs.existsSync.mockReturnValue(false);
|
mockFs.existsSync.mockReturnValue(false);
|
||||||
|
|
||||||
expect(() => parseExecutableSpec()).toThrow(
|
expect(() => parseExecutableSpec()).toThrow(
|
||||||
'qwen CLI not found. Please:',
|
'Bundled qwen CLI not found',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -373,83 +361,44 @@ describe('CLI Path Utilities', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('auto-detection fallback', () => {
|
describe('auto-detection fallback', () => {
|
||||||
it('should auto-detect when no spec provided', () => {
|
it('should auto-detect bundled CLI when no spec provided', () => {
|
||||||
// Mock environment variable
|
// Mock existsSync to return true for bundled CLI
|
||||||
const originalEnv = process.env['QWEN_CODE_CLI_PATH'];
|
|
||||||
process.env['QWEN_CODE_CLI_PATH'] = '/usr/local/bin/qwen';
|
|
||||||
// Mock existsSync to return false for bundled CLI, true for env var path
|
|
||||||
mockFs.existsSync.mockImplementation((p) => {
|
mockFs.existsSync.mockImplementation((p) => {
|
||||||
const pathStr = p.toString();
|
const pathStr = p.toString();
|
||||||
if (
|
return (
|
||||||
pathStr.includes('cli/cli.js') ||
|
pathStr.includes('cli/cli.js') || pathStr.includes('cli\\cli.js')
|
||||||
pathStr.includes('cli\\cli.js')
|
);
|
||||||
) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return pathStr.includes('/usr/local/bin/qwen');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const result = prepareSpawnInfo();
|
const result = prepareSpawnInfo();
|
||||||
|
|
||||||
expect(result).toEqual({
|
expect(result.command).toBe(process.execPath);
|
||||||
command: path.resolve('/usr/local/bin/qwen'),
|
expect(result.args[0]).toContain('cli.js');
|
||||||
args: [],
|
expect(result.type).toBe('node');
|
||||||
type: 'native',
|
expect(result.originalInput).toBe('');
|
||||||
originalInput: '',
|
|
||||||
});
|
|
||||||
|
|
||||||
// Restore env
|
|
||||||
process.env['QWEN_CODE_CLI_PATH'] = originalEnv;
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('findNativeCliPath', () => {
|
describe('findNativeCliPath', () => {
|
||||||
it('should find CLI from environment variable', () => {
|
it('should find bundled CLI', () => {
|
||||||
const originalEnv = process.env['QWEN_CODE_CLI_PATH'];
|
// Mock existsSync to return true for bundled CLI
|
||||||
process.env['QWEN_CODE_CLI_PATH'] = '/custom/path/to/qwen';
|
|
||||||
// Mock existsSync to return false for bundled CLI, true for env var path
|
|
||||||
mockFs.existsSync.mockImplementation((p) => {
|
mockFs.existsSync.mockImplementation((p) => {
|
||||||
const pathStr = p.toString();
|
const pathStr = p.toString();
|
||||||
if (pathStr.includes('cli/cli.js') || pathStr.includes('cli\\cli.js')) {
|
return (
|
||||||
return false;
|
pathStr.includes('cli/cli.js') || pathStr.includes('cli\\cli.js')
|
||||||
}
|
);
|
||||||
return pathStr.includes('/custom/path/to/qwen');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const result = findNativeCliPath();
|
const result = findNativeCliPath();
|
||||||
|
|
||||||
expect(result).toBe(path.resolve('/custom/path/to/qwen'));
|
expect(result).toContain('cli.js');
|
||||||
|
|
||||||
process.env['QWEN_CODE_CLI_PATH'] = originalEnv;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should search common installation locations', () => {
|
it('should throw descriptive error when bundled CLI not found', () => {
|
||||||
const originalEnv = process.env['QWEN_CODE_CLI_PATH'];
|
|
||||||
delete process.env['QWEN_CODE_CLI_PATH'];
|
|
||||||
|
|
||||||
// Mock fs.existsSync to return true for volta bin
|
|
||||||
// Use path.join to match platform-specific path separators
|
|
||||||
const voltaBinPath = path.join('.volta', 'bin', 'qwen');
|
|
||||||
mockFs.existsSync.mockImplementation((p) => {
|
|
||||||
return p.toString().includes(voltaBinPath);
|
|
||||||
});
|
|
||||||
|
|
||||||
const result = findNativeCliPath();
|
|
||||||
|
|
||||||
expect(result).toContain(voltaBinPath);
|
|
||||||
|
|
||||||
process.env['QWEN_CODE_CLI_PATH'] = originalEnv;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should throw descriptive error when CLI not found', () => {
|
|
||||||
const originalEnv = process.env['QWEN_CODE_CLI_PATH'];
|
|
||||||
delete process.env['QWEN_CODE_CLI_PATH'];
|
|
||||||
mockFs.existsSync.mockReturnValue(false);
|
mockFs.existsSync.mockReturnValue(false);
|
||||||
|
|
||||||
expect(() => findNativeCliPath()).toThrow('qwen CLI not found. Please:');
|
expect(() => findNativeCliPath()).toThrow('Bundled qwen CLI not found');
|
||||||
|
|
||||||
process.env['QWEN_CODE_CLI_PATH'] = originalEnv;
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -664,13 +613,10 @@ describe('CLI Path Utilities', () => {
|
|||||||
mockFs.existsSync.mockReturnValue(false);
|
mockFs.existsSync.mockReturnValue(false);
|
||||||
|
|
||||||
expect(() => parseExecutableSpec('/missing/file')).toThrow(
|
expect(() => parseExecutableSpec('/missing/file')).toThrow(
|
||||||
'Set QWEN_CODE_CLI_PATH environment variable',
|
'Executable file not found at',
|
||||||
);
|
);
|
||||||
expect(() => parseExecutableSpec('/missing/file')).toThrow(
|
expect(() => parseExecutableSpec('/missing/file')).toThrow(
|
||||||
'Install qwen globally: npm install -g qwen',
|
'Please check the file path and ensure the file exists',
|
||||||
);
|
|
||||||
expect(() => parseExecutableSpec('/missing/file')).toThrow(
|
|
||||||
'Force specific runtime: bun:/path/to/cli.js or tsx:/path/to/index.ts',
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user