From: Dan Brook Date: Sat, 29 Oct 2011 22:42:38 +0000 (+0100) Subject: Allow the model to be user defined. X-Git-Tag: 0.003007~26 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FGitalist.git;a=commitdiff_plain;h=0fd9a84a1f3002b002585a3cb3dc59de8eb8d2c6 Allow the model to be user defined. 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. --- diff --git a/Makefile.PL b/Makefile.PL index 47d1db9..746985c 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -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'; diff --git a/lib/Gitalist.pm b/lib/Gitalist.pm index f1825e3..949c5a6 100644 --- a/lib/Gitalist.pm +++ b/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'; @@ -258,6 +258,18 @@ This is compatible with C's C. If provided every must contain a file of the same name to be visible. This is similar to C'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) 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 (see above). + =back =head2 paging diff --git a/lib/Gitalist/Model/CollectionOfRepos.pm b/lib/Gitalist/Model/CollectionOfRepos.pm index 128d0ba..1e709c4 100644 --- a/lib/Gitalist/Model/CollectionOfRepos.pm +++ b/lib/Gitalist/Model/CollectionOfRepos.pm @@ -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', @@ -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); } diff --git a/t/lib/TestModelFancy.pm b/t/lib/TestModelFancy.pm new file mode 100644 index 0000000..940b60f --- /dev/null +++ b/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); + } +} diff --git a/t/lib/TestModelSimple.pm b/t/lib/TestModelSimple.pm new file mode 100644 index 0000000..2f87698 --- /dev/null +++ b/t/lib/TestModelSimple.pm @@ -0,0 +1,4 @@ +use MooseX::Declare; + +class TestModelSimple extends Gitalist::Git::CollectionOfRepositories::FromDirectory { +} diff --git a/t/model_collectionofrepos.t b/t/model_collectionofrepos.t index 7e5dc5d..bc0c71f 100644 --- a/t/model_collectionofrepos.t +++ b/t/model_collectionofrepos.t @@ -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; @@ -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); @@ -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. @@ -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';