mirror of
https://github.com/tauri-apps/tauri.git
synced 2024-08-16 11:20:28 +03:00
feat(cli/add): add default permission to capabilities (#9124)
* feat(cli/add): add default permission to capabilities also cleanup `tauri add` command * license headers & clippy * print permission name * do not error out if default permission is not set --------- Co-authored-by: Lucas Nogueira <lucas@tauri.app>
This commit is contained in:
parent
acdd76833d
commit
7213b9e472
6
.changes/acl-default-permission-verification.md
Normal file
6
.changes/acl-default-permission-verification.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
"tauri-build": patch:enhance
|
||||
"tauri-utils": patch:enhance
|
||||
---
|
||||
|
||||
Fallback to an empty permission set if the plugin did not define its `default` permissions.
|
6
.changes/tauri-cli-add-default-perm.md
Normal file
6
.changes/tauri-cli-add-default-perm.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
'tauri-cli': 'patch:feat'
|
||||
'@tauri-apps/cli': 'patch:feat'
|
||||
---
|
||||
|
||||
Add default permission for a plugin to capabilities when using `tauri add <plugin>`.
|
@ -131,13 +131,14 @@ fn capabilities_schema(acl_manifests: &BTreeMap<String, Manifest>) -> RootSchema
|
||||
permission_schemas.push(schema_from(key, set_id, Some(&set.description)));
|
||||
}
|
||||
|
||||
if let Some(default) = &manifest.default_permission {
|
||||
permission_schemas.push(schema_from(
|
||||
key,
|
||||
"default",
|
||||
Some(default.description.as_ref()),
|
||||
));
|
||||
}
|
||||
permission_schemas.push(schema_from(
|
||||
key,
|
||||
"default",
|
||||
manifest
|
||||
.default_permission
|
||||
.as_ref()
|
||||
.map(|d| d.description.as_ref()),
|
||||
));
|
||||
|
||||
for (permission_id, permission) in &manifest.permissions {
|
||||
permission_schemas.push(schema_from(
|
||||
@ -198,9 +199,14 @@ fn capabilities_schema(acl_manifests: &BTreeMap<String, Manifest>) -> RootSchema
|
||||
};
|
||||
|
||||
let mut permission_schemas = Vec::new();
|
||||
if let Some(default) = &manifest.default_permission {
|
||||
permission_schemas.push(schema_from(key, "default", Some(&default.description)));
|
||||
}
|
||||
permission_schemas.push(schema_from(
|
||||
key,
|
||||
"default",
|
||||
manifest
|
||||
.default_permission
|
||||
.as_ref()
|
||||
.map(|d| d.description.as_ref()),
|
||||
));
|
||||
for set in manifest.permission_sets.values() {
|
||||
permission_schemas.push(schema_from(key, &set.identifier, Some(&set.description)));
|
||||
}
|
||||
@ -471,12 +477,10 @@ pub fn validate_capabilities(
|
||||
let permission_exists = acl_manifests
|
||||
.get(key)
|
||||
.map(|manifest| {
|
||||
if permission_name == "default" {
|
||||
manifest.default_permission.is_some()
|
||||
} else {
|
||||
manifest.permissions.contains_key(permission_name)
|
||||
|| manifest.permission_sets.contains_key(permission_name)
|
||||
}
|
||||
// the default permission is always treated as valid, the CLI automatically adds it on the `tauri add` command
|
||||
permission_name == "default"
|
||||
|| manifest.permissions.contains_key(permission_name)
|
||||
|| manifest.permission_sets.contains_key(permission_name)
|
||||
})
|
||||
.unwrap_or(false);
|
||||
|
||||
|
@ -367,15 +367,8 @@ fn get_permissions<'a>(
|
||||
manifest
|
||||
.default_permission
|
||||
.as_ref()
|
||||
.ok_or_else(|| Error::UnknownPermission {
|
||||
key: if key == APP_ACL_KEY {
|
||||
"app manifest".to_string()
|
||||
} else {
|
||||
key.to_string()
|
||||
},
|
||||
permission: permission_name.to_string(),
|
||||
})
|
||||
.and_then(|default| get_permission_set_permissions(manifest, default))
|
||||
.map(|default| get_permission_set_permissions(manifest, default))
|
||||
.unwrap_or_else(|| Ok(Vec::new()))
|
||||
} else if let Some(set) = manifest.permission_sets.get(permission_name) {
|
||||
get_permission_set_permissions(manifest, set)
|
||||
} else if let Some(permission) = manifest.permissions.get(permission_name) {
|
||||
|
@ -80,10 +80,10 @@ fn capability_from_path<P: AsRef<Path>>(path: P) -> Option<TomlOrJson> {
|
||||
#[derive(Debug, Parser)]
|
||||
#[clap(about = "Add a permission to capabilities")]
|
||||
pub struct Options {
|
||||
/// Permission to remove.
|
||||
identifier: String,
|
||||
/// Permission to add.
|
||||
pub identifier: String,
|
||||
/// Capability to add the permission to.
|
||||
capability: Option<String>,
|
||||
pub capability: Option<String>,
|
||||
}
|
||||
|
||||
pub fn command(options: Options) -> Result<()> {
|
||||
@ -114,7 +114,10 @@ pub fn command(options: Options) -> Result<()> {
|
||||
|
||||
let mut capabilities = if capabilities.len() > 1 {
|
||||
let selections = prompts::multiselect(
|
||||
"Choose which capabilities to add the permission to:",
|
||||
&format!(
|
||||
"Choose which capabilities to add the permission `{}` to:",
|
||||
options.identifier
|
||||
),
|
||||
capabilities
|
||||
.iter()
|
||||
.map(|(c, p)| {
|
||||
|
@ -6,7 +6,7 @@ use clap::{Parser, Subcommand};
|
||||
|
||||
use crate::Result;
|
||||
|
||||
mod add;
|
||||
pub mod add;
|
||||
mod ls;
|
||||
mod new;
|
||||
mod rm;
|
||||
|
@ -2,15 +2,15 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use anyhow::Context;
|
||||
use clap::Parser;
|
||||
use colored::Colorize;
|
||||
use regex::Regex;
|
||||
|
||||
use crate::{
|
||||
acl,
|
||||
helpers::{
|
||||
app_paths::{app_dir, tauri_dir},
|
||||
cross_command,
|
||||
cargo,
|
||||
npm::PackageManager,
|
||||
},
|
||||
Result,
|
||||
@ -18,165 +18,6 @@ use crate::{
|
||||
|
||||
use std::{collections::HashMap, process::Command};
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
#[clap(about = "Add a tauri plugin to the project")]
|
||||
pub struct Options {
|
||||
/// The plugin to add.
|
||||
pub plugin: String,
|
||||
/// Git tag to use.
|
||||
#[clap(short, long)]
|
||||
pub tag: Option<String>,
|
||||
/// Git rev to use.
|
||||
#[clap(short, long)]
|
||||
pub rev: Option<String>,
|
||||
/// Git branch to use.
|
||||
#[clap(short, long)]
|
||||
pub branch: Option<String>,
|
||||
}
|
||||
|
||||
pub fn command(options: Options) -> Result<()> {
|
||||
let plugin = options.plugin;
|
||||
let plugin_snake_case = plugin.replace('-', "_");
|
||||
let crate_name = format!("tauri-plugin-{plugin}");
|
||||
let npm_name = format!("@tauri-apps/plugin-{plugin}");
|
||||
|
||||
let mut plugins = plugins();
|
||||
let metadata = plugins.remove(plugin.as_str()).unwrap_or_default();
|
||||
|
||||
let tauri_dir = tauri_dir();
|
||||
|
||||
let mut cargo = Command::new("cargo");
|
||||
cargo.current_dir(&tauri_dir).arg("add").arg(&crate_name);
|
||||
|
||||
if options.tag.is_some() || options.rev.is_some() || options.branch.is_some() {
|
||||
cargo
|
||||
.arg("--git")
|
||||
.arg("https://github.com/tauri-apps/plugins-workspace");
|
||||
}
|
||||
|
||||
if metadata.desktop_only {
|
||||
cargo
|
||||
.arg("--target")
|
||||
.arg(r#"cfg(not(any(target_os = "android", target_os = "ios")))"#);
|
||||
}
|
||||
|
||||
let npm_spec = match (options.tag, options.rev, options.branch) {
|
||||
(Some(tag), None, None) => {
|
||||
cargo.args(["--tag", &tag]);
|
||||
format!("tauri-apps/tauri-plugin-{plugin}#{tag}")
|
||||
}
|
||||
(None, Some(rev), None) => {
|
||||
cargo.args(["--rev", &rev]);
|
||||
format!("tauri-apps/tauri-plugin-{plugin}#{rev}")
|
||||
}
|
||||
(None, None, Some(branch)) => {
|
||||
cargo.args(["--branch", &branch]);
|
||||
format!("tauri-apps/tauri-plugin-{plugin}#{branch}")
|
||||
}
|
||||
(None, None, None) => npm_name,
|
||||
_ => anyhow::bail!("Only one of --tag, --rev and --branch can be specified"),
|
||||
};
|
||||
|
||||
log::info!("Installing Cargo dependency {crate_name}...");
|
||||
let status = cargo.status().context("failed to run `cargo add`")?;
|
||||
if !status.success() {
|
||||
anyhow::bail!("Failed to install Cargo dependency");
|
||||
}
|
||||
|
||||
if !metadata.rust_only {
|
||||
if let Some(manager) = std::panic::catch_unwind(app_dir)
|
||||
.map(Some)
|
||||
.unwrap_or_default()
|
||||
.map(PackageManager::from_project)
|
||||
.and_then(|managers| managers.into_iter().next())
|
||||
{
|
||||
let mut cmd = match manager {
|
||||
PackageManager::Npm => cross_command("npm"),
|
||||
PackageManager::Pnpm => cross_command("pnpm"),
|
||||
PackageManager::Yarn => cross_command("yarn"),
|
||||
PackageManager::YarnBerry => cross_command("yarn"),
|
||||
PackageManager::Bun => cross_command("bun"),
|
||||
};
|
||||
|
||||
cmd.arg("add").arg(&npm_spec);
|
||||
|
||||
log::info!("Installing NPM dependency {npm_spec}...");
|
||||
let status = cmd
|
||||
.status()
|
||||
.with_context(|| format!("failed to run {manager}"))?;
|
||||
if !status.success() {
|
||||
anyhow::bail!("Failed to install NPM dependency");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add plugin init code to main.rs or lib.rs
|
||||
let plugin_init_fn = if plugin == "stronghold" {
|
||||
"Builder::new(|pass| todo!()).build()"
|
||||
} else if metadata.builder {
|
||||
"Builder::new().build()"
|
||||
} else {
|
||||
"init()"
|
||||
};
|
||||
let plugin_init = format!(".plugin(tauri_plugin_{plugin_snake_case}::{plugin_init_fn})");
|
||||
let re = Regex::new(r"(tauri\s*::\s*Builder\s*::\s*default\(\))(\s*)")?;
|
||||
for file in [tauri_dir.join("src/main.rs"), tauri_dir.join("src/lib.rs")] {
|
||||
let contents = std::fs::read_to_string(&file)?;
|
||||
|
||||
if contents.contains(&plugin_init) {
|
||||
log::info!(
|
||||
"Plugin initialization code already found on {}",
|
||||
file.display()
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if re.is_match(&contents) {
|
||||
let out = re.replace(&contents, format!("$1$2{plugin_init}$2"));
|
||||
|
||||
log::info!("Adding plugin to {}", file.display());
|
||||
std::fs::write(file, out.as_bytes())?;
|
||||
|
||||
// run cargo fmt
|
||||
log::info!("Running `cargo fmt`...");
|
||||
let _ = Command::new("cargo")
|
||||
.arg("fmt")
|
||||
.current_dir(&tauri_dir)
|
||||
.status();
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
let builder_code = if metadata.builder {
|
||||
format!(r#"+ .plugin(tauri_plugin_{plugin_snake_case}::Builder::new().build())"#,)
|
||||
} else {
|
||||
format!(r#"+ .plugin(tauri_plugin_{plugin_snake_case}::init())"#)
|
||||
};
|
||||
|
||||
let rust_code = format!(
|
||||
r#" {}
|
||||
{}
|
||||
{}"#,
|
||||
"tauri::Builder::default()".dimmed(),
|
||||
builder_code.normal().green(),
|
||||
r#".invoke_handler(tauri::generate_handler![])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");"#
|
||||
.dimmed(),
|
||||
);
|
||||
|
||||
log::warn!(
|
||||
"Couldn't find `{}` in `{}` or `{}`, you must enable the plugin in your Rust code manually:\n\n{}",
|
||||
"tauri::Builder".cyan(),
|
||||
"main.rs".cyan(),
|
||||
"lib.rs".cyan(),
|
||||
rust_code
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct PluginMetadata {
|
||||
desktop_only: bool,
|
||||
@ -221,3 +62,137 @@ fn plugins() -> HashMap<&'static str, PluginMetadata> {
|
||||
|
||||
plugins
|
||||
}
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
#[clap(about = "Add a tauri plugin to the project")]
|
||||
pub struct Options {
|
||||
/// The plugin to add.
|
||||
pub plugin: String,
|
||||
/// Git tag to use.
|
||||
#[clap(short, long)]
|
||||
pub tag: Option<String>,
|
||||
/// Git rev to use.
|
||||
#[clap(short, long)]
|
||||
pub rev: Option<String>,
|
||||
/// Git branch to use.
|
||||
#[clap(short, long)]
|
||||
pub branch: Option<String>,
|
||||
}
|
||||
|
||||
pub fn command(options: Options) -> Result<()> {
|
||||
let plugin = options.plugin;
|
||||
let plugin_snake_case = plugin.replace('-', "_");
|
||||
let crate_name = format!("tauri-plugin-{plugin}");
|
||||
let npm_name = format!("@tauri-apps/plugin-{plugin}");
|
||||
|
||||
let mut plugins = plugins();
|
||||
let metadata = plugins.remove(plugin.as_str()).unwrap_or_default();
|
||||
|
||||
let tauri_dir = tauri_dir();
|
||||
|
||||
cargo::install_one(cargo::CargoInstallOptions {
|
||||
name: &crate_name,
|
||||
branch: options.branch.as_deref(),
|
||||
rev: options.rev.as_deref(),
|
||||
tag: options.tag.as_deref(),
|
||||
cwd: Some(&tauri_dir),
|
||||
target: metadata
|
||||
.desktop_only
|
||||
.then_some(r#"cfg(not(any(target_os = "android", target_os = "ios")))"#),
|
||||
})?;
|
||||
|
||||
if !metadata.rust_only {
|
||||
if let Some(manager) = std::panic::catch_unwind(app_dir)
|
||||
.map(Some)
|
||||
.unwrap_or_default()
|
||||
.map(PackageManager::from_project)
|
||||
.and_then(|managers| managers.into_iter().next())
|
||||
{
|
||||
let npm_spec = match (options.tag, options.rev, options.branch) {
|
||||
(Some(tag), None, None) => {
|
||||
format!("tauri-apps/tauri-plugin-{plugin}#{tag}")
|
||||
}
|
||||
(None, Some(rev), None) => {
|
||||
format!("tauri-apps/tauri-plugin-{plugin}#{rev}")
|
||||
}
|
||||
(None, None, Some(branch)) => {
|
||||
format!("tauri-apps/tauri-plugin-{plugin}#{branch}")
|
||||
}
|
||||
(None, None, None) => npm_name,
|
||||
_ => anyhow::bail!("Only one of --tag, --rev and --branch can be specified"),
|
||||
};
|
||||
manager.install(&[npm_spec])?;
|
||||
}
|
||||
}
|
||||
|
||||
let _ = acl::permission::add::command(acl::permission::add::Options {
|
||||
identifier: format!("{plugin}:default"),
|
||||
capability: None,
|
||||
});
|
||||
|
||||
// add plugin init code to main.rs or lib.rs
|
||||
let plugin_init_fn = if plugin == "stronghold" {
|
||||
"Builder::new(|pass| todo!()).build()"
|
||||
} else if metadata.builder {
|
||||
"Builder::new().build()"
|
||||
} else {
|
||||
"init()"
|
||||
};
|
||||
let plugin_init = format!(".plugin(tauri_plugin_{plugin_snake_case}::{plugin_init_fn})");
|
||||
|
||||
let re = Regex::new(r"(tauri\s*::\s*Builder\s*::\s*default\(\))(\s*)")?;
|
||||
for file in [tauri_dir.join("src/main.rs"), tauri_dir.join("src/lib.rs")] {
|
||||
let contents = std::fs::read_to_string(&file)?;
|
||||
|
||||
if contents.contains(&plugin_init) {
|
||||
log::info!(
|
||||
"Plugin initialization code already found on {}",
|
||||
file.display()
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if re.is_match(&contents) {
|
||||
let out = re.replace(&contents, format!("$1$2{plugin_init}$2"));
|
||||
|
||||
log::info!("Adding plugin to {}", file.display());
|
||||
std::fs::write(file, out.as_bytes())?;
|
||||
|
||||
// run cargo fmt
|
||||
log::info!("Running `cargo fmt`...");
|
||||
let _ = Command::new("cargo")
|
||||
.arg("fmt")
|
||||
.current_dir(&tauri_dir)
|
||||
.status();
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
let builder_code = if metadata.builder {
|
||||
format!(r#"+ .plugin(tauri_plugin_{plugin_snake_case}::Builder::new().build())"#,)
|
||||
} else {
|
||||
format!(r#"+ .plugin(tauri_plugin_{plugin_snake_case}::init())"#)
|
||||
};
|
||||
|
||||
let rust_code = format!(
|
||||
r#" {}
|
||||
{}
|
||||
{}"#,
|
||||
"tauri::Builder::default()".dimmed(),
|
||||
builder_code.normal().green(),
|
||||
r#".invoke_handler(tauri::generate_handler![])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");"#
|
||||
.dimmed(),
|
||||
);
|
||||
|
||||
log::warn!(
|
||||
"Couldn't find `{}` in `{}` or `{}`, you must enable the plugin in your Rust code manually:\n\n{}",
|
||||
"tauri::Builder".cyan(),
|
||||
"main.rs".cyan(),
|
||||
"lib.rs".cyan(),
|
||||
rust_code
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
87
tooling/cli/src/helpers/cargo.rs
Normal file
87
tooling/cli/src/helpers/cargo.rs
Normal file
@ -0,0 +1,87 @@
|
||||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use std::{path::Path, process::Command};
|
||||
|
||||
use anyhow::Context;
|
||||
|
||||
#[derive(Debug, Default, Clone, Copy)]
|
||||
pub struct CargoInstallOptions<'a> {
|
||||
pub name: &'a str,
|
||||
pub rev: Option<&'a str>,
|
||||
pub tag: Option<&'a str>,
|
||||
pub branch: Option<&'a str>,
|
||||
pub cwd: Option<&'a std::path::Path>,
|
||||
pub target: Option<&'a str>,
|
||||
}
|
||||
|
||||
pub fn install(dependencies: &[String], cwd: Option<&Path>) -> crate::Result<()> {
|
||||
let dependencies_str = if dependencies.len() > 1 {
|
||||
"dependencies"
|
||||
} else {
|
||||
"dependency"
|
||||
};
|
||||
log::info!(
|
||||
"Installing Cargo {dependencies_str} {}...",
|
||||
dependencies
|
||||
.iter()
|
||||
.map(|d| format!("\"{d}\""))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
);
|
||||
|
||||
let mut cmd = Command::new("cargo");
|
||||
cmd.arg("add").args(dependencies);
|
||||
|
||||
if let Some(cwd) = cwd {
|
||||
cmd.current_dir(cwd);
|
||||
}
|
||||
|
||||
let status = cmd.status().with_context(|| "failed to run cargo")?;
|
||||
|
||||
if !status.success() {
|
||||
anyhow::bail!("Failed to install Cargo {dependencies_str}");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn install_one(options: CargoInstallOptions) -> crate::Result<()> {
|
||||
let mut cargo = Command::new("cargo");
|
||||
cargo.args(["add", options.name]);
|
||||
|
||||
if options.tag.is_some() || options.rev.is_some() || options.branch.is_some() {
|
||||
cargo.args(["--git", "https://github.com/tauri-apps/plugins-workspace"]);
|
||||
}
|
||||
|
||||
match (options.tag, options.rev, options.branch) {
|
||||
(Some(tag), None, None) => {
|
||||
cargo.args(["--tag", &tag]);
|
||||
}
|
||||
(None, Some(rev), None) => {
|
||||
cargo.args(["--rev", &rev]);
|
||||
}
|
||||
(None, None, Some(branch)) => {
|
||||
cargo.args(["--branch", &branch]);
|
||||
}
|
||||
(None, None, None) => {}
|
||||
_ => anyhow::bail!("Only one of --tag, --rev and --branch can be specified"),
|
||||
};
|
||||
|
||||
if let Some(target) = options.target {
|
||||
cargo.args(["--target", target]);
|
||||
}
|
||||
|
||||
if let Some(cwd) = options.cwd {
|
||||
cargo.current_dir(cwd);
|
||||
}
|
||||
|
||||
log::info!("Installing Cargo dependency \"{}\"...", options.name);
|
||||
let status = cargo.status().context("failed to run `cargo add`")?;
|
||||
if !status.success() {
|
||||
anyhow::bail!("Failed to install Cargo dependency");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
@ -3,6 +3,7 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pub mod app_paths;
|
||||
pub mod cargo;
|
||||
pub mod config;
|
||||
pub mod flock;
|
||||
pub mod framework;
|
||||
|
@ -2,8 +2,10 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use crate::{helpers::cross_command, Result};
|
||||
use std::{fmt::Display, path::Path, process::ExitStatus};
|
||||
use anyhow::Context;
|
||||
|
||||
use crate::helpers::cross_command;
|
||||
use std::{fmt::Display, path::Path, process::Command};
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||
pub enum PackageManager {
|
||||
@ -69,48 +71,42 @@ impl PackageManager {
|
||||
found
|
||||
}
|
||||
|
||||
pub fn install(&self, dependencies: &[String]) -> Result<ExitStatus> {
|
||||
fn cross_command(&self) -> Command {
|
||||
match self {
|
||||
PackageManager::Yarn => {
|
||||
let mut cmd = cross_command("yarn");
|
||||
cmd
|
||||
.arg("add")
|
||||
.args(dependencies)
|
||||
.status()
|
||||
.map_err(Into::into)
|
||||
}
|
||||
PackageManager::YarnBerry => {
|
||||
let mut cmd = cross_command("yarn");
|
||||
cmd
|
||||
.arg("add")
|
||||
.args(dependencies)
|
||||
.status()
|
||||
.map_err(Into::into)
|
||||
}
|
||||
PackageManager::Npm => {
|
||||
let mut cmd = cross_command("npm");
|
||||
cmd
|
||||
.arg("install")
|
||||
.args(dependencies)
|
||||
.status()
|
||||
.map_err(Into::into)
|
||||
}
|
||||
PackageManager::Pnpm => {
|
||||
let mut cmd = cross_command("pnpm");
|
||||
cmd
|
||||
.arg("install")
|
||||
.args(dependencies)
|
||||
.status()
|
||||
.map_err(Into::into)
|
||||
}
|
||||
PackageManager::Bun => {
|
||||
let mut cmd = cross_command("bun");
|
||||
cmd
|
||||
.arg("install")
|
||||
.args(dependencies)
|
||||
.status()
|
||||
.map_err(Into::into)
|
||||
}
|
||||
PackageManager::Yarn => cross_command("yarn"),
|
||||
PackageManager::YarnBerry => cross_command("yarn"),
|
||||
PackageManager::Npm => cross_command("npm"),
|
||||
PackageManager::Pnpm => cross_command("pnpm"),
|
||||
PackageManager::Bun => cross_command("bun"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn install(&self, dependencies: &[String]) -> crate::Result<()> {
|
||||
let dependencies_str = if dependencies.len() > 1 {
|
||||
"dependencies"
|
||||
} else {
|
||||
"dependency"
|
||||
};
|
||||
log::info!(
|
||||
"Installing NPM {dependencies_str} {}...",
|
||||
dependencies
|
||||
.iter()
|
||||
.map(|d| format!("\"{d}\""))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
);
|
||||
|
||||
let status = self
|
||||
.cross_command()
|
||||
.arg("add")
|
||||
.args(dependencies)
|
||||
.status()
|
||||
.with_context(|| format!("failed to run {self}"))?;
|
||||
|
||||
if !status.success() {
|
||||
anyhow::bail!("Failed to install NPM {dependencies_str}");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -3,14 +3,13 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use crate::{
|
||||
helpers::{app_paths::walk_builder, npm::PackageManager},
|
||||
helpers::{app_paths::walk_builder, cargo, npm::PackageManager},
|
||||
Result,
|
||||
};
|
||||
|
||||
use std::{
|
||||
fs::{read_to_string, write},
|
||||
path::Path,
|
||||
process::Command,
|
||||
};
|
||||
|
||||
const CORE_API_MODULES: &[&str] = &["dpi", "event", "path", "core", "window", "mocks"];
|
||||
@ -78,23 +77,11 @@ pub fn migrate(app_dir: &Path, tauri_dir: &Path) -> Result<()> {
|
||||
}
|
||||
|
||||
if !new_npm_packages.is_empty() {
|
||||
log::info!(
|
||||
"Installing NPM packages for plugins: {}",
|
||||
new_npm_packages.join(", ")
|
||||
);
|
||||
pm.install(&new_npm_packages)?;
|
||||
}
|
||||
|
||||
if !new_cargo_packages.is_empty() {
|
||||
log::info!(
|
||||
"Installing Cargo dependencies for plugins: {}",
|
||||
new_cargo_packages.join(", ")
|
||||
);
|
||||
Command::new("cargo")
|
||||
.arg("add")
|
||||
.args(new_cargo_packages)
|
||||
.current_dir(tauri_dir)
|
||||
.status()?;
|
||||
cargo::install(&new_cargo_packages, Some(tauri_dir))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
Loading…
Reference in New Issue
Block a user