Skip to content

Commit 9be314f

Browse files
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>
1 parent bc5b5e6 commit 9be314f

File tree

5 files changed

+134
-97
lines changed

5 files changed

+134
-97
lines changed

.changes/cli-plugins-migrate.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'tauri-cli': 'patch:enhance'
3+
'@tauri-apps/cli': 'patch:enhance'
4+
---
5+
6+
Add plugins to `Cargo.toml` when using `tauri migrate`

tooling/cli/src/add.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,16 @@ use std::{collections::HashMap, process::Command};
2222
#[clap(about = "Add a tauri plugin to the project")]
2323
pub struct Options {
2424
/// The plugin to add.
25-
plugin: String,
25+
pub plugin: String,
2626
/// Git tag to use.
2727
#[clap(short, long)]
28-
tag: Option<String>,
28+
pub tag: Option<String>,
2929
/// Git rev to use.
3030
#[clap(short, long)]
31-
rev: Option<String>,
31+
pub rev: Option<String>,
3232
/// Git branch to use.
3333
#[clap(short, long)]
34-
branch: Option<String>,
34+
pub branch: Option<String>,
3535
}
3636

3737
pub fn command(options: Options) -> Result<()> {

tooling/cli/src/migrate/config.rs

Lines changed: 64 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,12 @@ use tauri_utils::{
1414
};
1515

1616
use std::{
17+
collections::HashSet,
1718
fs::{create_dir_all, write},
1819
path::Path,
1920
};
2021

21-
macro_rules! move_allowlist_object {
22-
($plugins: ident, $value: expr, $plugin: literal, $field: literal) => {{
23-
if $value != Default::default() {
24-
$plugins
25-
.entry($plugin)
26-
.or_insert_with(|| Value::Object(Default::default()))
27-
.as_object_mut()
28-
.unwrap()
29-
.insert($field.into(), serde_json::to_value($value.clone())?);
30-
}
31-
}};
32-
}
33-
34-
pub fn migrate(tauri_dir: &Path) -> Result<()> {
22+
pub fn migrate(tauri_dir: &Path) -> Result<MigratedConfig> {
3523
if let Ok((mut config, config_path)) =
3624
tauri_utils_v1::config::parse::parse_value(tauri_dir.join("tauri.conf.json"))
3725
{
@@ -50,7 +38,7 @@ pub fn migrate(tauri_dir: &Path) -> Result<()> {
5038
.into_iter()
5139
.map(|p| PermissionEntry::PermissionRef(p.to_string().try_into().unwrap()))
5240
.collect();
53-
permissions.extend(migrated.permissions);
41+
permissions.extend(migrated.permissions.clone());
5442

5543
let capabilities_path = config_path.parent().unwrap().join("capabilities");
5644
create_dir_all(&capabilities_path)?;
@@ -73,18 +61,23 @@ pub fn migrate(tauri_dir: &Path) -> Result<()> {
7361
],
7462
})?,
7563
)?;
64+
65+
return Ok(migrated);
7666
}
7767

78-
Ok(())
68+
Ok(Default::default())
7969
}
8070

