mirror of https://github.com/tauri-apps/tauri
fix(cli): migrate v1 plugins NPM packages (#10794)
This commit is contained in:
parent
02b2f964a7
commit
edb2ca31f7
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
"tauri-cli": patch:bug
|
||||
"@tauri-apps/cli": patch:bug
|
||||
---
|
||||
|
||||
Migrate v1 plugins NPM packages.
|
|
@ -1213,6 +1213,12 @@ dependencies = [
|
|||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "diff"
|
||||
version = "0.1.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8"
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.7"
|
||||
|
@ -4026,6 +4032,16 @@ version = "0.1.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
|
||||
|
||||
[[package]]
|
||||
name = "pretty_assertions"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66"
|
||||
dependencies = [
|
||||
"diff",
|
||||
"yansi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "primeorder"
|
||||
version = "0.13.6"
|
||||
|
@ -5465,6 +5481,7 @@ dependencies = [
|
|||
"oxc_span",
|
||||
"phf 0.11.2",
|
||||
"plist",
|
||||
"pretty_assertions",
|
||||
"regex",
|
||||
"resvg",
|
||||
"semver",
|
||||
|
@ -6843,6 +6860,12 @@ dependencies = [
|
|||
"lzma-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yansi"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec"
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.7.32"
|
||||
|
|
|
@ -115,6 +115,7 @@ tempfile = "3"
|
|||
|
||||
[dev-dependencies]
|
||||
insta = "1"
|
||||
pretty_assertions = "1"
|
||||
|
||||
[target."cfg(windows)".dependencies.windows-sys]
|
||||
version = "0.59"
|
||||
|
|
|
@ -117,6 +117,40 @@ impl PackageManager {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn remove<P: AsRef<Path>>(&self, dependencies: &[String], app_dir: P) -> crate::Result<()> {
|
||||
let dependencies_str = if dependencies.len() > 1 {
|
||||
"dependencies"
|
||||
} else {
|
||||
"dependency"
|
||||
};
|
||||
log::info!(
|
||||
"Removing NPM {dependencies_str} {}...",
|
||||
dependencies
|
||||
.iter()
|
||||
.map(|d| format!("\"{d}\""))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
);
|
||||
|
||||
let status = self
|
||||
.cross_command()
|
||||
.arg(if *self == Self::Npm {
|
||||
"uninstall"
|
||||
} else {
|
||||
"remove"
|
||||
})
|
||||
.args(dependencies)
|
||||
.current_dir(app_dir)
|
||||
.status()
|
||||
.with_context(|| format!("failed to run {self}"))?;
|
||||
|
||||
if !status.success() {
|
||||
anyhow::bail!("Failed to remove NPM {dependencies_str}");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn current_package_version<P: AsRef<Path>>(
|
||||
&self,
|
||||
name: &str,
|
||||
|
|
|
@ -52,13 +52,26 @@ const MODULES_MAP: phf::Map<&str, &str> = phf::phf_map! {
|
|||
"@tauri-apps/api/process" => "@tauri-apps/plugin-process",
|
||||
"@tauri-apps/api/shell" => "@tauri-apps/plugin-shell",
|
||||
"@tauri-apps/api/updater" => "@tauri-apps/plugin-updater",
|
||||
// v1 plugins to v2
|
||||
"tauri-plugin-sql-api" => "@tauri-apps/plugin-sql",
|
||||
"tauri-plugin-store-api" => "@tauri-apps/plugin-store",
|
||||
"tauri-plugin-upload-api" => "@tauri-apps/plugin-upload",
|
||||
"tauri-plugin-fs-extra-api" => "@tauri-apps/plugin-fs",
|
||||
"tauri-plugin-fs-watch-api" => "@tauri-apps/plugin-fs",
|
||||
"tauri-plugin-autostart-api" => "@tauri-apps/plugin-autostart",
|
||||
"tauri-plugin-websocket-api" => "@tauri-apps/plugin-websocket",
|
||||
"tauri-plugin-positioner-api" => "@tauri-apps/plugin-positioner",
|
||||
"tauri-plugin-stronghold-api" => "@tauri-apps/plugin-stronghold",
|
||||
"tauri-plugin-window-state-api" => "@tauri-apps/plugin-window-state",
|
||||
"tauri-plugin-authenticator-api" => "@tauri-apps/plugin-authenticator",
|
||||
};
|
||||
const JS_EXTENSIONS: &[&str] = &["js", "mjs", "jsx", "ts", "mts", "tsx", "svelte", "vue"];
|
||||
|
||||
/// Returns a list of paths that could not be migrated
|
||||
/// Returns a list of migrated plugins
|
||||
pub fn migrate(app_dir: &Path) -> Result<Vec<String>> {
|
||||
let mut new_npm_packages = Vec::new();
|
||||
let mut new_plugins = Vec::new();
|
||||
let mut npm_packages_to_remove = Vec::new();
|
||||
|
||||
let pre = env!("CARGO_PKG_VERSION_PRE");
|
||||
let npm_version = if pre.is_empty() {
|
||||
|
@ -92,7 +105,12 @@ pub fn migrate(app_dir: &Path) -> Result<Vec<String>> {
|
|||
let ext = path.extension().unwrap_or_default();
|
||||
if JS_EXTENSIONS.iter().any(|e| e == &ext) {
|
||||
let js_contents = std::fs::read_to_string(path)?;
|
||||
let new_contents = migrate_imports(path, &js_contents, &mut new_plugins)?;
|
||||
let new_contents = migrate_imports(
|
||||
path,
|
||||
&js_contents,
|
||||
&mut new_plugins,
|
||||
&mut npm_packages_to_remove,
|
||||
)?;
|
||||
if new_contents != js_contents {
|
||||
fs::write(path, new_contents)
|
||||
.with_context(|| format!("Error writing {}", path.display()))?;
|
||||
|
@ -101,9 +119,16 @@ pub fn migrate(app_dir: &Path) -> Result<Vec<String>> {
|
|||
}
|
||||
}
|
||||
|
||||
new_npm_packages.sort();
|
||||
new_npm_packages.dedup();
|
||||
if !npm_packages_to_remove.is_empty() {
|
||||
npm_packages_to_remove.sort();
|
||||
npm_packages_to_remove.dedup();
|
||||
pm.remove(&npm_packages_to_remove, app_dir)
|
||||
.context("Error removing npm packages")?;
|
||||
}
|
||||
|
||||
if !new_npm_packages.is_empty() {
|
||||
new_npm_packages.sort();
|
||||
new_npm_packages.dedup();
|
||||
pm.install(&new_npm_packages, app_dir)
|
||||
.context("Error installing new npm packages")?;
|
||||
}
|
||||
|
@ -115,6 +140,7 @@ fn migrate_imports<'a>(
|
|||
path: &'a Path,
|
||||
js_source: &'a str,
|
||||
new_plugins: &mut Vec<String>,
|
||||
npm_packages_to_remove: &mut Vec<String>,
|
||||
) -> crate::Result<String> {
|
||||
let mut magic_js_source = MagicString::new(js_source);
|
||||
|
||||
|
@ -158,31 +184,35 @@ fn migrate_imports<'a>(
|
|||
if let Statement::ImportDeclaration(stmt) = import {
|
||||
let module = stmt.source.value.as_str();
|
||||
|
||||
// skip parsing non @tauri-apps/api imports
|
||||
if !module.starts_with("@tauri-apps/api") {
|
||||
continue;
|
||||
}
|
||||
|
||||
// convert module to its pluginfied module or renamed one
|
||||
// import { ... } from "@tauri-apps/api/window" -> import { ... } from "@tauri-apps/api/webviewWindow"
|
||||
// import { ... } from "@tauri-apps/api/cli" -> import { ... } from "@tauri-apps/plugin-cli"
|
||||
if let Some(&module) = MODULES_MAP.get(module) {
|
||||
if let Some(&new_module) = MODULES_MAP.get(module) {
|
||||
// +1 and -1, to skip modifying the import quotes
|
||||
magic_js_source
|
||||
.overwrite(
|
||||
script_start + stmt.source.span.start as i64 + 1,
|
||||
script_start + stmt.source.span.end as i64 - 1,
|
||||
module,
|
||||
new_module,
|
||||
Default::default(),
|
||||
)
|
||||
.map_err(|e| anyhow::anyhow!("{e}"))
|
||||
.context("failed to replace import source")?;
|
||||
|
||||
// if module was pluginified, add to packages
|
||||
let module = module.split_once("plugin-");
|
||||
if let Some((_, module)) = module {
|
||||
new_plugins.push(module.to_string());
|
||||
if let Some(plugin_name) = new_module.strip_prefix("@tauri-apps/plugin-") {
|
||||
new_plugins.push(plugin_name.to_string());
|
||||
}
|
||||
|
||||
// if the module is a v1 plugin, we should remove it
|
||||
if module.starts_with("tauri-plugin-") {
|
||||
npm_packages_to_remove.push(module.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
// skip parsing non @tauri-apps/api imports
|
||||
if !module.starts_with("@tauri-apps/api") {
|
||||
continue;
|
||||
}
|
||||
|
||||
let Some(specifiers) = &mut stmt.specifiers else {
|
||||
|
@ -317,6 +347,7 @@ fn migrate_imports<'a>(
|
|||
mod tests {
|
||||
|
||||
use super::*;
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
#[test]
|
||||
fn migrates_vue() {
|
||||
|
@ -376,8 +407,15 @@ const appWindow = getCurrentWebviewWindow()
|
|||
"#;
|
||||
|
||||
let mut new_plugins = Vec::new();
|
||||
let mut npm_packages_to_remove = Vec::new();
|
||||
|
||||
let migrated = migrate_imports(Path::new("file.vue"), input, &mut new_plugins).unwrap();
|
||||
let migrated = migrate_imports(
|
||||
Path::new("file.vue"),
|
||||
input,
|
||||
&mut new_plugins,
|
||||
&mut npm_packages_to_remove,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(migrated, expected);
|
||||
|
||||
|
@ -392,6 +430,7 @@ const appWindow = getCurrentWebviewWindow()
|
|||
"fs"
|
||||
]
|
||||
);
|
||||
assert_eq!(npm_packages_to_remove, Vec::<String>::new());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -436,8 +475,15 @@ const appWindow = getCurrentWebviewWindow()
|
|||
"#;
|
||||
|
||||
let mut new_plugins = Vec::new();
|
||||
let mut npm_packages_to_remove = Vec::new();
|
||||
|
||||
let migrated = migrate_imports(Path::new("file.svelte"), input, &mut new_plugins).unwrap();
|
||||
let migrated = migrate_imports(
|
||||
Path::new("file.svelte"),
|
||||
input,
|
||||
&mut new_plugins,
|
||||
&mut npm_packages_to_remove,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(migrated, expected);
|
||||
|
||||
|
@ -452,6 +498,7 @@ const appWindow = getCurrentWebviewWindow()
|
|||
"fs"
|
||||
]
|
||||
);
|
||||
assert_eq!(npm_packages_to_remove, Vec::<String>::new());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -466,6 +513,8 @@ import { open } from "@tauri-apps/api/dialog";
|
|||
import { register } from "@tauri-apps/api/globalShortcut";
|
||||
import clipboard from "@tauri-apps/api/clipboard";
|
||||
import * as fs from "@tauri-apps/api/fs";
|
||||
import { Store } from "tauri-plugin-store-api";
|
||||
import Database from "tauri-plugin-sql-api";
|
||||
import "./App.css";
|
||||
|
||||
function App() {
|
||||
|
@ -535,6 +584,8 @@ import { open } from "@tauri-apps/plugin-dialog";
|
|||
import { register } from "@tauri-apps/plugin-global-shortcut";
|
||||
import clipboard from "@tauri-apps/plugin-clipboard-manager";
|
||||
import * as fs from "@tauri-apps/plugin-fs";
|
||||
import { Store } from "@tauri-apps/plugin-store";
|
||||
import Database from "@tauri-apps/plugin-sql";
|
||||
import "./App.css";
|
||||
import * as dialog from "@tauri-apps/plugin-dialog"
|
||||
import * as cli as superCli from "@tauri-apps/plugin-cli"
|
||||
|
@ -598,8 +649,15 @@ export default App;
|
|||
"#;
|
||||
|
||||
let mut new_plugins = Vec::new();
|
||||
let mut npm_packages_to_remove = Vec::new();
|
||||
|
||||
let migrated = migrate_imports(Path::new("file.js"), input, &mut new_plugins).unwrap();
|
||||
let migrated = migrate_imports(
|
||||
Path::new("file.js"),
|
||||
input,
|
||||
&mut new_plugins,
|
||||
&mut npm_packages_to_remove,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(migrated, expected);
|
||||
|
||||
|
@ -611,8 +669,14 @@ export default App;
|
|||
"dialog",
|
||||
"global-shortcut",
|
||||
"clipboard-manager",
|
||||
"fs"
|
||||
"fs",
|
||||
"store",
|
||||
"sql"
|
||||
]
|
||||
);
|
||||
assert_eq!(
|
||||
npm_packages_to_remove,
|
||||
vec!["tauri-plugin-store-api", "tauri-plugin-sql-api"]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue