mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-21 17:27:54 +00:00
📦 Release qwen-code CLI as a Standalone Bundled Package (#866)
This commit is contained in:
114
packages/core/src/utils/ripgrepUtils.ts
Normal file
114
packages/core/src/utils/ripgrepUtils.ts
Normal file
@@ -0,0 +1,114 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2025 Qwen
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { fileExists } from './fileUtils.js';
|
||||
|
||||
// Get the directory of the current module
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
type Platform = 'darwin' | 'linux' | 'win32';
|
||||
type Architecture = 'x64' | 'arm64';
|
||||
|
||||
/**
|
||||
* Maps process.platform values to vendor directory names
|
||||
*/
|
||||
function getPlatformString(platform: string): Platform {
|
||||
switch (platform) {
|
||||
case 'darwin':
|
||||
case 'linux':
|
||||
case 'win32':
|
||||
return platform;
|
||||
default:
|
||||
throw new Error(`Unsupported platform: ${platform}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps process.arch values to vendor directory names
|
||||
*/
|
||||
function getArchitectureString(arch: string): Architecture {
|
||||
switch (arch) {
|
||||
case 'x64':
|
||||
case 'arm64':
|
||||
return arch;
|
||||
default:
|
||||
throw new Error(`Unsupported architecture: ${arch}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path to the bundled ripgrep binary for the current platform
|
||||
*/
|
||||
export function getRipgrepPath(): string {
|
||||
const platform = getPlatformString(process.platform);
|
||||
const arch = getArchitectureString(process.arch);
|
||||
|
||||
// Binary name includes .exe on Windows
|
||||
const binaryName = platform === 'win32' ? 'rg.exe' : 'rg';
|
||||
|
||||
// Path resolution:
|
||||
// When running from transpiled code: dist/src/utils/ripgrepUtils.js -> ../../../vendor/ripgrep/
|
||||
// When running from bundle: dist/index.js -> vendor/ripgrep/
|
||||
|
||||
// Detect if we're running from a bundle (single file)
|
||||
// In bundle, __filename will be something like /path/to/dist/index.js
|
||||
// In transpiled code, __filename will be /path/to/dist/src/utils/ripgrepUtils.js
|
||||
const isBundled = !__filename.includes(path.join('src', 'utils'));
|
||||
|
||||
const vendorPath = isBundled
|
||||
? path.join(
|
||||
__dirname,
|
||||
'vendor',
|
||||
'ripgrep',
|
||||
`${arch}-${platform}`,
|
||||
binaryName,
|
||||
)
|
||||
: path.join(
|
||||
__dirname,
|
||||
'..',
|
||||
'..',
|
||||
'..',
|
||||
'vendor',
|
||||
'ripgrep',
|
||||
`${arch}-${platform}`,
|
||||
binaryName,
|
||||
);
|
||||
|
||||
return vendorPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if ripgrep binary is available
|
||||
*/
|
||||
export async function canUseRipgrep(): Promise<boolean> {
|
||||
try {
|
||||
const rgPath = getRipgrepPath();
|
||||
return await fileExists(rgPath);
|
||||
} catch (_error) {
|
||||
// Unsupported platform/arch
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures ripgrep binary exists and returns its path
|
||||
* @throws Error if ripgrep binary is not available
|
||||
*/
|
||||
export async function ensureRipgrepPath(): Promise<string> {
|
||||
const rgPath = getRipgrepPath();
|
||||
|
||||
if (!(await fileExists(rgPath))) {
|
||||
throw new Error(
|
||||
`Ripgrep binary not found at ${rgPath}. ` +
|
||||
`Platform: ${process.platform}, Architecture: ${process.arch}`,
|
||||
);
|
||||
}
|
||||
|
||||
return rgPath;
|
||||
}
|
||||
Reference in New Issue
Block a user