Repository: electron-userland/electron-builder
File: packages/app-builder-lib/src/node-module-collector/packageManager.ts (TypeScript)

Code before:
  if (process.env.npm_config_user_agent) {
    const userAgent = process.env.npm_config_user_agent
    if (userAgent.includes("pnpm")) return PM.PNPM
    if (userAgent.includes("yarn")) return PM.YARN
    if (userAgent.includes("npm")) return PM.NPM
  }

  if (process.env.npm_execpath) {
    const execPath = process.env.npm_execpath
    if (execPath.includes("pnpm")) return PM.PNPM
    if (execPath.includes("yarn")) return PM.YARN
    if (execPath.includes("npm")) return PM.NPM
  }

  const packageJsonPath = path.join(process.cwd(), "package.json")
  if (fs.existsSync(packageJsonPath)) {
    const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"))

    if (packageJson.packageManager) {
      if (packageJson.packageManager.startsWith("pnpm@")) return PM.PNPM
      if (packageJson.packageManager.startsWith("yarn@")) return PM.YARN
      if (packageJson.packageManager.startsWith("npm@")) return PM.NPM
    }
  }

  return null
}

export function detectPackageManagerByLockfile(cwd: string): PM | null {
  const has = (file: string) => fs.existsSync(path.join(cwd, file))

  const yarn = has("yarn.lock")
  const pnpm = has("pnpm-lock.yaml")
  const npm = has("package-lock.json")

  const detected: PM[] = []
  if (yarn) detected.push(PM.YARN)
  if (pnpm) detected.push(PM.PNPM)
  if (npm) detected.push(PM.NPM)

  if (detected.length === 1) {
    return detected[0]
  }

  return null
}

export function detectYarnBerry() {
  // yarn --version
  const version = execSync("yarn --version").toString().trim()
  if (parseInt(version.split(".")[0]) > 1) return PM.YARN_BERRY

Review comment (performance):
I think we can optimize this here, but also, this new logic seems to remove `process.env.YARN_VERSION`, `process.env.YARN_REGISTRY`, and `process.env.npm_package_json` logic. `YARN_BERRY` detection was removed as well. Is that intentional?

Code after:

export function detectPackageManagerByEnv(): PM | null {
  const packageJsonPath = path.join(process.cwd(), "package.json")
  const packageManager = fs.existsSync(packageJsonPath) ? JSON.parse(fs.readFileSync(packageJsonPath, "utf8"))?.packageManager : undefined

  const priorityChecklist = [
    (key: string) => process.env.npm_config_user_agent?.includes(key),
    (key: string) => process.env.npm_execpath?.includes(key),
    (key: string) => packageManager?.startsWith(`${key}@`),
  ]

  const pms = Object.values(PM).filter(pm => pm !== PM.YARN_BERRY)
  for (const checker of priorityChecklist) {
    for (const pm of pms) {
      if (checker(pm)) {
        return pm
      }
    }
  }
  return null
}

export function detectPackageManagerByLockfile(cwd: string): PM | null {
  const has = (file: string) => fs.existsSync(path.join(cwd, file))

  const detected: PM[] = []
  if (has("yarn.lock")) {
    detected.push(PM.YARN)
  }
  if (has("pnpm-lock.yaml")) {
    detected.push(PM.PNPM)
  }
  if (has("package-lock.json")) {
    detected.push(PM.NPM)
  }
  if (has("bun.lock") || has("bun.lockb")) {
    detected.push(PM.BUN)
  }

  if (detected.length === 1) {
    return detected[0]
  }

  return null
}

export function detectYarnBerry() {
  // yarn --version
  const version = execSync("yarn --version").toString().trim()
  if (parseInt(version.split(".")[0]) > 1) return PM.YARN_BERRY
  return PM.YARN