1 #!/usr/bin/env perl
2 #
3 # pkg-repgen: generates a binary repository for pkg-get
4 #
5 # requires prt-get
6 #
7 # html index generation code adapted from Jukka Heino's portspage
8 #
9 # usage: pkg-repgen [<pkgname1>..<pkgnameN>]
10 #
11
12 use warnings;
13 use strict;
14 use Getopt::Long;
15
16 our $prtget = "/usr/bin/prt-get"; our $prtdir;
17 our $title = "CRUX Packages"; our $header; our $footer;
18 GetOptions("prtdir=s"=>\$prtdir, "title=s"=>\$title, "header=s"=>\$header, "footer=s"=>\$footer);
19
20 # Use compression-mode defined in pkgmk-conf
21 our $compress = "gz";
22 open CONFIG, "/etc/pkgmk.conf" or die "Could not open /etc/pkgmk.conf";
23 while (<CONFIG>) {
24 $compress = $1 if m/^PKGMK_COMPRESSION_MODE="(.*)"\n/;
25 }
26 close CONFIG;
27
28 if ($#ARGV >= 0) { # single packages
29 pkgrepo_single();
30 pkgdeps_single();
31 pkgread();
32 pkginst();
33 } else {
34 if ($prtdir) {
35 $prtget = "$prtget --no-std-config --config-set=\"prtdir $prtdir\"";
36 }
37 pkgrepo();
38 pkgdeps();
39 pkgread();
40 pkginst();
41 }
42
43 ######################## single packages ########################
44
45 # generate dependencies
46 sub pkgdeps_single {
47 print "+ Generating dependencies\n";
48 my $hasnew = 0;
49 foreach my $p (@ARGV) {
50 my @packages = glob("$p#*.pkg.tar.$compress");
51 if ($#packages == 0) {
52 my $found = 0;
53 my $package = $packages[0];
54 $package =~ s/#.*//;
55 my $deps = `$prtget printf "%e" --filter="$package"`;
56 if ($deps ne "") {
57 my $isnew = `grep "$p .*:" PKGDEPS`;
58 if ($isnew eq ""){ # package is new, put deps at the end.
59 open (my $fh, '>>PKGDEPS');
60 printf $fh "%-30s : %-s\n", $package, $deps;
61 close $fh;
62 $hasnew = 1;
63 } else {
64 system("sed -i \"/^$p /s/: .*\$/: $deps/\" PKGDEPS");
65 }
66 }
67
68 } else {
69 print "Package '$p' not found or duplicate\n"
70 }
71 }
72 if ($hasnew == 1){system("sort -o PKGDEPS PKGDEPS")};
73 }
74
75 # generate the main repository file
76 sub pkgrepo_single {
77 print "+ Generating repository\n";
78 my $hasnew = 0;
79 foreach my $p (@ARGV) {
80 my @packages = glob("$p#*.pkg.tar.$compress");
81 if ($#packages == 0) {
82 my $found = 0;
83 my $package = $packages[0];
84 my $name = $package;
85 $name =~ s/#.*//;
86 my $du = (-s $package);
87 my $md5 = `md5sum $package`;
88 $md5 =~ s/ .*$|\n//g;
89 my $des=`$prtget printf %d --filter="$name"`;
90 $des =~ s/:/ /g;
91 if ($des eq ""){$des = "N.A."};
92 my $flags=`$prtget printf %E:%O:%R --filter="$name"`;
93 if ($flags eq "") {$flags = "no:no:no"}
94 my $isnew = `grep "$p#" PKGREPO`;
95 if ($isnew eq ""){ # package is new, put it at the end
96 open (my $fh, '>>PKGREPO');
97 printf $fh "%-s:%-s:%-s:%-s:%-s\n", $package,$du,$md5,$des,$flags;
98 close $fh;
99 $hasnew = 1;
100 } else {
101 my $newp = "$package:$du:$md5:$des:$flags";
102 system("sed -i \"s/^$p#.*\$/$newp/\" PKGREPO");
103 }
104 #printf $fh "%-s:%-s:%-s:%-s\n", $du,$md5,$des,$flags;
105 } else {
106 print "Package '$p' not found or duplicate\n"
107 }
108 }
109 if ($hasnew == 1){system("sort -o PKGREPO PKGREPO")};
110 }
111
112
113 ######################## full repository ########################
114
115 # generate dependencies
116 sub pkgdeps {
117 print "+ Generating dependencies\n";
118 my @packages = glob("*#*.pkg.tar.$compress");
119 open (my $fh, '>PKGDEPS');
120 foreach my $package (@packages) {
121 $package =~ s/#.*//;
122 my $deps = `$prtget printf "%e" --filter="$package"`;
123 if ($deps ne "") {
124 printf $fh "%-30s : %-s\n", $package, $deps;
125 }
126 }
127 close $fh;
128 }
129
130 # generate the main repository file and index page
131 sub pkgrepo {
132 print "+ Generating repository\n";
133 my @packages = glob("*#*.pkg.tar.$compress");
134 our $odd = "odd";
135 my $count = 0;
136 open (my $fh, '>PKGREPO');
137 printheader();
138 open (my $ih, '>>index.html');
139 foreach my $package (@packages) {
140 my $date = (stat($package))[9];
141 $count++;
142 $package =~ s/\n//g;
143 my $name = $package;
144 $name =~ s/#.*//;
145 my $du = (-s $package);
146 my $md5 = `md5sum $package`;
147 $md5 =~ s/ .*$|\n//g;
148 my $des=`$prtget printf %d --filter="$name"`;
149 $des =~ s/:/ /g;
150 if ($des eq ""){$des = "N.A."};
151 my $flags=`$prtget printf %E:%O:%R --filter="$name"`;
152 if ($flags eq "") {$flags = "no:no:no"}
153 printf $fh "%-s:%-s:%-s:%-s:%-s\n", $package,$du,$md5,$des,$flags;
154 my $version = $package;
155 $version =~ s/^.*\#//;
156 $version =~ s/\.pkg\.tar\.[gbx]z*//;
157 print $ih "<tr class=\"$odd\">";
158 print $ih "<td>$name</td>";
159 my $url = $package;
160 $url =~ s/\#/\%23/;
161 print $ih "<td><a href=\"$url\">$version</a></td>";
162 print $ih "<td>$des</td>";
163 print $ih "<td>" . isotime($date, 1) . "</td>";
164 print $ih "</tr>\n";
165
166 if ($odd eq "odd") { $odd = "even"; }
167 else { $odd = "odd"; }
168 }
169 close $fh;
170 close $ih;
171 printfooter($count);
172 }
173
174 # generate README file
175 sub pkgread {
176 print "+ Generating README\n";
177 my @packages = glob("*#*.pkg.tar.$compress");
178 open (my $fh, '>PKGREAD');
179 print $fh "# README files for repository. Do NOT remove this line.\n";
180 foreach my $package (@packages) {
181 $package =~ s/#.*//;
182 my $path = `$prtget path $package`;
183 $path =~ s/\n//g;
184 if (-f "$path/README"){
185 print $fh "##### PKGREADME: $package\n";
186 open(my $readme, "$path/README");
187 while (<$readme>){
188 my $line = $_;
189 print $fh $line;
190 }
191 close($readme);
192 }
193 }
194 close $fh;
195 }
196
197 # generate pre-post install scripts file
198 sub pkginst {
199 print "+ Generating scripts\n";
200 open (my $fh, '>PKGINST');
201 print $fh
202 "
203 #!/bin/bash
204 #
205 # PKGINST: pre-post install scripts for CRUX packages
206 ";
207 my @packages = glob("*#*.pkg.tar.$compress");
208 foreach my $package (@packages) {
209 $package =~ s/#.*//;
210 my $path = `$prtget path $package`;
211 $path =~ s/\n//g;
212 my $normal= $package;
213 $normal =~ s/[^[:alnum:]]/_/g;
214 if (-f "$path/pre-install"){
215 print $fh "${normal}_pre_install() {\n";
216 open(my $pre, "$path/pre-install");
217 while (<$pre>){
218 my $line = $_;
219 print $fh $line;
220 }
221 close($pre);
222 print $fh "}\n\n";
223 }
224 if (-f "$path/post-install"){
225 print $fh "${normal}_post_install() {\n";
226 open(my $post, "$path/post-install");
227 while (<$post>){
228 my $line = $_;
229 print $fh $line;
230 }
231 close($post);
232 print $fh "}\n\n";
233 }
234 }
235 print $fh "\n\n";
236 print $fh 'if [ ! -z "$1" ]; then $1; fi';
237 print $fh "\n";
238 close $fh;
239 }
240
241
242 ######################## html index subs ########################
243
244 sub printheader {
245 open (my $ih, '>index.html');
246 print $ih <<EOH;
247 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
248 "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
249 <html xmlns="http://www.w3.org/1999/xhtml">
250 <head>
251 EOH
252
253 print $ih " <title>$title</title>\n";
254
255 print $ih <<EOH;
256 <style type="text/css">
257 body
258 {
259 font-family: Verdana, sans-serif;
260 font-size: 85%;
261 padding: 2em;
262 }
263 a
264 {
265 color: #67550d;
266 }
267 table
268 {
269 border: solid #e5dccf 1px;
270 font-size: 85%;
271 }
272 td
273 {
274 padding: 6px;
275 }
276 tr.header
277 {
278 background-color: #e5dccf;
279 }
280 tr.odd
281 {
282 background-color: #f7f3ed;
283 }
284 tr.even
285 {
286 background-color: #fcf9f8;
287 }
288 </style>
289 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
290 </head>
291 <body>
292 EOH
293
294 print $ih " <h2>$title</h2>\n";
295 if ($header) {
296 open(FILE, $header) or die "Couldn't open header file";
297 while (<FILE>) {
298 print $ih " " . $_;
299 }
300 close(FILE);
301 }
302
303 print $ih " <table width=\"100%\" cellspacing=\"0\">\n";
304 print $ih " <tr class=\"header\"><td><b>Port</b></td><td><b>Version</b></td><td><b>Description</b></td>";
305 print $ih "<td><b>Last modified</b></td>";
306 print $ih "</tr>\n";
307 close($ih);
308 }
309
310 sub printfooter {
311 my $count = $_[0];
312 open (my $ih, '>>index.html');
313 print $ih " </table>\n";
314 print $ih " <p><b>$count packages</b></p>\n";
315 if ($footer) {
316 open(FILE, $footer) or die "Couldn't open footer file";
317 while (<FILE>) {
318 print $ih " " . $_;
319 }
320 close(FILE);
321 }
322 print $ih " <p><i>Generated by <a href=\"http://www.varlock.com\">pkg-repgen</a> on " . isotime() . ".</i></p>\n";
323 print $ih <<EOH;
324 </body>
325 </html>
326 EOH
327 close($ih);
328
329 }
330
331 sub isotime {
332 my $time = (shift or time);
333 my $accuracy = (shift or 2);
334 my @t = gmtime ($time);
335 my $year = $t[5] + 1900;
336 my $month = sprintf("%02d", $t[4] + 1);
337 my $day = sprintf("%02d", $t[3]);
338
339 if ($accuracy == 1) {
340 return "$year-$month-$day";
341 }
342
343 return "$year-$month-$day " . sprintf("%02d:%02d:%02d UTC", $t[2], $t[1], $t[0]);
344 }
|