merged from branch moose default tip
authorHeiko Schlittermann (JUMPER) <hs@schlittermann.de>
Wed, 27 Jul 2011 23:26:09 +0200
changeset 5 28392c81e909
parent 1 d2562d0417a9 (current diff)
parent 4 a4f1369eaa6e (diff)
merged from branch moose
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/.perltidyrc	Wed Jul 27 23:26:09 2011 +0200
@@ -0,0 +1,2 @@
+--paren-tightness=2
+--square-bracket-tightness=2
--- a/lib/BlockDev.pm	Wed Jul 20 22:35:03 2011 +0200
+++ b/lib/BlockDev.pm	Wed Jul 27 23:26:09 2011 +0200
@@ -1,19 +1,81 @@
 package BlockDev;
 
 use 5.010;
-use strict;
-use warnings;
-use Attribute::Params::Validate qw(:all);
+use Moose;
+use POSIX;
+use autodie qw(:all);
+use Cwd qw(abs_path);
 
 our $VERSION = "0.0";
 
-my %X;
+# extend the PATH with *sbin* if not there already
+foreach my $p (qw(/sbin /usr/sbin /usr/local/sbin)) {
+    $p ~~ [split(/:/ => $ENV{PATH})]
+	or $ENV{PATH} = "$p:$ENV{PATH}";
+}
+
+has dev => (is => "ro", isa => "Str");
 
 sub list {
     open(my $fh => "/proc/partitions");
     return map { (split)[3] } grep /^\s*\d+/ => <$fh>;
 }
 
+# process the arguments before actually calling the
+# constructor
+
+sub BUILDARGS {
+    my $class = shift;
+    my ($key, $value) = @_;
+
+    given ($key) {
+        when ("dev") {
+	    $value = "/dev/$value" if $value !~ /^\// and not -e $value and -b "/dev/$value";
+            -b $value or die "no blockdevice `$value'";
+            return { dev => $value };
+        }
+        when ("dir") {
+            -d $value or die "`$value' is not a directory";
+            `df --portability '$value'` =~ /^(?<dev>\/\S+).*?(?<mp>\S+)$/m;
+            die "$value does not have a real file system"
+              if not $+{dev};
+            return { dev => $+{dev} };
+        }
+        when (/^m(?:ount)?p(?:oint)?$/) {
+            -d $value or die "`$value` is not a directory";
+            open(my $mounts => "/proc/mounts");
+            join("" => <$mounts>) =~ /^(?<dev>\S+)\s$value\s/m
+              or die "$value is not a mountpoint";
+            return { dev => $+{dev} };
+        }
+	when ("uuid") {
+	    chomp(my $dev = `blkid -c /dev/null -U '$value'`);
+	    die "'$value' does not exist as UUID" if not $dev;
+	    return { dev => $dev }
+	}
+	when ("label") {
+	    chomp(my $dev = `blkid -c /dev/null -L '$value'`);
+	    die "'$value' does not exist as label" if not $dev;
+	    return { dev => $dev }
+	}
+        default { die "unknown initialization" }
+    }
+}
+
+sub path  { abs_path shift->dev }
+sub major { (stat shift->dev)[6] >> 8 }
+sub minor { (stat shift->dev)[6] & 0xff }
+sub size  {
+    my $self = shift;
+    open(my $fh => $self->path);
+    seek($fh, 0, SEEK_END);
+    return tell($fh);
+}
+
+
+1;
+__END__
+
 sub new : Validate(uuid => 0, dev => 0) : method {
     my $class = shift;
     my $self = bless \my $x => $class;
@@ -49,11 +111,6 @@
     return $X{$self}{dev} if exists $X{$self}{dev};
 }
 
-sub DESTROY {
-    my $self = shift;
-    delete $X{$self};
-}
-
 1;
 
 __END__
--- a/scratch/new	Wed Jul 20 22:35:03 2011 +0200
+++ b/scratch/new	Wed Jul 27 23:26:09 2011 +0200
@@ -6,6 +6,10 @@
 use BlockDev;
 
 
-my $dev = BlockDev->new(dev => "/dev/sda1");
-say scalar $dev->rdev();
+my $dev = BlockDev->new(@ARGV);
+say $dev->major;
+say $dev->minor;
+#say $dev->mami;
+say $dev->dev;
+say $dev->path;
 
--- a/t/00-module.t	Wed Jul 20 22:35:03 2011 +0200
+++ b/t/00-module.t	Wed Jul 27 23:26:09 2011 +0200
@@ -8,16 +8,37 @@
     use_ok "BlockDev";
 }
 
+my %part;
+{
+    open(my $pp => "/proc/partitions");
+    while (<$pp>) { chomp;
+	$. <= 2 and next;
+	my ($ma, $mi, $si, $dev) = split;
+	$part{$dev} = { major => $ma,
+			minor => $mi,
+			size => $si * 1024 };
+    }
+}
+
 my @devices = BlockDev->list();
 {   # device list
 
-    my @proc = ();
-    open(my $fh, "/proc/partitions");
-    while (<$fh>) {
-	/^\s*(\d+\s+){3}(?<dev>\S+)/ or next;
-	push @proc => $+{dev};
+    is_deeply([sort @devices] => [sort keys %part], "got all devices");
+}
+
+foreach (@devices) {
+
+    my $dev = BlockDev->new(dev => $_);
+    isa_ok($dev, "BlockDev");
+
+    ok(-b $dev->dev, "block device " . $dev->dev);
+    is($dev->major, $part{$_}{major}, "major $_");
+    is($dev->minor, $part{$_}{minor}, "minor $_");
+    SKIP: {
+	skip "need root permission" => 1 if $<;
+	is($dev->size, $part{$_}{size}, "size $part{$_}{size}");
     }
-    is_deeply(\@devices => \@proc, "got all devices");
+
 }
 
 done_testing();