From 21865ee327117f9a6079cc4e8271b3970d4555aa Mon Sep 17 00:00:00 2001 From: Samuel Sloniker Date: Sun, 30 Jun 2024 09:34:51 -0700 Subject: [PATCH] Add uninstaller Closes #2 Also document installer, fix some formatting issues, add encoding to an open(), and remove an obsolete TODO. --- unpack.py | 42 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/unpack.py b/unpack.py index 53ba19b..4d1247f 100644 --- a/unpack.py +++ b/unpack.py @@ -49,6 +49,7 @@ def _mkdir_p(parts: Sequence[str]) -> None: # (end code derived from `pathlib`) + class InvalidFileError(BaseException): """ CircuitPack package file is invalid. @@ -77,8 +78,9 @@ class _ResponseFile: # pylint: disable=too-few-public-methods return response -def unpack(package: Union[BinaryIO, _ResponseFile], target: str) -> Iterable[str]: - # TODO: add a way to limit where packages can store files? +def unpack( + package: Union[BinaryIO, _ResponseFile], target: str +) -> Iterable[str]: """ Unpack the given file-like object `package` into the directory `target`, which may, but is not required to, already exist. Return the unpacked @@ -135,14 +137,42 @@ def unpack_url(url: str, target: str) -> Iterable[str]: return unpack(_ResponseFile(requests.get(url)), target) -def install(name: str, version_hash: str, repo: str, target: str, records: str) -> None: + +def install( + name: str, version_hash: str, repo: str, target: str, records: str +) -> None: + """ + Download version `version_hash` of package `name` from `repo`, unpack it + into the directory `target`, and create a record file in `records`. + """ + if not repo.endswith("/"): repo = repo + "/" file_names = unpack_url(f"{repo}{name}.{version_hash}.cpa", target) - with open(f"{records}/{name}", "w+") as f: - f.write(f"{version_hash}\n") + with open(f"{records}/{name}", "w+", encoding="utf-8") as record: + record.write(f"{version_hash}\n") for file_name in file_names: - f.write(f"{file_name}\n") + record.write(f"{file_name}\n") + + +def uninstall(name: str, target: str, records: str) -> None: + """ + Uninstall package `name` from `target` using the information stored in + `records`. + """ + + with open(f"{records}/{name}", "r", encoding="utf-8") as record: + record.readline() # Skip over version hash + + while True: + file_name = record.readline().strip() + + if file_name: + os.remove(f"{target}/{file_name}") + else: + break + + os.remove(f"{records}/{name}")