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