Subject: | Feature request: sector-size/symlink-size (du doesn't count directory sizes - F::DU does; fdu incomplete) |
This patch adds the two features, removes the directory-size counting, and completes fdu (which may not be the right way to complete it - but is *one* way to do it, and at least let me easily test my changes).
I'm going to create a distribution from this patch so I can use it at work. I hope this is accepted functionally as-is. I've tried to adhere to your coding style as much as I could tell what it was with such a small sample. The only place I wasn't sure what it was, was for the %opts_to_du in fdu.
diff -u -r Filesys-DiskUsage-0.03/Changes Filesys-DiskUsage-0.04/Changes
--- Filesys-DiskUsage-0.03/Changes 2005-10-24 10:22:09.000000000 -0600
+++ Filesys-DiskUsage-0.04/Changes 2005-11-06 20:46:58.000000000 -0700
@@ -1,5 +1,8 @@
Revision history for Filesys::DiskUsage
+0.04 ...
+ - added sector-size and symlink-size patch
+
0.03 Mon Oct 24 17:21:00 2005
- added the fdu command
- directory excluding now works (thanks to Hussein Patni for pointing
diff -u -r Filesys-DiskUsage-0.03/README Filesys-DiskUsage-0.04/README
--- Filesys-DiskUsage-0.03/README 2005-10-24 10:19:16.000000000 -0600
+++ Filesys-DiskUsage-0.04/README 2005-11-06 21:00:08.000000000 -0700
@@ -1,4 +1,4 @@
-Filesys::DiskUsage version 0.03
+Filesys::DiskUsage version 0.04
===============================
=head1 NAME
@@ -52,7 +52,7 @@
=item dereference
-Follow symbolic links. Default is 0.
+Follow symbolic links. Default is 0. Overrides C<symlink-size>
Get the size of a directory, recursively, following symbolic links:
@@ -104,6 +104,26 @@
$total = du( { recursive => 0 } , <*> );
+=item sector-size => NUMBER
+
+All file sizes are rounded up to a multiple of this number. Any file
+that is not an exact multiple of this size will be treated as the next
+multple of this number as they would in a sector-based file system. Common
+values will be 512 or 1024. Default is 1 (no sectors).
+
+ $total = du( { sector-size => 1024 }, <*> );
+
+=item symlink-size => NUMBER
+
+Symlinks are assumed to be this size. Without this option, symlinks are
+ignored unless dereferenced. Setting this option to 0 will result in the
+files showing up in the hash, if C<make-hash> is set, with a size of 0.
+Setting this option to any other number will treat the size of the symlink
+as this number. This option is ignored if the C<dereference> option is
+set.
+
+ $total = du( { symlink-size => 1024, sector-size => 1024 }, <*> );
+
=item truncate-readable => NUMBER
Human readable formats decimal places are truncated by the value of
diff -u -r Filesys-DiskUsage-0.03/fdu Filesys-DiskUsage-0.04/fdu
--- Filesys-DiskUsage-0.03/fdu 2005-10-24 10:21:07.000000000 -0600
+++ Filesys-DiskUsage-0.04/fdu 2005-11-06 21:41:35.000000000 -0700
@@ -33,6 +33,14 @@
Likewise, but use powers of 1000 not 1024.
+=head2 -s=N
+
+Assume sector size of N.
+
+=head2 -l=N
+
+Assume link size of N (ignored if -L).
+
=head2 -m=MAX-DEPTH
Print the total for a directory (or file) only if it is N or fewer
@@ -48,24 +56,50 @@
=cut
use Getopt::Std qw(getopts);
+use lib 'blib/lib';
+use Filesys::DiskUsage qw/ du /;
our %opts = get_options();
show_help() if $opts{h};
show_version() if $opts{v};
+my %files = du( { 'make-hash' => 1, %opts }, @ARGV );
+my $human = $opts{'human-readable'} || $opts{'Human-readable'};
+
+my $total = 0;
+for (sort keys %files)
+{
+ print "$_ => $files{$_}\n";
+ $total += $files{$_} unless $human;
+}
+print "\nTotal: $total\n" unless $human;
+
# subroutines
sub get_options {
my %opts;
- getopts('hHLm:t:vX:', \%opts );
+ my %opts_to_du = (
+ L => 'dereference',
+ X => 'exclude',
+ h => 'human-readable',
+ H => 'Human-readable',
+ 'm' => 'max-depth',
+ 's' => 'sector-size',
+ l => 'symlink-size',
+ t => 'truncate-readable',
+ );
+
+ getopts('hHLm:t:vX:s:l:', \%opts );
foreach my $key ( keys %opts )
{
$opts{$key} = 1 unless defined $opts{$key}
}
- %opts;
+ #%opts;
+
+ map { $opts_to_du{$_} => $opts{$_} } keys %opts;
}
###
@@ -84,7 +118,7 @@
###
sub show_version {
- die"fdu version 0.01 (Filesys::DiskUsage", Filesys::DiskUsage->VERSION, ")\n";
+ die"fdu version 0.01 (Filesys::DiskUsage ", Filesys::DiskUsage->VERSION, ")\n";
}
=head1 AUTHOR
diff -u -r Filesys-DiskUsage-0.03/lib/Filesys/DiskUsage.pm Filesys-DiskUsage-0.04/lib/Filesys/DiskUsage.pm
--- Filesys-DiskUsage-0.03/lib/Filesys/DiskUsage.pm 2005-10-24 10:19:08.000000000 -0600
+++ Filesys-DiskUsage-0.04/lib/Filesys/DiskUsage.pm 2005-11-06 21:40:46.000000000 -0700
@@ -26,7 +26,7 @@
our @EXPORT = qw(
);
-our $VERSION = '0.03';
+our $VERSION = '0.04';
=head1 SYNOPSIS
@@ -75,7 +75,7 @@
=item dereference
-Follow symbolic links. Default is 0.
+Follow symbolic links. Default is 0. Overrides C<symlink-size>
Get the size of a directory, recursively, following symbolic links:
@@ -127,6 +127,26 @@
$total = du( { recursive => 0 } , <*> );
+=item sector-size => NUMBER
+
+All file sizes are rounded up to a multiple of this number. Any file
+that is not an exact multiple of this size will be treated as the next
+multple of this number as they would in a sector-based file system. Common
+values will be 512 or 1024. Default is 1 (no sectors).
+
+ $total = du( { sector-size => 1024 }, <*> );
+
+=item symlink-size => NUMBER
+
+Symlinks are assumed to be this size. Without this option, symlinks are
+ignored unless dereferenced. Setting this option to 0 will result in the
+files showing up in the hash, if C<make-hash> is set, with a size of 0.
+Setting this option to any other number will treat the size of the symlink
+as this number. This option is ignored if the C<dereference> option is
+set.
+
+ $total = du( { symlink-size => 1024, sector-size => 1024 }, <*> );
+
=item truncate-readable => NUMBER
Human readable formats decimal places are truncated by the value of
@@ -152,6 +172,8 @@
'make-hash' => 0,
'max-depth' => -1,
'recursive' => 1,
+ 'sector-size' => 1,
+ 'symlink-size' => undef,
'truncate-readable' => 2,
);
if (ref($_[0]) eq 'HASH') {%config = (%config, %{+shift})}
@@ -167,25 +189,31 @@
}
if (-l) { # is symbolic link
if ($config{'dereference'}) { # we want to follow it
- $sizes{$_} = du( { 'recursive' => $config{'recursive'},
- 'exclude' => $config{'exclude'},
+ $sizes{$_} = du( { 'recursive' => $config{'recursive'},
+ 'exclude' => $config{'exclude'},
+ 'sector-size' => $config{'sector-size'},
}, readlink($_));
}
else {
+ $sizes{$_} = $config{'symlink-size'} if defined $config{'symlink-size'};
next;
}
}
elsif (-f) { # is a file
- $sizes{$_} = -s;
+ $sizes{$_} = $config{'sector-size'} - 1 + -s;
+ $sizes{$_} -= $sizes{$_} % $config{'sector-size'};
}
elsif (-d) { # is a directory
- $sizes{$_} = -s;
+ # du doesn't count directory sizes - so we shouldn't either.
+ #$sizes{$_} = $config{'sector-size'} - 1 + -s;
+ #$sizes{$_} -= $sizes{$_} % $config{'sector-size'};
if ($config{recursive} && $config{'max-depth'}) {
opendir(DIR,$_);
my $dir = $_;
- $sizes{$_} += du( { 'recursive' => $config{'recursive'},
- 'max-depth' => $config{'max-depth'} -1,
- 'exclude' => $config{'exclude'},
+ $sizes{$_} += du( { 'recursive' => $config{'recursive'},
+ 'max-depth' => $config{'max-depth'} -1,
+ 'exclude' => $config{'exclude'},
+ 'sector-size' => $config{'sector-size'},
}, map {"$dir/$_"} grep {! /^\.\.?$/} readdir DIR );
}
}