Stop ->_build_project reinventing the wheel.
[catagits/Gitalist.git] / lib / Gitalist / Git / Repo.pm
1 use MooseX::Declare;
2
3 class Gitalist::Git::Repo {
4     use MooseX::Types::Common::String qw/NonEmptySimpleStr/;
5     use MooseX::Types::Path::Class qw/Dir/;
6     use MooseX::Types::Moose qw/ArrayRef/;
7     use aliased 'Gitalist::Git::Project';
8
9     has repo_dir => (
10         isa => Dir,
11         is => 'ro',
12         required => 1,
13         coerce => 1,
14     );
15
16     has projects => (
17         is => 'ro',
18         isa => ArrayRef['Gitalist::Git::Project'],
19         required => 1,
20         lazy_build => 1,
21     );
22
23     method BUILD {
24         # Make sure repo_dir is an absolute path so that
25         # ->contains() works correctly.
26         $self->repo_dir->resolve;
27     }
28
29     ## Public methods
30     method get_project (NonEmptySimpleStr $name) {
31         my $path = $self->repo_dir->subdir($name)->resolve;
32         die "Directory traversal prohibited"
33             unless $self->repo_dir->contains($path);
34         die "Not a valid Project"
35             unless $self->_is_git_repo($path);
36         return Project->new( $path );
37     }
38
39     ## Builders
40     method _build_projects {
41         my $dh = $self->repo_dir->open || die "Could not open repo_dir";
42         my @ret;
43         while (my $dir_entry = $dh->read) {
44             # try to get a project for each entry in repo_dir
45              eval {
46                  my $p = $self->get_project($dir_entry);
47                  push @ret, $p;
48             };
49          }
50
51         return [sort { $a->name cmp $b->name } @ret];
52     }
53
54     ## Private methods
55     # Determine whether a given directory is a git repo.
56     method _is_git_repo ($dir) {
57         return -f $dir->file('HEAD') || -f $dir->file('.git', 'HEAD');
58     }
59 }                               # end class
60
61 __END__
62
63 =head1 NAME
64
65 Gitalist::Git::Repo - Model of a repository directory
66
67 =head1 SYNOPSIS
68
69     my $repo = Gitalist::Git::Repo->new( repo_dir => $Dir );
70     my $project_list = $repo->projects;
71     my $first_project = @$project_list[0];
72     my $named_project = $repo->get_project('Gitalist');
73
74 =head1 DESCRIPTION
75
76 This class models a Gitalist Repo, which is a collection of
77 Projects (git repositories).  It is used for creating Project
78 objects to work with.
79
80
81 =head1 ATTRIBUTES
82
83 =head2 repo_dir (C<Path::Class::Dir>)
84
85 The filesystem root of the Repo.
86
87 =head2 projects
88
89 An array of all Repos found in C<repo_dir>.
90
91
92
93 =head1 METHODS
94
95 =head2 get_project (Str $name)
96
97 Returns a L<Gitalist::Git::Project> for the specified project
98 name.
99
100
101 =head1 SEE ALSO
102
103 L<Gitalist::Git::Project>
104
105
106 =head1 AUTHORS
107
108 See L<Gitalist> for authors.
109
110 =head1 LICENSE
111
112 See L<Gitalist> for the license.
113
114 =cut