-
Notifications
You must be signed in to change notification settings - Fork 18
fix: portable runtime layout #111
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
71b2dba
b1181d7
558702b
ff74aba
5b766ca
28ce722
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -14,17 +14,30 @@ def make_project_layout( | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| product_name: str = "AstrBot", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cargo_toml: str = '[package]\nname = "astrbot-desktop-tauri"\n', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| marker_name: str = "portable.flag\n", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tauri_resources: dict[str, str] | None = None, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) -> dict[str, Path]: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| project_root = Path(self.enterContext(tempfile.TemporaryDirectory())) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| script_path = project_root / "scripts" / "ci" / "package_windows_portable.py" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tauri_config_path = project_root / "src-tauri" / "tauri.conf.json" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cargo_toml_path = project_root / "src-tauri" / "Cargo.toml" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| marker_path = project_root / MODULE.PORTABLE_RUNTIME_MARKER_RELATIVE_PATH | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if tauri_resources is None: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tauri_resources = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "../resources/backend": "backend", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "../resources/webui": "webui", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| script_path.parent.mkdir(parents=True) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| script_path.write_text("# placeholder") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tauri_config_path.parent.mkdir(parents=True) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tauri_config_path.write_text(json.dumps({"productName": product_name})) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tauri_config_path.write_text( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| json.dumps( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "productName": product_name, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "bundle": {"resources": tauri_resources}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cargo_toml_path.write_text(cargo_toml) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| marker_path.parent.mkdir(parents=True, exist_ok=True) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| marker_path.write_text(marker_name) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -198,6 +211,41 @@ def test_load_project_config_from_returns_root_product_and_marker(self): | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.assertEqual(project_config.product_name, "AstrBot") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.assertEqual(project_config.binary_name, "astrbot-desktop-tauri") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.assertEqual(project_config.portable_marker_name, "portable.flag") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.assertEqual(project_config.backend_layout_relative_path, Path("backend")) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.assertEqual(project_config.webui_layout_relative_path, Path("webui")) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def test_load_project_config_from_reads_portable_layout_aliases_from_tauri_resources( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| layout = self.make_project_layout( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tauri_resources={ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "../resources/backend": "runtime/backend", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "../resources/webui": "runtime/webui", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| project_config = MODULE.load_project_config_from(layout["script_path"]) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.assertEqual( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| project_config.backend_layout_relative_path, Path("runtime/backend") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.assertEqual( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| project_config.webui_layout_relative_path, Path("runtime/webui") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def test_load_project_config_from_requires_exact_tauri_resource_source_keys(self): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| layout = self.make_project_layout( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tauri_resources={ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "./../resources/backend": "runtime/backend", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "../resources/webui": "runtime/webui", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with self.assertRaisesRegex( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ValueError, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| re.escape("Missing bundle.resources alias for ../resources/backend"), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MODULE.load_project_config_from(layout["script_path"]) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def test_normalize_legacy_nightly_version_returns_base_version_and_suffix(self): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.assertEqual( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -360,6 +408,8 @@ def test_resolve_main_executable_path_uses_binary_name_not_product_name(self): | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| product_name="AstrBot", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| binary_name="astrbot-desktop-tauri", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| portable_marker_name="portable.flag", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| backend_layout_relative_path=Path("backend"), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| webui_layout_relative_path=Path("webui"), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.assertEqual( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -424,12 +474,20 @@ def test_populate_portable_root_copies_release_bundle_contents(self): | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.assertTrue((destination_root / "WebView2Loader.dll").is_file()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.assertTrue( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| destination_root / "resources" / "backend" / "runtime-manifest.json" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| destination_root | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| / project_config.backend_layout_relative_path | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| / "runtime-manifest.json" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ).is_file() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.assertTrue( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (destination_root / "resources" / "webui" / "index.html").is_file() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| destination_root | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| / project_config.webui_layout_relative_path | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| / "index.html" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ).is_file() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.assertFalse((destination_root / "resources" / "backend").exists()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.assertFalse((destination_root / "resources" / "webui").exists()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.assertTrue((destination_root / "kill-backend-processes.ps1").is_file()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.assertTrue((destination_root / "portable.flag").is_file()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.assertTrue((destination_root / MODULE.PORTABLE_README_NAME).is_file()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
487
to
507
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion (testing): Assert that the legacy resources/backend and resources/webui paths are not created anymore Please also have this test assert that the old
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -466,6 +524,8 @@ def test_add_portable_runtime_files_writes_marker_and_readme(self): | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| product_name="AstrBot", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| binary_name="astrbot-desktop-tauri", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| portable_marker_name="portable.flag", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| backend_layout_relative_path=Path("backend"), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| webui_layout_relative_path=Path("webui"), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MODULE.add_portable_runtime_files(root, project_config) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -477,34 +537,78 @@ def test_add_portable_runtime_files_writes_marker_and_readme(self): | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def test_validate_portable_root_accepts_expected_layout(self): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| layout = self.make_project_layout() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| project_config = MODULE.load_project_config_from(layout["script_path"]) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with tempfile.TemporaryDirectory() as tmpdir: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| root = Path(tmpdir) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (root / "AstrBot.exe").write_text("binary") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (root / "resources" / "backend").mkdir(parents=True) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (root / "resources" / "webui").mkdir(parents=True) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (root / "resources" / "backend" / "runtime-manifest.json").write_text("{}") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (root / "resources" / "webui" / "index.html").write_text("<html></html>") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (root / project_config.backend_layout_relative_path).mkdir(parents=True) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (root / project_config.webui_layout_relative_path).mkdir(parents=True) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
553
to
+562
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion (testing): Add a validation test where backend/webui aliases are nested (e.g. The current Suggested implementation: MODULE.add_portable_runtime_files(root, project_config)
def test_validate_portable_root_accepts_expected_layout(self):
layout = self.make_project_layout()
project_config = MODULE.load_project_config_from(layout["script_path"])
with tempfile.TemporaryDirectory() as tmpdir:
root = Path(tmpdir)
# default layout: backend/ and webui/ at the portable root
(root / "AstrBot.exe").write_text("binary")
(root / "portable.flag").write_text("marker")
(root / "backend").mkdir()
(root / "webui").mkdir()
MODULE.validate_portable_root(root, project_config)
def test_validate_portable_root_accepts_nested_alias_layout(self):
layout = self.make_project_layout(
tauri_resources={
"../resources/backend": "runtime/backend",
"../resources/webui": "runtime/webui",
}
)
project_config = MODULE.load_project_config_from(layout["script_path"])
with tempfile.TemporaryDirectory() as tmpdir:
root = Path(tmpdir)
# binary + portable marker at root
(root / "AstrBot.exe").write_text("binary")
(root / "portable.flag").write_text("marker")
# resources are placed under their aliased nested locations
(root / "runtime" / "backend").mkdir(parents=True)
(root / "runtime" / "webui").mkdir(parents=True)
# Intentionally do NOT create root-level backend/ or webui/ directories.
# validate_portable_root should honor the aliased paths instead.
MODULE.validate_portable_root(root, project_config)If |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| root / project_config.backend_layout_relative_path / "runtime-manifest.json" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ).write_text("{}") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (root / project_config.webui_layout_relative_path / "index.html").write_text( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "<html></html>" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MODULE.validate_portable_root(root, project_config) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def test_validate_portable_root_accepts_nested_alias_layout(self): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| layout = self.make_project_layout( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tauri_resources={ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "../resources/backend": "runtime/backend", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "../resources/webui": "runtime/webui", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| project_config = MODULE.load_project_config_from(layout["script_path"]) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MODULE.validate_portable_root(root) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with tempfile.TemporaryDirectory() as tmpdir: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| root = Path(tmpdir) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (root / "AstrBot.exe").write_text("binary") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (root / project_config.portable_marker_name).write_text("marker") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (root / project_config.backend_layout_relative_path).mkdir(parents=True) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (root / project_config.webui_layout_relative_path).mkdir(parents=True) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| root / project_config.backend_layout_relative_path / "runtime-manifest.json" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ).write_text("{}") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (root / project_config.webui_layout_relative_path / "index.html").write_text( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "<html></html>" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MODULE.validate_portable_root(root, project_config) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.assertFalse((root / "backend").exists()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.assertFalse((root / "webui").exists()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def test_validate_portable_root_requires_expected_files(self): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| layout = self.make_project_layout() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| project_config = MODULE.load_project_config_from(layout["script_path"]) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with tempfile.TemporaryDirectory() as tmpdir: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| root = Path(tmpdir) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (root / "AstrBot.exe").write_text("binary") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with self.assertRaisesRegex(ValueError, "runtime-manifest.json"): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MODULE.validate_portable_root(root) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MODULE.validate_portable_root(root, project_config) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def test_validate_portable_root_requires_top_level_exe(self): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| layout = self.make_project_layout() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| project_config = MODULE.load_project_config_from(layout["script_path"]) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with tempfile.TemporaryDirectory() as tmpdir: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| root = Path(tmpdir) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (root / "resources" / "backend").mkdir(parents=True) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (root / "resources" / "webui").mkdir(parents=True) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (root / "resources" / "backend" / "runtime-manifest.json").write_text("{}") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (root / "resources" / "webui" / "index.html").write_text("<html></html>") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (root / project_config.backend_layout_relative_path).mkdir(parents=True) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (root / project_config.webui_layout_relative_path).mkdir(parents=True) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| root / project_config.backend_layout_relative_path / "runtime-manifest.json" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ).write_text("{}") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (root / project_config.webui_layout_relative_path / "index.html").write_text( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "<html></html>" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with self.assertRaisesRegex(ValueError, r"top-level \*\.exe"): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MODULE.validate_portable_root(root) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MODULE.validate_portable_root(root, project_config) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if __name__ == "__main__": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.