Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changes/android-debug-application-id-suffix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"tauri-cli": "patch:bug"
---

Scope Android debug `applicationIdSuffix` updates to the `buildTypes.debug` block.
92 changes: 80 additions & 12 deletions crates/tauri-cli/src/mobile/android/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,32 +223,56 @@ fn sync_debug_application_id_suffix(
}

fn set_debug_application_id_suffix(build_gradle: &str, suffix: Option<&str>) -> Option<String> {
static BUILD_TYPES_RE: OnceLock<regex::Regex> = OnceLock::new();
static DEBUG_BUILD_TYPE_RE: OnceLock<regex::Regex> = OnceLock::new();

let build_types_re = BUILD_TYPES_RE.get_or_init(|| {
regex::Regex::new(r#"(?m)\bbuildTypes\b\s*\{"#).expect("valid buildTypes regex")
});
let debug_build_type_re = DEBUG_BUILD_TYPE_RE.get_or_init(|| {
regex::Regex::new(r#"(?m)(?:\bgetByName\(\s*"debug"\s*\)|\bdebug\b)\s*\{"#)
.expect("valid debug build type regex")
});

for build_type_match in debug_build_type_re.find_iter(build_gradle) {
let Some(opening_brace) = build_gradle[build_type_match.start()..]
for build_types_match in build_types_re.find_iter(build_gradle) {
let Some(build_types_opening_brace) = build_gradle[build_types_match.start()..]
.find('{')
.map(|index| build_type_match.start() + index)
.map(|index| build_types_match.start() + index)
else {
continue;
};
let Some(closing_brace) = find_matching_brace(build_gradle, opening_brace) else {
let Some(build_types_closing_brace) =
find_matching_brace(build_gradle, build_types_opening_brace)
else {
continue;
};

let debug_block = &build_gradle[opening_brace..closing_brace];
let updated_debug_block = set_application_id_suffix_in_block(debug_block, suffix);
let mut updated_build_gradle =
String::with_capacity(build_gradle.len() + updated_debug_block.len());
updated_build_gradle.push_str(&build_gradle[..opening_brace]);
updated_build_gradle.push_str(&updated_debug_block);
updated_build_gradle.push_str(&build_gradle[closing_brace..]);
return Some(updated_build_gradle);
let build_types_block = &build_gradle[build_types_opening_brace..build_types_closing_brace];
for build_type_match in debug_build_type_re.find_iter(build_types_block) {
let build_type_start = build_types_opening_brace + build_type_match.start();
let Some(opening_brace) = build_gradle[build_type_start..]
.find('{')
.map(|index| build_type_start + index)
else {
continue;
};
let Some(closing_brace) = find_matching_brace(build_gradle, opening_brace) else {
continue;
};

if closing_brace > build_types_closing_brace {
continue;
}

let debug_block = &build_gradle[opening_brace..closing_brace];
let updated_debug_block = set_application_id_suffix_in_block(debug_block, suffix);
let mut updated_build_gradle =
String::with_capacity(build_gradle.len() + updated_debug_block.len());
updated_build_gradle.push_str(&build_gradle[..opening_brace]);
updated_build_gradle.push_str(&updated_debug_block);
updated_build_gradle.push_str(&build_gradle[closing_brace..]);
return Some(updated_build_gradle);
}
}

None
Expand Down Expand Up @@ -1144,6 +1168,50 @@ android {
assert!(updated.contains(r#"applicationIdSuffix = ".release""#));
}

#[test]
fn writes_debug_suffix_only_in_build_types_debug_block() {
let build_gradle = r#"
android {
signingConfigs {
debug {
storeFile = file("debug.keystore")
}
}
buildTypes {
debug {
manifestPlaceholders["usesCleartextTraffic"] = "true"
}
}
}
"#;

let updated = set_debug_application_id_suffix(build_gradle, Some(".debug")).unwrap();
let (signing_configs_block, build_types_block) =
updated.split_once(" buildTypes {").unwrap();

assert!(!signing_configs_block.contains("applicationIdSuffix"));
assert!(build_types_block.contains(
r#" debug {
applicationIdSuffix = ".debug"
manifestPlaceholders["usesCleartextTraffic"] = "true""#
));
}

#[test]
fn ignores_debug_blocks_outside_build_types() {
let build_gradle = r#"
android {
signingConfigs {
debug {
storeFile = file("debug.keystore")
}
}
}
"#;

assert!(set_debug_application_id_suffix(build_gradle, Some(".debug")).is_none());
}

#[test]
fn writes_debug_suffix_before_nested_blocks() {
let build_gradle = r#"
Expand Down
Loading