Skip to content

Commit

Permalink
feat(cli): automate API -> plugin migration (#7561)
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasfernog committed Aug 8, 2023
1 parent d010bc0 commit 8af2497
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 4 deletions.
6 changes: 6 additions & 0 deletions .changes/migrate-plugins.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"tauri-cli": patch:feat
"@tauri-apps/cli": patch:feat
---

The `migrate` command now automatically reads all JavaScript files and updates `@tauri-apps/api` import paths and install the missing plugins.
9 changes: 7 additions & 2 deletions tooling/cli/src/helpers/app_paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use tauri_utils::config::parse::{

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

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

let mut builder = WalkBuilder::new(dir);
let mut builder = WalkBuilder::new(path);
builder.add_custom_ignore_filename(".taurignore");
let _ = builder.add_ignore(default_gitignore);
builder
}

fn lookup<F: Fn(&PathBuf) -> bool>(dir: &Path, checker: F) -> Option<PathBuf> {
let mut builder = walk_builder(dir);
builder
.require_git(false)
.ignore(false)
Expand Down
40 changes: 39 additions & 1 deletion tooling/cli/src/helpers/npm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT

use std::{fmt::Display, path::Path};
use crate::{helpers::cross_command, Result};
use std::{fmt::Display, path::Path, process::ExitStatus};

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

found
}

pub fn install(&self, dependencies: &[String]) -> Result<ExitStatus> {
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)
}
}
}
}
93 changes: 93 additions & 0 deletions tooling/cli/src/migrate/frontend.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT

use crate::{
helpers::{app_paths::walk_builder, npm::PackageManager},
Result,
};

use std::{
fs::{read_to_string, write},
path::Path,
process::Command,
};

const CORE_API_MODULES: &[&str] = &["event", "path", "tauri", "mocks"];
const JS_EXTENSIONS: &[&str] = &["js", "jsx", "ts", "tsx", "mjs"];

pub fn migrate(app_dir: &Path, tauri_dir: &Path) -> Result<()> {
let mut new_npm_packages = Vec::new();
let mut new_cargo_packages = Vec::new();

let pm = PackageManager::from_project(app_dir)
.into_iter()
.next()
.unwrap_or(PackageManager::Npm);

let tauri_api_import_regex = regex::Regex::new(r"@tauri-apps/api/(\w+)").unwrap();

for entry in walk_builder(app_dir).build().flatten() {
if entry.file_type().map(|t| t.is_file()).unwrap_or_default() {
let path = entry.path();
let ext = path.extension().unwrap_or_default();
if JS_EXTENSIONS.iter().any(|e| e == &ext) {
let js_contents = read_to_string(path)?;

let new_contents =
tauri_api_import_regex.replace_all(&js_contents, |cap: &regex::Captures<'_>| {
let module = cap.get(1).unwrap().as_str();
let original = cap.get(0).unwrap().as_str();

if CORE_API_MODULES.contains(&module) {
original.to_string()
} else {
let plugin = format!("@tauri-apps/plugin-{module}");
log::info!(
"Replacing `{original}` with `{plugin}` on {}",
path.display()
);

new_npm_packages.push(plugin.clone());
new_cargo_packages.push(format!(
"tauri-plugin-{}",
if module == "clipboard" {
"clipboard-manager"
} else {
module
}
));

plugin
}
});

if new_contents != js_contents {
write(path, new_contents.as_bytes())?;
}
}
}
}

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()?;
}

Ok(())
}
8 changes: 7 additions & 1 deletion tooling/cli/src/migrate/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,22 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT

use crate::{helpers::app_paths::tauri_dir, Result};
use crate::{
helpers::app_paths::{app_dir, tauri_dir},
Result,
};

mod config;
mod frontend;
mod manifest;

pub fn command() -> Result<()> {
let tauri_dir = tauri_dir();
let app_dir = app_dir();

config::migrate(&tauri_dir)?;
manifest::migrate(&tauri_dir)?;
frontend::migrate(app_dir, &tauri_dir)?;

Ok(())
}

0 comments on commit 8af2497

Please sign in to comment.