1 package ExtUtils::Packlist;
9 $VERSION = eval $VERSION;
11 # Used for generating filehandle globs. IO::File might not be available!
18 Make a filehandle. Same kind of idea as Symbol::gensym().
27 my $fh = \*{$fhname++};
34 my ($class, $packfile) = @_;
35 $class = ref($class) || $class;
37 tie(%self, $class, $packfile);
38 return(bless(\%self, $class));
43 my ($class, $packfile) = @_;
44 my $self = { packfile => $packfile };
46 $self->read($packfile) if (defined($packfile) && -f $packfile);
52 $_[0]->{data}->{$_[1]} = $_[2];
57 return($_[0]->{data}->{$_[1]});
62 my $reset = scalar(keys(%{$_[0]->{data}}));
63 return(each(%{$_[0]->{data}}));
68 return(each(%{$_[0]->{data}}));
73 return(exists($_[0]->{data}->{$_[1]}));
78 return(delete($_[0]->{data}->{$_[1]}));
83 %{$_[0]->{data}} = ();
92 my ($self, $packfile) = @_;
93 $self = tied(%$self) || $self;
95 if (defined($packfile)) { $self->{packfile} = $packfile; }
96 else { $packfile = $self->{packfile}; }
97 Carp::croak("No packlist filename specified") if (! defined($packfile));
99 open($fh, "<$packfile") || Carp::croak("Can't open file $packfile: $!");
102 while (defined($line = <$fh>))
105 my ($key, $data) = $line;
106 if ($key =~ /^(.*?)( \w+=.*)$/)
109 $data = { map { split('=', $_) } split(' ', $2)};
111 $key =~ s!/\./!/!g; # Some .packlists have spurious '/./' bits in the paths
112 $self->{data}->{$key} = $data;
119 my ($self, $packfile) = @_;
120 $self = tied(%$self) || $self;
121 if (defined($packfile)) { $self->{packfile} = $packfile; }
122 else { $packfile = $self->{packfile}; }
123 Carp::croak("No packlist filename specified") if (! defined($packfile));
125 open($fh, ">$packfile") || Carp::croak("Can't open file $packfile: $!");
126 foreach my $key (sort(keys(%{$self->{data}})))
129 if (ref($self->{data}->{$key}))
131 my $data = $self->{data}->{$key};
132 foreach my $k (sort(keys(%$data)))
134 print $fh (" $k=$data->{$k}");
144 my ($self, $remove) = @_;
145 $self = tied(%$self) || $self;
147 foreach my $key (sort(keys(%{$self->{data}})))
151 push(@missing, $key);
152 delete($self->{data}{$key}) if ($remove);
161 $self = tied(%$self) || $self;
162 return($self->{packfile});
171 ExtUtils::Packlist - manage .packlist files
175 use ExtUtils::Packlist;
176 my ($pl) = ExtUtils::Packlist->new('.packlist');
177 $pl->read('/an/old/.packlist');
178 my @missing_files = $pl->validate();
179 $pl->write('/a/new/.packlist');
181 $pl->{'/some/file/name'}++;
183 $pl->{'/some/other/file/name'} = { type => 'file',
184 from => '/some/file' };
188 ExtUtils::Packlist provides a standard way to manage .packlist files.
189 Functions are provided to read and write .packlist files. The original
190 .packlist format is a simple list of absolute pathnames, one per line. In
191 addition, this package supports an extended format, where as well as a filename
192 each line may contain a list of attributes in the form of a space separated
193 list of key=value pairs. This is used by the installperl script to
194 differentiate between files and links, for example.
198 The hash reference returned by the new() function can be used to examine and
199 modify the contents of the .packlist. Items may be added/deleted from the
200 .packlist by modifying the hash. If the value associated with a hash key is a
201 scalar, the entry written to the .packlist by any subsequent write() will be a
202 simple filename. If the value is a hash, the entry written will be the
203 filename followed by the key=value pairs from the hash. Reading back the
204 .packlist will recreate the original entries.
212 This takes an optional parameter, the name of a .packlist. If the file exists,
213 it will be opened and the contents of the file will be read. The new() method
214 returns a reference to a hash. This hash holds an entry for each line in the
215 .packlist. In the case of old-style .packlists, the value associated with each
216 key is undef. In the case of new-style .packlists, the value associated with
217 each key is a hash containing the key=value pairs following the filename in the
222 This takes an optional parameter, the name of the .packlist to be read. If
223 no file is specified, the .packlist specified to new() will be read. If the
224 .packlist does not exist, Carp::croak will be called.
228 This takes an optional parameter, the name of the .packlist to be written. If
229 no file is specified, the .packlist specified to new() will be overwritten.
233 This checks that every file listed in the .packlist actually exists. If an
234 argument which evaluates to true is given, any missing files will be removed
235 from the internal hash. The return value is a list of the missing files, which
236 will be empty if they all exist.
238 =item packlist_file()
240 This returns the name of the associated .packlist file
246 Here's C<modrm>, a little utility to cleanly remove an installed module.
248 #!/usr/local/bin/perl -w
252 use ExtUtils::Packlist;
253 use ExtUtils::Installed;
257 my $dh = IO::Dir->new($dir) || return(0);
258 my @count = $dh->read();
260 return(@count == 2 ? 1 : 0);
263 # Find all the installed packages
264 print("Finding all installed modules...\n");
265 my $installed = ExtUtils::Installed->new();
267 foreach my $module (grep(!/^Perl$/, $installed->modules())) {
268 my $version = $installed->version($module) || "???";
269 print("Found module $module Version $version\n");
270 print("Do you want to delete $module? [n] ");
271 my $r = <STDIN>; chomp($r);
272 if ($r && $r =~ /^y/i) {
273 # Remove all the files
274 foreach my $file (sort($installed->files($module))) {
278 my $pf = $installed->packlist($module)->packlist_file();
281 foreach my $dir (sort($installed->directory_tree($module))) {
282 if (emptydir($dir)) {
283 print("rmdir $dir\n");
292 Alan Burlison <Alan.Burlison@uk.sun.com>