Skip to content

Commit

Permalink
Allow the model to be user defined.
Browse files Browse the repository at this point in the history
Given --model-class that class will be used instead of the whatever Gitalist
reasons from the model options. If --model-args is defined then they will be
used when constructing the model object in addition to the default arguments.
  • Loading branch information
Dan Brook authored and bobtfish committed Nov 13, 2011
1 parent 8bbfc70 commit 0fd9a84
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 28 deletions.
2 changes: 1 addition & 1 deletion Makefile.PL
Expand Up @@ -57,7 +57,7 @@ if ($ENV{GITALIST_RELEASE_TESTING}) {
}, $FindBin::Bin . "/lib");
}

requires 'Catalyst::Runtime' => '5.8001402';
requires 'Catalyst::Runtime' => '5.90006';
requires 'Catalyst::Plugin::ConfigLoader';
requires 'Catalyst::Plugin::StackTrace';
requires 'Catalyst::Plugin::Static::Simple';
Expand Down
14 changes: 13 additions & 1 deletion lib/Gitalist.pm
@@ -1,7 +1,7 @@
package Gitalist;
use Moose;
BEGIN { require 5.008006; }
use Catalyst::Runtime 5.80;
use Catalyst::Runtime 5.90006;
use namespace::autoclean;

extends 'Catalyst';
Expand Down Expand Up @@ -258,6 +258,18 @@ This is compatible with C<gitweb>'s C<projects.list>.
If provided every must contain a file of the same name to be
visible. This is similar to C<gitweb>'s functionality.
=item class
If you want a different way of surfacing repositories you can use your
own model (i.e something that composes
L<Gitalist::Git::CollectionOfRepositories>) and specify the class name with
this config option.
=item args
Any additional arguments to be passed into the Model constructor, only
of use when used in conjunction with C<class> (see above).
=back
=head2 paging
Expand Down
53 changes: 39 additions & 14 deletions lib/Gitalist/Model/CollectionOfRepos.pm
Expand Up @@ -50,6 +50,16 @@ has repos => (
coerce => 1,
);

has class => (
isa => NonEmptySimpleStr,
is => 'ro',
);

has args => (
isa => 'HashRef',
is => 'ro',
default => sub { {} },
);

