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