mirror of
https://github.com/tauri-apps/tauri.git
synced 2024-10-26 09:58:16 +03:00
feat(cli/migrate): add plugins to Cargo.toml (#8951)
* feat(cli/migrate): add plugins to Cargo.toml closes #8933 * small cleanup --------- Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
This commit is contained in:
parent
bc5b5e671a
commit
9be314f07a
6
.changes/cli-plugins-migrate.md
Normal file
6
.changes/cli-plugins-migrate.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
'tauri-cli': 'patch:enhance'
|
||||||
|
'@tauri-apps/cli': 'patch:enhance'
|
||||||
|
---
|
||||||
|
|
||||||
|
Add plugins to `Cargo.toml` when using `tauri migrate`
|
@ -22,16 +22,16 @@ use std::{collections::HashMap, process::Command};
|
|||||||
#[clap(about = "Add a tauri plugin to the project")]
|
#[clap(about = "Add a tauri plugin to the project")]
|
||||||
pub struct Options {
|
pub struct Options {
|
||||||
/// The plugin to add.
|
/// The plugin to add.
|
||||||
plugin: String,
|
pub plugin: String,
|
||||||
/// Git tag to use.
|
/// Git tag to use.
|
||||||
#[clap(short, long)]
|
#[clap(short, long)]
|
||||||
tag: Option<String>,
|
pub tag: Option<String>,
|
||||||
/// Git rev to use.
|
/// Git rev to use.
|
||||||
#[clap(short, long)]
|
#[clap(short, long)]
|
||||||
rev: Option<String>,
|
pub rev: Option<String>,
|
||||||
/// Git branch to use.
|
/// Git branch to use.
|
||||||
#[clap(short, long)]
|
#[clap(short, long)]
|
||||||
branch: Option<String>,
|
pub branch: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn command(options: Options) -> Result<()> {
|
pub fn command(options: Options) -> Result<()> {
|
||||||
|
@ -14,24 +14,12 @@ use tauri_utils::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
|
collections::HashSet,
|
||||||
fs::{create_dir_all, write},
|
fs::{create_dir_all, write},
|
||||||
path::Path,
|
path::Path,
|
||||||
};
|
};
|
||||||
|
|
||||||
macro_rules! move_allowlist_object {
|
pub fn migrate(tauri_dir: &Path) -> Result<MigratedConfig> {
|
||||||
($plugins: ident, $value: expr, $plugin: literal, $field: literal) => {{
|
|
||||||
if $value != Default::default() {
|
|
||||||
$plugins
|
|
||||||
.entry($plugin)
|
|
||||||
.or_insert_with(|| Value::Object(Default::default()))
|
|
||||||
.as_object_mut()
|
|
||||||
.unwrap()
|
|
||||||
.insert($field.into(), serde_json::to_value($value.clone())?);
|
|
||||||
}
|
|
||||||
}};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn migrate(tauri_dir: &Path) -> Result<()> {
|
|
||||||
if let Ok((mut config, config_path)) =
|
if let Ok((mut config, config_path)) =
|
||||||
tauri_utils_v1::config::parse::parse_value(tauri_dir.join("tauri.conf.json"))
|
tauri_utils_v1::config::parse::parse_value(tauri_dir.join("tauri.conf.json"))
|
||||||
{
|
{
|
||||||
@ -50,7 +38,7 @@ pub fn migrate(tauri_dir: &Path) -> Result<()> {
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|p| PermissionEntry::PermissionRef(p.to_string().try_into().unwrap()))
|
.map(|p| PermissionEntry::PermissionRef(p.to_string().try_into().unwrap()))
|
||||||
.collect();
|
.collect();
|
||||||
permissions.extend(migrated.permissions);
|
permissions.extend(migrated.permissions.clone());
|
||||||
|
|
||||||
let capabilities_path = config_path.parent().unwrap().join("capabilities");
|
let capabilities_path = config_path.parent().unwrap().join("capabilities");
|
||||||
create_dir_all(&capabilities_path)?;
|
create_dir_all(&capabilities_path)?;
|
||||||
@ -73,18 +61,23 @@ pub fn migrate(tauri_dir: &Path) -> Result<()> {
|
|||||||
],
|
],
|
||||||
})?,
|
})?,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
return Ok(migrated);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(Default::default())
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MigratedConfig {
|
#[derive(Default)]
|
||||||
permissions: Vec<PermissionEntry>,
|
pub struct MigratedConfig {
|
||||||
|
pub permissions: Vec<PermissionEntry>,
|
||||||
|
pub plugins: HashSet<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn migrate_config(config: &mut Value) -> Result<MigratedConfig> {
|
fn migrate_config(config: &mut Value) -> Result<MigratedConfig> {
|
||||||
let mut migrated = MigratedConfig {
|
let mut migrated = MigratedConfig {
|
||||||
permissions: Vec::new(),
|
permissions: Vec::new(),
|
||||||
|
plugins: HashSet::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(config) = config.as_object_mut() {
|
if let Some(config) = config.as_object_mut() {
|
||||||
@ -101,8 +94,9 @@ fn migrate_config(config: &mut Value) -> Result<MigratedConfig> {
|
|||||||
if let Some(tauri_config) = config.get_mut("tauri").and_then(|c| c.as_object_mut()) {
|
if let Some(tauri_config) = config.get_mut("tauri").and_then(|c| c.as_object_mut()) {
|
||||||
// allowlist
|
// allowlist
|
||||||
if let Some(allowlist) = tauri_config.remove("allowlist") {
|
if let Some(allowlist) = tauri_config.remove("allowlist") {
|
||||||
let allowlist = process_allowlist(tauri_config, &mut plugins, allowlist)?;
|
let allowlist = process_allowlist(tauri_config, allowlist)?;
|
||||||
let permissions = allowlist_to_permissions(allowlist);
|
let permissions = allowlist_to_permissions(allowlist);
|
||||||
|
migrated.plugins = plugins_from_permissions(&permissions);
|
||||||
migrated.permissions = permissions;
|
migrated.permissions = permissions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,8 +172,11 @@ fn process_build(config: &mut Map<String, Value>) {
|
|||||||
if let Some(dist_dir) = build_config.remove("distDir") {
|
if let Some(dist_dir) = build_config.remove("distDir") {
|
||||||
build_config.insert("frontendDist".into(), dist_dir);
|
build_config.insert("frontendDist".into(), dist_dir);
|
||||||
}
|
}
|
||||||
if let Some(dist_dir) = build_config.remove("devPath") {
|
if let Some(dev_path) = build_config.remove("devPath") {
|
||||||
build_config.insert("devUrl".into(), dist_dir);
|
let is_url = url::Url::parse(dev_path.as_str().unwrap_or_default()).is_ok();
|
||||||
|
if is_url {
|
||||||
|
build_config.insert("devUrl".into(), dev_path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if let Some(with_global_tauri) = build_config.remove("withGlobalTauri") {
|
if let Some(with_global_tauri) = build_config.remove("withGlobalTauri") {
|
||||||
config
|
config
|
||||||
@ -282,13 +279,10 @@ fn process_security(security: &mut Map<String, Value>) -> Result<()> {
|
|||||||
|
|
||||||
fn process_allowlist(
|
fn process_allowlist(
|
||||||
tauri_config: &mut Map<String, Value>,
|
tauri_config: &mut Map<String, Value>,
|
||||||
plugins: &mut Map<String, Value>,
|
|
||||||
allowlist: Value,
|
allowlist: Value,
|
||||||
) -> Result<tauri_utils_v1::config::AllowlistConfig> {
|
) -> Result<tauri_utils_v1::config::AllowlistConfig> {
|
||||||
let allowlist: tauri_utils_v1::config::AllowlistConfig = serde_json::from_value(allowlist)?;
|
let allowlist: tauri_utils_v1::config::AllowlistConfig = serde_json::from_value(allowlist)?;
|
||||||
|
|
||||||
move_allowlist_object!(plugins, allowlist.shell.open, "shell", "open");
|
|
||||||
|
|
||||||
if allowlist.protocol.asset_scope != Default::default() {
|
if allowlist.protocol.asset_scope != Default::default() {
|
||||||
let security = tauri_config
|
let security = tauri_config
|
||||||
.entry("security")
|
.entry("security")
|
||||||
@ -524,6 +518,34 @@ fn process_updater(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const KNOWN_PLUGINS: &[&str] = &[
|
||||||
|
"fs",
|
||||||
|
"shell",
|
||||||
|
"dialog",
|
||||||
|
"http",
|
||||||
|
"notification",
|
||||||
|
"global-shortcut",
|
||||||
|
"os",
|
||||||
|
"process",
|
||||||
|
"clipboard-manager",
|
||||||
|
];
|
||||||
|
|
||||||
|
fn plugins_from_permissions(permissions: &Vec<PermissionEntry>) -> HashSet<String> {
|
||||||
|
let mut plugins = HashSet::new();
|
||||||
|
|
||||||
|
for permission in permissions {
|
||||||
|
let permission = permission.identifier().get();
|
||||||
|
for plugin in KNOWN_PLUGINS {
|
||||||
|
if permission.starts_with(plugin) {
|
||||||
|
plugins.insert(plugin.to_string());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
plugins
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
fn migrate(original: &serde_json::Value) -> serde_json::Value {
|
fn migrate(original: &serde_json::Value) -> serde_json::Value {
|
||||||
@ -846,4 +868,22 @@ mod test {
|
|||||||
"connect-src migration failed"
|
"connect-src migration failed"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn migrate_invalid_url_dev_path() {
|
||||||
|
let original = serde_json::json!({
|
||||||
|
"build": {
|
||||||
|
"devPath": "../src",
|
||||||
|
"distDir": "../src"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let migrated = migrate(&original);
|
||||||
|
|
||||||
|
assert!(migrated["build"].get("devUrl").is_none());
|
||||||
|
assert_eq!(
|
||||||
|
migrated["build"]["distDir"],
|
||||||
|
original["build"]["frontendDist"]
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ use toml_edit::{Document, Entry, Item, Table, TableLike, Value};
|
|||||||
|
|
||||||
use std::{fs::File, io::Write, path::Path};
|
use std::{fs::File, io::Write, path::Path};
|
||||||
|
|
||||||
const CRATE_TYPES: &[&str] = &["staticlib", "cdylib", "rlib"];
|
const CRATE_TYPES: [&str; 3] = ["lib", "staticlib", "cdylib"];
|
||||||
|
|
||||||
pub fn migrate(tauri_dir: &Path) -> Result<()> {
|
pub fn migrate(tauri_dir: &Path) -> Result<()> {
|
||||||
let manifest_path = tauri_dir.join("Cargo.toml");
|
let manifest_path = tauri_dir.join("Cargo.toml");
|
||||||
@ -57,12 +57,11 @@ fn migrate_manifest(manifest: &mut Document) -> Result<()> {
|
|||||||
|
|
||||||
migrate_dependency(build_dependencies, "tauri-build", &version, &[]);
|
migrate_dependency(build_dependencies, "tauri-build", &version, &[]);
|
||||||
|
|
||||||
let lib = manifest
|
if let Some(lib) = manifest
|
||||||
.as_table_mut()
|
.as_table_mut()
|
||||||
.entry("lib")
|
.get_mut("lib")
|
||||||
.or_insert(Item::Table(Table::new()))
|
.and_then(|l| l.as_table_mut())
|
||||||
.as_table_mut()
|
{
|
||||||
.expect("manifest lib isn't a table");
|
|
||||||
match lib.entry("crate-type") {
|
match lib.entry("crate-type") {
|
||||||
Entry::Occupied(mut e) => {
|
Entry::Occupied(mut e) => {
|
||||||
if let Item::Value(Value::Array(types)) = e.get_mut() {
|
if let Item::Value(Value::Array(types)) = e.get_mut() {
|
||||||
@ -87,6 +86,7 @@ fn migrate_manifest(manifest: &mut Document) -> Result<()> {
|
|||||||
e.insert(Item::Value(arr.into()));
|
e.insert(Item::Value(arr.into()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -265,35 +265,6 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn migrate_lib(toml: &str) {
|
|
||||||
let mut manifest = toml.parse::<toml_edit::Document>().expect("invalid toml");
|
|
||||||
super::migrate_manifest(&mut manifest).expect("failed to migrate manifest");
|
|
||||||
|
|
||||||
let lib = manifest
|
|
||||||
.as_table()
|
|
||||||
.get("lib")
|
|
||||||
.expect("missing manifest lib")
|
|
||||||
.as_table()
|
|
||||||
.expect("manifest lib isn't a table");
|
|
||||||
|
|
||||||
let crate_types = lib
|
|
||||||
.get("crate-type")
|
|
||||||
.expect("missing lib crate-type")
|
|
||||||
.as_array()
|
|
||||||
.expect("crate-type must be an array");
|
|
||||||
let mut not_added_crate_types = super::CRATE_TYPES.to_vec();
|
|
||||||
for t in crate_types {
|
|
||||||
let t = t.as_str().expect("crate-type must be a string");
|
|
||||||
if let Some(i) = not_added_crate_types.iter().position(|ty| ty == &t) {
|
|
||||||
not_added_crate_types.remove(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assert!(
|
|
||||||
not_added_crate_types.is_empty(),
|
|
||||||
"missing crate-type: {not_added_crate_types:?}"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn migrate_table() {
|
fn migrate_table() {
|
||||||
migrate_deps(|features| {
|
migrate_deps(|features| {
|
||||||
@ -332,22 +303,32 @@ mod tests {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn migrate_missing_lib() {
|
|
||||||
migrate_lib("[dependencies]");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn migrate_missing_crate_types() {
|
|
||||||
migrate_lib("[lib]");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn migrate_add_crate_types() {
|
fn migrate_add_crate_types() {
|
||||||
migrate_lib(
|
let toml = r#"
|
||||||
r#"
|
|
||||||
[lib]
|
[lib]
|
||||||
crate-type = ["something"]"#,
|
crate-type = ["something"]"#;
|
||||||
|
|
||||||
|
let mut manifest = toml.parse::<toml_edit::Document>().expect("invalid toml");
|
||||||
|
super::migrate_manifest(&mut manifest).expect("failed to migrate manifest");
|
||||||
|
|
||||||
|
if let Some(crate_types) = manifest
|
||||||
|
.as_table()
|
||||||
|
.get("lib")
|
||||||
|
.and_then(|l| l.get("crate-type"))
|
||||||
|
.and_then(|c| c.as_array())
|
||||||
|
{
|
||||||
|
let mut not_added_crate_types = super::CRATE_TYPES.to_vec();
|
||||||
|
for t in crate_types {
|
||||||
|
let t = t.as_str().expect("crate-type must be a string");
|
||||||
|
if let Some(i) = not_added_crate_types.iter().position(|ty| ty == &t) {
|
||||||
|
not_added_crate_types.remove(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert!(
|
||||||
|
not_added_crate_types.is_empty(),
|
||||||
|
"missing crate-type: {not_added_crate_types:?}"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,9 +15,19 @@ pub fn command() -> Result<()> {
|
|||||||
let tauri_dir = tauri_dir();
|
let tauri_dir = tauri_dir();
|
||||||
let app_dir = app_dir();
|
let app_dir = app_dir();
|
||||||
|
|
||||||
config::migrate(&tauri_dir)?;
|
let migrated = config::migrate(&tauri_dir)?;
|
||||||
manifest::migrate(&tauri_dir)?;
|
manifest::migrate(&tauri_dir)?;
|
||||||
frontend::migrate(app_dir, &tauri_dir)?;
|
frontend::migrate(app_dir, &tauri_dir)?;
|
||||||
|
|
||||||
|
// Add plugins
|
||||||
|
for plugin in migrated.plugins {
|
||||||
|
crate::add::command(crate::add::Options {
|
||||||
|
plugin,
|
||||||
|
branch: None,
|
||||||
|
tag: None,
|
||||||
|
rev: None,
|
||||||
|
})?
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user