diff --git a/lib/ShipIt/ProjectType.pm b/lib/ShipIt/ProjectType.pm index ce0119c..62f1169 100644 --- a/lib/ShipIt/ProjectType.pm +++ b/lib/ShipIt/ProjectType.pm @@ -2,6 +2,7 @@ package ShipIt::ProjectType; use strict; use ShipIt::ProjectType::Perl; use ShipIt::ProjectType::AutoConf; +use ShipIt::Util qw(find_subclasses); =head1 NAME @@ -37,6 +38,12 @@ sub new { $pt = ShipIt::ProjectType::AutoConf->new; return $pt if $pt; + for my $class (grep {!/::(Perl|AutoConf)$/} find_subclasses($class)) { + eval "CORE::require $class"; + $pt = $class->new; + return $pt if $pt; + } + die "Unknown project type. Can't find Makefile.PL, Build.PL, configure.ac, etc.."; } diff --git a/lib/ShipIt/Util.pm b/lib/ShipIt/Util.pm index 86b2224..8f3f3bc 100644 --- a/lib/ShipIt/Util.pm +++ b/lib/ShipIt/Util.pm @@ -4,7 +4,7 @@ use Carp qw(croak confess); require Exporter; our @ISA = qw(Exporter); our @EXPORT_OK = qw(slurp write_file bool_prompt edit_file $term make_var tempdir_obj - in_dir); + find_subclasses in_dir); use Term::ReadLine (); use File::Temp (); use File::Path (); @@ -62,6 +62,20 @@ sub make_var { return $1; } +sub find_subclasses { + # search for any other custom project type modules + my $class = shift; + my @classes = (); + for my $dir (@INC) { + for my $file (glob("$dir/" . join("/", split(/::/, $class)) . "/*.pm")) { + if($file =~ /\/(\w+)\.pm/) { + push(@classes, "$class" . "::" . "$1"); + } + } + } + return @classes; +} + # returns either $obj or ($obj->dir, $obj), when in list context. # when $obj goes out of scope, all temp directory contents are wiped. sub tempdir_obj { diff --git a/lib/ShipIt/VC.pm b/lib/ShipIt/VC.pm index 42968a8..06278d6 100644 --- a/lib/ShipIt/VC.pm +++ b/lib/ShipIt/VC.pm @@ -41,6 +41,14 @@ sub new { return ShipIt::VC::Git->new($conf) if -e ".git"; return ShipIt::VC::Mercurial->new($conf) if -e ".hg"; return ShipIt::VC::SVK->new($conf) if $class->is_svk_co; + + # look for any custom modules with an expensive search after exhausting the known ones + for my $class (grep {!/::(SVN|Git|Mercurial|SVK)$/} find_subclasses($class)) { + eval "CORE::require $class"; + my $vc = $class->new($conf); + return $vc if $vc; + } + die "Unknown/undetected version control system. Currently only svn/svk/git/hg are supported."; }