Skip to content

Commit 06718b4

Browse files
authored
feat(bundler): improve GitHub mirror URL generation with custom templates (#11096)
1 parent 9af08f9 commit 06718b4

File tree

4 files changed

+105
-17
lines changed

4 files changed

+105
-17
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"tauri-bundler": patch:feat
3+
"tauri-cli": patch:feat
4+
---
5+
6+
Add the `TAURI_BUNDLER_TOOLS_GITHUB_MIRROR_TEMPLATE` environment variable to specify a more accessible mirror template, facilitating companies, organizations, or individuals who cannot access GitHub to download the necessary files through their own mirror servers.

crates/tauri-bundler/Cargo.toml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ zip = { version = "2.0", default-features = false, features = ["deflate"] }
4444
dunce = "1"
4545
url = "2"
4646
uuid = { version = "1", features = ["v4", "v5"] }
47+
regex = "1"
4748

4849
[target."cfg(target_os = \"windows\")".dependencies]
4950
bitness = "0.4"
@@ -60,9 +61,6 @@ time = { version = "0.3", features = ["formatting"] }
6061
plist = "1"
6162
tauri-macos-sign = { version = "0.1.1-rc.0", path = "../tauri-macos-sign" }
6263

63-
[target."cfg(any(target_os = \"macos\", target_os = \"windows\"))".dependencies]
64-
regex = "1"
65-
6664
[target."cfg(target_os = \"linux\")".dependencies]
6765
heck = "0.5"
6866
ar = "0.9.0"

crates/tauri-bundler/src/bundle/windows/util.rs

Lines changed: 97 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ use std::{
88
path::{Path, PathBuf},
99
};
1010

11+
use regex::Regex;
1112
use sha2::Digest;
12-
use ureq::AgentBuilder;
1313
use url::Url;
1414
use zip::ZipArchive;
1515

@@ -69,24 +69,53 @@ pub fn download_webview2_offline_installer(base_path: &Path, arch: &str) -> crat
6969
Ok(file_path)
7070
}
7171

