mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-11-06 01:53:56 -06:00
fix: name the address a download was refused at
This commit is contained in:
1 parent
d78af1b00d
commit
aaaafd5771
5 files changed
+92
-13
No files matched your search
+1
-1
@@ -16,7 +16,7 @@
|
||||
# and Invoke-WebRequest throws on a cut transfer before the hash is read:
|
||||
# the site's build rewrites this line there (scripts/sitebootstrap.py).
|
||||
$mismatchAdvice = "The download was most likely cut short: try again. Within minutes of an update of this project the two files can come from caches of different ages. Waiting five minutes settles that."
|
||||
$defaultInstallSha256 = "65f7d49de83de9d99734293009762adaff6f844c2c3627f507d4dc3b029f57be"
|
||||
$defaultInstallSha256 = "fa8d130b046b1c1d1bc2e8da49905a7572d81ee95d023b483cdcf009a1d4a64c"
|
||||
$maximumInstallerBytes = 2MB
|
||||
$installerExit = 0
|
||||
$installer = if ($PSScriptRoot) { Join-Path $PSScriptRoot "install.py" } else { $null }
|
||||
|
||||
+34
-3
@@ -5759,8 +5759,9 @@ def _download_one(
|
||||
reason = f"HTTP {exc.code}"
|
||||
if exc.code in (403, 429):
|
||||
reason += " (GitHub rate limit or access refused)"
|
||||
if exc.code >= 500 or exc.code == 429:
|
||||
reason = NetworkReason(reason)
|
||||
reason = (NetworkReason if exc.code >= 500 or exc.code == 429
|
||||
else HttpReason)(reason)
|
||||
reason.url = url
|
||||
if verbose:
|
||||
print(f" Attempt {attempt} failed: {exc}", file=sys.stderr)
|
||||
if tmp_path is not None and partial is None and tmp_path.exists():
|
||||
@@ -6264,6 +6265,32 @@ class NetworkReason(str):
|
||||
"""A failure the connection caused: cut, timed out, refused by a server
|
||||
or a proxy. The summary names the network instead of the folder."""
|
||||
|
||||
url = ""
|
||||
|
||||
|
||||
class HttpReason(str):
|
||||
"""A file the server answered for with an error of its own (HTTP 404):
|
||||
the summary names the address, where "HTTP 404" alone told the user
|
||||
neither what failed nor that running again changes nothing."""
|
||||
|
||||
url = ""
|
||||
|
||||
|
||||
def _http_failure_lines(failures: list[tuple[str, str]]) -> list[str]:
|
||||
"""The address the first refused file was asked at, and what chose it:
|
||||
a mirror named with RETROBIOS_BASE_URL that holds the lists and not yet
|
||||
the files, or a list out of step with the files it names."""
|
||||
refused = [reason for _dest, reason in failures if isinstance(reason, HttpReason)]
|
||||
if not refused:
|
||||
return []
|
||||
more = f" (and {_plural(len(refused) - 1, 'other file')})" if len(refused) > 1 else ""
|
||||
lines = [f" The server answered {refused[0]} for {refused[0].url}{more}."]
|
||||
if os.environ.get("RETROBIOS_BASE_URL"):
|
||||
return lines + _address_lines(refused[0].url)[1:]
|
||||
return lines + [" The file list names files the server does not hold, and running "
|
||||
"again changes nothing until the two match.",
|
||||
f" More help: {TROUBLESHOOTING_PAGE}"]
|
||||
|
||||
|
||||
def _transfer_failure(exc: BaseException) -> bool:
|
||||
"""Whether a download error came from the connection, not the disk."""
|
||||
@@ -6409,8 +6436,12 @@ def _report_outcome(
|
||||
if any(reason == READ_ONLY for _dest, reason in failures or []):
|
||||
advice.append(" Files marked read-only are in the way: clear that attribute "
|
||||
"(or delete them), then run again.")
|
||||
advice += _http_failure_lines(failures or [])
|
||||
if any(isinstance(reason, NetworkReason) for _dest, reason in failures or []):
|
||||
advice.append(NETWORK_FAILURE_ADVICE)
|
||||
if os.environ.get("RETROBIOS_BASE_URL"):
|
||||
# A mirror that is down read as this machine's connection.
|
||||
advice += _address_lines(BASE_URL)[1:]
|
||||
if any(str(reason).startswith(NOT_KEPT) for _dest, reason in failures or []):
|
||||
# The same run fails the same way: "retry only those" sent a phone
|
||||
# user round the loop with nothing changed.
|
||||
@@ -6472,7 +6503,7 @@ def _report_outcome(
|
||||
|
||||
if errors and not downloaded:
|
||||
say(f"\nNothing was installed. {_plural(errors, 'file')} failed.")
|
||||
if failures and all(isinstance(r, (NetworkReason, OfflineReason))
|
||||
if failures and all(isinstance(r, (NetworkReason, HttpReason, OfflineReason))
|
||||
for _d, r in failures):
|
||||
# The folder was never the problem: naming it as the place being
|
||||
# written to sent people looking at their disk.
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ DEFAULT_INSTALL_URL="https://raw.githubusercontent.com/Abdess/retrobios/main/ins
|
||||
# curl or wget stop on a cut transfer before the hash is read: the site's
|
||||
# build rewrites this line there (scripts/sitebootstrap.py).
|
||||
MISMATCH_ADVICE="The download was most likely cut short: try again. Within minutes of an update of this project the two files can come from caches of different ages. Waiting five minutes settles that."
|
||||
DEFAULT_INSTALL_SHA256="65f7d49de83de9d99734293009762adaff6f844c2c3627f507d4dc3b029f57be"
|
||||
DEFAULT_INSTALL_SHA256="fa8d130b046b1c1d1bc2e8da49905a7572d81ee95d023b483cdcf009a1d4a64c"
|
||||
MAX_INSTALLER_BYTES=2097152
|
||||
|
||||
cleanup() {
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
{
|
||||
"dest": "roms/ports/retrobios/install.py",
|
||||
"repo_path": "install.py",
|
||||
"size": 1094917,
|
||||
"sha256": "65f7d49de83de9d99734293009762adaff6f844c2c3627f507d4dc3b029f57be",
|
||||
"size": 1096372,
|
||||
"sha256": "fa8d130b046b1c1d1bc2e8da49905a7572d81ee95d023b483cdcf009a1d4a64c",
|
||||
"executable": false
|
||||
},
|
||||
{
|
||||
@@ -71,8 +71,8 @@
|
||||
"muos": {
|
||||
"archive": {
|
||||
"dest": "ARCHIVE/RetroBIOS.muxapp",
|
||||
"size": 1148544,
|
||||
"sha256": "ba22f19af63c4003f7195636f6c7a5ebe3900ce6a300fe089058ff78eff52eb2"
|
||||
"size": 1149999,
|
||||
"sha256": "143e0067766ccb85f299ca125c1dbdaa5ebec15e85ea49a9e354a677fb7f931d"
|
||||
},
|
||||
"members": [
|
||||
{
|
||||
@@ -92,8 +92,8 @@
|
||||
{
|
||||
"name": "RetroBIOS/install.py",
|
||||
"repo_path": "install.py",
|
||||
"size": 1094917,
|
||||
"sha256": "65f7d49de83de9d99734293009762adaff6f844c2c3627f507d4dc3b029f57be",
|
||||
"size": 1096372,
|
||||
"sha256": "fa8d130b046b1c1d1bc2e8da49905a7572d81ee95d023b483cdcf009a1d4a64c",
|
||||
"executable": false
|
||||
},
|
||||
{
|
||||
@@ -166,8 +166,8 @@
|
||||
{
|
||||
"dest": ".config/modules/retrobios/install.py",
|
||||
"repo_path": "install.py",
|
||||
"size": 1094917,
|
||||
"sha256": "65f7d49de83de9d99734293009762adaff6f844c2c3627f507d4dc3b029f57be",
|
||||
"size": 1096372,
|
||||
"sha256": "fa8d130b046b1c1d1bc2e8da49905a7572d81ee95d023b483cdcf009a1d4a64c",
|
||||
"executable": false
|
||||
},
|
||||
{
|
||||
|
||||
@@ -5160,6 +5160,54 @@ class ANetworkFailureNamesTheNetwork(unittest.TestCase):
|
||||
self.assertNotIn("being written to", text)
|
||||
|
||||
|
||||
class AnHttpErrorNamesItsAddress(unittest.TestCase):
|
||||
"""A file the server answered 404 for ended on "HTTP 404" alone: no
|
||||
address, no cause, and a mirror chosen with RETROBIOS_BASE_URL went
|
||||
unnamed, as it did behind a NETWORK failure of that mirror."""
|
||||
|
||||
def _said(self, failures: list, base_url: str = "") -> str:
|
||||
out = io.StringIO()
|
||||
env = {"RETROBIOS_BASE_URL": base_url} if base_url else {}
|
||||
with unittest.mock.patch.dict(os.environ, env), contextlib.redirect_stdout(out), \
|
||||
self.assertRaises(SystemExit) as raised:
|
||||
install._report_outcome([Path("/bios")], 0, 0, len(failures), 0, False,
|
||||
failures=failures)
|
||||
self.assertEqual(raised.exception.code, 2)
|
||||
return " ".join(out.getvalue().split())
|
||||
|
||||
def _reason(self, kind: type, words: str, url: str) -> str:
|
||||
reason = kind(words)
|
||||
reason.url = url
|
||||
return reason
|
||||
|
||||
def test_the_address_and_the_cause_are_said(self):
|
||||
url = "https://raw.githubusercontent.com/Abdess/retrobios/main/bios/a.bin"
|
||||
failures = [("a.bin", self._reason(install.HttpReason, "HTTP 404", url)),
|
||||
("b.bin", self._reason(install.HttpReason, "HTTP 404", url + "x"))]
|
||||
with unittest.mock.patch.dict(os.environ):
|
||||
os.environ.pop("RETROBIOS_BASE_URL", None)
|
||||
text = self._said(failures)
|
||||
self.assertIn(f"The server answered HTTP 404 for {url} (and 1 other file).", text)
|
||||
self.assertIn("running again changes nothing", text)
|
||||
self.assertIn("BIOS folder: /bios", text)
|
||||
self.assertNotIn("RETROBIOS_BASE_URL", text)
|
||||
|
||||
def test_a_mirror_named_in_the_environment_is_said(self):
|
||||
mirror = "http://127.0.0.1:18766"
|
||||
for kind, words in ((install.HttpReason, "HTTP 404"),
|
||||
(install.NetworkReason, "the connection timed out")):
|
||||
with self.subTest(kind=kind.__name__):
|
||||
text = self._said([("a.bin", self._reason(kind, words, f"{mirror}/a.bin"))],
|
||||
base_url=mirror)
|
||||
self.assertIn("RETROBIOS_BASE_URL is set in this environment", text)
|
||||
|
||||
def test_the_download_records_the_address(self):
|
||||
error = urllib.error.HTTPError("https://x/bios/a.bin", 404, "Not Found", None, None)
|
||||
reason = ANetworkFailureNamesTheNetwork._fail(self, error)
|
||||
self.assertIsInstance(reason, install.HttpReason)
|
||||
self.assertTrue(reason.url.endswith("/bios/a.bin"), reason.url)
|
||||
|
||||
|
||||
class RetroBatIsFoundWhereItSaysItIs(unittest.TestCase):
|
||||
"""RetroBat on D:\\RetroBat was not detected, and --platform retrobat
|
||||
wrote 7.6 GB into C:\\RetroBat\\bios, a folder it does not read.
|
||||
|
||||
Reference in new issue
Block a user