Skip to content

Commit

Permalink
Add support for Bun
Browse files Browse the repository at this point in the history
  • Loading branch information
Strengthless committed Sep 10, 2023
1 parent c7c63bf commit e036d6b
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 13 deletions.
18 changes: 13 additions & 5 deletions src/detectPackageManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import chalk from "chalk"
import process from "process"
import findWorkspaceRoot from "find-yarn-workspace-root"

export type PackageManager = "yarn" | "npm" | "npm-shrinkwrap"
export type PackageManager = "yarn" | "npm" | "npm-shrinkwrap" | "bun"

function printNoYarnLockfileError() {
console.log(`
Expand All @@ -17,9 +17,9 @@ ${chalk.red.bold("**ERROR**")} ${chalk.red(
function printNoLockfilesError() {
console.log(`
${chalk.red.bold("**ERROR**")} ${chalk.red(
`No package-lock.json, npm-shrinkwrap.json, or yarn.lock file.
`No package-lock.json, npm-shrinkwrap.json, yarn.lock, or bun.lockb file.
You must use either npm@>=5, yarn, or npm-shrinkwrap to manage this project's
You must use either npm@>=5, yarn, npm-shrinkwrap, or bun to manage this project's
dependencies.`,
)}
`)
Expand Down Expand Up @@ -47,7 +47,13 @@ export const detectPackageManager = (
const shrinkWrapExists = fs.existsSync(
join(appRootPath, "npm-shrinkwrap.json"),
)
const yarnLockExists = fs.existsSync(join(appRootPath, "yarn.lock"))
const yarnLockExists = fs.existsSync(
join(findWorkspaceRoot() ?? appRootPath, "pnpm-lock.yaml"),
)
// Bun workspaces seem to work the same as yarn workspaces - https://bun.sh/docs/install/workspaces
const bunLockbExists = fs.existsSync(
join(findWorkspaceRoot() ?? appRootPath, "bun.lockb"),
)
if ((packageLockExists || shrinkWrapExists) && yarnLockExists) {
if (overridePackageManager) {
return overridePackageManager
Expand All @@ -62,8 +68,10 @@ export const detectPackageManager = (
} else {
return shrinkWrapExists ? "npm-shrinkwrap" : "npm"
}
} else if (yarnLockExists || findWorkspaceRoot()) {
} else if (yarnLockExists) {
return "yarn"
} else if (bunLockbExists) {
return "bun"
} else {
printNoLockfilesError()
process.exit(1)
Expand Down
29 changes: 21 additions & 8 deletions src/getPackageResolution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import yaml from "yaml"
import findWorkspaceRoot from "find-yarn-workspace-root"
import { getPackageVersion } from "./getPackageVersion"
import { coerceSemVer } from "./coerceSemVer"
import { parseBunLockfile } from "./parseBunLockfile"

export function getPackageResolution({
packageDetails,
Expand All @@ -17,24 +18,32 @@ export function getPackageResolution({
packageManager: PackageManager
appPath: string
}) {
if (packageManager === "yarn") {
let lockFilePath = "yarn.lock"
if (packageManager === "yarn" || packageManager === "bun") {
const isBun = packageManager === "bun"
const lockFileName = isBun ? "bun.lockb" : "yarn.lock"
let lockFilePath = lockFileName
if (!existsSync(lockFilePath)) {
const workspaceRoot = findWorkspaceRoot()
if (!workspaceRoot) {
throw new Error("Can't find yarn.lock file")
throw new Error(`Can't find ${lockFileName} file`)
}
lockFilePath = join(workspaceRoot, "yarn.lock")
lockFilePath = join(workspaceRoot, lockFilePath)
}
if (!existsSync(lockFilePath)) {
throw new Error("Can't find yarn.lock file")
throw new Error(`Can't find ${lockFileName} file`)
}
const lockFileString = readFileSync(lockFilePath).toString()
const lockFileString = isBun
? parseBunLockfile(lockFilePath)
: readFileSync(lockFilePath).toString()
let appLockFile
if (lockFileString.includes("yarn lockfile v1")) {
const parsedYarnLockFile = parseYarnLockFile(lockFileString)
if (parsedYarnLockFile.type !== "success") {
throw new Error("Could not parse yarn v1 lock file")
throw new Error(
`Could not parse yarn v1 lock file ${
isBun ? "- was originally a bun.lockb file" : ""
}`,
)
} else {
appLockFile = parsedYarnLockFile.object
}
Expand All @@ -43,7 +52,11 @@ export function getPackageResolution({
appLockFile = yaml.parse(lockFileString)
} catch (e) {
console.log(e)
throw new Error("Could not parse yarn v2 lock file")
throw new Error(
`Could not parse yarn v2 lock file ${
isBun ? "- was originally a bun.lockb file (should not happen)" : ""
}`,
)
}
}

Expand Down
15 changes: 15 additions & 0 deletions src/parseBunLockfile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { spawnSync } from "child_process"

// From https://github.com/oven-sh/bun/blob/ffe4f561a3af53b9f5a41c182de55d7199b5d692/packages/bun-vscode/src/features/lockfile.ts#L39,
// rewritten to use spawnSync instead of spawn.
export function parseBunLockfile(lockFilePath: string): string {
const process = spawnSync("bun", [lockFilePath], {
stdio: ["ignore", "pipe", "pipe"],
})
if (process.status !== 0) {
throw new Error(
`Bun exited with code: ${process.status}\n${process.stderr.toString()}`,
)
}
return process.stdout.toString()
}

0 comments on commit e036d6b

Please sign in to comment.