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"]}')
|