@netlify/build-info
Version:
Build info utility
92 lines • 3.75 kB
JavaScript
import { parse } from 'semver';
/** The definition of all available package managers */
export const AVAILABLE_PACKAGE_MANAGERS = {
["yarn" /* PkgManager.YARN */]: {
name: "yarn" /* PkgManager.YARN */,
installCommand: 'yarn install',
runCommand: 'yarn run',
lockFiles: ['yarn.lock'],
forceEnvironment: 'NETLIFY_USE_YARN',
},
["pnpm" /* PkgManager.PNPM */]: {
name: "pnpm" /* PkgManager.PNPM */,
installCommand: 'pnpm install',
runCommand: 'pnpm run',
lockFiles: ['pnpm-lock.yaml'],
forceEnvironment: 'NETLIFY_USE_PNPM',
},
["npm" /* PkgManager.NPM */]: {
name: "npm" /* PkgManager.NPM */,
installCommand: 'npm install',
runCommand: 'npm run',
lockFiles: ['package-lock.json'],
},
["bun" /* PkgManager.BUN */]: {
name: "bun" /* PkgManager.BUN */,
installCommand: 'bun install',
runCommand: 'bun run',
lockFiles: ['bun.lockb', 'bun.lock'],
},
};
/**
* generate a map out of key is lock file and value the package manager
* this is to reduce the complexity in loops
*/
const lockFileMap = Object.values(AVAILABLE_PACKAGE_MANAGERS).reduce((cur, pkgManager) => pkgManager.lockFiles.reduce((cur, lockFile) => ({ ...cur, [lockFile]: pkgManager }), cur), {});
/**
* Detects the used package manager based on
* 1. packageManager field
* 2. environment variable that forces the usage
* 3. a lock file that is present in this directory or up in the tree for workspaces
*/
export const detectPackageManager = async (project) => {
try {
const pkgPaths = await project.fs.findUpMultiple('package.json', {
cwd: project.baseDirectory,
stopAt: project.root,
});
// if there is no package json than there is no package manager to detect
if (!pkgPaths.length) {
return null;
}
for (const pkgPath of pkgPaths) {
const { packageManager } = await project.fs.readJSON(pkgPath);
if (packageManager) {
const [parsed, version] = packageManager.split('@');
if (AVAILABLE_PACKAGE_MANAGERS[parsed]) {
const pkgManager = AVAILABLE_PACKAGE_MANAGERS[parsed];
pkgManager.version = parse(version) || undefined;
return pkgManager;
}
}
}
// the package manager can be enforced via an environment variable as well
for (const pkgManager of Object.values(AVAILABLE_PACKAGE_MANAGERS)) {
if (pkgManager.forceEnvironment && project.getEnv(pkgManager.forceEnvironment) === 'true') {
return pkgManager;
}
}
// find the correct lock file the tree up
const lockFilePath = await project.fs.findUp(Object.keys(lockFileMap), {
cwd: project.baseDirectory,
stopAt: project.root,
});
// if we found a lock file and the usage is not prohibited through an environment variable
// return the found package manager
if (lockFilePath) {
const lockFile = project.fs.basename(lockFilePath);
const pkgManager = lockFileMap[lockFile];
// check if it is not got disabled
if (!(pkgManager.forceEnvironment && project.getEnv(pkgManager.forceEnvironment) === 'false')) {
return pkgManager;
}
}
}
catch (error) {
project.report(error);
}
// always default to npm
// TODO: add some reporting here to log that we fall backed
return AVAILABLE_PACKAGE_MANAGERS["npm" /* PkgManager.NPM */];
};
//# sourceMappingURL=detect-package-manager.js.map