X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FGitalist%2FGit%2FObject.pm;h=7d46632b465268e1f51638d9e21cff1fb98633db;hb=96410fb53cae4b097d227548ef75600f5d8f19b4;hp=034636589ae132c6ba2ad0713d0a5f8af3a5f7ff;hpb=8dbe8024e1109d4a92d8ddb89b9a505c350e9292;p=catagits%2FGitalist.git diff --git a/lib/Gitalist/Git/Object.pm b/lib/Gitalist/Git/Object.pm index 0346365..7d46632 100644 --- a/lib/Gitalist/Git/Object.pm +++ b/lib/Gitalist/Git/Object.pm @@ -1,69 +1,145 @@ use MooseX::Declare; +use Moose::Autobox; -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', +class Gitalist::Git::Object with Gitalist::Git::Serializable is dirty { + use MooseX::Storage::Meta::Attribute::Trait::DoNotSerialize; + + use MooseX::Types::Moose qw/Str Int Bool Maybe ArrayRef/; + use MooseX::Types::Common::String qw/NonEmptySimpleStr/; + use overload '""' => '_to_string', fallback => 1; + + # repository and sha1 are required initargs + has repository => ( isa => 'Gitalist::Git::Repository', required => 1, is => 'ro', - handles => [ 'run_cmd' ], + weak_ref => 1, + handles => { + _run_cmd => 'run_cmd', + _run_cmd_fh => 'run_cmd_fh', + _run_cmd_list => 'run_cmd_list', + _get_gpp_object => 'get_gpp_object', + }, ); - has sha1 => ( isa => Str, - required => 1, - is => 'ro' ); - - has $_ => ( isa => Str, + has sha1 => ( isa => NonEmptySimpleStr, required => 1, + is => 'ro' ); + + has type => ( isa => NonEmptySimpleStr, is => 'ro', - lazy_build => 1 ) - for qw/type modestr size/; + required => 1 ); + + has $_ => ( isa => NonEmptySimpleStr, + required => 1, + is => 'ro', + lazy_build => 1 ) + for qw/modestr size/; + + has _gpp_obj => ( isa => 'Git::PurePerl::Object', + required => 1, + is => 'ro', + lazy_build => 1, + handles => [ 'content' ], + traits => ['DoNotSerialize'] + ); # objects can't determine their mode or filename - has file => ( isa => Str, + has file => ( isa => NonEmptySimpleStr, required => 0, is => 'ro' ); has mode => ( isa => Int, - required => 1, - default => 0, - is => 'ro' ); + required => 1, + default => 0, + is => 'ro' ); + + method BUILD { $self->$_() for qw/_gpp_obj size modestr/ } + +## Private methods + method _to_string { + return $self->sha1; + }; - method BUILD { - $self->$_() for qw/type modestr size/; # Ensure to build early. +## Builders + method _build__gpp_obj { + return $self->_get_gpp_object($self->sha1) } - method _build_type { - my $output = $self->run_cmd(qw/cat-file -t/, $self->{sha1}); - chomp($output); - return $output; + method "_build_size" { + my $v = $self->_cat_file_with_flag('s'); + chomp($v); + return $v; } - method _build_modestr { - my $modestr = mode_to_string($self->{mode}); - return $modestr; + method _cat_file_with_flag ($flag) { + $self->_run_cmd('cat-file', '-' . $flag, $self->{sha1}) } - method _build_size { - my $output = $self->run_cmd(qw/cat-file -s/, $self->{sha1}); - chomp($output); - return $output; + method _build_modestr { + return _mode_str($self->mode); } -=head2 contents + # via gitweb.pm circa line 1305 + use Fcntl ':mode'; + use constant { + S_IFINVALID => 0030000, + S_IFGITLINK => 0160000, + }; -Return the contents of a given file. + # submodule/subrepository, a commit object reference + sub S_ISGITLINK($) { + return (($_[0] & S_IFMT) == S_IFGITLINK) + } -=cut + # convert file mode in octal to symbolic file mode string + sub _mode_str { + my $mode = shift; - method contents { - if ( $self->type ne 'blob' ) { - die "object $self->sha1 is not a file\n" + if (S_ISGITLINK($mode)) { + return 'm---------'; + } elsif (S_ISDIR($mode & S_IFMT)) { + return 'drwxr-xr-x'; + } elsif ($^O ne 'MSWin32' and S_ISLNK($mode)) { # this is ENOLINKS country, we can't stop here! + return 'lrwxrwxrwx'; + } elsif (S_ISREG($mode)) { + # git cares only about the executable bit + if ($mode & S_IXUSR) { + return '-rwxr-xr-x'; + } else { + return '-rw-r--r--'; + } + } else { + return '----------'; } - - my $output = $self->run_cmd(qw/cat-file -p/, $self->sha1); - return unless $output; - - return $output; } } # end class + +__END__ + +=head1 NAME + +Gitalist::Git::Object - Model of a git object. + +=head1 SYNOPSIS + + my $object = Repository->get_object($sha1); + +=head1 DESCRIPTION + +Abstract base class for git objects. + + +=head1 ATTRIBUTES + + +=head1 METHODS + + +=head1 AUTHORS + +See L for authors. + +=head1 LICENSE + +See L for the license. + +=cut