3 class Gitalist::Git::Project {
4 # FIXME, use Types::Path::Class and coerce
5 use MooseX::Types::Common::String qw/NonEmptySimpleStr/;
6 use MooseX::Types::Moose qw/Str Maybe/;
9 use Gitalist::Git::Util;
10 use aliased 'Gitalist::Git::Object';
12 our $SHA1RE = qr/[0-9a-fA-F]{40}/;
14 has name => ( isa => NonEmptySimpleStr,
15 is => 'ro', required => 1 );
16 has path => ( isa => "Path::Class::Dir",
17 is => 'ro', required => 1);
19 has description => ( isa => Str,
23 has owner => ( isa => NonEmptySimpleStr,
27 has last_change => ( isa => Maybe['DateTime'],
31 has _util => ( isa => 'Gitalist::Git::Util',
34 handles => [ 'run_cmd' ],
38 $self->$_() for qw/_util last_change owner description/; # Ensure to build early.
42 my $util = Gitalist::Git::Util->new(
43 gitdir => $self->project_dir($self->path),
48 method _build_description {
51 $description = $self->path->file('description')->slurp;
58 my ($gecos, $name) = (getpwuid $self->path->stat->uid)[6,0];
60 return length($gecos) ? $gecos : $name;
63 method _build_last_change {
65 my $output = $self->run_cmd(
66 qw{ for-each-ref --format=%(committer)
67 --sort=-committerdate --count=1 refs/heads
69 if (my ($epoch, $tz) = $output =~ /\s(\d+)\s+([+-]\d+)$/) {
70 my $dt = DateTime->from_epoch(epoch => $epoch);
71 $dt->set_time_zone($tz);
79 Find the hash of a given head (defaults to HEAD).
83 method head_hash (Str $head?) {
84 my $output = $self->run_cmd(qw/rev-parse --verify/, $head || 'HEAD' );
85 return unless defined $output;
87 my($sha1) = $output =~ /^($SHA1RE)$/;
93 Return an array of contents for a given tree.
94 The tree is specified by sha1, and defaults to HEAD.
95 The keys for each item will be:
104 method list_tree (Str $sha1?) {
105 $sha1 ||= $self->head_hash;
107 my $output = $self->run_cmd(qw/ls-tree -z/, $sha1);
108 return unless defined $output;
111 for my $line (split /\0/, $output) {
112 my ($mode, $type, $object, $file) = split /\s+/, $line, 4;
113 push @ret, Object->new( mode => oct $mode,
123 # FIXME - Why not just stay in Path::Class land and return a P::C::D here?
125 my $dir = $self->path->stringify;
127 if -f dir($dir)->file('.git/HEAD');
135 Returns a hash containing properties of this project. The keys will
139 description (empty if .git/description is empty/unnamed)
148 description => $self->description,
149 owner => $self->owner,
150 last_change => $self->last_change,