Skip to content

Commit e152662

Browse files
authored
feat: support Bun package manager (#7723)
* Support bun * clippy
1 parent 1327991 commit e152662

6 files changed

Lines changed: 71 additions & 9 deletions

File tree

.changes/support-bun.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'tauri-cli': 'patch:feat'
3+
'@tauri-apps/cli': 'patch:feat'
4+
---
5+
6+
Support Bun package manager in CLI

tooling/cli/node/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Tauri is a polyglot and generic system that is very composable and allows engine
1919

2020
Tauri apps can have custom menus and have tray-type interfaces. They can be updated, and are managed by the user's operating system as expected. They are very small, because they use the system's webview. They do not ship a runtime, since the final binary is compiled from rust. This makes the reversing of Tauri apps not a trivial task.
2121
## This module
22-
Written in Typescript and packaged such that it can be used with `npm`, `pnpm`, and `yarn`, this library provides a node.js runner for common tasks when using Tauri, like `yarn tauri dev`. For the most part it is a wrapper around [tauri-cli](https://github.com/tauri-apps/tauri/blob/dev/tooling/cli).
22+
Written in Typescript and packaged such that it can be used with `npm`, `pnpm`, `yarn`, and `bun`, this library provides a node.js runner for common tasks when using Tauri, like `yarn tauri dev`. For the most part it is a wrapper around [tauri-cli](https://github.com/tauri-apps/tauri/blob/dev/tooling/cli).
2323

2424
To learn more about the details of how all of these pieces fit together, please consult this [ARCHITECTURE.md](https://github.com/tauri-apps/tauri/blob/dev/ARCHITECTURE.md) document.
2525

tooling/cli/node/tauri.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
const cli = require('./main')
88
const path = require('path')
99

10-
const [bin, script, ...arguments] = process.argv
10+
const [bin, script, ...args] = process.argv
1111
const binStem = path.parse(bin).name.toLowerCase()
1212

1313
// We want to make a helpful binary name for the underlying CLI helper, if we
@@ -20,7 +20,7 @@ if (bin === '@tauri-apps/cli') {
2020
}
2121
// Even if started by a package manager, the binary will be NodeJS.
2222
// Some distribution still use "nodejs" as the binary name.
23-
else if (binStem.match(/(nodejs|node)\-?([0-9]*)*$/g)) {
23+
else if (binStem.match(/(nodejs|node|bun)\-?([0-9]*)*$/g)) {
2424
const managerStem = process.env.npm_execpath
2525
? path.parse(process.env.npm_execpath).name.toLowerCase()
2626
: null
@@ -32,7 +32,7 @@ else if (binStem.match(/(nodejs|node)\-?([0-9]*)*$/g)) {
3232
manager = 'npm'
3333
break
3434

35-
// Yarn and pnpm have the same stem name as their bin.
35+
// Yarn, pnpm, and bun have the same stem name as their bin.
3636
// We assume all unknown package managers do as well.
3737
default:
3838
manager = managerStem
@@ -48,10 +48,10 @@ else if (binStem.match(/(nodejs|node)\-?([0-9]*)*$/g)) {
4848
}
4949
} else {
5050
// We don't know what started it, assume it's already stripped.
51-
arguments.unshift(bin)
51+
args.unshift(bin)
5252
}
5353

54-
cli.run(arguments, binName).catch((err) => {
54+
cli.run(args, binName).catch((err) => {
5555
cli.logError(err.message)
5656
process.exit(1)
5757
})

tooling/cli/src/completions.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use log::info;
1010

1111
use std::{fs::write, path::PathBuf};
1212

13-
const PKG_MANAGERS: &[&str] = &["cargo", "pnpm", "npm", "yarn"];
13+
const PKG_MANAGERS: &[&str] = &["cargo", "pnpm", "npm", "yarn", "bun"];
1414

1515
#[derive(Debug, Clone, Parser)]
1616
#[clap(about = "Shell completions")]
@@ -25,7 +25,7 @@ pub struct Options {
2525

2626
fn completions_for(shell: Shell, manager: &'static str, cmd: Command) -> Vec<u8> {
2727
let tauri = cmd.name("tauri");
28-
let mut command = if manager == "npm" {
28+
let mut command = if manager == "npm" || manager == "bun" {
2929
Command::new(manager)
3030
.bin_name(manager)
3131
.subcommand(Command::new("run").subcommand(tauri))
@@ -47,6 +47,8 @@ fn get_completions(shell: Shell, cmd: Command) -> Result<String> {
4747
"complete -F _cargo -o bashdefault -o default {} tauri\n",
4848
if manager == &"npm" {
4949
"npm run"
50+
} else if manager == &"bun" {
51+
"bun run"
5052
} else {
5153
manager
5254
}

tooling/cli/src/info/env_nodejs.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,28 @@ pub fn items(metadata: &VersionMetadata) -> (Vec<SectionItem>, Option<String>) {
8888
|| None,
8989
false,
9090
),
91+
SectionItem::new(
92+
|| {
93+
cross_command("bun")
94+
.arg("-v")
95+
.output()
96+
.map(|o| {
97+
if o.status.success() {
98+
let v = String::from_utf8_lossy(o.stdout.as_slice()).to_string();
99+
Some((
100+
format!("bun: {}", v.split('\n').next().unwrap()),
101+
Status::Neutral,
102+
))
103+
} else {
104+
None
105+
}
106+
})
107+
.ok()
108+
.unwrap_or_default()
109+
},
110+
|| None,
111+
false,
112+
),
91113
SectionItem::new(
92114
move || {
93115
yarn_version_c

tooling/cli/src/info/packages_nodejs.rs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ enum PackageManager {
2020
Pnpm,
2121
Yarn,
2222
YarnBerry,
23+
Bun,
2324
}
2425

2526
impl Display for PackageManager {
@@ -32,6 +33,7 @@ impl Display for PackageManager {
3233
PackageManager::Pnpm => "pnpm",
3334
PackageManager::Yarn => "yarn",
3435
PackageManager::YarnBerry => "yarn berry",
36+
PackageManager::Bun => "bun",
3537
}
3638
)
3739
}
@@ -94,6 +96,18 @@ fn npm_latest_version(pm: &PackageManager, name: &str) -> crate::Result<Option<S
9496
Ok(None)
9597
}
9698
}
99+
// Bun doesn't support `info` command
100+
PackageManager::Bun => {
101+
let mut cmd = cross_command("npm");
102+
103+
let output = cmd.arg("show").arg(name).arg("version").output()?;
104+
if output.status.success() {
105+
let stdout = String::from_utf8_lossy(&output.stdout);
106+
Ok(Some(stdout.replace('\n', "")))
107+
} else {
108+
Ok(None)
109+
}
110+
}
97111
}
98112
}
99113

@@ -139,6 +153,16 @@ fn npm_package_version<P: AsRef<Path>>(
139153
.output()?,
140154
None,
141155
),
156+
// Bun doesn't support `list` command
157+
PackageManager::Bun => (
158+
cross_command("npm")
159+
.arg("list")
160+
.arg(name)
161+
.args(["version", "--depth", "0"])
162+
.current_dir(app_dir)
163+
.output()?,
164+
None,
165+
),
142166
};
143167
if output.status.success() {
144168
let stdout = String::from_utf8_lossy(&output.stdout);
@@ -158,6 +182,7 @@ fn get_package_manager<T: AsRef<str>>(app_dir_entries: &[T]) -> PackageManager {
158182
let mut use_npm = false;
159183
let mut use_pnpm = false;
160184
let mut use_yarn = false;
185+
let mut use_bun = false;
161186

162187
for name in app_dir_entries {
163188
if name.as_ref() == "package-lock.json" {
@@ -166,10 +191,12 @@ fn get_package_manager<T: AsRef<str>>(app_dir_entries: &[T]) -> PackageManager {
166191
use_pnpm = true;
167192
} else if name.as_ref() == "yarn.lock" {
168193
use_yarn = true;
194+
} else if name.as_ref() == "bun.lockb" {
195+
use_bun = true;
169196
}
170197
}
171198

172-
if !use_npm && !use_pnpm && !use_yarn {
199+
if !use_npm && !use_pnpm && !use_yarn && !use_bun {
173200
println!(
174201
"{}: no lock files found, defaulting to npm",
175202
"WARNING".yellow()
@@ -188,6 +215,9 @@ fn get_package_manager<T: AsRef<str>>(app_dir_entries: &[T]) -> PackageManager {
188215
if use_yarn {
189216
found.push(PackageManager::Yarn);
190217
}
218+
if use_bun {
219+
found.push(PackageManager::Bun);
220+
}
191221

192222
if found.len() > 1 {
193223
let pkg_manger = found[0];
@@ -204,6 +234,8 @@ fn get_package_manager<T: AsRef<str>>(app_dir_entries: &[T]) -> PackageManager {
204234
PackageManager::Npm
205235
} else if use_pnpm {
206236
PackageManager::Pnpm
237+
} else if use_bun {
238+
PackageManager::Bun
207239
} else {
208240
PackageManager::Yarn
209241
}

0 commit comments

Comments
 (0)