2022-09-04 02:12:40 +02:00
|
|
|
import logging
|
|
|
|
import os
|
|
|
|
|
|
|
|
from shutil import copyfileobj
|
2023-04-16 20:48:48 +00:00
|
|
|
from typing import Optional, Union
|
2022-09-04 02:12:40 +02:00
|
|
|
from urllib.request import urlopen
|
|
|
|
|
|
|
|
from exec.file import get_temp_dir, makedir
|
2022-02-18 03:30:21 +01:00
|
|
|
|
|
|
|
|
2022-02-17 03:11:33 +01:00
|
|
|
class PackageInfo:
|
|
|
|
name: str
|
|
|
|
version: str
|
2022-08-31 15:36:21 +02:00
|
|
|
|
|
|
|
|
|
|
|
class BinaryPackage(PackageInfo):
|
2022-12-07 15:25:01 +01:00
|
|
|
arch: str
|
2022-02-17 03:11:33 +01:00
|
|
|
filename: str
|
2022-02-18 03:30:21 +01:00
|
|
|
resolved_url: Optional[str]
|
2023-04-16 20:48:48 +00:00
|
|
|
_desc: Optional[dict[str, Union[str, list[str]]]]
|
2022-02-17 03:11:33 +01:00
|
|
|
|
|
|
|
def __init__(
|
|
|
|
self,
|
|
|
|
name: str,
|
|
|
|
version: str,
|
2022-12-07 15:25:01 +01:00
|
|
|
arch: str,
|
2022-02-17 03:11:33 +01:00
|
|
|
filename: str,
|
2022-11-09 15:22:06 +01:00
|
|
|
resolved_url: Optional[str] = None,
|
2022-02-17 03:11:33 +01:00
|
|
|
):
|
|
|
|
self.name = name
|
|
|
|
self.version = version
|
2022-12-07 15:25:01 +01:00
|
|
|
self.arch = arch
|
2022-02-17 03:11:33 +01:00
|
|
|
self.filename = filename
|
|
|
|
self.resolved_url = resolved_url
|
|
|
|
|
|
|
|
def __repr__(self):
|
|
|
|
return f'{self.name}@{self.version}'
|
|
|
|
|
2022-08-31 15:36:21 +02:00
|
|
|
@classmethod
|
|
|
|
def parse_desc(clss, desc_str: str, resolved_repo_url=None):
|
2022-02-17 03:11:33 +01:00
|
|
|
"""Parses a desc file, returning a PackageInfo"""
|
2023-04-16 20:48:48 +00:00
|
|
|
desc: dict[str, Union[str, list[str]]] = {}
|
2023-01-09 03:18:03 +01:00
|
|
|
for segment in f'\n{desc_str}'.split('\n%'):
|
|
|
|
if not segment.strip():
|
|
|
|
continue
|
|
|
|
key, elements = (e.strip() for e in segment.strip().split('%\n', 1))
|
|
|
|
elements_split = elements.split('\n')
|
|
|
|
desc[key] = elements if len(elements_split) == 1 else elements_split
|
|
|
|
validated: dict[str, str] = {}
|
|
|
|
for key in ['NAME', 'VERSION', 'ARCH', 'FILENAME']:
|
|
|
|
assert key in desc
|
|
|
|
value = desc[key]
|
|
|
|
assert isinstance(value, str)
|
|
|
|
validated[key] = value
|
2022-12-07 16:56:35 +01:00
|
|
|
p = clss(
|
2023-01-09 03:18:03 +01:00
|
|
|
name=validated['NAME'],
|
|
|
|
version=validated['VERSION'],
|
|
|
|
arch=validated['ARCH'],
|
|
|
|
filename=validated['FILENAME'],
|
|
|
|
resolved_url='/'.join([resolved_repo_url, validated['FILENAME']]),
|
2022-12-07 16:56:35 +01:00
|
|
|
)
|
|
|
|
p._desc = desc
|
|
|
|
return p
|
2022-09-01 03:57:54 +02:00
|
|
|
|
|
|
|
def acquire(self) -> str:
|
|
|
|
raise NotImplementedError()
|
|
|
|
|
|
|
|
|
|
|
|
class LocalPackage(BinaryPackage):
|
2022-09-04 02:12:40 +02:00
|
|
|
|
|
|
|
def acquire(self) -> str:
|
|
|
|
assert self.resolved_url and self.filename and self.filename in self.resolved_url
|
|
|
|
path = f'{self.resolved_url.split("file://")[1]}'
|
|
|
|
assert os.path.exists(path) or print(path)
|
|
|
|
return path
|
2022-09-01 03:57:54 +02:00
|
|
|
|
|
|
|
|
|
|
|
class RemotePackage(BinaryPackage):
|
2022-09-04 02:12:40 +02:00
|
|
|
|
|
|
|
def acquire(self, dest_dir: Optional[str] = None) -> str:
|
|
|
|
assert self.resolved_url and '.pkg.tar.' in self.resolved_url
|
|
|
|
url = f"{self.resolved_url}"
|
|
|
|
assert url
|
|
|
|
|
|
|
|
dest_dir = dest_dir or get_temp_dir()
|
|
|
|
makedir(dest_dir)
|
|
|
|
dest_file_path = os.path.join(dest_dir, self.filename)
|
|
|
|
|
|
|
|
logging.info(f"Trying to download package {url}")
|
|
|
|
with urlopen(url) as fsrc, open(dest_file_path, 'wb') as fdst:
|
|
|
|
copyfileobj(fsrc, fdst)
|
|
|
|
logging.info(f"{self.filename} downloaded from repos")
|
|
|
|
return dest_file_path
|