projects/aports·blob 3.7.0_rc1 · refs

250 lines · 6.0 KiB

1#!/usr/bin/perl
2
3use strict;
4use warnings;
5use autodie qw(:all);
6use feature qw(:5.14);
7use LWP::UserAgent;
8use LWP::ConnCache;
9use JSON;
10
11our $packager = '';
12my %pkgmap = ();
13my %licenses = ();
14
15my $template = <<'EOF';
16[% authors %]
17pkgname=[% pkgname %]
18_pkgreal=[% pkgreal %]
19pkgver=[% pkgver %]
20pkgrel=0
21pkgdesc="[% pkgdesc %]"
22url="http://packages.python.org/pypi/[% pkgreal %]"
23arch="noarch"
24license="[% license %]"
25pydepends=""
26pymakedepends=""
27depends="python3 $pydepends"
28checkdepends="python3-dev"
29makedepends="py3-setuptools $pymakedepends"
30subpackages=""
31source="[% source %]"
32builddir="$srcdir/$_pkgreal-$pkgver"
33
34build() {
35 python3 setup.py build
36}
37
38package() {
39 PYTHONPATH=$pkgdir`python3 -c "import site; print(site.getsitepackages()[0])"` \
40 python3 setup.py install \
41 --prefix=/usr \
42 --root="$pkgdir" \
43 --single-version-externally-managed
44}
45
46check() {
47 python3 setup.py test
48}
49
50EOF
51
52my $ua = LWP::UserAgent->new();
53my $json = JSON->new;
54$ua->env_proxy;
55$ua->conn_cache(LWP::ConnCache->new);
56
57sub read_file {
58 my ($filename) = @_;
59 open my $fh, '<:utf8', $filename;
60 local $/;
61 my $text = <$fh>;
62 return $text;
63}
64
65sub read_assignments_from_file {
66 my ($filename) = @_;
67 return () if ( ! -e $filename );
68 my $text = read_file($filename);
69 my %sline = $text =~ /^(\w+)\s*=\s*([^\"\n]*)$/mg;
70 my %mline = $text =~ /^(\w+)\s*=\s*\"([^\"]*)\"$/mg;
71 my %hash = ( %sline, %mline );
72
73 my $authors = join("\n", $text =~ /^# Contributor: .*$/mg, $text =~ /^# Maintainer: .*$/mg);
74 $hash{'authors'} = $authors if length($authors) > 1;
75
76 return \%hash;
77}
78
79sub map_pypi_to_apk {
80 my ($pypi) = @_;
81 return $pkgmap{$pypi} unless !exists($pkgmap{$pypi});
82 return 'py3-'.lc($pypi);
83}
84
85sub map_license {
86 my ($license) = @_;
87
88 $license =~ s/ or / /g;
89
90 return $license;
91}
92
93sub get_source {
94 my ($distdata) = @_;
95
96 for my $url (@{$distdata->{urls}}) {
97 return $url->{url} if $url->{python_version} eq 'source'
98 }
99 die "Unable to locate sources for $distdata->{name}.\n";
100}
101
102sub read_apkbuild {
103 return read_assignments_from_file('APKBUILD');
104}
105
106sub write_apkbuild {
107 my ($distdata, $authors) = @_;
108
109 my %repl = (
110 authors => ($authors or "# Contributor: $packager\n# Maintainer: $packager"),
111 pkgname => map_pypi_to_apk($distdata->{info}{name}),
112 pkgreal => $distdata->{info}{name},
113 pkgver => $distdata->{info}{version},
114 source => get_source($distdata),
115 license => map_license($distdata->{info}{license}),
116 pkgdesc => $distdata->{info}{summary},
117 );
118 $template =~ s/\[% (.*?) %\]/$repl{$1}/g;
119
120 open my $fh, '>:utf8', 'APKBUILD';
121 print {$fh} $template;
122 close $fh;
123
124 say "Wrote $repl{pkgname}/APKBUILD";
125
126 return \%repl;
127}
128
129sub prepare_tree {
130 system('abuild checksum unpack prepare');
131}
132
133sub get_data {
134 my ($package) = @_;
135 my $response = $ua->get("https://pypi.python.org/pypi/$package/json");
136 $response->is_success or die $response->status_line;
137 my $distdata = $json->decode($response->decoded_content);
138
139 return $distdata;
140}
141
142sub get_deps {
143 my ($data) = @_;
144
145 chdir "src/$data->{pkgreal}-$data->{pkgver}";
146 my $reqs = `python3 ./setup.py --requires`;
147
148 my @reqs = split /\n/, $reqs;
149
150 foreach my $i (0 .. $#reqs) {
151 $reqs[$i] =~ s/(\(|\s+).*$//;
152 $reqs[$i] = map_pypi_to_apk($reqs[$i]);
153 }
154
155 chdir '../..';
156
157 my $apk = read_file('APKBUILD');
158
159 $reqs = join ' ', @reqs;
160
161 $apk =~ s/pymakedepends=""/pymakedepends="$reqs"/;
162
163 open my $fh, '>:utf8', 'APKBUILD';
164
165 print $fh $apk;
166
167 say "Requires: $reqs";
168}
169
170my $abuild_conf = read_assignments_from_file('/etc/abuild.conf');
171$packager = $abuild_conf->{PACKAGER} if $abuild_conf->{PACKAGER};
172
173my $user_abuild_conf = read_assignments_from_file($ENV{"HOME"} . "/.abuild/abuild.conf");
174$packager = $user_abuild_conf->{PACKAGER} if $user_abuild_conf->{PACKAGER};
175
176sub usage {
177 say <<'EOF';
178Usage: apkbuild-pypi [create <package> | check | recreate | upgrade | update]
179
180In the repository root:
181 create <package>: Creates an APKBUILD for <package>
182
183In the package root:
184 check : Reports current & latest version of the package
185 recreate : Recreates the APKBUILD
186 upgrade : Upgrades to the latest version of the package
187 update : Updates APKBUILD metadata
188EOF
189}
190
191given ($ARGV[0]) {
192 when ('create') {
193 my $package = $ARGV[1];
194 $package or die usage;
195
196 my $distdata = get_data($package);
197 my $apkname = map_pypi_to_apk($package);
198
199 mkdir $apkname;
200 chdir $apkname;
201
202 my $data = write_apkbuild($distdata, undef);
203 prepare_tree;
204
205 get_deps($data);
206 } when ('recreate') {
207 my $apkbuild = read_apkbuild;
208 my $distdata = get_data($apkbuild->{_pkgreal});
209 my $data = write_apkbuild($distdata, $apkbuild->{authors});
210
211 prepare_tree;
212 get_deps($data);
213 } when ('upgrade') {
214 my $apkbuild = read_apkbuild;
215 my $distdata = get_data($apkbuild->{_pkgreal});
216
217 my $pkgver = $distdata->{info}{version};
218
219 if ($pkgver ne $apkbuild->{pkgver}) {
220 say "Upgrading PyPI package from $apkbuild->{pkgver} to $pkgver";
221
222 my $text = read_file('APKBUILD');
223
224 $text =~ s/^(pkgver)=.*$/$1=$pkgver/mg or
225 die "Can't find pkgver line in APKBUILD";
226 $text =~ s/^(pkgrel)=.*$/$1=0/mg or
227 die "Can't find pkgrel line in APKBUILD";
228
229 open my $fh, '>:utf8', 'APKBUILD';
230 print $fh $text;
231 close $fh;
232 } else {
233 say "Already up to date with PyPI";
234 }
235 } when ('check') {
236 my $apkbuild = read_apkbuild;
237 my $distdata = get_data($apkbuild->{_pkgreal});
238
239 my $pkgver = $distdata->{info}{version};
240
241 say "$apkbuild->{pkgname}: Latest version: $pkgver Packaged version: $apkbuild->{pkgver}";
242 if ($pkgver ne $apkbuild->{pkgver}) {
243 exit(1);
244 }
245 } when ('update') {
246 prepare_tree;
247 } default {
248 die usage;
249 }
250}