1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
import re
from collections import defaultdict
from itertools import chain
from typing import Optional, Union
from .errors import PackageNotFound
from .aur_deps import depends_strip
key_value_pattern = re.compile(r'(?P<KEY>.+?)=(?P<VALUE>.+)')
multivalued_attrs = {
'source', 'provides', 'conflicts', 'depends', 'replaces', 'optdepends', 'makedepends', 'checkdepends',
'md5sums', 'sha1sums', 'sha224sums', 'sha256sums', 'sha384sums', 'sha512sums', 'arch'
}
class SRCINFO:
def __init__(self, pkgbase: str, pkgbase_opt: dict, pkgs_opt: dict):
self.pkgbase = pkgbase
self.pkgbase_opt = pkgbase_opt
self.pkgs_opt = pkgs_opt
@classmethod
def parse(cls, source: str):
pkgbase = None
pkgbase_opt = defaultdict(list)
pkgs_opt = {}
handler = None
for l in source.splitlines():
m = key_value_pattern.search(l.strip())
if m is None:
continue
key, value = m.group('KEY').strip(), m.group('VALUE').strip()
if key == 'pkgbase':
pkgbase = value
handler = pkgbase_opt
elif key == 'pkgname':
pkgs_opt[value] = defaultdict(list)
handler = pkgs_opt[value]
else:
if key in multivalued_attrs:
handler[key].append(value)
else:
handler[key] = value
return SRCINFO(pkgbase, pkgbase_opt, pkgs_opt)
@property
def pkgs(self) -> dict:
return {
k: {i: self.get_pkg_opt(k, i) for i in chain(self.pkgbase_opt.keys(), v.keys())}
for k, v in self.pkgs_opt.items()
}
@property
def pkgs_name(self) -> list:
return list(self.pkgs_opt.keys())
def _chain_pkg_opt(self, pkgname: str, opt: str) -> chain:
if pkgname not in self.pkgs_name:
raise PackageNotFound(f'{pkgname} not found in {self.pkgbase}')
return chain(self.pkgbase_opt.get(opt, []), self.pkgs_opt[pkgname].get(opt, []))
def _chain_opt(self, opt: str) -> chain:
return chain(self.pkgbase_opt.get(opt, []), *(i.get(opt, []) for i in self.pkgs_opt.values()))
def get_pkg_opt(self, pkgname: str, opt: str) -> Union[list, str]:
if pkgname not in self.pkgs_name:
raise PackageNotFound(f'{pkgname} not found in {self.pkgbase}')
if opt in multivalued_attrs:
return list(self._chain_pkg_opt(pkgname, opt))
return self.pkgbase_opt.get(opt)
def get_opt(self, opt: str) -> Union[list, str]:
if opt in multivalued_attrs:
return list(self._chain_opt(opt))
return self.pkgbase_opt.get(opt)
@property
def depends(self) -> list[str]:
return list(map(depends_strip, self._chain_opt('depends')))
@property
def makedepends(self) -> list[str]:
return list(map(depends_strip, self._chain_opt('makedepends')))
@property
def optdepends(self) -> list[str]:
return list(self._chain_opt('optdepends'))
@property
def version(self) -> tuple[Optional[str], str, str]:
return self.pkgbase_opt.get('epoch', None), \
self.pkgbase_opt['pkgver'], self.pkgbase_opt['pkgrel']
def get_version(self) -> str:
epoch = f"{self.pkgbase_opt['epoch']}:" if self.pkgbase_opt.get('epoch') else ''
return f"{epoch}{self.pkgbase_opt['pkgver']}-{self.pkgbase_opt['pkgrel']}"
|