81-
struct MigratedConfig {
82-
permissions: Vec<PermissionEntry>,
71+
#[derive(Default)]
72+
pub struct MigratedConfig {
73+
pub permissions: Vec<PermissionEntry>,
74+
pub plugins: HashSet<String>,
8375
}
8476

8577
fn migrate_config(config: &mut Value) -> Result<MigratedConfig> {
8678
let mut migrated = MigratedConfig {
8779
permissions: Vec::new(),
80+
plugins: HashSet::new(),
8881
};
8982

9083
if let Some(config) = config.as_object_mut() {
@@ -101,8 +94,9 @@ fn migrate_config(config: &mut Value) -> Result<MigratedConfig> {
10194
if let Some(tauri_config) = config.get_mut("tauri").and_then(|c| c.as_object_mut()) {
10295
// allowlist
10396
if let Some(allowlist) = tauri_config.remove("allowlist") {
104-
let allowlist = process_allowlist(tauri_config, &mut plugins, allowlist)?;
97+
let allowlist = process_allowlist(tauri_config, allowlist)?;
10598
let permissions = allowlist_to_permissions(allowlist);
99+
migrated.plugins = plugins_from_permissions(&permissions);
106100
migrated.permissions = permissions;
107101
}
108102

@@ -178,8 +172,11 @@ fn process_build(config: &mut Map<String, Value>) {
178172
if let Some(dist_dir) = build_config.remove("distDir") {
179173
build_config.insert("frontendDist".into(), dist_dir);
180174
}
181-
if let Some(dist_dir) = build_config.remove("devPath") {
182-
build_config.insert("devUrl".into(), dist_dir);
175+
if let Some(dev_path) = build_config.remove("devPath") {
176+
let is_url = url::Url::parse(dev_path.as_str().unwrap_or_default()).is_ok();
177+
if is_url {
178+
build_config.insert("devUrl".into(), dev_path);
179+
}
183180
}
184181
if let Some(with_global_tauri) = build_config.remove("withGlobalTauri") {
185182
config
@@ -282,13 +279,10 @@ fn process_security(security: &mut Map<String, Value>) -> Result<()> {
282279

283280
fn process_allowlist(
284281
tauri_config: &mut Map<String, Value>,
285-
plugins: &mut Map<String, Value>,
286282
allowlist: Value,
287283
) -> Result<tauri_utils_v1::config::AllowlistConfig> {
288284
let allowlist: tauri_utils_v1::config::AllowlistConfig = serde_json::from_value(allowlist)?;
289285

290-
move_allowlist_object!(plugins, allowlist.shell.open, "shell", "open");
291-
292286
if allowlist.protocol.asset_scope != Default::default() {
293287
let security = tauri_config
294288
.entry("security")
@@ -524,6 +518,34 @@ fn process_updater(
524518
Ok(())
525519
}
526520

521+
const KNOWN_PLUGINS: &[&str] = &[
522+
"fs",
523+
"shell",
524+
"dialog",
525+
"http",
526+
"notification",
527+
"global-shortcut",
528+
"os",
529+
"process",
530+
"clipboard-manager",
531+
];
532+
533+
fn plugins_from_permissions(permissions: &Vec<PermissionEntry>) -> HashSet<String> {
534+
let mut plugins = HashSet::new();
535+
536+
for permission in permissions {
537+
let permission = permission.identifier().get();
538+
for plugin in KNOWN_PLUGINS {
539+
if permission.starts_with(plugin) {
540+
plugins.insert(plugin.to_string());
541+
break;
542+
}
543+
}
544+
}
545+
546+
plugins
547+
}
548+
527549
#[cfg(test)]
528550
mod test {
529551
fn migrate(original: &serde_json::Value) -> serde_json::Value {
@@ -846,4 +868,22 @@ mod test {
846868
"connect-src migration failed"
847869
);
848870
}
871+
872+
#[test]
873+
fn migrate_invalid_url_dev_path() {
874+
let original = serde_json::json!({
875+
"build": {
876+
"devPath": "../src",
877+
"distDir": "../src"
878+
}
879+
});
880+
881+
let migrated = migrate(&original);
882+
883+
assert!(migrated["build"].get("devUrl").is_none());
884+
assert_eq!(
885+
migrated["build"]["distDir"],
886+
original["build"]["frontendDist"]
887+
);
888+
}
849889
}

tooling/cli/src/migrate/manifest.rs

Lines changed: 49 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use toml_edit::{Document, Entry, Item, Table, TableLike, Value};
1111

1212
use std::{fs::File, io::Write, path::Path};
1313

14-
const CRATE_TYPES: &[&str] = &["staticlib", "cdylib", "rlib"];
14+
const CRATE_TYPES: [&str; 3] = ["lib", "staticlib", "cdylib"];
1515

1616
pub fn migrate(tauri_dir: &Path) -> Result<()> {
1717
let manifest_path = tauri_dir.join("Cargo.toml");
@@ -57,34 +57,34 @@ fn migrate_manifest(manifest: &mut Document) -> Result<()> {
5757

5858
migrate_dependency(build_dependencies, "tauri-build", &version, &[]);
5959

60-
let lib = manifest
60+
if let Some(lib) = manifest
6161
.as_table_mut()
62-
.entry("lib")
63-
.or_insert(Item::Table(Table::new()))
64-
.as_table_mut()
65-
.expect("manifest lib isn't a table");
66-
match lib.entry("crate-type") {
67-
Entry::Occupied(mut e) => {
68-
if let Item::Value(Value::Array(types)) = e.get_mut() {
69-
let mut crate_types_to_add = CRATE_TYPES.to_vec();
70-
for t in types.iter() {
71-
// type is already in the manifest, skip adding it
72-
if let Some(i) = crate_types_to_add
73-
.iter()
74-
.position(|ty| Some(ty) == t.as_str().as_ref())
75-
{
76-
crate_types_to_add.remove(i);
62+
.get_mut("lib")
63+
.and_then(|l| l.as_table_mut())
64+
{
65+
match lib.entry("crate-type") {
66+
Entry::Occupied(mut e) => {
67+
if let Item::Value(Value::Array(types)) = e.get_mut() {
68+
let mut crate_types_to_add = CRATE_TYPES.to_vec();
69+
for t in types.iter() {
70+
// type is already in the manifest, skip adding it
71+
if let Some(i) = crate_types_to_add
72+
.iter()
73+
.position(|ty| Some(ty) == t.as_str().as_ref())
74+
{
75+
crate_types_to_add.remove(i);
76+
}
77+
}
78+
for t in crate_types_to_add {
79+
types.push(t);
7780
}
78-
}
79-
for t in crate_types_to_add {
80-
types.push(t);
8181
}
8282
}
83-
}
84-
Entry::Vacant(e) => {
85-
let mut arr = toml_edit::Array::new();
86-
arr.extend(CRATE_TYPES.to_vec());
87-
e.insert(Item::Value(arr.into()));
83+
Entry::Vacant(e) => {
84+
let mut arr = toml_edit::Array::new();
85+
arr.extend(CRATE_TYPES.to_vec());
86+
e.insert(Item::Value(arr.into()));
87+
}
8888
}
8989
}
9090

@@ -265,35 +265,6 @@ mod tests {
265265
}
266266
}
267267

268-
fn migrate_lib(toml: &str) {
269-
let mut manifest = toml.parse::<toml_edit::Document>().expect("invalid toml");
270-
super::migrate_manifest(&mut manifest).expect("failed to migrate manifest");
271-
272-
let lib = manifest
273-
.as_table()
274-
.get("lib")
275-
.expect("missing manifest lib")
276-
.as_table()
277-
.expect("manifest lib isn't a table");
278-
279-
let crate_types = lib
280-
.get("crate-type")
281-
.expect("missing lib crate-type")
282-
.as_array()
283-
.expect("crate-type must be an array");
284-
let mut not_added_crate_types = super::CRATE_TYPES.to_vec();
285-
for t in crate_types {
286-
let t = t.as_str().expect("crate-type must be a string");
287-
if let Some(i) = not_added_crate_types.iter().position(|ty| ty == &t) {
288-
not_added_crate_types.remove(i);
289-
}
290-
}
291-
assert!(
292-
not_added_crate_types.is_empty(),
293-
"missing crate-type: {not_added_crate_types:?}"
294-
);
295-
}
296-
297268
#[test]
298269
fn migrate_table() {
299270
migrate_deps(|features| {
@@ -332,22 +303,32 @@ mod tests {
332303
})
333304
}
334305

335-
#[test]
336-
fn migrate_missing_lib() {
337-
migrate_lib("[dependencies]");
338-
}
339-
340-
#[test]
341-
fn migrate_missing_crate_types() {
342-
migrate_lib("[lib]");
343-
}
344-
345306
#[test]
346307
fn migrate_add_crate_types() {
347-
migrate_lib(
348-
r#"
308+
let toml = r#"
349309
[lib]
350-
crate-type = ["something"]"#,
351-
);
310+
crate-type = ["something"]"#;
311+
312+
let mut manifest = toml.parse::<toml_edit::Document>().expect("invalid toml");
313+
super::migrate_manifest(&mut manifest).expect("failed to migrate manifest");
314+
315+
if let Some(crate_types) = manifest
316+
.as_table()
317+
.get("lib")
318+
.and_then(|l| l.get("crate-type"))
319+
.and_then(|c| c.as_array())
320+
{
321+
let mut not_added_crate_types = super::CRATE_TYPES.to_vec();
322+
for t in crate_types {
323+
let t = t.as_str().expect("crate-type must be a string");
324+
if let Some(i) = not_added_crate_types.iter().position(|ty| ty == &t) {
325+
not_added_crate_types.remove(i);
326+
}
327+
}
328+
assert!(
329+
not_added_crate_types.is_empty(),
330+
"missing crate-type: {not_added_crate_types:?}"
331+
);
332+
}
352333
}
353334
}

tooling/cli/src/migrate/mod.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,19 @@ pub fn command() -> Result<()> {
1515
let tauri_dir = tauri_dir();
1616
let app_dir = app_dir();
1717

18-
config::migrate(&tauri_dir)?;
18+
let migrated = config::migrate(&tauri_dir)?;
1919
manifest::migrate(&tauri_dir)?;
2020
frontend::migrate(app_dir, &tauri_dir)?;
2121

22+
// Add plugins
23+
for plugin in migrated.plugins {
24+
crate::add::command(crate::add::Options {
25+
plugin,
26+
branch: None,
27+
tag: None,
28+
rev: None,
29+
})?
30+
}
31+
2232
Ok(())
2333
}

0 commit comments

Comments
 (0)