prep for release
[gitmo/MooseX-ConfigFromFile.git] / lib / MooseX / ConfigFromFile.pm
index e6b7d44..bb5b984 100644 (file)
@@ -1,19 +1,21 @@
 package MooseX::ConfigFromFile;
 
 use Moose::Role;
-use MooseX::Types::Path::Class qw( File );
-
-our $VERSION   = '0.02';
-
+use MooseX::Types::Path::Tiny 'Path';
+use Try::Tiny qw/ try /;
 use Carp qw(croak);
+use namespace::autoclean;
+
+our $VERSION = '0.07';
 
 requires 'get_config_from_file';
 
 has configfile => (
     is => 'ro',
-    isa => File,
+    isa => Path,
     coerce => 1,
     predicate => 'has_configfile',
+    do { try { require MooseX::Getopt; (traits => ['Getopt']) } },
 );
 
 sub new_with_config {
@@ -25,11 +27,22 @@ sub new_with_config {
         $configfile = $opts{configfile}
     }
     else {
-        my $cfmeta = $class->meta->get_attribute('configfile');
-        $configfile = $cfmeta->default if $cfmeta->has_default;
+        # This would only succeed if the consumer had defined a new configfile
+        # sub to override the generated reader
+        $configfile = try { $class->configfile };
+
+        # this is gross, but since a lot of users have swapped in their own
+        # default subs, we have to keep calling it rather than calling a
+        # builder sub directly - and it might not even be a coderef either
+        my $cfmeta = $class->meta->find_attribute_by_name('configfile');
+        $configfile ||= $cfmeta->default if $cfmeta->has_default;
+
+        if (ref $configfile eq 'CODE') {
+            $configfile = $configfile->($class);
+        }
     }
 
-    if(defined $configfile) {
+    if (defined $configfile) {
         my $hash = $class->get_config_from_file($configfile);
 
         no warnings 'uninitialized';
@@ -82,7 +95,7 @@ MooseX::ConfigFromFile - An abstract Moose role for setting attributes from a co
   with 'MooseX::SomeSpecificConfigRole';
 
   # optionally, default the configfile:
-  has +configfile ( default => '/tmp/foo.yaml' );
+  around configfile => sub { '/tmp/foo.yaml' };
 
   # ... insert your stuff here ...
 
@@ -114,11 +127,22 @@ during its normal C<new_with_options>.
 
 =head2 configfile
 
-This is a L<Path::Class::File> object which can be coerced from a regular pathname
-string.  This is the file your attributes are loaded from.  You can add a default
-configfile in the class using the role and it will be honored at the appropriate time:
+This is a L<Path::Tiny> object which can be coerced from a regular pathname
+string or any object that supports stringification.
+This is the file your attributes are loaded from.  You can add a default
+configfile in the consuming class and it will be honored at the appropriate time
+(note that a simple sub declaration is not sufficient, as there is already a
+sub by that name being added by Moose as the attribute reader)
+
+  around configfile => sub { '/etc/myapp.yaml' };
 
-  has +configfile ( default => '/etc/myapp.yaml' );
+Note that you can alternately just provide a C<configfile> method which returns
+the config file when called - this will be used in preference to the default of
+the attribute.
+
+If you have L<MooseX::Getopt> installed, this attribute will also have the
+C<Getopt> trait supplied, so you can also set the configfile from the
+command line.
 
 =head1 Class Methods
 
@@ -138,16 +162,28 @@ This class method is not implemented in this role, but it is required of all sub
 Its two arguments are the classname and the configfile, and it is expected to return
 a hashref of arguments to pass to C<new()> which are sourced from the configfile.
 
-=head2 meta
-
-The Moose meta stuff, included here because otherwise pod tests fail sometimes
+=head1 COPYRIGHT
 
-=head1 BUGS
+Copyright (c) - the MooseX::ConfigFromFile "AUTHOR" and "CONTRIBUTORS" as listed below.
 
 =head1 AUTHOR
 
 Brandon L. Black, E<lt>blblack@gmail.comE<gt>
 
+=head1 CONTRIBUTORS
+
+=over
+
+=item Tomas Doran
+
+=item Karen Etheridge
+
+=item Chris Prather
+
+=item Zbigniew Lukasiak
+
+=back
+
 =head1 LICENSE
 
 This library is free software; you can redistribute it and/or modify