|
4 | 4 |
|
5 | 5 | use std::{ |
6 | 6 | env::{var, var_os}, |
7 | | - fs::{copy, create_dir, create_dir_all, remove_dir_all, write}, |
| 7 | + fs::{copy, create_dir, create_dir_all, read_to_string, remove_dir_all, write}, |
8 | 8 | path::{Path, PathBuf}, |
9 | 9 | }; |
10 | 10 |
|
@@ -180,6 +180,52 @@ pub fn update_entitlements<F: FnOnce(&mut plist::Dictionary)>(f: F) -> Result<() |
180 | 180 | Ok(()) |
181 | 181 | } |
182 | 182 |
|
| 183 | +fn xml_block_comment(id: &str) -> String { |
| 184 | + format!("<!-- {id}. AUTO-GENERATED. DO NOT REMOVE. -->") |
| 185 | +} |
| 186 | + |
| 187 | +fn insert_into_xml(xml: &str, block_identifier: &str, parent_tag: &str, contents: &str) -> String { |
| 188 | + let block_comment = xml_block_comment(block_identifier); |
| 189 | + |
| 190 | + let mut rewritten = Vec::new(); |
| 191 | + let mut found_block = false; |
| 192 | + let parent_closing_tag = format!("</{parent_tag}>"); |
| 193 | + for line in xml.split('\n') { |
| 194 | + if line.contains(&block_comment) { |
| 195 | + found_block = !found_block; |
| 196 | + continue; |
| 197 | + } |
| 198 | + |
| 199 | + // found previous block which should be removed |
| 200 | + if found_block { |
| 201 | + continue; |
| 202 | + } |
| 203 | + |
| 204 | + if let Some(index) = line.find(&parent_closing_tag) { |
| 205 | + let identation = " ".repeat(index + 4); |
| 206 | + rewritten.push(format!("{}{}", identation, block_comment)); |
| 207 | + for l in contents.split('\n') { |
| 208 | + rewritten.push(format!("{}{}", identation, l)); |
| 209 | + } |
| 210 | + rewritten.push(format!("{}{}", identation, block_comment)); |
| 211 | + } |
| 212 | + |
| 213 | + rewritten.push(line.to_string()); |
| 214 | + } |
| 215 | + |
| 216 | + rewritten.join("\n").to_string() |
| 217 | +} |
| 218 | + |
| 219 | +pub fn update_android_manifest(block_identifier: &str, parent: &str, insert: String) -> Result<()> { |
| 220 | + if let Some(project_path) = var_os("TAURI_ANDROID_PROJECT_PATH").map(PathBuf::from) { |
| 221 | + let manifest_path = project_path.join("app/src/main/AndroidManifest.xml"); |
| 222 | + let manifest = read_to_string(&manifest_path)?; |
| 223 | + let rewritten = insert_into_xml(&manifest, block_identifier, parent, &insert); |
| 224 | + write(manifest_path, rewritten)?; |
| 225 | + } |
| 226 | + Ok(()) |
| 227 | +} |
| 228 | + |
183 | 229 | pub(crate) fn generate_gradle_files(project_dir: PathBuf) -> Result<()> { |
184 | 230 | let gradle_settings_path = project_dir.join("tauri.settings.gradle"); |
185 | 231 | let app_build_gradle_path = project_dir.join("app").join("tauri.build.gradle.kts"); |
@@ -232,3 +278,39 @@ dependencies {" |
232 | 278 |
|
233 | 279 | Ok(()) |
234 | 280 | } |
| 281 | + |
| 282 | +#[cfg(test)] |
| 283 | +mod tests { |
| 284 | + #[test] |
| 285 | + fn insert_into_xml() { |
| 286 | + let manifest = format!( |
| 287 | + r#"<manifest> |
| 288 | + <application> |
| 289 | + <intent-filter> |
| 290 | + </intent-filter> |
| 291 | + </application> |
| 292 | +</manifest>"# |
| 293 | + ); |
| 294 | + let id = "tauritest"; |
| 295 | + let new = super::insert_into_xml(&manifest, id, "application", "<something></something>"); |
| 296 | + |
| 297 | + let block_id_comment = super::xml_block_comment(id); |
| 298 | + let expected = format!( |
| 299 | + r#"<manifest> |
| 300 | + <application> |
| 301 | + <intent-filter> |
| 302 | + </intent-filter> |
| 303 | + {block_id_comment} |
| 304 | + <something></something> |
| 305 | + {block_id_comment} |
| 306 | + </application> |
| 307 | +</manifest>"# |
| 308 | + ); |
| 309 | + |
| 310 | + assert_eq!(new, expected); |
| 311 | + |
| 312 | + // assert it's still the same after an empty update |
| 313 | + let new = super::insert_into_xml(&expected, id, "application", "<something></something>"); |
| 314 | + assert_eq!(new, expected); |
| 315 | + } |
| 316 | +} |
0 commit comments