Merge from vendor branch TNF:
[pkgsrc.git] / pkgtools / port2pkg / files / port2pkg.pl
1 #!/usr/bin/env perl
2 #
3 # $NetBSD: port2pkg.pl,v 1.4 2000/04/26 16:18:59 sakamoto Exp $
4 #
5
6 require 'getopts.pl';
7 $^W=1;
8 use strict;
9 use vars qw($opt_m);
10 my($maintainer) = "packages\@netbsd.org";
11 my($makefile, $master_site_subdir, $extract_cmd);
12 my($portsdir, $pkgdir);
13 my($namespace, $portname, $portversion, $distname,
14    $pkgname, $pkgnameprefix, $pkgnamesuffix);
15 my(@man, @cat);
16
17 &usage_and_exit() if (! &Getopts('m:'));
18 $|=1;
19
20 $portsdir = shift;
21 $pkgdir = shift;
22 &usage_and_exit() if (! $portsdir || ! $pkgdir);
23
24 $maintainer = $opt_m if ($opt_m);
25 die "$portsdir: $!\n" if (! -d "$portsdir");
26 if (! -d "$pkgdir") {
27         if (mkdir($pkgdir, 0755) == 0) {
28                 die "$pkgdir: $!\n";
29         }
30 }
31
32 system("${GTAR} cCf $portsdir - .|${GTAR} xCf $pkgdir -");
33
34 &read_Makefile();
35 &conv_Makefile();
36 &conv_PLIST();
37 &add_NetBSD_ID();
38
39 system("(cd $pkgdir; pkglint)");
40 0;
41
42 sub usage_and_exit {
43         print "port2pkg [-m maintainer] portsdir pkgdir\n";
44         exit;
45 }
46
47 sub read_Makefile {
48         open(PORTS, "$portsdir/Makefile")
49                 || die "$portsdir/Makefile: $!\n";
50         while (<PORTS>) {
51                 if (/\\$/) {
52                         chop;
53                         chop;
54                 }
55                 $makefile .= $_;
56         }
57         close(PORTS);
58
59         my ($extract_before_args, $extract_after_args);
60         foreach my $line (split(/\n/, $makefile)) {
61                 $_ = $line;
62                 if (/^PORTNAME\?*=(\s*)(.*)/) {
63                         $namespace = $1;
64                         $portname = $2;
65                 } elsif (/^PORTVERSION\?*=\s*(.*)/) {
66                         $portversion = $1;
67                 } elsif (/^PKGNAMEPREFIX\?*=\s*(.*)/) {
68                         $pkgnameprefix = $1;
69                 } elsif (/^PKGNAMESUFFIX\?*=\s*(.*)/) {
70                         $pkgnamesuffix = $1;
71                 } elsif (/^DISTNAME\?*=\s*(.*)/) {
72                         $distname = $1;
73                 } elsif (/^MASTER_SITE_SUBDIR\?*=\s*(.*)/) {
74                         $master_site_subdir = $1;
75                         if (!($master_site_subdir =~ /\/$/)) {
76                                 $master_site_subdir .= "/";
77                         }
78                 } elsif (/^MAN(.)\?*=\s*(.*)/) {
79                         $man[$1] .= $2;
80                 } elsif (/^CAT(.)\?*=\s*(.*)/) {
81                         $cat[$1] .= $2;
82                 } elsif (/^EXTRACT_CMD\?*=\s*(.*)/) {
83                         $extract_cmd = $1;
84                 } elsif (/^EXTRACT_BEFORE_ARGS\?*=\s*(.*)/) {
85                         $extract_before_args = $1;
86                 } elsif (/^EXTRACT_AFTER_ARGS\?*=\s*(.*)/) {
87                         $extract_after_args = $1;
88                 }
89         }
90
91         if (defined($extract_cmd) && $extract_cmd ne "") {
92                 if ($extract_before_args ne "") {
93                         $extract_before_args = " $extract_before_args";
94                 }
95                 if ($extract_after_args ne "") {
96                         $extract_after_args = " $extract_after_args";
97                 }
98                 $extract_cmd = "$extract_cmd$extract_before_args" .
99                         " \${DOWNLOADED_DISTFILE}$extract_after_args";
100         }
101
102         if (defined($distname)) {
103                 $distname =~ s/\${PORTNAME}/$portname/;
104                 $distname =~ s/\${PORTVERSION}/$portversion/;
105
106                 if ($distname ne "$portname-$portversion") {
107                         $pkgname = "$portname-$portversion";
108                 }
109         } else {
110                 $distname = "$portname-$portversion";
111         }
112         if (defined($pkgnameprefix)) {
113                 $pkgname = $distname unless (defined($pkgname));
114                 $pkgname = $pkgnameprefix . $pkgname;
115         }
116         if (defined($pkgnamesuffix)) {
117                 $pkgname = $distname unless (defined($pkgname));
118                 $pkgname .= $pkgnamesuffix;
119         }
120 }
121
122 sub conv_Makefile {
123         open(PORTS, "$portsdir/Makefile")
124                 || die "$portsdir/Makefile: $!\n";
125         open(PKG, ">$pkgdir/Makefile")
126                 || die "$pkgdir/Makefile: $!\n";
127
128         print PKG "# \$NetBSD\$\n";
129
130         # header
131         while (<PORTS>) {
132                 last if (! /^\#/);
133
134                 if (/\$FreeBSD(: .*) \$/ || /\$Id(: .*) \$/) {
135                         print PKG "\# FreeBSD Id$1\n";
136                 } else {
137                         print;
138                 }
139         }
140         print PKG;
141
142         # body
143         my ($nextline, $remove, $master_sites, $noportdocs);
144         while (<PORTS>) {
145                 if (/\\$/) {
146                         $nextline++;
147                         next if ($remove);
148                 } else {
149                         $nextline = 0;
150                         if ($remove) {
151                                 $remove = 0;
152                                 next;
153                         }
154                 }
155
156                 s|^\.include <bsd.port.pre.mk>|.include \"../../mk/bsd.prefs.mk\"|;
157                 s|^\.include <bsd.port.mk>|.include \"../../mk/bsd.pkg.mk\"|;
158                 s|^FETCH_(DEPENDS)|BUILD_$1|;
159                 s|^LIB_(DEPENDS)|$1|;
160                 s|\$\{PORTSDIR\}|../..|g;
161                 s|PLIST_SUB|PLIST_SUBST|;
162
163                 if (defined($master_site_subdir) &&
164                     $master_site_subdir ne "" &&
165                     ($master_sites || /^MASTER_SITES\?*=/)) {
166                         s|([^L][^O][^C][^A][^L])\}|$1:=$master_site_subdir}|g;
167
168                         if ($nextline) {
169                                 $master_sites = 1;
170                         } else {
171                                 $master_sites = 0;
172                         }
173                 }
174
175                 if (/(\/usr\/local)/ ||
176                     /(\/usr\/X11R6)/ ||
177                     /(ldconfig)/i ||
178                     /(MASTERDIR)/ ||
179                     /(.*cat.*MESSAGE.*)/i) {
180                         print "WARN: found \"$1\"\n";
181                 }
182
183                 if (/^PORTVERSION/ ||
184                     /^PKGNAMEPREFIX/ ||
185                     /^PKGNAMESUFFIX/ ||
186                     /^DISTNAME/ ||
187                     /^MAN(.)\?*=/ ||
188                     /^CAT(.)\?*=/ ||
189                     /^MASTER_SITE_SUBDIR/ ||
190                     /^EXTRACT_BEFORE_ARGS/ ||
191                     /^EXTRACT_AFTER_ARGS/) {
192                         $remove if ($nextline);
193                 } elsif (/^PORTNAME/) {
194                         print PKG "DISTNAME=$namespace$distname\n";
195                         print PKG "PKGNAME=$namespace$pkgname\n" if defined($pkgname);
196                         $remove if ($nextline);
197                 } elsif (/^(EXTRACT_CMD\?*=)/) {
198                         print PKG "$1\t$extract_cmd\n";
199                         $remove if ($nextline);
200                 } elsif (/^(MAINTAINER\?*=)/) {
201                         print PKG "$1\t$maintainer\n";
202                         $remove if ($nextline);
203
204                         open(DESCR, "$pkgdir/pkg/DESCR")
205                                 || die "$pkgdir/pkg/DESCR: $!\n";
206                         while (<DESCR>) {
207                                 chop;
208                                 if (/^WWW:[\s]*(.*)/) {
209                                         print PKG "HOMEPAGE=\t$1\n";
210                                 }
211                         }
212                         close(DESCR);
213                 } elsif ($noportdocs || /^\.if.*NOPORTDOCS/) {
214                         if (/^\.if/) {
215                                 $noportdocs++;
216                                 print PKG $_ if ($noportdocs > 2);
217                         } elsif (/^\.endif/) {
218                                 $noportdocs--;
219                                 print PKG $_ if ($noportdocs > 2);
220                         } else {
221                                 print PKG $_;
222                         }
223                 } else {
224                         print PKG $_;
225                 }
226         }
227
228         close(PORTS);
229         close(PKG);
230 }
231
232 sub add_manual {
233         my ($FILE, $category) = @_;
234
235         for (my $i = 1; $i <= 8; $i++) {
236                 next if (!defined(eval "\$$category\[\$i\]"));
237                         foreach my $item (sort(split(/[ \t\n]+/,
238                             eval "\$$category\[\$i\]"))) {
239                                 print $FILE "$category/$category$i/$item\n";
240                 }
241         }
242 }
243
244 sub conv_PLIST {
245         my ($file, $plist);
246         return 0 if (opendir(PKGDIR, "$portsdir/pkg") == 0);
247         while ($plist = readdir(PKGDIR)) {
248                 next if (!($plist =~ /^PLIST/));
249
250                 open(PORTS, "$portsdir/pkg/$plist")
251                         || die "$portsdir/pkg/$plist: $!\n";
252                 open(PKG, ">$pkgdir/pkg/$plist")
253                         || die "$pkgdir/pkg/$plist: $!\n";
254
255                 print PKG "\@comment \$NetBSD\$\n";
256                 my ($cat_added, $man_added);
257                 while (<PORTS>) {
258                         s|\%\%([^\%]+)\%\%|\${$1}|g;
259                         next if (/^\@.*ldconfig/);
260                         if (defined($cat_added) && $cat_added == 0 && /^[d-z]/){
261                                 &add_manual(*PKG, "cat");
262                                 $cat_added++;
263                         }
264                         if (defined($man_added) && $man_added == 0 && /^[n-z]/){
265                                 &add_manual(*PKG, "man");
266                                 $man_added++;
267                         }
268
269                         print PKG $_;
270                 }
271                 if (defined($cat_added) && $cat_added == 0)
272                         {&add_manual(*PKG, "cat");}
273                 if (defined($man_added) && $man_added == 0)
274                         {&add_manual(*PKG, "man");}
275
276                 close(PKG);
277                 close(PORTS);
278         }
279         closedir(PKGDIR);
280 }
281
282 sub add_NetBSD_ID {
283         my ($patch);
284         if (open(MD5, "$portsdir/files/md5")) {
285                 open(NMD5, ">$pkgdir/files/md5")
286                         || die "$pkgdir/files/md5: $!\n";
287                 print NMD5 "\$NetBSD\$\n\n";
288                 while (<MD5>) {
289                         print NMD5 $_;
290                 }
291                 close(NMD5);
292                 close(MD5);
293         }
294
295         return 0 if (opendir(PATCHDIR, "$portsdir/patches") == 0);
296         while ($patch = readdir(PATCHDIR)) {
297                 if ($patch eq "\." || $patch eq "\.."
298                         || $patch eq "CVS") {next;}
299                 if (open(PATCH, "$portsdir/patches/$patch")) {
300                         open(NPATCH, ">$pkgdir/patches/$patch")
301                                 || die "$pkgdir/patches/$patch: $!\n";
302                         print NPATCH "\$NetBSD\$\n\n";
303                         while (<PATCH>) {
304                                 if (/(FreeBSD)/i ||
305                                     /(#!.*perl)/) {
306                                         print "WARN: $pkgdir/patches/" .
307                                           "$patch includes \"$1\".\n";
308                                 }
309                                 print NPATCH $_;
310                         }
311                         close(NPATCH);
312                         close(PATCH);
313                 }
314         }
315         closedir(PATCHDIR);
316 }