72-
fn create_agent_and_url(url: &str) -> crate::Result<(ureq::Agent, String)> {
73-
match std::env::var("TAURI_BUNDLER_TOOLS_GITHUB_MIRROR") {
74-
Ok(cdn) if url.starts_with("https://github.com/") => {
75-
let mut parsed_cdn = Url::parse(&cdn)?;
76-
parsed_cdn.set_path(url);
77-
Ok((AgentBuilder::new().build(), parsed_cdn.into()))
78-
}
79-
_ => Ok((
80-
AgentBuilder::new().try_proxy_from_env(true).build(),
81-
url.to_owned(),
82-
)),
72+
fn generate_github_mirror_url_from_template(github_url: &str) -> Option<String> {
73+
std::env::var("TAURI_BUNDLER_TOOLS_GITHUB_MIRROR_TEMPLATE")
74+
.ok()
75+
.and_then(|template| {
76+
let re =
77+
Regex::new(r"https://github.com/([^/]+)/([^/]+)/releases/download/([^/]+)/(.*)").unwrap();
78+
re.captures(github_url).map(|caps| {
79+
template
80+
.replace("<owner>", &caps[1])
81+
.replace("<repo>", &caps[2])
82+
.replace("<version>", &caps[3])
83+
.replace("<asset>", &caps[4])
84+
})
85+
})
86+
}
87+
88+
fn generate_github_mirror_url_from_base(github_url: &str) -> Option<String> {
89+
std::env::var("TAURI_BUNDLER_TOOLS_GITHUB_MIRROR")
90+
.ok()
91+
.and_then(|cdn| Url::parse(&cdn).ok())
92+
.map(|mut cdn| {
93+
cdn.set_path(github_url);
94+
cdn.to_string()
95+
})
96+
}
97+
98+
fn generate_github_alternative_url(url: &str) -> Option<(ureq::Agent, String)> {
99+
if !url.starts_with("https://github.com/") {
100+
return None;
83101
}
102+
103+
generate_github_mirror_url_from_template(url)
104+
.or_else(|| generate_github_mirror_url_from_base(url))
105+
.map(|alt_url| (ureq::AgentBuilder::new().build(), alt_url))
106+
}
107+
108+
fn create_agent_and_url(url: &str) -> (ureq::Agent, String) {
109+
generate_github_alternative_url(url).unwrap_or((
110+
ureq::AgentBuilder::new().try_proxy_from_env(true).build(),
111+
url.to_owned(),
112+
))
84113
}
85114

86115
pub fn download(url: &str) -> crate::Result<Vec<u8>> {
87-
log::info!(action = "Downloading"; "{}", url);
116+
let (agent, final_url) = create_agent_and_url(url);
88117

89-
let (agent, final_url) = create_agent_and_url(url)?;
118+
log::info!(action = "Downloading"; "{}", final_url);
90119

91120
let response = agent.get(&final_url).call().map_err(Box::new)?;
92121
let mut bytes = Vec::new();
@@ -196,3 +225,57 @@ pub fn os_bitness<'a>() -> Option<&'a str> {
196225
_ => None,
197226
}
198227
}
228+
229+
#[cfg(test)]
230+
mod tests {
231+
use super::generate_github_mirror_url_from_template;
232+
use std::env;
233+
234+
const GITHUB_ASSET_URL: &str =
235+
"https://github.com/wixtoolset/wix3/releases/download/wix3112rtm/wix311-binaries.zip";
236+
const NON_GITHUB_ASSET_URL: &str = "https://someotherwebsite.com/somefile.zip";
237+
238+
#[test]
239+
fn test_generate_mirror_url_no_env_var() {
240+
env::remove_var("TAURI_BUNDLER_TOOLS_GITHUB_MIRROR_TEMPLATE");
241+
242+
assert!(generate_github_mirror_url_from_template(GITHUB_ASSET_URL).is_none());
243+
}
244+
245+
#[test]
246+
fn test_generate_mirror_url_non_github_url() {
247+
env::set_var(
248+
"TAURI_BUNDLER_TOOLS_GITHUB_MIRROR_TEMPLATE",
249+
"https://mirror.example.com/<owner>/<repo>/releases/download/<version>/<asset>",
250+
);
251+
252+
assert!(generate_github_mirror_url_from_template(NON_GITHUB_ASSET_URL).is_none());
253+
}
254+
255+
struct TestCase {
256+
template: &'static str,
257+
expected_url: &'static str,
258+
}
259+
260+
#[test]
261+
fn test_generate_mirror_url_correctly() {
262+
let test_cases = vec![
263+
TestCase {
264+
template: "https://mirror.example.com/<owner>/<repo>/releases/download/<version>/<asset>",
265+
expected_url: "https://mirror.example.com/wixtoolset/wix3/releases/download/wix3112rtm/wix311-binaries.zip",
266+
},
267+
TestCase {
268+
template: "https://mirror.example.com/<asset>",
269+
expected_url: "https://mirror.example.com/wix311-binaries.zip",
270+
},
271+
];
272+
273+
for case in test_cases {
274+
env::set_var("TAURI_BUNDLER_TOOLS_GITHUB_MIRROR_TEMPLATE", case.template);
275+
assert_eq!(
276+
generate_github_mirror_url_from_template(GITHUB_ASSET_URL),
277+
Some(case.expected_url.to_string())
278+
);
279+
}
280+
}
281+
}

crates/tauri-cli/ENVIRONMENT_VARIABLES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ These environment variables are inputs to the CLI which may have an equivalent C
1616
- `TAURI_LINUX_AYATANA_APPINDICATOR` — Set this var to `true` or `1` to force usage of `libayatana-appindicator` for system tray on Linux.
1717
- `TAURI_BUNDLER_WIX_FIPS_COMPLIANT` — Specify the bundler's WiX `FipsCompliant` option.
1818
- `TAURI_BUNDLER_TOOLS_GITHUB_MIRROR` - Specify a GitHub mirror to download files and tools used by tauri bundler.
19+
- `TAURI_BUNDLER_TOOLS_GITHUB_MIRROR_TEMPLATE` - Specify a GitHub mirror template to download files and tools used by tauri bundler, for example: `https://mirror.example.com/<owner>/<repo>/releases/download/<version>/<asset>`.
1920
- `TAURI_SKIP_SIDECAR_SIGNATURE_CHECK` - Skip signing sidecars.
2021
- `TAURI_SIGNING_PRIVATE_KEY` — Private key used to sign your app bundles, can be either a string or a path to the file.
2122
- `TAURI_SIGNING_PRIVATE_KEY_PASSWORD` — The signing private key password, see `TAURI_SIGNING_PRIVATE_KEY`.

0 commit comments

Comments
 (0)