From: Dipesh Patel Date: Wed, 18 Aug 2010 22:29:20 +0000 (+0100) Subject: First pass attempt to recursively search through directories. X-Git-Tag: 0.002007~13 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FGitalist.git;a=commitdiff_plain;h=576d59a02a5949610ab322871be4d46e8b2e62fa First pass attempt to recursively search through directories. Go throught directories using Dir->recursive. However bit expensive as will carry on even if git repo found so may change. --- diff --git a/lib/Gitalist/Git/CollectionOfRepositories/FromDirectoryRecursive.pm b/lib/Gitalist/Git/CollectionOfRepositories/FromDirectoryRecursive.pm new file mode 100644 index 0000000..fe3b43a --- /dev/null +++ b/lib/Gitalist/Git/CollectionOfRepositories/FromDirectoryRecursive.pm @@ -0,0 +1,93 @@ +use MooseX::Declare; + +class Gitalist::Git::CollectionOfRepositories::FromDirectoryRecursive + with Gitalist::Git::CollectionOfRepositories { + use MooseX::Types::Common::String qw/NonEmptySimpleStr/; + use MooseX::Types::Path::Class qw/Dir/; + + has repo_dir => ( + isa => Dir, + is => 'ro', + required => 1, + coerce => 1, + ); + + method BUILD { + # Make sure repo_dir is an absolute path so that + # ->contains() works correctly. + $self->repo_dir->resolve; + } + + method _get_path_for_repository_name (NonEmptySimpleStr $name) { + my $path = $self->repo_dir->subdir($name)->resolve; + die "Directory traversal prohibited" + unless $self->repo_dir->contains($path); + return $path; + } + + ## Builders + method _build_repositories { + my @ret = $self->_recurse_directories( $self->repo_dir ); + return \@ret; + } + + method _recurse_directories (Dir $dir) { + my @ret; + # can't use Dir->recurse since will kep going even if + # know its a git repo so will do manually + $dir->recurse( + callback => sub { + my ( $dir ) = @_; + print STDERR Data::Dumper->Dump([$dir]); + if ( $dir->is_dir ) { + eval { + # slight hack since get_repo expects string + # prob needs rewrite. + my @list = $dir->dir_list(); + my $p = $self->get_repository($list[$#list]); + push @ret, $p; + }; + } + } + ); + return @ret; + } + +} # end class + +__END__ + +=head1 NAME + +Gitalist::Git::CollectionOfRepositories::FromDirectoryRecursive - Model of recursive directories containing git repositories + +=head1 SYNOPSIS + + my $repo = Gitalist::Git::CollectionOfRepositories::FromDirectoryRecursive->new( repo_dir => $Dir ); + my $repository_list = $repo->repositories; + my $first_repository = $repository_list->[0]; + my $named_repository = $repo->get_repository('Gitalist'); + +=head1 DESCRIPTION + +This class provides a list of Repositories recursively found in the given directory. + +=head1 ATTRIBUTES + +=head2 repo_dir (C) + +The filesystem root of the C. + +=head1 SEE ALSO + +L, L + +=head1 AUTHORS + +See L for authors. + +=head1 LICENSE + +See L for the license. + +=cut diff --git a/t/02git_CollectionOfRepositories_FromDirectoryRecursive.t b/t/02git_CollectionOfRepositories_FromDirectoryRecursive.t new file mode 100644 index 0000000..dbaf46e --- /dev/null +++ b/t/02git_CollectionOfRepositories_FromDirectoryRecursive.t @@ -0,0 +1,53 @@ +use FindBin qw/$Bin/; +BEGIN { + my $env = "$FindBin::Bin/script/env"; + if (-r $env) { + do $env or die $@; + } +} + +use strict; +use warnings; +use Test::More qw/no_plan/; +use Test::Exception; + +use Data::Dumper; + +BEGIN { use_ok 'Gitalist::Git::CollectionOfRepositories::FromDirectoryRecursive' } + +my $repo_dir = "$Bin/lib/repositories"; +my $repo = Gitalist::Git::CollectionOfRepositories::FromDirectoryRecursive->new( repo_dir => $repo_dir ); +isa_ok($repo, 'Gitalist::Git::CollectionOfRepositories::FromDirectoryRecursive'); + +is($repo->repo_dir, $repo_dir, "repo->repo_dir is correct" ); + +# 'bare.git' is a bare git repository in the repository dir + +my $repository_list = $repo->repositories; +ok(scalar @{$repository_list} == 5, '->repositories is an array with the correct number of members' ); +isa_ok($repository_list->[0], 'Gitalist::Git::Repository'); +is($repository_list->[0]->{name}, 'bare.git', '->repositories has correct name for "bare.git" repo' ); + +dies_ok { + my $repository = $repo->get_repository('NoSuchRepository'); +} 'throws exception for invalid repository'; + +dies_ok { + my $repository = $repo->get_repository(); +} 'throws exception for no repository'; + +dies_ok { + my $repository = $repo->get_repository('../../../'); +} 'throws exception for directory traversal'; + +my $repository = $repo->get_repository('repo1'); +isa_ok($repository, 'Gitalist::Git::Repository'); + + +# check for bug where get_repository blew up if repo_dir +# was a relative path +lives_ok { + my $repo2_dir = "$Bin/lib/../lib/repositories"; + my $repo2 = Gitalist::Git::CollectionOfRepositories::FromDirectoryRecursive->new( repo_dir => $repo2_dir ); + my $repo2_proj = $repo2->get_repository('repo1'); +} 'relative repo_dir properly handled'; diff --git a/t/lib/repositories/recursive/nothinginhere/emptyfile b/t/lib/repositories/recursive/nothinginhere/emptyfile new file mode 100644 index 0000000..e69de29