Skip to content

Commit 1e1d839

Browse files
authored
feat(build): add function to rewrite AndroidManifest.xml (#7450)
1 parent 522de0e commit 1e1d839

2 files changed

Lines changed: 88 additions & 1 deletion

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"tauri-build": patch:feat
3+
---
4+
5+
Added the `mobile::update_android_manifest` function.

core/tauri-build/src/mobile.rs

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
use std::{
66
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},
88
path::{Path, PathBuf},
99
};
1010

@@ -180,6 +180,52 @@ pub fn update_entitlements<F: FnOnce(&mut plist::Dictionary)>(f: F) -> Result<()
180180
Ok(())
181181
}
182182

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+
183229
pub(crate) fn generate_gradle_files(project_dir: PathBuf) -> Result<()> {
184230
let gradle_settings_path = project_dir.join("tauri.settings.gradle");
185231
let app_build_gradle_path = project_dir.join("app").join("tauri.build.gradle.kts");
@@ -232,3 +278,39 @@ dependencies {"
232278

233279
Ok(())
234280
}
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

Comments
 (0)