Gave ::Project methods to return Objects, and several methods which
Zachary Stevens [Sat, 7 Nov 2009 16:57:11 +0000 (16:57 +0000)]
should really be called on the objects themselves.  This is
transitional from Git.pm

lib/Gitalist/Git/Object.pm
lib/Gitalist/Git/Project.pm
t/02git_object.t
t/02git_project.t

index 407680d..bfdf55b 100644 (file)
@@ -3,31 +3,41 @@ use MooseX::Declare;
 class Gitalist::Git::Object {
     use MooseX::Types::Moose qw/Str Int/;
     use File::Stat::ModeString qw/mode_to_string/;
+    # project and sha1 are required initargs
     has project => ( isa => 'Gitalist::Git::Project',
                      required => 1,
                      is => 'ro',
                      handles => [ 'run_cmd' ],
                  );
-    has $_ => ( isa => Str,
-                  required => 1,
-                  is => 'ro' )
-        for qw/sha1 file/;
+    has sha1 ( isa => Str,
+               required => 1,
+               is => 'ro' );
+
     has $_ => ( isa => Str,
                   required => 1,
                   is => 'ro',
                   lazy_build => 1 )
         for qw/type modestr size/;
-    has $_ => ( isa => Int,
-                  required => 1,
-                  is => 'ro' )
-        for qw/mode/;
+
+    # objects can't determine their mode or filename
+    has file => ( isa => Str,
+                  required => 0,
+                  is => 'ro' );
+    has mode => ( isa => Int,
+                required => 1,
+                default => 0,
+                is => 'ro' );
+
+    method BUILD {
+        $self->$_() for qw/type modestr size/; # Ensure to build early.
+    }
 
     method _build_type {
         my $output = $self->run_cmd(qw/cat-file -t/, $self->{sha1});
         chomp($output);
         return $output;
     }
-    
+
     method _build_modestr {
         my $modestr = mode_to_string($self->{mode});
         return $modestr;
index de3f05f..1e612f9 100644 (file)
@@ -119,6 +119,55 @@ The keys for each item will be:
         return @ret;
     }
 
+    use Gitalist::Git::Object;
+    method get_object (Str $sha1) {
+        return Gitalist::Git::Object->new(
+            project => $self,
+            sha1 => $sha1,
+        );
+    }
+    
+    # Should be in ::Object
+    method get_object_mode_string (Gitalist::Git::Object $object) {
+        return unless $object && $object->{mode};
+        return $object->{modestr};
+    }
+
+    method get_object_type ($object) {
+        chomp(my $output = $self->run_cmd(qw/cat-file -t/, $object));
+        return unless $output;
+
+        return $output;
+    }
+
+    method cat_file ($object) {
+        my $type = $self->get_object_type($object);
+        die "object `$object' is not a file\n"
+            if (!defined $type || $type ne 'blob');
+
+        my $output = $self->run_cmd(qw/cat-file -p/, $object);
+        return unless $output;
+
+        return $output;
+    }
+
+    method hash_by_path ($base, $path?, $type?) {
+        $path ||= '';
+        $path =~ s{/+$}();
+
+        my $output = $self->run_cmd('ls-tree', $base, '--', $path)
+            or return;
+        my($line) = $output ? split(/\n/, $output) : ();
+
+        #'100644 blob 0fa3f3a66fb6a137f6ec2c19351ed4d807070ffa panic.c'
+        $line =~ m/^([0-9]+) (.+) ($SHA1RE)\t/;
+        return defined $type && $type ne $2
+            ? ()
+                : $3;
+    }
+
+
+
     # Compatibility
 
 =head2 info
index ef31017..92b3710 100644 (file)
@@ -29,18 +29,15 @@ is($object->mode, 16384, 'mode is correct');
 is($object->modestr, 'd---------', "modestr is correct" );
 is($object->size, 33, "size is correct");
 
-# Create object from hash.
+# Create object from sha1.
 my $obj2 = Gitalist::Git::Object->new(
     project => $project,
     sha1 => '5716ca5987cbf97d6bb54920bea6adde242d87e6',
-    file => 'file1',
-    mode => 33188,
 );
 isa_ok($obj2, 'Gitalist::Git::Object');
 is($obj2->sha1,'5716ca5987cbf97d6bb54920bea6adde242d87e6', 'sha1 is correct');
 is($obj2->type, 'blob', 'type is correct');
-is($obj2->file, 'file1', 'file is correct');
-is($obj2->mode, 33188, 'mode is correct');
-is($obj2->modestr, '-rw-r--r--', "modestr is correct" );
+is($obj2->mode, 0, 'mode is correct');
+is($obj2->modestr, '?---------', "modestr is correct" );
 is($obj2->contents, "bar\n", 'obj2 contents is correct');
 is($obj2->size, 4, "size is correct");
index f7d6487..19409e7 100644 (file)
@@ -25,5 +25,16 @@ is($proj->info->{name}, qw/repo1/, 'repo name in info hash');
 is($proj->head_hash, qw/36c6c6708b8360d7023e8a1649c45bcf9b3bd818/, 'head_hash for HEAD is correct');
 
 is(scalar $proj->list_tree, 2, 'expected number of entries in tree');
-isa_ok(($proj->list_tree)[0], 'Gitalist::Git::Object');
-
+isa_ok(($proj->list_tree)[1], 'Gitalist::Git::Object');
+
+# Return an ::Object from a sha1
+my $obj1 = $proj->get_object('5716ca5987cbf97d6bb54920bea6adde242d87e6');
+isa_ok($obj1, 'Gitalist::Git::Object');
+
+# Test methods that really should be called on ::Object
+# This is transitional from Git.pm
+my $obj = ($proj->list_tree)[1];
+isa_ok($obj, 'Gitalist::Git::Object');
+is($proj->get_object_mode_string($obj), '-rw-r--r--', "get_object_mode_string");
+is($proj->get_object_type('5716ca5987cbf97d6bb54920bea6adde242d87e6'), 'blob', "get_object_type");
+is($proj->cat_file('5716ca5987cbf97d6bb54920bea6adde242d87e6'), "bar\n", 'cat_file');