fixed typos
[gpg4win.git] / src / pkg-to-nsi.pl
1 #! /usr/bin/perl -w
2 # pkg-to-nsi.pl - Helper script to create NSI snippets from archive files.
3 # Copyright (C) 2007 g10 Code GmbH
4
5 # This file is part of Gpg4win.
6
7 # Gpg4win is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2 of the License, or
10 # (at your option) any later version.
11
12 # Gpg4win is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 # GNU General Public License for more details.
16
17 # You should have received a copy of the GNU General Public License
18 # along with this program; if not, write to the Free Software
19 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20
21 use strict;
22 use warnings;
23 use diagnostics;
24
25 # This is a small script to convert the list of files in a binary
26 # package to an NSI install or uninstall snippet.
27 #
28 # Usage: ./pkg-to-nsi.pl [--filter FILTER1,FILTER2,...]... \
29 #                        --inst|--uninst PACKAGE
30 #
31 # For example:
32 #
33 #  perl pkg-to-nsi.pl --filter crystal,22x22,32x32,48x48,64x64,128x128 \
34 #                     --inst ../packages/oxygen-icons-20071220-bin.zip
35 #
36 # The result can be used as the basis for a NSI file.  Do NOT cut and paste
37 # this without thinking.  Some merging needs to be done.  For example, some
38 # files will be installed in different locations (bin,lib to root), and
39 # files only included in previous installations may need to be removed from
40 # future installations, etc.
41
42 # Operation.
43 $::op = '--inst';
44
45 # Filter expressions.
46 @::filter = ();
47
48 while ($ARGV[0] =~ m,^-,)
49 {
50     my $opt;
51     $opt = shift @ARGV;
52     if ($opt eq '--inst' or $opt eq '--uninst')
53     {
54         $::op = $opt;
55     }
56     elsif ($opt eq '--filter')
57     {
58         die "--filter needs argument" if ($#ARGV < 0);
59         push @::filter, split (',', shift @ARGV);
60     }
61     else
62     {
63         die "unknown option $opt";
64     }
65 }
66
67 if ($::op ne '--inst' and $::op ne '--uninst')
68 {
69     die "unknown operation $::op";
70 }
71
72 $_ = shift @ARGV;
73 @::files = ();
74
75 if ($_ =~ m/\.zip$/)
76 {
77     @::files = `unzip -l -qq $_ | colrm 1 28`;
78 }
79 elsif ($_ =~ m/\.tar\.gz$/)
80 {
81     @::files = `tar tzf $_`;
82 }
83 elsif ($_ =~ m/\.tar\.bz2$/)
84 {
85     @::files = `tar tjf $_`;
86 }
87 else
88 {
89     die "unknown file type $_";
90 }
91
92
93 @::files = sort @::files;
94
95
96 if ($::op eq '--inst')
97 {
98     my $cdir = "";
99
100     foreach my $file (@::files)
101     {
102         chomp $file;
103         
104         next if ($file =~ m,/$,);
105         my $matches = 0;
106         foreach my $filter (@::filter)
107         {
108             if ($file =~ m,$filter,)
109             {
110                 $matches = 1;
111                 last;
112             }
113         }
114         next if $matches;
115
116         $file =~ m,(?:(.*)/)?([^/]+),;
117         my $dir = $1;
118         my $base = $2;
119         if ($dir ne $cdir)
120         {
121             $cdir = $dir;
122             $dir =~ s,/,\\,g;
123             
124             print "\n" . '  SetOutPath "$INSTDIR\\' . $dir . '"' . "\n\n";
125         }
126         print '  File ${prefix}/' . $file . "\n";
127     }
128 }
129 elsif ($::op eq '--uninst')
130 {
131     my $in_rmdir = 0;
132     # All directories we have seen.
133     my %dir_seen;
134     # All directories that occur.
135     my %dirs;
136
137     @::files = reverse @::files;
138
139     foreach my $file (@::files)
140     {
141         chomp $file;
142
143         # We handle all dirs at the end.
144         next if ($file =~ m,/$,);
145
146         my $matches = 0;
147
148         # Apply filters.
149         foreach my $filter (@::filter)
150         {
151             if ($file =~ m,$filter,)
152             {
153                 $matches = 1;
154                 last;
155             }
156         }
157         next if $matches;
158
159         # Remember directories.
160         my $dir = $file;
161         
162         chomp $dir;
163         while ($dir =~ m,/,)
164         {
165             $dir =~ s,/[^/]+$,/,;
166             $dirs{$dir}++;
167                 $dir =~ s,/$,,;
168         }
169         
170         # Delete file.
171         $file =~ m,(?:(.*)/)?([^/]+),;
172         $dir = $1;
173         $dir_seen{$dir}++;
174         do
175         {
176             $dir =~ s,/[^/]+$,,;
177             $dir_seen{$dir}++;
178         }
179         while ($dir =~ m,/,);
180         
181         if ($in_rmdir)
182         {
183             print "\n";
184             $in_rmdir = 0;
185             }
186         
187         $file =~ s,/,\\,g;
188         print '  Delete "$INSTDIR\\' . $file . '"' . "\n";
189     }
190
191     # Delete all dirs not yet deleted.
192     foreach my $file (reverse sort keys %dirs)
193     {
194         chomp $file;
195
196         if ($file =~ m,/$,)
197         {
198             chop $file;
199
200             next if not defined $dir_seen{$file};
201
202             $file =~ s,/,\\,g;
203
204             if (not $in_rmdir)
205             {
206                 print "\n";
207                 $in_rmdir = 1;
208             }
209
210             print '  RMDir "$INSTDIR\\' . $file . '"' . "\n";
211         }
212     }
213     print '  RMDir "$INSTDIR"'. "\n";
214 }