Allow the model to be user defined.
[catagits/Gitalist.git] / lib / Gitalist / Model / CollectionOfRepos.pm
1 package Gitalist::Model::CollectionOfRepos;
2
3 use Moose;
4 use Gitalist::Git::CollectionOfRepositories::FromDirectoryRecursive;
5 use Gitalist::Git::CollectionOfRepositories::FromListOfDirectories;
6 use Gitalist::Git::CollectionOfRepositories::FromDirectory::WhiteList;
7 use MooseX::Types::Moose qw/Maybe ArrayRef/;
8 use MooseX::Types::Common::String qw/NonEmptySimpleStr/;
9 use Moose::Util::TypeConstraints;
10 use Moose::Autobox;
11 use namespace::autoclean;
12
13 extends 'Catalyst::Model';
14
15 with 'Catalyst::Component::InstancePerContext';
16
17 my $repo_dir_t = subtype NonEmptySimpleStr,
18     where { -d $_ },
19     message { 'Cannot find repository dir: "' . $_ . '", please set up gitalist.conf, or set GITALIST_REPO_DIR environment or pass the --repo_dir parameter when starting the application' };
20
21 my $arrayof_repos_dir_t = subtype ArrayRef[$repo_dir_t],
22     where { 1 },
23     message { 'Cannot find repository directories listed in config - these are invalid directories: ' . join(', ', $_->flatten) };
24
25 coerce $arrayof_repos_dir_t,
26     from NonEmptySimpleStr,
27     via { [ $_ ] };
28
29 has config_repo_dir => (
30     isa => NonEmptySimpleStr,
31     is => 'ro',
32     init_arg => 'repo_dir',
33     predicate => 'has_config_repo_dir',
34 );
35
36 has repo_dir => (
37     isa => $repo_dir_t,
38     is => 'ro',
39     lazy_build => 1
40 );
41
42 has repos => (
43     isa => $arrayof_repos_dir_t,
44     is => 'ro',
45     default => sub { [] },
46     traits => ['Array'],
47     handles => {
48         _repos_count => 'count',
49     },
50     coerce => 1,
51 );
52
53 has class => (
54     isa => NonEmptySimpleStr,
55     is  => 'ro',
56 );
57
58 has args => (
59     isa     => 'HashRef',
60     is      => 'ro',
61     default => sub { {} },
62 );
63
64 has search_recursively => (
65     is      => 'ro',
66     isa     => 'Bool',
67     default => 0,
68 );
69
70 has export_ok => (
71     is  => 'ro',
72     isa => 'Str',
73 );
74
75 has whitelist => (
76     is  => 'ro',
77     isa => 'Str',
78 );
79
80 sub _build_repo_dir {
81     my $self = shift;
82     $ENV{GITALIST_REPO_DIR} ?
83         $ENV{GITALIST_REPO_DIR}
84       : $self->has_config_repo_dir
85       ? $self->config_repo_dir
86         : '';
87 }
88
89 after BUILD => sub {
90     my $self = shift;
91     # Explode loudly at app startup time if there is no list of
92     # repositories or repos dir, rather than on first hit
93     $self->_repos_count || $self->repo_dir;
94 };
95
96 sub _default_model_class {
97     my($self) = @_;
98
99     if($self->whitelist && -f $self->whitelist) {
100         return 'FromDirectory::WhiteList';
101     } elsif ($self->_repos_count && !$self->search_recursively) {
102         return 'FromListOfDirectories';
103     } elsif($self->search_recursively) {
104         return 'FromDirectoryRecursive';
105     }
106
107     return 'FromDirectory';
108 }
109
110 sub build_per_context_instance {
111     my ($self, $app) = @_;
112
113     my %args = (
114         export_ok => $self->export_ok || '',
115         %{ $self->args }
116     );
117
118     my $class = $self->class;
119     Class::MOP::load_class($class) if $class;
120
121     my $default = $self->_default_model_class;
122
123     $args{whitelist} = $self->whitelist if $default eq 'FromDirectory::WhiteList';
124     $args{repos}     = $self->repos     if $default eq 'FromListOfDirectories';
125     $args{repo_dir}  = $self->repo_dir  if $default =~ /\b(?:WhiteList|FromDirectory(?:Recursive)?)$/;
126
127     $class ||= "Gitalist::Git::CollectionOfRepositories::$default";
128
129     $app->log->debug("Using class '$class'");
130
131     return $class->new(%args);
132 }
133
134 __PACKAGE__->meta->make_immutable;
135
136 __END__
137
138 =encoding UTF-8
139
140 =head1 NAME
141
142 Gitalist::Model::CollectionOfRepos - Model::CollectionOfRepos module for Gitalist
143
144 =head1 AUTHORS
145
146 See L<Gitalist> for authors.
147
148 =head1 LICENSE
149
150 See L<Gitalist> for the license.
151
152 =cut