Skip to content

Commit 62cefab

Browse files
committed
Bun support.
1 parent 0e6957c commit 62cefab

File tree

2 files changed

+51
-12
lines changed

2 files changed

+51
-12
lines changed

npm/resolve.go

+43-11
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ func resolvePackageInContext(mgr string, cwd string, packageName string, global
107107
}
108108
}
109109

110+
if mgr == "bun" {
111+
return nil, fmt.Errorf("bun does not support package resolution")
112+
}
113+
110114
stdout := bytes.NewBuffer(nil)
111115
var cmd *exec.Cmd
112116
if global {
@@ -241,6 +245,17 @@ func (p *Package) ResolveImport(mgr string, imp string) (path string, err error)
241245
func (pkg *Package) TryEscapeScript(mgr string, scriptName string) (executable string, arguments []string) {
242246
script := pkg.Scripts[scriptName]
243247

248+
// Apply fallbacks
249+
engine := "node"
250+
if mgr == "bun" {
251+
engine = "bun"
252+
executable = "bun"
253+
arguments = []string{"run", scriptName}
254+
} else {
255+
executable = mgr
256+
arguments = []string{"run", "-s", scriptName}
257+
}
258+
244259
// If known script with no shell-like characters:
245260
if script != "" && !strings.Contains(script, "&") && !strings.Contains(script, "|") && !strings.Contains(script, ">") {
246261
// If we successfully split the script:
@@ -249,39 +264,56 @@ func (pkg *Package) TryEscapeScript(mgr string, scriptName string) (executable s
249264
cmd := parts[0]
250265
var importedScript string
251266
var executedScript string
267+
252268
switch cmd {
269+
case "node", "nodejs", "deno", "bun":
270+
// enforce engine
271+
return engine, parts[1:]
253272
case "tsx":
254273
importedScript = "tsx"
274+
if mgr == "bun" {
275+
return // Not necessary as bun can run TypeScript directly
276+
}
255277
case "tsc":
256-
importedScript = "typescript"
278+
executedScript = "typescript"
257279
case "ts-node":
258280
importedScript = "ts-node"
281+
if mgr == "bun" {
282+
return // Not necessary as bun can run TypeScript directly
283+
}
259284
case "ts-node-esm":
260285
importedScript = "ts-node/esm"
286+
if mgr == "bun" {
287+
return // Not necessary as bun can run TypeScript directly
288+
}
261289
case "vite":
262290
executedScript = "vite/$bin/vite"
263291
}
292+
264293
// If we have a known script, try to run it with node
265294
if importedScript != "" || executedScript != "" {
266-
_, err := exec.LookPath("node")
295+
// Bun does not support --import
296+
if importedScript != "" {
297+
return
298+
}
299+
_, err := exec.LookPath(engine)
267300
if err != nil {
268-
return mgr, []string{"run", "-s", scriptName}
301+
return
269302
}
270303

271-
scriptName = cmp.Or(executedScript, importedScript)
272-
if p, err := pkg.ResolveImport(mgr, scriptName); err == nil {
304+
resolvedScriptName := cmp.Or(executedScript, importedScript)
305+
if p, err := pkg.ResolveImport(mgr, resolvedScriptName); err == nil {
273306
var args []string
274307
if importedScript != "" {
275-
args = []string{
276-
"--experimental-specifier-resolution=node",
277-
"--import",
278-
"file://" + p,
308+
if engine == "node" {
309+
args = []string{"--experimental-specifier-resolution=node"}
279310
}
311+
args = append(args, "--import", "file://"+p)
280312
} else {
281313
args = []string{p}
282314
}
283315
args = append(args, parts[1:]...)
284-
return "node", args
316+
return engine, args
285317
}
286318
}
287319

@@ -293,7 +325,7 @@ func (pkg *Package) TryEscapeScript(mgr string, scriptName string) (executable s
293325
}
294326

295327
// Fallback to running the script with the package manager
296-
return mgr, []string{"run", "-s", scriptName}
328+
return
297329
}
298330

299331
func ResolveGlobalPackage(mgr string, pkg string) (p *Package, err error) {

service/svc_wrappers.go

+8-1
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ func (app *NpmApp) Prepare(opt Options) error {
8484
app.PackageManager = "pnpm"
8585
} else if _, err := exec.LookPath("yarn"); err == nil {
8686
app.PackageManager = "yarn"
87+
} else if _, err := exec.LookPath("bun"); err == nil {
88+
app.PackageManager = "bun"
8789
}
8890
}
8991

@@ -117,7 +119,11 @@ func (app *NpmApp) Prepare(opt Options) error {
117119
app.Run = run
118120
}
119121
if !app.NoInstall {
120-
app.Build = append(app.Build, NewCommand(app.PackageManager, "install", "--production=false"))
122+
if app.PackageManager == "bun" {
123+
app.Build = append(app.Build, NewCommand(app.PackageManager, "install"))
124+
} else {
125+
app.Build = append(app.Build, NewCommand(app.PackageManager, "install", "--production=false"))
126+
}
121127
}
122128
if app.BuildScript != "none" {
123129
cmd, args := pkg.TryEscapeScript(app.PackageManager, app.BuildScript)
@@ -255,6 +261,7 @@ func init() {
255261
Registry.Define("Npm", func() any { return &NpmApp{} })
256262
Registry.Define("Pnpm", func() any { return &NpmApp{PackageManager: "pnpm"} })
257263
Registry.Define("Yarn", func() any { return &NpmApp{PackageManager: "yarn"} })
264+
Registry.Define("Bun", func() any { return &NpmApp{PackageManager: "bun"} })
258265
Registry.Define("Go", func() any { return &GoApp{} })
259266
Registry.Define("Py", func() any { return &PyApp{} })
260267
Registry.Define("Flask", func() any { return &FlaskApp{} })

0 commit comments

Comments
 (0)