mirror of
https://github.com/tauri-apps/tauri.git
synced 2026-04-01 10:01:07 +02:00
feat(cli): add deno support (#11304)
* feat(cli): add deno support ref: https://github.com/denoland/deno/issues/20738 * Update packages_nodejs.rs * typo --------- Co-authored-by: Lucas Nogueira <lucas@tauri.app>
This commit is contained in:
6
.changes/deno.md
Normal file
6
.changes/deno.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"tauri-cli": "patch:feat"
|
||||
"@tauri-apps/cli": "patch:feat"
|
||||
---
|
||||
|
||||
Add Deno support in tauri-cli operations.
|
||||
@@ -93,9 +93,10 @@ pub fn run(options: Options) -> Result<()> {
|
||||
}));
|
||||
|
||||
let npm_spec = match (npm_version_req, options.tag, options.rev, options.branch) {
|
||||
(Some(version), _, _, _) => {
|
||||
format!("{npm_name}@{version}")
|
||||
}
|
||||
(Some(version_req), _, _, _) => match manager {
|
||||
PackageManager::Deno => format!("npm:{npm_name}@{version_req}"),
|
||||
_ => format!("{npm_name}@{version_req}"),
|
||||
},
|
||||
(None, Some(tag), None, None) => {
|
||||
format!("tauri-apps/tauri-plugin-{plugin}#{tag}")
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ use clap_complete::{generate, Shell};
|
||||
|
||||
use std::{fs::write, path::PathBuf};
|
||||
|
||||
const PKG_MANAGERS: &[&str] = &["cargo", "pnpm", "npm", "yarn", "bun"];
|
||||
const PKG_MANAGERS: &[&str] = &["cargo", "pnpm", "npm", "yarn", "bun", "deno"];
|
||||
|
||||
#[derive(Debug, Clone, Parser)]
|
||||
#[clap(about = "Generate Tauri CLI shell completions for Bash, Zsh, PowerShell or Fish")]
|
||||
@@ -28,6 +28,10 @@ fn completions_for(shell: Shell, manager: &'static str, cmd: Command) -> Vec<u8>
|
||||
Command::new(manager)
|
||||
.bin_name(manager)
|
||||
.subcommand(Command::new("run").subcommand(tauri))
|
||||
} else if manager == "deno" {
|
||||
Command::new(manager)
|
||||
.bin_name(manager)
|
||||
.subcommand(Command::new("task").subcommand(tauri))
|
||||
} else {
|
||||
Command::new(manager).bin_name(manager).subcommand(tauri)
|
||||
};
|
||||
@@ -41,13 +45,15 @@ fn get_completions(shell: Shell, cmd: Command) -> Result<String> {
|
||||
let completions = if shell == Shell::Bash {
|
||||
let mut completions =
|
||||
String::from_utf8_lossy(&completions_for(shell, "cargo", cmd)).into_owned();
|
||||
for manager in PKG_MANAGERS {
|
||||
for &manager in PKG_MANAGERS {
|
||||
completions.push_str(&format!(
|
||||
"complete -F _cargo -o bashdefault -o default {} tauri\n",
|
||||
if manager == &"npm" {
|
||||
if manager == "npm" {
|
||||
"npm run"
|
||||
} else if manager == &"bun" {
|
||||
} else if manager == "bun" {
|
||||
"bun run"
|
||||
} else if manager == "deno" {
|
||||
"deno task"
|
||||
} else {
|
||||
manager
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ pub enum PackageManager {
|
||||
Yarn,
|
||||
YarnBerry,
|
||||
Bun,
|
||||
Deno,
|
||||
}
|
||||
|
||||
impl Display for PackageManager {
|
||||
@@ -27,6 +28,7 @@ impl Display for PackageManager {
|
||||
PackageManager::Yarn => "yarn",
|
||||
PackageManager::YarnBerry => "yarn berry",
|
||||
PackageManager::Bun => "bun",
|
||||
PackageManager::Deno => "deno",
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -34,46 +36,26 @@ impl Display for PackageManager {
|
||||
|
||||
impl PackageManager {
|
||||
pub fn from_project<P: AsRef<Path>>(path: P) -> Vec<Self> {
|
||||
let mut use_npm = false;
|
||||
let mut use_pnpm = false;
|
||||
let mut use_yarn = false;
|
||||
let mut use_bun = false;
|
||||
let mut found = Vec::new();
|
||||
|
||||
if let Ok(entries) = std::fs::read_dir(path) {
|
||||
for entry in entries.flatten() {
|
||||
let path = entry.path();
|
||||
let name = path.file_name().unwrap().to_string_lossy();
|
||||
if name.as_ref() == "package-lock.json" {
|
||||
use_npm = true;
|
||||
found.push(PackageManager::Npm);
|
||||
} else if name.as_ref() == "pnpm-lock.yaml" {
|
||||
use_pnpm = true;
|
||||
found.push(PackageManager::Pnpm);
|
||||
} else if name.as_ref() == "yarn.lock" {
|
||||
use_yarn = true;
|
||||
found.push(PackageManager::Yarn);
|
||||
} else if name.as_ref() == "bun.lockb" {
|
||||
use_bun = true;
|
||||
found.push(PackageManager::Bun);
|
||||
} else if name.as_ref() == "deno.lock" {
|
||||
found.push(PackageManager::Deno);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !use_npm && !use_pnpm && !use_yarn && !use_bun {
|
||||
return Vec::new();
|
||||
}
|
||||
|
||||
let mut found = Vec::new();
|
||||
|
||||
if use_npm {
|
||||
found.push(PackageManager::Npm);
|
||||
}
|
||||
if use_pnpm {
|
||||
found.push(PackageManager::Pnpm);
|
||||
}
|
||||
if use_yarn {
|
||||
found.push(PackageManager::Yarn);
|
||||
}
|
||||
if use_bun {
|
||||
found.push(PackageManager::Bun);
|
||||
}
|
||||
|
||||
found
|
||||
}
|
||||
|
||||
@@ -84,6 +66,7 @@ impl PackageManager {
|
||||
PackageManager::Npm => cross_command("npm"),
|
||||
PackageManager::Pnpm => cross_command("pnpm"),
|
||||
PackageManager::Bun => cross_command("bun"),
|
||||
PackageManager::Deno => cross_command("deno"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,15 +158,6 @@ impl PackageManager {
|
||||
.output()?,
|
||||
Some(regex::Regex::new("\"Version\":\"([\\da-zA-Z\\-\\.]+)\"").unwrap()),
|
||||
),
|
||||
PackageManager::Npm => (
|
||||
cross_command("npm")
|
||||
.arg("list")
|
||||
.arg(name)
|
||||
.args(["version", "--depth", "0"])
|
||||
.current_dir(app_dir)
|
||||
.output()?,
|
||||
None,
|
||||
),
|
||||
PackageManager::Pnpm => (
|
||||
cross_command("pnpm")
|
||||
.arg("list")
|
||||
@@ -193,8 +167,8 @@ impl PackageManager {
|
||||
.output()?,
|
||||
None,
|
||||
),
|
||||
// Bun doesn't support `list` command
|
||||
PackageManager::Bun => (
|
||||
// Bun and Deno don't support `list` command
|
||||
PackageManager::Npm | PackageManager::Bun | PackageManager::Deno => (
|
||||
cross_command("npm")
|
||||
.arg("list")
|
||||
.arg(name)
|
||||
|
||||
@@ -62,17 +62,10 @@ pub fn items(metadata: &VersionMetadata) -> Vec<SectionItem> {
|
||||
.ok()
|
||||
.unwrap_or_default()
|
||||
}),
|
||||
SectionItem::new().action(|| {
|
||||
manager_version("pnpm")
|
||||
.map(|v| format!("pnpm: {}", v))
|
||||
.into()
|
||||
}),
|
||||
SectionItem::new().action(|| {
|
||||
manager_version("yarn")
|
||||
.map(|v| format!("yarn: {}", v))
|
||||
.into()
|
||||
}),
|
||||
SectionItem::new().action(|| manager_version("npm").map(|v| format!("npm: {}", v)).into()),
|
||||
SectionItem::new().action(|| manager_version("bun").map(|v| format!("bun: {}", v)).into()),
|
||||
SectionItem::new().action(|| manager_version("pnpm").map(|v| format!("pnpm: {v}")).into()),
|
||||
SectionItem::new().action(|| manager_version("yarn").map(|v| format!("yarn: {v}")).into()),
|
||||
SectionItem::new().action(|| manager_version("npm").map(|v| format!("npm: {v}")).into()),
|
||||
SectionItem::new().action(|| manager_version("bun").map(|v| format!("bun: {v}")).into()),
|
||||
SectionItem::new().action(|| manager_version("deno").map(|v| format!("deno: {v}")).into()),
|
||||
]
|
||||
}
|
||||
|
||||
@@ -50,7 +50,8 @@ pub fn npm_latest_version(pm: &PackageManager, name: &str) -> crate::Result<Opti
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
PackageManager::Npm => {
|
||||
// Bun and Deno don't support show command
|
||||
PackageManager::Npm | PackageManager::Deno | PackageManager::Bun => {
|
||||
let mut cmd = cross_command("npm");
|
||||
|
||||
let output = cmd.arg("show").arg(name).arg("version").output()?;
|
||||
@@ -72,41 +73,13 @@ pub fn npm_latest_version(pm: &PackageManager, name: &str) -> crate::Result<Opti
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn package_manager(app_dir: &PathBuf) -> PackageManager {
|
||||
let mut use_npm = false;
|
||||
let mut use_pnpm = false;
|
||||
let mut use_yarn = false;
|
||||
let mut use_bun = false;
|
||||
let found = PackageManager::from_project(app_dir);
|
||||
|
||||
for entry in std::fs::read_dir(app_dir)
|
||||
.unwrap()
|
||||
.map(|e| e.unwrap().file_name().to_string_lossy().into_owned())
|
||||
{
|
||||
match entry.as_str() {
|
||||
"pnpm-lock.yaml" => use_pnpm = true,
|
||||
"package-lock.json" => use_npm = true,
|
||||
"yarn.lock" => use_yarn = true,
|
||||
"bun.lockb" => use_bun = true,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
if !use_npm && !use_pnpm && !use_yarn && !use_bun {
|
||||
if found.is_empty() {
|
||||
println!(
|
||||
"{}: no lock files found, defaulting to npm",
|
||||
"WARNING".yellow()
|
||||
@@ -114,45 +87,25 @@ pub fn package_manager(app_dir: &PathBuf) -> PackageManager {
|
||||
return PackageManager::Npm;
|
||||
}
|
||||
|
||||
let mut found = Vec::new();
|
||||
|
||||
if use_npm {
|
||||
found.push(PackageManager::Npm);
|
||||
}
|
||||
if use_pnpm {
|
||||
found.push(PackageManager::Pnpm);
|
||||
}
|
||||
if use_yarn {
|
||||
found.push(PackageManager::Yarn);
|
||||
}
|
||||
if use_bun {
|
||||
found.push(PackageManager::Bun);
|
||||
}
|
||||
let pkg_manager = found[0];
|
||||
|
||||
if found.len() > 1 {
|
||||
let pkg_manger = found[0];
|
||||
println!(
|
||||
"{}: Only one package manager should be used, but found {}.\n Please remove unused package manager lock files, will use {} for now!",
|
||||
"WARNING".yellow(),
|
||||
found.iter().map(ToString::to_string).collect::<Vec<_>>().join(" and "),
|
||||
pkg_manger
|
||||
pkg_manager
|
||||
);
|
||||
return pkg_manger;
|
||||
}
|
||||
|
||||
if use_npm {
|
||||
PackageManager::Npm
|
||||
} else if use_pnpm {
|
||||
PackageManager::Pnpm
|
||||
} else if use_bun {
|
||||
PackageManager::Bun
|
||||
} else if manager_version("yarn")
|
||||
.map(|v| v.chars().next().map(|c| c > '1').unwrap_or_default())
|
||||
.unwrap_or(false)
|
||||
if pkg_manager == PackageManager::Yarn
|
||||
&& manager_version("yarn")
|
||||
.map(|v| v.chars().next().map(|c| c > '1').unwrap_or_default())
|
||||
.unwrap_or(false)
|
||||
{
|
||||
PackageManager::YarnBerry
|
||||
} else {
|
||||
PackageManager::Yarn
|
||||
pkg_manager
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -171,6 +171,7 @@ fn default_dev_command(pm: PackageManager) -> &'static str {
|
||||
PackageManager::Npm => "npm run dev",
|
||||
PackageManager::Pnpm => "pnpm dev",
|
||||
PackageManager::Bun => "bun dev",
|
||||
PackageManager::Deno => "deno task dev",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,6 +182,7 @@ fn default_build_command(pm: PackageManager) -> &'static str {
|
||||
PackageManager::Npm => "npm run build",
|
||||
PackageManager::Pnpm => "pnpm build",
|
||||
PackageManager::Bun => "bun build",
|
||||
PackageManager::Deno => "deno task build",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -90,6 +90,9 @@ pub fn exec(
|
||||
|
||||
return (binary, build_args);
|
||||
}
|
||||
} else if bin_stem == "deno" {
|
||||
build_args.insert(0, "task");
|
||||
return (std::ffi::OsString::from("deno"), build_args);
|
||||
} else if !cfg!(debug_assertions) && bin_stem == "cargo-tauri" {
|
||||
return (std::ffi::OsString::from("cargo"), build_args);
|
||||
}
|
||||
|
||||
@@ -14,9 +14,9 @@ const binStem = path.parse(bin).name.toLowerCase()
|
||||
// can successfully detect what command likely started the execution.
|
||||
let binName
|
||||
|
||||
// deno run -A --unstable --node-modules-dir npm:@tauri-apps/cli
|
||||
if (bin === '@tauri-apps/cli') {
|
||||
binName = '@tauri-apps/cli'
|
||||
// deno run -A npm:@tauri-apps/cli or deno task tauri
|
||||
if (globalThis.navigator?.userAgent?.includes('Deno')) {
|
||||
binName = bin
|
||||
}
|
||||
// Even if started by a package manager, the binary will be NodeJS.
|
||||
// Some distribution still use "nodejs" as the binary name.
|
||||
|
||||
Reference in New Issue
Block a user