mirror of
https://github.com/ScoopInstaller/Nirsoft.git
synced 2026-11-08 01:14:36 +08:00
fix: initialize persistent config files before linking (#66)
This commit is contained in:
parent
8f1d7107bd
commit
9c57215e52
3
.github/workflows/update.yml
vendored
3
.github/workflows/update.yml
vendored
@ -38,6 +38,9 @@ jobs:
|
||||
python -m pip install --upgrade pip
|
||||
pip install -r requirements.txt
|
||||
|
||||
- name: Test manifest generation
|
||||
run: python -m unittest discover -s test -p "test_*.py"
|
||||
|
||||
- name: Run python update.py (can take up to 3 hours)
|
||||
# ignore syntax error on the following line
|
||||
run: python update.py ${{ inputs.sleep_seconds }} ${{ inputs.recheck_404s }}
|
||||
|
||||
@ -23,5 +23,9 @@
|
||||
},
|
||||
"autoupdate": {
|
||||
"url": "https://www.nirsoft.net/utils/pinginfoview.zip"
|
||||
}
|
||||
},
|
||||
"pre_install": [
|
||||
"if (!(Test-Path \"$persist_dir\\pinginfoview_lng.ini\") -and !(Test-Path \"$dir\\pinginfoview_lng.ini\")) { New-Item \"$dir\\pinginfoview_lng.ini\" -ItemType File | Out-Null }",
|
||||
"if (!(Test-Path \"$persist_dir\\pinginfoview.cfg\") -and !(Test-Path \"$dir\\pinginfoview.cfg\")) { New-Item \"$dir\\pinginfoview.cfg\" -ItemType File | Out-Null }"
|
||||
]
|
||||
}
|
||||
103
test/test_update.py
Normal file
103
test/test_update.py
Normal file
@ -0,0 +1,103 @@
|
||||
"""Offline regression tests for generated persistent configuration files.
|
||||
|
||||
Run with: python -m unittest discover -s test -p "test_*.py"
|
||||
"""
|
||||
|
||||
import contextlib
|
||||
import io
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
import subprocess
|
||||
import tempfile
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
import update
|
||||
|
||||
|
||||
class PersistTests(unittest.TestCase):
|
||||
def generate(self, name="pinginfoview", x64=False):
|
||||
pad = f"""<XML_DIZ_INFO>
|
||||
<Program_Info><Program_Version>3.25</Program_Version>
|
||||
<Program_Name>{name}</Program_Name></Program_Info>
|
||||
<Web_Info>
|
||||
<Application_URLs><Application_Info_URL>https://www.nirsoft.net/</Application_Info_URL></Application_URLs>
|
||||
<Download_URLs><Primary_Download_URL>https://www.nirsoft.net/utils/{name}.zip</Primary_Download_URL></Download_URLs>
|
||||
</Web_Info>
|
||||
</XML_DIZ_INFO>"""
|
||||
row = {"exe": f"{name}.exe", "hash": "0" * 64}
|
||||
original_dir = os.getcwd()
|
||||
with tempfile.TemporaryDirectory() as temporary_dir:
|
||||
try:
|
||||
os.chdir(temporary_dir)
|
||||
Path("bucket").mkdir()
|
||||
with patch.object(update, "update_row", side_effect=[(True, row), (x64, row)]):
|
||||
with contextlib.redirect_stdout(io.StringIO()):
|
||||
update.do_padfile(f"{name}.xml", pad, {})
|
||||
return json.loads(Path(f"bucket/{name}.json").read_text(encoding="utf-8"))
|
||||
finally:
|
||||
os.chdir(original_dir)
|
||||
|
||||
def test_pinginfoview_has_file_initialization(self):
|
||||
manifest = self.generate()
|
||||
self.assertEqual(len(manifest["pre_install"]), 2)
|
||||
for filename, command in zip(manifest["persist"], manifest["pre_install"]):
|
||||
self.assertIn(filename, command)
|
||||
self.assertIn("-ItemType File", command)
|
||||
|
||||
def test_password_archive_is_extracted_before_initialization(self):
|
||||
for x64 in (False, True):
|
||||
with self.subTest(x64=x64):
|
||||
manifest = self.generate("netpass", x64=x64)
|
||||
self.assertEqual(len(manifest["pre_install"]), 4)
|
||||
self.assertIn("7z x", manifest["pre_install"][1])
|
||||
self.assertTrue(all("-ItemType File" in line for line in manifest["pre_install"][2:]))
|
||||
urls = ([arch["url"] for arch in manifest["architecture"].values()]
|
||||
if x64 else [manifest["url"]])
|
||||
self.assertTrue(all(url.endswith("#dl.zip_") for url in urls))
|
||||
|
||||
@unittest.skipUnless(os.name == "nt" and shutil.which("pwsh"), "Requires PowerShell on Windows")
|
||||
def test_hooks_create_files_and_preserve_existing_configuration(self):
|
||||
hooks = "\n".join(self.generate()["pre_install"])
|
||||
for existing in ("none", "source", "persist", "directory"):
|
||||
with self.subTest(existing=existing), tempfile.TemporaryDirectory() as temporary_dir:
|
||||
root = Path(temporary_dir)
|
||||
source = root / "app"
|
||||
persistent = root / "persist"
|
||||
source.mkdir()
|
||||
persistent.mkdir()
|
||||
cfg = "pinginfoview.cfg"
|
||||
content = b"[General]\r\nSort=14\r\n"
|
||||
if existing in ("source", "persist"):
|
||||
(source if existing == "source" else persistent).joinpath(cfg).write_bytes(content)
|
||||
elif existing == "directory":
|
||||
(persistent / cfg).mkdir()
|
||||
(persistent / cfg / "keep.txt").write_bytes(content)
|
||||
script = root / "hooks.ps1"
|
||||
script.write_text(
|
||||
'param($dir, $persist_dir)\n$ErrorActionPreference = "Stop"\n' + hooks,
|
||||
encoding="utf-8",
|
||||
)
|
||||
# Running twice also checks that reinstallation is safe.
|
||||
for _ in range(2):
|
||||
subprocess.run(
|
||||
["pwsh", "-NoProfile", "-File", str(script), str(source), str(persistent)],
|
||||
check=True, capture_output=True, text=True,
|
||||
)
|
||||
self.assertTrue((source / "pinginfoview_lng.ini").is_file())
|
||||
if existing == "none":
|
||||
self.assertTrue((source / cfg).is_file())
|
||||
elif existing == "source":
|
||||
self.assertEqual((source / cfg).read_bytes(), content)
|
||||
else:
|
||||
self.assertFalse((source / cfg).exists())
|
||||
if existing == "persist":
|
||||
self.assertEqual((persistent / cfg).read_bytes(), content)
|
||||
else:
|
||||
self.assertEqual((persistent / cfg / "keep.txt").read_bytes(), content)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@ -346,6 +346,14 @@ def do_padfile(pad_name: str, pad_data: str, urls: Urls) -> Urls:
|
||||
r"7z x $dir\\$zip -p'" + password + "' $('-o' + $dir) | Out-Null"
|
||||
]
|
||||
|
||||
# Missing persist paths are treated as directories by Scoop. Initialize files
|
||||
# after extracting password-protected archives, without replacing existing data.
|
||||
manifest.setdefault("pre_install", []).extend(
|
||||
f'if (!(Test-Path "$persist_dir\\{filename}") -and !(Test-Path "$dir\\{filename}")) '
|
||||
f'{{ New-Item "$dir\\{filename}" -ItemType File | Out-Null }}'
|
||||
for filename in manifest["persist"]
|
||||
)
|
||||
|
||||
rewrite_json(json_file, manifest)
|
||||
|
||||
return urls
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user