Merge in master changes.
[catagits/Gitalist.git] / lib / Gitalist / Model / Git.pm
index d96d1aa..77f324a 100644 (file)
@@ -1,6 +1,7 @@
 package Gitalist::Model::Git;
 
 use Moose;
+use MooseX::Types::Common::String qw/NonEmptySimpleStr/; # FIXME, use Types::Path::Class and coerce
 use namespace::autoclean;
 
 BEGIN { extends 'Catalyst::Model' }
@@ -12,38 +13,38 @@ use File::Find::Rule;
 use DateTime::Format::Mail;
 use File::Stat::ModeString;
 use List::MoreUtils qw/any/;
-use Scalar::Util qw/blessed/;
+use File::Which;
 
-{
-       my $git;
-       sub git {
-               return $git
-                       if $git;
-
-               if (my $config_git = Gitalist->config->{git}) {
-                       $git = $config_git if -x $config_git;
-               }
-               else {
-                       require File::Which;
-                       $git = File::Which::which('git');
-               }
-
-               if (!$git) {
-                       die <<EOR
+has repo_dir => ( isa => NonEmptySimpleStr, is => 'ro', lazy_build => 1 ); # Fixme - path::class
+has git      => ( isa => NonEmptySimpleStr, is => 'ro', lazy_build => 1 );
+
+sub BUILD {
+    my ($self) = @_;
+    $self->git; # Cause lazy value build.
+       $self->repo_dir;
+}
+
+sub _build_git {
+       my $git = File::Which::which('git');
+
+       if (!$git) {
+               die <<EOR
 Could not find a git executable.
 Please specify the which git executable to use in gitweb.yml
 EOR
-               }
-
-               return $git;
        }
+
+       return $git;
+}
+
+sub _build_repo_dir {
+       return Gitalist->config->{repo_dir};
 }
 
 sub is_git_repo {
     my ($self, $dir) = @_;
 
-    #FIXME: Only handles bare repos. Is that enough?
-    return -f $dir->file('HEAD') or -f $dir->file('.git/HEAD');
+    return -f $dir->file('HEAD') || -f $dir->file('.git/HEAD');
 }
 
 sub project_info {
@@ -70,7 +71,6 @@ sub get_project_properties {
         delete $props{description};
     }
 
-       #Carp::cluck "dir is: $dir";
     $props{owner} = (getpwuid $dir->stat->uid)[6];
 
     my $output = $self->run_cmd_in($dir, qw{
@@ -90,7 +90,7 @@ sub get_project_properties {
 sub list_projects {
     my ($self) = @_;
 
-    my $base = dir(Gitalist->config->{repo_dir});
+    my $base = dir($self->repo_dir);
 
     my @ret;
     my $dh = $base->open;
@@ -100,20 +100,25 @@ sub list_projects {
         my $obj = $base->subdir($file);
         next unless -d $obj;
         next unless $self->is_git_repo($obj);
+               # XXX Leaky abstraction alert!
+               my $is_bare = !-d $obj->subdir('.git');
 
+               my $name = (File::Spec->splitdir($obj))[-1];
         push @ret, {
-            name => ($obj->dir_list)[-1],
-            $self->get_project_properties($obj),
+            name => ($name . ( $is_bare ? '' : '/.git' )),
+            $self->get_project_properties(
+                               $is_bare ? $obj : $obj->subdir('.git')
+                       ),
         };
     }
 
-    return \@ret;
+    return [sort { $a->{name} cmp $b->{name} } @ret];
 }
 
 sub run_cmd {
     my ($self, @args) = @_;
 
-    open my $fh, '-|', __PACKAGE__->git, @args
+    open my $fh, '-|', $self->git, @args
         or die "failed to run git command";
     binmode $fh, ':encoding(UTF-8)';
 
@@ -139,9 +144,7 @@ sub run_cmd_in {
 sub git_dir_from_project_name {
     my ($self, $project) = @_;
 
-       warn 'er, dir    - '.dir(Gitalist->config->{repo_dir});
-       warn 'er, subdir - '.dir(Gitalist->config->{repo_dir})->subdir($project);
-    return dir(Gitalist->config->{repo_dir})->subdir($project);
+    return dir($self->repo_dir)->subdir($project);
 }
 
 sub get_head_hash {