feat(download): 把 download.region / download.mirror_preference 接进源选择(M294)

两个键此前在引擎侧零消费者:设置页画着三档 chip,改它不影响任何一次下载。
现在它们是 RegionProfile 之上的一层显式覆盖(读时叠加,不落盘,region.json
仍是自动判定的结论):

  显式 mirror_preference(official/mirror)
    > 显式 region(cn/global)
      > 自动探测(时区+语言+系统信号)与 24h 缓存

- core::download::preference(新):两个枚举的 from_raw(未知值/空串 ⇒ auto)
  与 apply;两个键都落到 RegionMode 这一个「谁在前」开关上,不造第二套排序
- region::RegionProfile::overridden:在已有判定上叠一层模式(探测逻辑不动)
- DownloadTuning 加 region / mirror_preference 与 apply_source_selection
  (组合顺序 = 优先级),shared::build 改用它;默认 Auto ⇒ 逐值等于今天
- 未进 RawTuning:CLI 的 tuning() 用完整字段字面量构造它,加字段会连累
  crates/cli(不在本 mission scope),改走 with_source_selection 入口
- presenter 的 tuning_of 读这两个键(否则 GUI 侧仍是假行)

判据断具体源名序列:不设/auto/未知 ⇒ ["bmclapi","official"] /
["official","bmclapi"] 逐项不变;official/mirror/cn/global ⇒ 顺序跟着换;
另有一条从设置原文到引擎 plan() 的端到端用例。
This commit is contained in:
worker-mirrorwire committed 2026-11-13 08:26:30 +08:00
1 parent c2fc4b7f26
commit 0f64acbd05
9 files changed
+454 -5

No files matched your search

+2 -2
View File
@@ -141,7 +141,7 @@ pub fn constructions(cache_root: impl AsRef<Path>) -> usize {
/// 真实构造(**presenter 侧**唯一一处 `DownloadEngine::new` 的宿主装配;CLI 走 [`engine_with_tuning`])。
/// 装配参数从该数据根的 [`wanted`] 取,不用裸 `EngineConfig::default()`(M193):并发 → `Semaphore`
/// 容量、尝试次数 → `attempts_for()` 上限、gh_proxy → 地区档案(`expand()` 只认档案里那个前缀)。
/// 容量、尝试次数 → `attempts_for()` 上限、gh_proxy/地区/镜像偏好 → 地区档案(`expand()` 只认它)。
fn build(cache_root: &Path) -> DownloadEngine {
let now = now_ms();
let tune = wanted(cache_root);
@@ -154,7 +154,7 @@ fn build(cache_root: &Path) -> DownloadEngine {
DownloadEngine::new(
tune.apply_to(EngineConfig::default()),
Arc::new(MirrorTable::builtin()),
Arc::new(tune.apply_gh_proxy(region)),
Arc::new(tune.apply_source_selection(region)),
Arc::new(HealthRegistry::open_in(cache_root, now)),
Arc::new(ContentCache::open(cache_root)),
)