fix: build_tauri 支持从 .crate 缓存解出 NSIS 模板并保留配置行尾
registry/src 被 cargo gc 清理后改为从 tauri-bundler-*.crate 提取 installer.nsi; tauri.conf.json 备份/还原改用字节读写,避免 Windows 把 LF 改成 CRLF。
This commit is contained in:
+47
-10
@@ -17,9 +17,11 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
|
import os
|
||||||
import re
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
import sys
|
import sys
|
||||||
|
import tarfile
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
||||||
@@ -96,23 +98,57 @@ _RESTORE_OVERRIDE = """Function RestorePreviousInstallLocation
|
|||||||
FunctionEnd"""
|
FunctionEnd"""
|
||||||
|
|
||||||
|
|
||||||
def find_nsis_template() -> Path:
|
def _cargo_home() -> Path:
|
||||||
registry = Path.home() / ".cargo" / "registry" / "src"
|
return Path(os.environ.get("CARGO_HOME") or (Path.home() / ".cargo"))
|
||||||
|
|
||||||
|
|
||||||
|
def _read_template_from_src() -> str | None:
|
||||||
|
"""优先读取 registry/src 下已解压的 tauri-bundler 模板。"""
|
||||||
|
registry = _cargo_home() / "registry" / "src"
|
||||||
if not registry.exists():
|
if not registry.exists():
|
||||||
_env.die(f"未找到 Cargo registry:{registry}", "先运行一次 cargo tauri build 拉取 tauri-bundler。")
|
return None
|
||||||
candidates = [
|
candidates = [
|
||||||
path
|
path
|
||||||
for path in registry.rglob("installer.nsi")
|
for path in registry.rglob("installer.nsi")
|
||||||
if "tauri-bundler-" in str(path) and path.parts[-4:] == ("bundle", "windows", "nsis", "installer.nsi")
|
if "tauri-bundler-" in str(path) and path.parts[-4:] == ("bundle", "windows", "nsis", "installer.nsi")
|
||||||
]
|
]
|
||||||
if not candidates:
|
if not candidates:
|
||||||
_env.die("未找到 Tauri NSIS 模板(installer.nsi)", "先运行一次 cargo tauri build 拉取 tauri-bundler。")
|
return None
|
||||||
return sorted(candidates, reverse=True)[0]
|
return sorted(candidates, reverse=True)[0].read_text(encoding="utf-8")
|
||||||
|
|
||||||
|
|
||||||
|
def _read_template_from_crate() -> str | None:
|
||||||
|
"""registry/src 被 cargo gc 清理时,从缓存的 tauri-bundler-*.crate 包内直接解出模板。"""
|
||||||
|
cache = _cargo_home() / "registry" / "cache"
|
||||||
|
if not cache.exists():
|
||||||
|
return None
|
||||||
|
crates = sorted(cache.rglob("tauri-bundler-*.crate"), reverse=True)
|
||||||
|
member_suffix = "src/bundle/windows/nsis/installer.nsi"
|
||||||
|
for crate in crates:
|
||||||
|
try:
|
||||||
|
with tarfile.open(crate, "r:gz") as archive:
|
||||||
|
for member in archive.getmembers():
|
||||||
|
if member.name.endswith(member_suffix):
|
||||||
|
extracted = archive.extractfile(member)
|
||||||
|
if extracted is not None:
|
||||||
|
return extracted.read().decode("utf-8")
|
||||||
|
except (tarfile.TarError, OSError):
|
||||||
|
continue
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def read_nsis_template_text() -> str:
|
||||||
|
content = _read_template_from_src() or _read_template_from_crate()
|
||||||
|
if content is None:
|
||||||
|
_env.die(
|
||||||
|
"未找到 Tauri NSIS 模板(installer.nsi)",
|
||||||
|
"先运行一次 cargo tauri build 拉取 tauri-bundler。",
|
||||||
|
)
|
||||||
|
return content
|
||||||
|
|
||||||
|
|
||||||
def make_nsis_template(tmp_dir: Path) -> Path:
|
def make_nsis_template(tmp_dir: Path) -> Path:
|
||||||
source = find_nsis_template()
|
content = read_nsis_template_text()
|
||||||
content = source.read_text(encoding="utf-8")
|
|
||||||
|
|
||||||
hook_path = str(NSIS_HOOK.resolve())
|
hook_path = str(NSIS_HOOK.resolve())
|
||||||
include_line = f'!include "{hook_path}"'
|
include_line = f'!include "{hook_path}"'
|
||||||
@@ -141,16 +177,17 @@ def make_nsis_template(tmp_dir: Path) -> Path:
|
|||||||
|
|
||||||
def build_with_windows_nsis(tmp_dir: Path) -> None:
|
def build_with_windows_nsis(tmp_dir: Path) -> None:
|
||||||
template = make_nsis_template(tmp_dir)
|
template = make_nsis_template(tmp_dir)
|
||||||
original = TAURI_CONF.read_text(encoding="utf-8")
|
# 按字节备份/还原,避免 Windows 文本写入把原文件 LF 改成 CRLF。
|
||||||
|
original = TAURI_CONF.read_bytes()
|
||||||
try:
|
try:
|
||||||
config = json.loads(original)
|
config = json.loads(original.decode("utf-8"))
|
||||||
config["bundle"]["windows"]["nsis"]["template"] = str(template)
|
config["bundle"]["windows"]["nsis"]["template"] = str(template)
|
||||||
TAURI_CONF.write_text(json.dumps(config, ensure_ascii=False, indent=2), encoding="utf-8")
|
TAURI_CONF.write_text(json.dumps(config, ensure_ascii=False, indent=2), encoding="utf-8")
|
||||||
_env.remove_path(_env.SRC_TAURI_DIR / "target" / "release" / "bundle")
|
_env.remove_path(_env.SRC_TAURI_DIR / "target" / "release" / "bundle")
|
||||||
_env.step("编译 Tauri 桌面版(cargo tauri build)")
|
_env.step("编译 Tauri 桌面版(cargo tauri build)")
|
||||||
_env.run(["cargo", "tauri", "build"], cwd=_env.SRC_TAURI_DIR)
|
_env.run(["cargo", "tauri", "build"], cwd=_env.SRC_TAURI_DIR)
|
||||||
finally:
|
finally:
|
||||||
TAURI_CONF.write_text(original, encoding="utf-8")
|
TAURI_CONF.write_bytes(original)
|
||||||
|
|
||||||
|
|
||||||
def collect_installers(platform: str) -> None:
|
def collect_installers(platform: str) -> None:
|
||||||
|
|||||||
Reference in New Issue
Block a user