mirror of
https://github.com/tauri-apps/tauri.git
synced 2026-04-01 10:01:07 +02:00
refactor(android): fix race conditions processing Android plugin project as dependency (#6968)
This commit is contained in:
committed by
GitHub
parent
6fb5734d2f
commit
59db76af4c
@@ -15,9 +15,7 @@ use tauri_utils::{
|
||||
};
|
||||
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
env::var_os,
|
||||
fs::{read_to_string, write},
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
@@ -270,51 +268,7 @@ pub fn try_build(attributes: Attributes) -> Result<()> {
|
||||
println!("cargo:rustc-env=TAURI_ANDROID_PACKAGE_PREFIX={android_package_prefix}");
|
||||
|
||||
if let Some(project_dir) = var_os("TAURI_ANDROID_PROJECT_PATH").map(PathBuf::from) {
|
||||
let gradle_settings_path = project_dir.join("tauri.settings.gradle");
|
||||
let app_build_gradle_path = project_dir.join("app").join("tauri.build.gradle.kts");
|
||||
|
||||
let mut gradle_settings =
|
||||
"// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.\n".to_string();
|
||||
let mut app_build_gradle = "// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
val implementation by configurations
|
||||
dependencies {"
|
||||
.to_string();
|
||||
|
||||
let plugins_json_path = project_dir.join(".tauri").join("plugins.json");
|
||||
let mut plugins: HashMap<String, mobile::PluginMetadata> = if plugins_json_path.exists() {
|
||||
let s = read_to_string(&plugins_json_path)?;
|
||||
println!("cargo:rerun-if-changed={}", plugins_json_path.display());
|
||||
serde_json::from_str(&s)?
|
||||
} else {
|
||||
Default::default()
|
||||
};
|
||||
|
||||
plugins.insert(
|
||||
"tauri-android".into(),
|
||||
mobile::PluginMetadata {
|
||||
path: var_os("DEP_TAURI_ANDROID_LIBRARY_PATH").map(PathBuf::from).expect("missing `DEP_TAURI_ANDROID_LIBRARY_PATH` environment variable; did you add `tauri` as a dependency to this crate?"),
|
||||
},
|
||||
);
|
||||
|
||||
for (plugin_name, plugin) in plugins {
|
||||
gradle_settings.push_str(&format!("include ':{plugin_name}'"));
|
||||
gradle_settings.push('\n');
|
||||
gradle_settings.push_str(&format!(
|
||||
"project(':{plugin_name}').projectDir = new File({:?})",
|
||||
tauri_utils::display_path(plugin.path)
|
||||
));
|
||||
gradle_settings.push('\n');
|
||||
|
||||
app_build_gradle.push('\n');
|
||||
app_build_gradle.push_str(&format!(r#" implementation(project(":{plugin_name}"))"#));
|
||||
}
|
||||
app_build_gradle.push_str("\n}");
|
||||
|
||||
write(&gradle_settings_path, gradle_settings)
|
||||
.context("failed to write tauri.settings.gradle")?;
|
||||
|
||||
write(&app_build_gradle_path, app_build_gradle)
|
||||
.context("failed to write tauri.build.gradle.kts")?;
|
||||
mobile::generate_gradle_files(project_dir)?;
|
||||
}
|
||||
|
||||
cfg_alias("dev", !has_feature("custom-protocol"));
|
||||
|
||||
@@ -3,19 +3,15 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
env::{var, var_os},
|
||||
fs::{copy, create_dir, create_dir_all, read_to_string, remove_dir_all, File},
|
||||
io::Write,
|
||||
fs::{copy, create_dir, create_dir_all, remove_dir_all, write},
|
||||
path::{Path, PathBuf},
|
||||
thread::sleep,
|
||||
time::{Duration, SystemTime},
|
||||
};
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Eq, PartialEq)]
|
||||
#[derive(Debug, Default, Deserialize, Serialize, Eq, PartialEq)]
|
||||
pub(crate) struct PluginMetadata {
|
||||
pub path: PathBuf,
|
||||
}
|
||||
@@ -69,48 +65,7 @@ impl PluginBuilder {
|
||||
)
|
||||
.context("failed to copy tauri-api to the plugin project")?;
|
||||
|
||||
if let Some(project_dir) = var_os("TAURI_ANDROID_PROJECT_PATH").map(PathBuf::from) {
|
||||
let pkg_name = var("CARGO_PKG_NAME").unwrap();
|
||||
println!("cargo:rerun-if-env-changed=TAURI_ANDROID_PROJECT_PATH");
|
||||
|
||||
let plugins_json_path = project_dir.join(".tauri").join("plugins.json");
|
||||
let mut plugins: HashMap<String, PluginMetadata> = if plugins_json_path.exists() {
|
||||
let s = read_to_string(&plugins_json_path)?;
|
||||
serde_json::from_str(&s)?
|
||||
} else {
|
||||
Default::default()
|
||||
};
|
||||
|
||||
let metadata = PluginMetadata { path: source };
|
||||
let already_set = plugins
|
||||
.get(&pkg_name)
|
||||
.map(|m| m == &metadata)
|
||||
.unwrap_or(false);
|
||||
if !already_set {
|
||||
plugins.insert(pkg_name, metadata);
|
||||
let mut file = File::create(&plugins_json_path)?;
|
||||
file.write_all(serde_json::to_string(&plugins)?.as_bytes())?;
|
||||
file.flush()?;
|
||||
|
||||
// wait for the file to be written before moving to the app build script
|
||||
let now = SystemTime::now()
|
||||
.checked_sub(Duration::from_millis(10))
|
||||
.unwrap();
|
||||
let mut attempts = 0;
|
||||
while !plugins_json_path
|
||||
.metadata()
|
||||
.map(|m| m.modified().unwrap() >= now)
|
||||
.unwrap_or(false)
|
||||
{
|
||||
attempts += 1;
|
||||
if attempts == 10 {
|
||||
anyhow::bail!("Could not determine whether the plugins.json file has been modified or not, please rerun the build.");
|
||||
}
|
||||
sleep(Duration::from_millis(100));
|
||||
}
|
||||
}
|
||||
println!("cargo:rerun-if-changed={}", plugins_json_path.display());
|
||||
}
|
||||
println!("cargo:android_library_path={}", source.display());
|
||||
}
|
||||
}
|
||||
#[cfg(target_os = "macos")]
|
||||
@@ -190,3 +145,56 @@ fn copy_folder(source: &Path, target: &Path, ignore_paths: &[&str]) -> Result<()
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn generate_gradle_files(project_dir: PathBuf) -> Result<()> {
|
||||
let gradle_settings_path = project_dir.join("tauri.settings.gradle");
|
||||
let app_build_gradle_path = project_dir.join("app").join("tauri.build.gradle.kts");
|
||||
|
||||
let mut gradle_settings =
|
||||
"// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.\n".to_string();
|
||||
let mut app_build_gradle = "// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
val implementation by configurations
|
||||
dependencies {"
|
||||
.to_string();
|
||||
|
||||
for (env, value) in std::env::vars_os() {
|
||||
let env = env.to_string_lossy();
|
||||
if env.starts_with("DEP_") && env.ends_with("_ANDROID_LIBRARY_PATH") {
|
||||
let name_len = env.len() - "DEP_".len() - "_ANDROID_LIBRARY_PATH".len();
|
||||
let mut plugin_name = env
|
||||
.chars()
|
||||
.skip("DEP_".len())
|
||||
.take(name_len)
|
||||
.collect::<String>()
|
||||
.to_lowercase()
|
||||
.replace('_', "-");
|
||||
if plugin_name == "tauri" {
|
||||
plugin_name = "tauri-android".into();
|
||||
}
|
||||
let plugin_path = PathBuf::from(value);
|
||||
|
||||
gradle_settings.push_str(&format!("include ':{plugin_name}'"));
|
||||
gradle_settings.push('\n');
|
||||
gradle_settings.push_str(&format!(
|
||||
"project(':{plugin_name}').projectDir = new File({:?})",
|
||||
tauri_utils::display_path(plugin_path)
|
||||
));
|
||||
gradle_settings.push('\n');
|
||||
|
||||
app_build_gradle.push('\n');
|
||||
app_build_gradle.push_str(&format!(r#" implementation(project(":{plugin_name}"))"#));
|
||||
}
|
||||
}
|
||||
|
||||
app_build_gradle.push_str("\n}");
|
||||
|
||||
write(&gradle_settings_path, gradle_settings).context("failed to write tauri.settings.gradle")?;
|
||||
|
||||
write(&app_build_gradle_path, app_build_gradle)
|
||||
.context("failed to write tauri.build.gradle.kts")?;
|
||||
|
||||
println!("cargo:rerun-if-changed={}", gradle_settings_path.display());
|
||||
println!("cargo:rerun-if-changed={}", app_build_gradle_path.display());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -116,6 +116,7 @@ fn main() {
|
||||
)
|
||||
.expect("failed to write proguard-tauri.pro");
|
||||
}
|
||||
|
||||
let lib_path =
|
||||
PathBuf::from(std::env::var_os("CARGO_MANIFEST_DIR").unwrap()).join("mobile/android");
|
||||
println!("cargo:android_library_path={}", lib_path.display());
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
name = "tauri-plugin-sample"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
links = "tauri-plugin-sample"
|
||||
|
||||
[dependencies]
|
||||
tauri = { path = "../../../../core/tauri" }
|
||||
|
||||
@@ -81,6 +81,12 @@ pub fn command(options: Options, noise_level: NoiseLevel) -> Result<()> {
|
||||
set_var("WRY_RUSTWEBVIEWCLIENT_CLASS_EXTENSION", "");
|
||||
set_var("WRY_RUSTWEBVIEW_CLASS_INIT", "");
|
||||
|
||||
let profile = if options.debug {
|
||||
Profile::Debug
|
||||
} else {
|
||||
Profile::Release
|
||||
};
|
||||
|
||||
ensure_init(config.project_dir(), MobileTarget::Android)?;
|
||||
|
||||
let mut env = env()?;
|
||||
@@ -101,7 +107,7 @@ pub fn command(options: Options, noise_level: NoiseLevel) -> Result<()> {
|
||||
)?;
|
||||
|
||||
let open = options.open;
|
||||
run_build(options, config, &mut env, noise_level)?;
|
||||
run_build(options, profile, config, &mut env, noise_level)?;
|
||||
|
||||
if open {
|
||||
open_and_wait(config, &env);
|
||||
@@ -115,16 +121,11 @@ pub fn command(options: Options, noise_level: NoiseLevel) -> Result<()> {
|
||||
|
||||
fn run_build(
|
||||
mut options: Options,
|
||||
profile: Profile,
|
||||
config: &AndroidConfig,
|
||||
env: &mut Env,
|
||||
noise_level: NoiseLevel,
|
||||
) -> Result<()> {
|
||||
let profile = if options.debug {
|
||||
Profile::Debug
|
||||
} else {
|
||||
Profile::Release
|
||||
};
|
||||
|
||||
if !(options.apk || options.aab) {
|
||||
// if the user didn't specify the format to build, we'll do both
|
||||
options.apk = true;
|
||||
|
||||
@@ -24,7 +24,7 @@ use std::{
|
||||
env::{set_var, temp_dir},
|
||||
ffi::OsString,
|
||||
fmt::Write,
|
||||
fs::{create_dir_all, read_to_string, remove_file, write},
|
||||
fs::{read_to_string, write},
|
||||
net::SocketAddr,
|
||||
path::PathBuf,
|
||||
process::{exit, ExitStatus},
|
||||
@@ -315,13 +315,8 @@ fn ensure_init(project_dir: PathBuf, target: Target) -> Result<()> {
|
||||
project_dir.display(),
|
||||
target.command_name(),
|
||||
)
|
||||
} else {
|
||||
if target == Target::Android {
|
||||
create_dir_all(project_dir.join(".tauri"))?;
|
||||
let _ = remove_file(project_dir.join(".tauri").join("plugins.json"));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn log_finished(outputs: Vec<PathBuf>, kind: &str) {
|
||||
|
||||
@@ -15,7 +15,7 @@ open class BuildTask : DefaultTask() {
|
||||
var release: Boolean? = null
|
||||
|
||||
@TaskAction
|
||||
fun build() {
|
||||
fun assemble() {
|
||||
val executable = """{{tauri-binary}}""";
|
||||
try {
|
||||
runTauriCli(executable)
|
||||
|
||||
@@ -6,6 +6,7 @@ description = ""
|
||||
edition = "2021"
|
||||
rust-version = "1.65"
|
||||
exclude = ["/examples", "/webview-dist", "/webview-src", "/node_modules"]
|
||||
links = "tauri-plugin-{{ plugin_name }}"
|
||||
|
||||
[dependencies]
|
||||
tauri = {{ tauri_dep }}
|
||||
|
||||
Reference in New Issue
Block a user