aboutsummaryrefslogtreecommitdiff
path: root/utils/aur/AURUtils/srcinfo.py
blob: 34d2240cca887c15ac194df209bf5180a3388f85 (plain)
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']}"