has search_recursively => (
is => 'ro',
Expand Down Expand Up @@ -83,26 +93,41 @@ after BUILD => sub {
$self->_repos_count || $self->repo_dir;
};

sub build_per_context_instance {
my ($self, $app) = @_;
sub _default_model_class {
my($self) = @_;

my %args = (export_ok => $self->export_ok || '');
my $class;
if($self->whitelist && -f $self->whitelist) {
$class = 'Gitalist::Git::CollectionOfRepositories::FromDirectory::WhiteList';
$args{repo_dir} = $self->repo_dir;
$args{whitelist} = $self->whitelist;
return 'FromDirectory::WhiteList';
} elsif ($self->_repos_count && !$self->search_recursively) {
$class = 'Gitalist::Git::CollectionOfRepositories::FromListOfDirectories';
$args{repos} = $self->repos;
return 'FromListOfDirectories';
} elsif($self->search_recursively) {
$class = 'Gitalist::Git::CollectionOfRepositories::FromDirectoryRecursive';
$args{repo_dir} = $self->repo_dir;
} else {
$class = 'Gitalist::Git::CollectionOfRepositories::FromDirectory';
$args{repo_dir} = $self->repo_dir;
return 'FromDirectoryRecursive';
}

return 'FromDirectory';
}

sub build_per_context_instance {
my ($self, $app) = @_;

my %args = (
export_ok => $self->export_ok || '',
%{ $self->args }
);

my $class = $self->class;
Class::MOP::load_class($class) if $class;

my $default = $self->_default_model_class;

$args{whitelist} = $self->whitelist if $default eq 'FromDirectory::WhiteList';
$args{repos} = $self->repos if $default eq 'FromListOfDirectories';
$args{repo_dir} = $self->repo_dir if $default =~ /\b(?:WhiteList|FromDirectory(?:Recursive)?)$/;

$class ||= "Gitalist::Git::CollectionOfRepositories::$default";

$app->log->debug("Using class '$class'");

return $class->new(%args);
}

Expand Down
24 changes: 24 additions & 0 deletions t/lib/TestModelFancy.pm
@@ -0,0 +1,24 @@
use MooseX::Declare;

class TestModelFancy with Gitalist::Git::CollectionOfRepositories {
use MooseX::Types::Path::Class qw/Dir/;

has fanciness => (
is => 'ro',
isa => 'Bool',
);

has repo_dir => (
isa => Dir,
is => 'ro',
required => 1,
coerce => 1,
);

method _build_repositories {
[$self->get_repository('repo1')]
}
method _get_repo_from_name($name) {
Gitalist::Git::Repository->new($self->repo_dir->subdir($name)->resolve);
}
}
4 changes: 4 additions & 0 deletions t/lib/TestModelSimple.pm
@@ -0,0 +1,4 @@
use MooseX::Declare;

class TestModelSimple extends Gitalist::Git::CollectionOfRepositories::FromDirectory {
}
52 changes: 40 additions & 12 deletions t/model_collectionofrepos.t
Expand Up @@ -11,7 +11,7 @@ use warnings;

use Test::More;
use Test::Exception;
use FindBin;
use lib "$Bin/lib"; # Used for testing of --model-class etc

use Moose ();
use Moose::Object;
Expand Down Expand Up @@ -39,13 +39,14 @@ $mock_ctx_meta->add_around_method_modifier( stash => sub { # Nicked straight fro
}
return $stash;
});

our $ctx_gen = sub {
my ($cb, $stash) = @_;
$stash ||= {};
my ($cb, %args) = @_;
my $ctx = $mock_ctx_meta->new_object(
response => Catalyst::Response->new,
request => Catalyst::Request->new,
stash => { %$stash }, # Shallow copy to try and help the user out. Should we clone?
response => Catalyst::Response->new,
request => Catalyst::Request->new,
stash => {},
%args
);
$ctx->response->_context($ctx);
$ctx->request->_context($ctx);
Expand All @@ -64,11 +65,11 @@ throws_ok { Gitalist::Model::CollectionOfRepos->COMPONENT($ctx_gen->(), { repo_d

{
my $td = tempdir( CLEANUP => 1 );
test_with_config({ repo_dir => $td }, 'repo_dir is tempdir');
test_with_config({ repo_dir => $td }, msg => 'repo_dir is tempdir');
# NOTE - This is cheating, there isn't a real git repository here, so things will explode (hopefully)
# if we go much further..
test_with_config({ repos => $td }, 'repos is tempdir (scalar)');
test_with_config({ repos => [$td] }, 'repos is tempdir (array)');
test_with_config({ repos => $td }, msg => 'repos is tempdir (scalar)');
test_with_config({ repos => [$td] }, msg => 'repos is tempdir (array)');
}

# Note - we treat an empty list of repos as if it doesn't exist at all.
Expand Down Expand Up @@ -123,10 +124,37 @@ throws_ok { Gitalist::Model::CollectionOfRepos->COMPONENT($ctx_gen->(), { repos
isa_ok $i, 'Gitalist::Git::CollectionOfRepositories::FromListOfDirectories';
}

throws_ok {
test_with_config({
repo_dir => "$FindBin::Bin/lib/repositories",
class => 'ThisIsMadeOfLies',
});
} qr/Can't locate ThisIsMadeOfLies/, "Died trying to load a non-existent class";

{
my $i = test_with_config({
repo_dir => "$FindBin::Bin/lib/repositories",
class => 'TestModelSimple'
});
is scalar($i->repositories->flatten), 3, 'Found 3 repos';
isa_ok $i, 'TestModelSimple';
}

{
my $i = test_with_config({
repo_dir => "$FindBin::Bin/lib/repositories",
class => 'TestModelFancy',
args => { fanciness => 1 },
});
is scalar($i->repositories->flatten), 1, 'Found 1 repo';
isa_ok $i, 'TestModelFancy';
ok $i->fanciness, "The TestModelFancy is fancy (so --model-args worked)";
}

sub test_with_config {
my ($config, $msg) = @_;
my $ctx = $ctx_gen->();
my ($config, %opts) = @_;
my $msg = delete $opts{msg} || 'Built Model without exception';
my $ctx = $ctx_gen->(undef, %opts);
my $m;
lives_ok { $m = Gitalist::Model::CollectionOfRepos->COMPONENT($ctx, $config) } $msg;
ok $m, 'Has model';
Expand Down

0 comments on commit 0fd9a84

Please sign in to comment.