mirror of
https://github.com/tauri-apps/tauri.git
synced 2026-04-03 10:11:15 +02:00
6
.changes/support-bun.md
Normal file
6
.changes/support-bun.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'tauri-cli': 'patch:feat'
|
||||
'@tauri-apps/cli': 'patch:feat'
|
||||
---
|
||||
|
||||
Support Bun package manager in CLI
|
||||
@@ -19,7 +19,7 @@ Tauri is a polyglot and generic system that is very composable and allows engine
|
||||
|
||||
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.
|
||||
## This module
|
||||
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).
|
||||
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).
|
||||
|
||||
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.
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
const cli = require('./main')
|
||||
const path = require('path')
|
||||
|
||||
const [bin, script, ...arguments] = process.argv
|
||||
const [bin, script, ...args] = process.argv
|
||||
const binStem = path.parse(bin).name.toLowerCase()
|
||||
|
||||
// We want to make a helpful binary name for the underlying CLI helper, if we
|
||||
@@ -20,7 +20,7 @@ if (bin === '@tauri-apps/cli') {
|
||||
}
|
||||
// Even if started by a package manager, the binary will be NodeJS.
|
||||
// Some distribution still use "nodejs" as the binary name.
|
||||
else if (binStem.match(/(nodejs|node)\-?([0-9]*)*$/g)) {
|
||||
else if (binStem.match(/(nodejs|node|bun)\-?([0-9]*)*$/g)) {
|
||||
const managerStem = process.env.npm_execpath
|
||||
? path.parse(process.env.npm_execpath).name.toLowerCase()
|
||||
: null
|
||||
@@ -32,7 +32,7 @@ else if (binStem.match(/(nodejs|node)\-?([0-9]*)*$/g)) {
|
||||
manager = 'npm'
|
||||
break
|
||||
|
||||
// Yarn and pnpm have the same stem name as their bin.
|
||||
// Yarn, pnpm, and bun have the same stem name as their bin.
|
||||
// We assume all unknown package managers do as well.
|
||||
default:
|
||||
manager = managerStem
|
||||
@@ -48,10 +48,10 @@ else if (binStem.match(/(nodejs|node)\-?([0-9]*)*$/g)) {
|
||||
}
|
||||
} else {
|
||||
// We don't know what started it, assume it's already stripped.
|
||||
arguments.unshift(bin)
|
||||
args.unshift(bin)
|
||||
}
|
||||
|
||||
cli.run(arguments, binName).catch((err) => {
|
||||
cli.run(args, binName).catch((err) => {
|
||||
cli.logError(err.message)
|
||||
process.exit(1)
|
||||
})
|
||||
|
||||
@@ -10,7 +10,7 @@ use log::info;
|
||||
|
||||
use std::{fs::write, path::PathBuf};
|
||||
|
||||
const PKG_MANAGERS: &[&str] = &["cargo", "pnpm", "npm", "yarn"];
|
||||
const PKG_MANAGERS: &[&str] = &["cargo", "pnpm", "npm", "yarn", "bun"];
|
||||
|
||||
#[derive(Debug, Clone, Parser)]
|
||||
#[clap(about = "Shell completions")]
|
||||
@@ -25,7 +25,7 @@ pub struct Options {
|
||||
|
||||
fn completions_for(shell: Shell, manager: &'static str, cmd: Command) -> Vec<u8> {
|
||||
let tauri = cmd.name("tauri");
|
||||
let mut command = if manager == "npm" {
|
||||
let mut command = if manager == "npm" || manager == "bun" {
|
||||
Command::new(manager)
|
||||
.bin_name(manager)
|
||||
.subcommand(Command::new("run").subcommand(tauri))
|
||||
@@ -47,6 +47,8 @@ fn get_completions(shell: Shell, cmd: Command) -> Result<String> {
|
||||
"complete -F _cargo -o bashdefault -o default {} tauri\n",
|
||||
if manager == &"npm" {
|
||||
"npm run"
|
||||
} else if manager == &"bun" {
|
||||
"bun run"
|
||||
} else {
|
||||
manager
|
||||
}
|
||||
|
||||
@@ -88,6 +88,28 @@ pub fn items(metadata: &VersionMetadata) -> (Vec<SectionItem>, Option<String>) {
|
||||
|| None,
|
||||
false,
|
||||
),
|
||||
SectionItem::new(
|
||||
|| {
|
||||
cross_command("bun")
|
||||
.arg("-v")
|
||||
.output()
|
||||
.map(|o| {
|
||||
if o.status.success() {
|
||||
let v = String::from_utf8_lossy(o.stdout.as_slice()).to_string();
|
||||
Some((
|
||||
format!("bun: {}", v.split('\n').next().unwrap()),
|
||||
Status::Neutral,
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.ok()
|
||||
.unwrap_or_default()
|
||||
},
|
||||
|| None,
|
||||
false,
|
||||
),
|
||||
SectionItem::new(
|
||||
move || {
|
||||
yarn_version_c
|
||||
|
||||
@@ -20,6 +20,7 @@ enum PackageManager {
|
||||
Pnpm,
|
||||
Yarn,
|
||||
YarnBerry,
|
||||
Bun,
|
||||
}
|
||||
|
||||
impl Display for PackageManager {
|
||||
@@ -32,6 +33,7 @@ impl Display for PackageManager {
|
||||
PackageManager::Pnpm => "pnpm",
|
||||
PackageManager::Yarn => "yarn",
|
||||
PackageManager::YarnBerry => "yarn berry",
|
||||
PackageManager::Bun => "bun",
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -94,6 +96,18 @@ fn npm_latest_version(pm: &PackageManager, name: &str) -> crate::Result<Option<S
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
// Bun doesn't support `info` command
|
||||
PackageManager::Bun => {
|
||||
let mut cmd = cross_command("npm");
|
||||
|
||||
let output = cmd.arg("show").arg(name).arg("version").output()?;
|
||||
if output.status.success() {
|
||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||
Ok(Some(stdout.replace('\n', "")))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,6 +153,16 @@ fn npm_package_version<P: AsRef<Path>>(
|
||||
.output()?,
|
||||
None,
|
||||
),
|
||||
// Bun doesn't support `list` command
|
||||
PackageManager::Bun => (
|
||||
cross_command("npm")
|
||||
.arg("list")
|
||||
.arg(name)
|
||||
.args(["version", "--depth", "0"])
|
||||
.current_dir(app_dir)
|
||||
.output()?,
|
||||
None,
|
||||
),
|
||||
};
|
||||
if output.status.success() {
|
||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||
@@ -158,6 +182,7 @@ fn get_package_manager<T: AsRef<str>>(app_dir_entries: &[T]) -> PackageManager {
|
||||
let mut use_npm = false;
|
||||
let mut use_pnpm = false;
|
||||
let mut use_yarn = false;
|
||||
let mut use_bun = false;
|
||||
|
||||
for name in app_dir_entries {
|
||||
if name.as_ref() == "package-lock.json" {
|
||||
@@ -166,10 +191,12 @@ fn get_package_manager<T: AsRef<str>>(app_dir_entries: &[T]) -> PackageManager {
|
||||
use_pnpm = true;
|
||||
} else if name.as_ref() == "yarn.lock" {
|
||||
use_yarn = true;
|
||||
} else if name.as_ref() == "bun.lockb" {
|
||||
use_bun = true;
|
||||
}
|
||||
}
|
||||
|
||||
if !use_npm && !use_pnpm && !use_yarn {
|
||||
if !use_npm && !use_pnpm && !use_yarn && !use_bun {
|
||||
println!(
|
||||
"{}: no lock files found, defaulting to npm",
|
||||
"WARNING".yellow()
|
||||
@@ -188,6 +215,9 @@ fn get_package_manager<T: AsRef<str>>(app_dir_entries: &[T]) -> PackageManager {
|
||||
if use_yarn {
|
||||
found.push(PackageManager::Yarn);
|
||||
}
|
||||
if use_bun {
|
||||
found.push(PackageManager::Bun);
|
||||
}
|
||||
|
||||
if found.len() > 1 {
|
||||
let pkg_manger = found[0];
|
||||
@@ -204,6 +234,8 @@ fn get_package_manager<T: AsRef<str>>(app_dir_entries: &[T]) -> PackageManager {
|
||||
PackageManager::Npm
|
||||
} else if use_pnpm {
|
||||
PackageManager::Pnpm
|
||||
} else if use_bun {
|
||||
PackageManager::Bun
|
||||
} else {
|
||||
PackageManager::Yarn
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user