Skip to content

Commit 8af2497

Browse files
authored
feat(cli): automate API -> plugin migration (#7561)
1 parent d010bc0 commit 8af2497

File tree

5 files changed

+152
-4
lines changed

5 files changed

+152
-4
lines changed

.changes/migrate-plugins.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"tauri-cli": patch:feat
3+
"@tauri-apps/cli": patch:feat
4+
---
5+
6+
The `migrate` command now automatically reads all JavaScript files and updates `@tauri-apps/api` import paths and install the missing plugins.

tooling/cli/src/helpers/app_paths.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use tauri_utils::config::parse::{
1818

1919
const TAURI_GITIGNORE: &[u8] = include_bytes!("../../tauri.gitignore");
2020

21-
fn lookup<F: Fn(&PathBuf) -> bool>(dir: &Path, checker: F) -> Option<PathBuf> {
21+
pub fn walk_builder(path: &Path) -> WalkBuilder {
2222
let mut default_gitignore = std::env::temp_dir();
2323
default_gitignore.push(".gitignore");
2424
if !default_gitignore.exists() {
@@ -28,9 +28,14 @@ fn lookup<F: Fn(&PathBuf) -> bool>(dir: &Path, checker: F) -> Option<PathBuf> {
2828
}
2929
}
3030

31-
let mut builder = WalkBuilder::new(dir);
31+
let mut builder = WalkBuilder::new(path);
3232
builder.add_custom_ignore_filename(".taurignore");
3333
let _ = builder.add_ignore(default_gitignore);
34+
builder
35+
}
36+
37+
fn lookup<F: Fn(&PathBuf) -> bool>(dir: &Path, checker: F) -> Option<PathBuf> {
38+
let mut builder = walk_builder(dir);
3439
builder
3540
.require_git(false)
3641
.ignore(false)

tooling/cli/src/helpers/npm.rs

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
// SPDX-License-Identifier: Apache-2.0
33
// SPDX-License-Identifier: MIT
44

5-
use std::{fmt::Display, path::Path};
5+
use crate::{helpers::cross_command, Result};
6+
use std::{fmt::Display, path::Path, process::ExitStatus};
67

78
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
89
pub enum PackageManager {
@@ -65,4 +66,41 @@ impl PackageManager {
6566

6667
found
6768
}
69+
70+
pub fn install(&self, dependencies: &[String]) -> Result<ExitStatus> {
71+
match self {
72+
PackageManager::Yarn => {
73+
let mut cmd = cross_command("yarn");
74+
cmd
75+
.arg("add")
76+
.args(dependencies)
77+
.status()
78+
.map_err(Into::into)
79+
}
80+
PackageManager::YarnBerry => {
81+
let mut cmd = cross_command("yarn");
82+
cmd
83+
.arg("add")
84+
.args(dependencies)
85+
.status()
86+
.map_err(Into::into)
87+
}
88+
PackageManager::Npm => {
89+
let mut cmd = cross_command("npm");
90+
cmd
91+
.arg("install")
92+
.args(dependencies)
93+
.status()
94+
.map_err(Into::into)
95+
}
96+
PackageManager::Pnpm => {
97+
let mut cmd = cross_command("pnpm");
98+
cmd
99+
.arg("install")
100+
.args(dependencies)
101+
.status()
102+
.map_err(Into::into)
103+
}
104+
}
105+
}
68106
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
2+
// SPDX-License-Identifier: Apache-2.0
3+
// SPDX-License-Identifier: MIT
4+
5+
use crate::{
6+
helpers::{app_paths::walk_builder, npm::PackageManager},
7+
Result,
8+
};
9+
10+
use std::{
11+
fs::{read_to_string, write},
12+
path::Path,
13+
process::Command,
14+
};
15+
16+
const CORE_API_MODULES: &[&str] = &["event", "path", "tauri", "mocks"];
17+
const JS_EXTENSIONS: &[&str] = &["js", "jsx", "ts", "tsx", "mjs"];
18+
19+
pub fn migrate(app_dir: &Path, tauri_dir: &Path) -> Result<()> {
20+
let mut new_npm_packages = Vec::new();
21+
let mut new_cargo_packages = Vec::new();
22+
23+
let pm = PackageManager::from_project(app_dir)
24+
.into_iter()
25+
.next()
26+
.unwrap_or(PackageManager::Npm);
27+
28+
let tauri_api_import_regex = regex::Regex::new(r"@tauri-apps/api/(\w+)").unwrap();
29+
30+
for entry in walk_builder(app_dir).build().flatten() {
31+
if entry.file_type().map(|t| t.is_file()).unwrap_or_default() {
32+
let path = entry.path();
33+
let ext = path.extension().unwrap_or_default();
34+
if JS_EXTENSIONS.iter().any(|e| e == &ext) {
35+
let js_contents = read_to_string(path)?;
36+
37+
let new_contents =
38+
tauri_api_import_regex.replace_all(&js_contents, |cap: &regex::Captures<'_>| {
39+
let module = cap.get(1).unwrap().as_str();
40+
let original = cap.get(0).unwrap().as_str();
41+
42+
if CORE_API_MODULES.contains(&module) {
43+
original.to_string()
44+
} else {
45+
let plugin = format!("@tauri-apps/plugin-{module}");
46+
log::info!(
47+
"Replacing `{original}` with `{plugin}` on {}",
48+
path.display()
49+
);
50+
51+
new_npm_packages.push(plugin.clone());
52+
new_cargo_packages.push(format!(
53+
"tauri-plugin-{}",
54+
if module == "clipboard" {
55+
"clipboard-manager"
56+
} else {
57+
module
58+
}
59+
));
60+
61+
plugin
62+
}
63+
});
64+
65+
if new_contents != js_contents {
66+
write(path, new_contents.as_bytes())?;
67+
}
68+
}
69+
}
70+
}
71+
72+
if !new_npm_packages.is_empty() {
73+
log::info!(
74+
"Installing NPM packages for plugins: {}",
75+
new_npm_packages.join(", ")
76+
);
77+
pm.install(&new_npm_packages)?;
78+
}
79+
80+
if !new_cargo_packages.is_empty() {
81+
log::info!(
82+
"Installing Cargo dependencies for plugins: {}",
83+
new_cargo_packages.join(", ")
84+
);
85+
Command::new("cargo")
86+
.arg("add")
87+
.args(new_cargo_packages)
88+
.current_dir(tauri_dir)
89+
.status()?;
90+
}
91+
92+
Ok(())
93+
}

tooling/cli/src/migrate/mod.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,22 @@
22
// SPDX-License-Identifier: Apache-2.0
33
// SPDX-License-Identifier: MIT
44

5-
use crate::{helpers::app_paths::tauri_dir, Result};
5+
use crate::{
6+
helpers::app_paths::{app_dir, tauri_dir},
7+
Result,
8+
};
69

710
mod config;
11+
mod frontend;
812
mod manifest;
913

1014
pub fn command() -> Result<()> {
1115
let tauri_dir = tauri_dir();
16+
let app_dir = app_dir();
1217

1318
config::migrate(&tauri_dir)?;
1419
manifest::migrate(&tauri_dir)?;
20+
frontend::migrate(app_dir, &tauri_dir)?;
1521

1622
Ok(())
1723
}

0 commit comments

Comments
 (0)