aboutsummaryrefslogtreecommitdiff
path: root/docker/bin/getpackage.py
blob: 0091dd62d89bc13fe9692f3b6fec76373ecf23bf (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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#!/usr/bin/env python3
# Create a list of package names required to build supplied AUR package.
# packages present in the official repos will be ignored.

# relevant docs:
# AUR API:
# https://wiki.archlinux.org/title/Aurweb_RPC_interface
# Package API:
# https://wiki.archlinux.org/title/Official_repositories_web_interface

import os
import sys
import requests
import json

#from packaging import version
#version.parse

def eprint(*args, **kwargs):
    print(*args, file=sys.stderr, **kwargs)


# TODO we should actually use version limits instead
def sanitize_name(_name):
    _name = _name.replace('<','=')
    _name = _name.replace('>','=')

    return _name.split('=')[0]


# TODO: Don't just take the first one. prioritize maybe Votes, version, git, bin, ...
def aur_search_package(_name):
    _name = sanitize_name(_name)

    data = requests.get(f'https://aur.archlinux.org/rpc/?v=5&type=search&by=name&arg={_name}').json()

    for r in data['results']:
        p = aur_get_package(r['Name'])
        if p is None:
            continue

        if 'Provides' in p:
            for prov in p['Provides']:
                if sanitize_name(prov) == _name:
                    return p

    return None


def aur_get_package(_name):
    _name = sanitize_name(_name)

    data = requests.get(f'https://aur.archlinux.org/rpc/?v=5&type=info&arg={_name}').json()

    if len(data['results']) != 1:
        return aur_search_package(_name)

    return data['results'][0]


def repo_search_package(_name):
    _name = sanitize_name(_name)

    data = requests.get(f'https://archlinux.org/packages/search/json/?q={_name}').json()
    for r in data['results']:
        p = repo_get_package(r['pkgname'], False)
        if p is None:
            continue

        if 'provides' in p:
            for prov in p['provides']:
                if sanitize_name(prov) == _name:
                    return p

    return None


def repo_get_package(_name, _search=True):
    _name = sanitize_name(_name)

    data = requests.get(f'https://archlinux.org/packages/search/json/?name={_name}').json()

    if len(data['results']) != 1:
        if _search:
            return repo_search_package(_name)
        else:
            return None

    return data['results'][0]


def build_aur_dependencies(_pkgname):
    _pkgname = sanitize_name(_pkgname)

    ret = []

    maybe_deps = aur_get_package(_pkgname)
    if maybe_deps is None:
        eprint(f'WARNING: {_pkgname} Was not found in AUR!')
        return []
    elif 'Depends' not in maybe_deps:
        return []

    deps = maybe_deps['Depends']

    for dep in deps:
        # if package exists in official repo
        if repo_get_package(dep) is not None:
            continue

        # detect depency cycles
        if dep in ret:
            continue

        ret.append(dep)
        ret.insert(0,dep)
        ret = build_aur_dependencies(dep) + ret

    return ret

if len(sys.argv) <= 1:
    eprint('CRITICAL: No package name provided.')
    exit(1)

PKG=sys.argv[1]

# name: version
TO_BUILD={}

maybe_base_pkg_info = aur_get_package(PKG)
if maybe_base_pkg_info is None:
    eprint(f'CRITICAL: Package {PKG} not found in AUR')
    exit(1)
base_pkg_info = maybe_base_pkg_info

aur_deps = build_aur_dependencies(PKG)

# We rely on the rigth order here.
# The dependency must be before the package that depends on it,
# otherwise makepkg will fail
for dep in aur_deps:
    pkg = aur_get_package(dep)

    if pkg is None:
        eprint(f'WARNING: Dependency {dep} Unmet!')
        continue

    TO_BUILD[pkg['Name']] = {
            'version':pkg['Version'],
            'base':pkg['PackageBase']
        }

TO_BUILD[base_pkg_info['Name']] = {
        'version':base_pkg_info['Version'],
        'base':base_pkg_info['PackageBase']
        }

for e in TO_BUILD:
    print(f'{e}\t{TO_BUILD[e]["base"]}\t{TO_BUILD[e]["version"]}')