projects/aports·blob v2.14.0 · refs

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