mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-24 04:39:06 -05:00
fix: name a folder or unreadable file in place
A folder or a file the user cannot read at a destination ended --check and the install on a traceback from the hashing pool. --check now gives the reason per file, and the install fails that file alone, before any download for a folder.
This commit is contained in:
1 parent
4b8e2f9de2
commit
3203c766fc
4 files changed
+53
-5
No files matched your search
+1
-1
@@ -11,7 +11,7 @@
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
$defaultInstallUrl = "https://raw.githubusercontent.com/Abdess/retrobios/main/install.py"
|
||||
$defaultInstallSha256 = "6d8af0dbca6697ba71692e5e482c8a16d9e8b9896652fec722d9c84f23bba047"
|
||||
$defaultInstallSha256 = "c361b511d9550b2115d918a0233115cd9f42920bce881f41395c3d7614be534d"
|
||||
$maximumInstallerBytes = 2MB
|
||||
$installerExit = 0
|
||||
$installer = if ($PSScriptRoot) { Join-Path $PSScriptRoot "install.py" } else { $null }
|
||||
|
||||
+18
-3
@@ -4046,9 +4046,18 @@ def _classify_local(entry: dict, dest: Path) -> str:
|
||||
for name in ("sha256", "sha1")
|
||||
if entry.get(name)
|
||||
}
|
||||
if not dest.is_file():
|
||||
# A folder at the file's place: --check says so, an install fails
|
||||
# on that file alone.
|
||||
return "mismatched"
|
||||
if not expected:
|
||||
return "up_to_date"
|
||||
actual = _digest_file(dest, tuple(expected))
|
||||
try:
|
||||
actual = _digest_file(dest, tuple(expected))
|
||||
except OSError:
|
||||
# Unreadable (no permission, a read error on a failing card): its
|
||||
# contents are not known to be the right ones.
|
||||
return "mismatched"
|
||||
if all(actual[name] == value for name, value in expected.items()):
|
||||
return "up_to_date"
|
||||
return "mismatched"
|
||||
@@ -4444,6 +4453,9 @@ def _download_one(
|
||||
if _write_refused(exc):
|
||||
return f["dest"], False, NOT_WRITABLE
|
||||
return f["dest"], False, exc.strerror or str(exc)
|
||||
if dest.is_dir():
|
||||
# Fetched, it failed only at the rename, on an errno and two paths.
|
||||
return f["dest"], False, FOLDER_IN_PLACE
|
||||
|
||||
if copy is not None:
|
||||
result = _copy_local(f, bios_path, dest, copy, progress)
|
||||
@@ -4834,6 +4846,7 @@ READ_ONLY = "file in place is read-only"
|
||||
# A file in place whose content differs, which could not be moved aside: it
|
||||
# is left as it is rather than lost.
|
||||
NOT_KEPT = "file in place could not be kept aside"
|
||||
FOLDER_IN_PLACE = "a folder sits where this file goes: move it away, then run again"
|
||||
|
||||
|
||||
def _clear_read_only(dest: Path) -> None:
|
||||
@@ -7539,12 +7552,14 @@ def _wrong_contents(
|
||||
owners: dict[str, list[dict]] | None = None,
|
||||
) -> str:
|
||||
"""Why the file at an entry's place is not the one the list installs."""
|
||||
if path.is_dir():
|
||||
return FOLDER_IN_PLACE
|
||||
try:
|
||||
size = path.stat().st_size
|
||||
with open(path, "rb") as handle:
|
||||
head = handle.read(4)
|
||||
except OSError:
|
||||
return ""
|
||||
except OSError as exc:
|
||||
return f"could not be read ({exc.strerror or exc}): its contents are unknown"
|
||||
sha1 = index.sha1(path)
|
||||
owner = _content_owner(sha1, entry, files, owners)
|
||||
if owner:
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ esac
|
||||
TEMP_INSTALLER=""
|
||||
TEMP_DIRECTORY=""
|
||||
DEFAULT_INSTALL_URL="https://raw.githubusercontent.com/Abdess/retrobios/main/install.py"
|
||||
DEFAULT_INSTALL_SHA256="6d8af0dbca6697ba71692e5e482c8a16d9e8b9896652fec722d9c84f23bba047"
|
||||
DEFAULT_INSTALL_SHA256="c361b511d9550b2115d918a0233115cd9f42920bce881f41395c3d7614be534d"
|
||||
MAX_INSTALLER_BYTES=2097152
|
||||
|
||||
cleanup() {
|
||||
|
||||
@@ -1501,5 +1501,38 @@ class TheTitleASetupPrints(unittest.TestCase):
|
||||
self.assertEqual(install.system_aliases(manifest)["Sony PlayStation"], "arcade")
|
||||
|
||||
|
||||
class SomethingElseAtADestination(unittest.TestCase):
|
||||
"""A folder, or a file this user cannot read, at a destination ended
|
||||
--check and the install on an IsADirectoryError traceback."""
|
||||
|
||||
def prepare(self, repo: FakeRepository) -> None:
|
||||
(repo.dest / "scph5500.bin").mkdir(parents=True)
|
||||
unreadable = repo.dest / "scph5501.bin"
|
||||
unreadable.write_bytes(b"x")
|
||||
unreadable.chmod(0)
|
||||
|
||||
@unittest.skipIf(os.name == "nt" or (hasattr(os, "geteuid") and os.geteuid() == 0),
|
||||
"a mode of 0 stops no read on Windows or as root")
|
||||
def test_each_says_why_in_the_check_and_the_install(self):
|
||||
with FakeRepository() as repo:
|
||||
self.prepare(repo)
|
||||
proc = repo.run("--check")
|
||||
self.assertEqual(proc.returncode, 1, proc.stderr)
|
||||
self.assertNotIn("Traceback", proc.stderr)
|
||||
self.assertIn(" wrong hash: scph5500.bin\n a folder sits where this "
|
||||
"file goes: move it away, then run again", proc.stdout)
|
||||
self.assertIn(" wrong hash: scph5501.bin\n could not be read "
|
||||
"(Permission denied)", proc.stdout)
|
||||
proc = repo.run("--yes")
|
||||
self.assertEqual(proc.returncode, 1, proc.stderr)
|
||||
self.assertNotIn("Traceback", proc.stderr)
|
||||
self.assertIn("failed: scph5500.bin (a folder sits where this file goes",
|
||||
proc.stdout)
|
||||
self.assertIn("failed: scph5501.bin (file in place could not be kept aside",
|
||||
proc.stdout)
|
||||
self.assertTrue((repo.dest / "scph5500.bin").is_dir())
|
||||
self.assertIn("gba_bios.bin", repo.installed())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user