fuc-new/doc/node_modules/@vuepress/helper/lib/node/utils/packageManager.js
hellcat 6adbc04d4b 1
2025-10-03 17:17:08 +08:00

152 lines
5.0 KiB
JavaScript

import { spawnSync } from 'node:child_process';
import { fs, path } from 'vuepress/utils';
const globalCache = new Map();
const localCache = new Map();
const PACKAGE_CONFIG = 'package.json';
const NPM_LOCK = 'package-lock.json';
const YARN_LOCK = 'yarn.lock';
const PNPM_LOCK = 'pnpm-lock.yaml';
const BUN_LOCK = 'bun.lockb';
const isInstalled = (packageManager) => {
try {
return (spawnSync(`${packageManager} --version`, { shell: true, stdio: 'ignore' })
.status === 0);
}
catch {
return false;
}
};
/**
* Check if a package manager is installed globally.
*
* 检查包管理器是否已全局安装
*
* @param packageManager - Package manager / 包管理器
*
* @returns Whether the package manager is installed / 包管理器是否已安装
*/
export const isPackageManagerInstalled = (packageManager) => {
const key = `global:${packageManager}`;
const status = globalCache.get(key);
if (status !== undefined)
return status;
if (isInstalled(packageManager)) {
globalCache.set(key, true);
return true;
}
return false;
};
/**
* Get package manager setting in package.json
*
* 获取 package.json 中的包管理器设置
*
* @param cwd - Current working directory / 当前工作目录
* @param deep - Whether to search in parent directories / 是否在父目录中搜索
*
* @returns The type of package manager / 包管理器类型
*/
export const getPackageManagerSetting = (cwd = process.cwd(), deep = true) => {
const key = `package:${cwd}`;
const status = localCache.get(key);
if (status !== undefined)
return status;
if (fs.existsSync(path.resolve(cwd, PACKAGE_CONFIG))) {
const { packageManager: packageManagerSettings } = JSON.parse(fs.readFileSync(path.resolve(cwd, PACKAGE_CONFIG), 'utf-8'));
if (packageManagerSettings) {
const packageManager = packageManagerSettings.split('@')[0];
localCache.set(key, packageManager);
return packageManager;
}
}
if (deep) {
let dir = cwd;
while (dir !== path.dirname(dir)) {
dir = path.dirname(dir);
if (fs.existsSync(path.resolve(cwd, PACKAGE_CONFIG))) {
const { packageManager: packageManagerSettings } = JSON.parse(fs.readFileSync(path.resolve(cwd, PACKAGE_CONFIG), 'utf-8'));
if (packageManagerSettings) {
const packageManager = packageManagerSettings.split('@')[0];
localCache.set(key, packageManager);
return packageManager;
}
}
}
}
return null;
};
/**
* Get the type of lock file.
*
* 获取锁文件的类型
*
* @param cwd - Current working directory / 当前工作目录
* @param deep - Whether to search in parent directories / 是否在父目录中搜索
*
* @returns The type of lock file / 锁文件类型
*/
export const getTypeofLockFile = (cwd = process.cwd(), deep = true) => {
const key = `local:${cwd}`;
const status = localCache.get(key);
if (status !== undefined)
return status;
if (fs.existsSync(path.resolve(cwd, PNPM_LOCK))) {
localCache.set(key, 'pnpm');
return 'pnpm';
}
if (fs.existsSync(path.resolve(cwd, YARN_LOCK))) {
localCache.set(key, 'yarn');
return 'yarn';
}
if (fs.existsSync(path.resolve(cwd, BUN_LOCK))) {
localCache.set(key, 'bun');
return 'bun';
}
if (fs.existsSync(path.resolve(cwd, NPM_LOCK))) {
localCache.set(key, 'npm');
return 'npm';
}
if (deep) {
let dir = cwd;
while (dir !== path.dirname(dir)) {
dir = path.dirname(dir);
if (fs.existsSync(path.resolve(dir, PNPM_LOCK))) {
localCache.set(key, 'pnpm');
return 'pnpm';
}
if (fs.existsSync(path.resolve(dir, YARN_LOCK))) {
localCache.set(key, 'yarn');
return 'yarn';
}
if (fs.existsSync(path.resolve(cwd, BUN_LOCK))) {
localCache.set(key, 'bun');
return 'bun';
}
if (fs.existsSync(path.resolve(dir, NPM_LOCK))) {
localCache.set(key, 'npm');
return 'npm';
}
}
}
return null;
};
/**
* Detect the package manager used in the current project.
*
* 检测当前项目使用的包管理器
*
* @param cwd - Current working directory / 当前工作目录
* @param deep - Whether to search in parent directories / 是否在父目录中搜索
*
* @returns The type of package manager / 包管理器类型
*/
export const getPackageManager = (cwd = process.cwd(), deep = true) => getPackageManagerSetting(cwd, deep) ||
getTypeofLockFile(cwd, deep) ||
(isPackageManagerInstalled('pnpm')
? 'pnpm'
: isPackageManagerInstalled('yarn')
? 'yarn'
: isPackageManagerInstalled('bun')
? 'bun'
: 'npm');