MooseX-Configuration-0.02000755001750001750 011507731704 15720 5ustar00autarchautarch000000000000README000644001750001750 40111507731702 16631 0ustar00autarchautarch000000000000MooseX-Configuration-0.02 This archive contains the distribution MooseX-Configuration, version 0.02: Define attributes which come from configuration files This software is Copyright (c) 2010 by Dave Rolsky. This is free software, licensed under: The Artistic License 2.0 Changes000644001750001750 30611507731702 17250 0ustar00autarchautarch000000000000MooseX-Configuration-0.020.02 2011-01-01 - When including a comment about an attribute's default, the comment always said that the default was 1, not the actual default value. 0.01 2010-12-06 - Initial release. LICENSE000644001750001750 2147711507731702 17036 0ustar00autarchautarch000000000000MooseX-Configuration-0.02This software is Copyright (c) 2010 by Dave Rolsky. This is free software, licensed under: The Artistic License 2.0 The Artistic License 2.0 Copyright (c) 2000-2006, The Perl Foundation. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble This license establishes the terms under which a given free software Package may be copied, modified, distributed, and/or redistributed. The intent is that the Copyright Holder maintains some artistic control over the development of that Package while still keeping the Package available as open source and free software. You are always permitted to make arrangements wholly outside of this license directly with the Copyright Holder of a given Package. If the terms of this license do not permit the full use that you propose to make of the Package, you should contact the Copyright Holder and seek a different licensing arrangement. Definitions "Copyright Holder" means the individual(s) or organization(s) named in the copyright notice for the entire Package. "Contributor" means any party that has contributed code or other material to the Package, in accordance with the Copyright Holder's procedures. "You" and "your" means any person who would like to copy, distribute, or modify the Package. "Package" means the collection of files distributed by the Copyright Holder, and derivatives of that collection and/or of those files. A given Package may consist of either the Standard Version, or a Modified Version. "Distribute" means providing a copy of the Package or making it accessible to anyone else, or in the case of a company or organization, to others outside of your company or organization. "Distributor Fee" means any fee that you charge for Distributing this Package or providing support for this Package to another party. It does not mean licensing fees. "Standard Version" refers to the Package if it has not been modified, or has been modified only in ways explicitly requested by the Copyright Holder. "Modified Version" means the Package, if it has been changed, and such changes were not explicitly requested by the Copyright Holder. "Original License" means this Artistic License as Distributed with the Standard Version of the Package, in its current version or as it may be modified by The Perl Foundation in the future. "Source" form means the source code, documentation source, and configuration files for the Package. "Compiled" form means the compiled bytecode, object code, binary, or any other form resulting from mechanical transformation or translation of the Source form. Permission for Use and Modification Without Distribution (1) You are permitted to use the Standard Version and create and use Modified Versions for any purpose without restriction, provided that you do not Distribute the Modified Version. Permissions for Redistribution of the Standard Version (2) You may Distribute verbatim copies of the Source form of the Standard Version of this Package in any medium without restriction, either gratis or for a Distributor Fee, provided that you duplicate all of the original copyright notices and associated disclaimers. At your discretion, such verbatim copies may or may not include a Compiled form of the Package. (3) You may apply any bug fixes, portability changes, and other modifications made available from the Copyright Holder. The resulting Package will still be considered the Standard Version, and as such will be subject to the Original License. Distribution of Modified Versions of the Package as Source (4) You may Distribute your Modified Version as Source (either gratis or for a Distributor Fee, and with or without a Compiled form of the Modified Version) provided that you clearly document how it differs from the Standard Version, including, but not limited to, documenting any non-standard features, executables, or modules, and provided that you do at least ONE of the following: (a) make the Modified Version available to the Copyright Holder of the Standard Version, under the Original License, so that the Copyright Holder may include your modifications in the Standard Version. (b) ensure that installation of your Modified Version does not prevent the user installing or running the Standard Version. In addition, the Modified Version must bear a name that is different from the name of the Standard Version. (c) allow anyone who receives a copy of the Modified Version to make the Source form of the Modified Version available to others under (i) the Original License or (ii) a license that permits the licensee to freely copy, modify and redistribute the Modified Version using the same licensing terms that apply to the copy that the licensee received, and requires that the Source form of the Modified Version, and of any works derived from it, be made freely available in that license fees are prohibited but Distributor Fees are allowed. Distribution of Compiled Forms of the Standard Version or Modified Versions without the Source (5) You may Distribute Compiled forms of the Standard Version without the Source, provided that you include complete instructions on how to get the Source of the Standard Version. Such instructions must be valid at the time of your distribution. If these instructions, at any time while you are carrying out such distribution, become invalid, you must provide new instructions on demand or cease further distribution. If you provide valid instructions or cease distribution within thirty days after you become aware that the instructions are invalid, then you do not forfeit any of your rights under this license. (6) You may Distribute a Modified Version in Compiled form without the Source, provided that you comply with Section 4 with respect to the Source of the Modified Version. Aggregating or Linking the Package (7) You may aggregate the Package (either the Standard Version or Modified Version) with other packages and Distribute the resulting aggregation provided that you do not charge a licensing fee for the Package. Distributor Fees are permitted, and licensing fees for other components in the aggregation are permitted. The terms of this license apply to the use and Distribution of the Standard or Modified Versions as included in the aggregation. (8) You are permitted to link Modified and Standard Versions with other works, to embed the Package in a larger work of your own, or to build stand-alone binary or bytecode versions of applications that include the Package, and Distribute the result without restriction, provided the result does not expose a direct interface to the Package. Items That are Not Considered Part of a Modified Version (9) Works (including, but not limited to, modules and scripts) that merely extend or make use of the Package, do not, by themselves, cause the Package to be a Modified Version. In addition, such works are not considered parts of the Package itself, and are not subject to the terms of this license. General Provisions (10) Any use, modification, and distribution of the Standard or Modified Versions is governed by this Artistic License. By using, modifying or distributing the Package, you accept this license. Do not use, modify, or distribute the Package, if you do not accept this license. (11) If your Modified Version has been derived from a Modified Version made by someone other than you, you are nevertheless required to ensure that your Modified Version complies with the requirements of this license. (12) This license does not grant you the right to use any trademark, service mark, tradename, or logo of the Copyright Holder. (13) This license includes the non-exclusive, worldwide, free-of-charge patent license to make, have made, use, offer to sell, sell, import and otherwise transfer the Package with respect to any patent claims licensable by the Copyright Holder that are necessarily infringed by the Package. If you institute patent litigation (including a cross-claim or counterclaim) against any party alleging that the Package constitutes direct or contributory patent infringement, then this Artistic License to you shall terminate on the date that such litigation is filed. (14) Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. INSTALL000644001750001750 176211507731702 17035 0ustar00autarchautarch000000000000MooseX-Configuration-0.02 This is the Perl distribution MooseX-Configuration. Installing MooseX-Configuration is straightforward. ## Installation with cpanm If you have cpanm, you only need one line: % cpanm MooseX::Configuration If you are installing into a system-wide directory, you may need to pass the "-S" flag to cpanm, which uses sudo to install the module: % cpanm -S MooseX::Configuration ## Installing with the CPAN shell Alternatively, if your CPAN shell is set up, you should just be able to do: % cpan MooseX::Configuration ## Manual installation As a last resort, you can manually install it. Download the tarball, untar it, then build it: % perl Makefile.PL % make && make test Then install it: % make install If you are installing into a system-wide directory, you may need to run: % sudo make install ## Documentation MooseX-Configuration documentation is available as POD. You can run perldoc from a shell to read the documentation: % perldoc MooseX::Configuration dist.ini000644001750001750 172511507731702 17447 0ustar00autarchautarch000000000000MooseX-Configuration-0.02name = MooseX-Configuration author = Dave Rolsky license = Artistic_2_0 copyright_holder = Dave Rolsky copyright_year = 2010 version = 0.02 [@Basic] [InstallGuide] [MetaJSON] [MetaResources] bugtracker.web = http://rt.cpan.org/NoAuth/Bugs.html?Dist=MooseX-Configuration bugtracker.mailto = bug-moosex-configuration@rt.cpan.org repository.url = http://hg.urth.org/hg/MooseX-Configuration repository.web = http://hg.urth.org/hg/MooseX-Configuration repository.type = hg [SurgicalPodWeaver] [PkgVersion] [PodSyntaxTests] [NoTabsTests] [EOLTests] [Signature] [CheckChangeLog] [Prereqs] Config::INI = 0 List::AllUtils = 0 Moose = 0 MooseX::Types = 0 MooseX::Types::Path::Class = 0 Path::Class = 0 Text::Autoformat = 0 autodie = 0 namespace::autoclean = 0 [Prereqs / TestRequires] File::Temp = 0 Test::More = 0.88 [@Mercurial] META.yml000644001750001750 143611507731702 17253 0ustar00autarchautarch000000000000MooseX-Configuration-0.02--- abstract: 'Define attributes which come from configuration files' author: - 'Dave Rolsky ' build_requires: File::Temp: 0 Test::More: 0.88 configure_requires: ExtUtils::MakeMaker: 6.31 dynamic_config: 0 generated_by: 'Dist::Zilla version 4.200000, CPAN::Meta::Converter version 2.101670' license: artistic_2 meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 name: MooseX-Configuration requires: Config::INI: 0 List::AllUtils: 0 Moose: 0 MooseX::Types: 0 MooseX::Types::Path::Class: 0 Path::Class: 0 Text::Autoformat: 0 autodie: 0 namespace::autoclean: 0 resources: bugtracker: http://rt.cpan.org/NoAuth/Bugs.html?Dist=MooseX-Configuration repository: http://hg.urth.org/hg/MooseX-Configuration version: 0.02 MANIFEST000644001750001750 56511507731702 17115 0ustar00autarchautarch000000000000MooseX-Configuration-0.02Changes INSTALL LICENSE MANIFEST META.json META.yml Makefile.PL README SIGNATURE dist.ini lib/MooseX/Configuration.pm lib/MooseX/Configuration/Trait/Attribute.pm lib/MooseX/Configuration/Trait/Attribute/ConfigKey.pm lib/MooseX/Configuration/Trait/Object.pm t/basic.t t/release-eol.t t/release-no-tabs.t t/release-pod-coverage.t t/release-pod-spell.t t/release-pod-syntax.t t000755001750001750 011507731702 16102 5ustar00autarchautarch000000000000MooseX-Configuration-0.02basic.t000644001750001750 430211507731702 17506 0ustar00autarchautarch000000000000MooseX-Configuration-0.02/tuse strict; use warnings; use autodie; use Test::More 0.88; use File::Temp qw( tempdir ); use Path::Class qw( dir file ); { package Conf; use Moose; use MooseX::Configuration; use MooseX::Types::Moose qw( ArrayRef Int Num Str ); has root_key_a => ( is => 'ro', isa => Str, key => 'a', required => 1, ); has root_key_b => ( is => 'ro', isa => Int, key => 'b', default => 'value of b', documentation => 'This is the b key', ); has foo_key_c => ( is => 'ro', isa => Num, section => 'foo', key => 'c', documentation => 'This is the c key', ); has foo_key_d => ( is => 'ro', isa => Num, section => 'foo', key => 'd', default => 42, documentation => 'This is the d key', ); has not_config => ( is => 'ro', isa => ArrayRef, ); } { ok( Conf->new( root_key_a => 'x' ), 'can create a Conf object without reading a config file' ); } my $tempdir = dir( tempdir( CLEANUP => 1 ) ); { my $file = $tempdir->file('test1.conf'); open my $fh, '>', $file; print {$fh} <<'EOF'; a = Foo b = 42 [foo] c = 4.2 EOF close $fh; my $conf = Conf->new( config_file => $file ); is( $conf->root_key_a(), 'Foo', 'got root_key_a from config file' ); is( $conf->root_key_b(), 42, 'got root_key_b from config file' ); is( $conf->foo_key_c(), 4.2, 'got foo_key_c from config file' ); my $buffer = q{}; open $fh, '>', \$buffer; $conf->write_config_file( generated_by => 'Test code', file => $fh, ); my $expect = <<'EOF'; ; Test code ; This configuration key is required. a = Foo ; This is the b key ; Defaults to "value of b" b = 42 [foo] ; This is the c key c = 4.2 ; This is the d key ; Defaults to 42 ; d = EOF is( $buffer, $expect, 'write_file generates expected file' ); } done_testing(); META.json000644001750001750 273411507731702 17425 0ustar00autarchautarch000000000000MooseX-Configuration-0.02{ "abstract" : "Define attributes which come from configuration files", "author" : [ "Dave Rolsky " ], "dynamic_config" : 0, "generated_by" : "Dist::Zilla version 4.200000, CPAN::Meta::Converter version 2.101670", "license" : [ "artistic_2" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : "2" }, "name" : "MooseX-Configuration", "prereqs" : { "configure" : { "requires" : { "ExtUtils::MakeMaker" : "6.31" } }, "runtime" : { "requires" : { "Config::INI" : 0, "List::AllUtils" : 0, "Moose" : 0, "MooseX::Types" : 0, "MooseX::Types::Path::Class" : 0, "Path::Class" : 0, "Text::Autoformat" : 0, "autodie" : 0, "namespace::autoclean" : 0 } }, "test" : { "requires" : { "File::Temp" : 0, "Test::More" : "0.88" } } }, "release_status" : "stable", "resources" : { "bugtracker" : { "mailto" : "bug-moosex-configuration@rt.cpan.org", "web" : "http://rt.cpan.org/NoAuth/Bugs.html?Dist=MooseX-Configuration" }, "repository" : { "type" : "hg", "url" : "http://hg.urth.org/hg/MooseX-Configuration", "web" : "http://hg.urth.org/hg/MooseX-Configuration" } }, "version" : "0.02" } SIGNATURE000644001750001750 366111507731704 17272 0ustar00autarchautarch000000000000MooseX-Configuration-0.02This file contains message digests of all files listed in MANIFEST, signed via the Module::Signature module, version 0.64. To verify the content in this distribution, first make sure you have Module::Signature installed, then type: % cpansign -v It will check each file's integrity, as well as the signature's validity. If "==> Signature verified OK! <==" is not displayed, the distribution may already have been compromised, and you should not run its Makefile.PL or Build.PL. -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 SHA1 6f212164f4bacd4cf30d1cd1ae92697b4a5a5e86 Changes SHA1 ac54d73db619a43244c3a52ecda8b51462dcaf58 INSTALL SHA1 23c628b4a8a36738405ccdacaeb912d2e727b4c0 LICENSE SHA1 3b8d9c832fdbf4fda0ee0693b0147915d51d0465 MANIFEST SHA1 2b41d6783201b7e04edb5376e371585125d8cca9 META.json SHA1 41a8592116cdd477f7bbec25034f0c93213b818a META.yml SHA1 1785be476e0642109f2285c423fa370ac741281e Makefile.PL SHA1 ad3fea6e3e8f1daed96fd0a36d4c11c3b9856ea7 README SHA1 b587548270533f204911131e49dd8bd31baf09c7 dist.ini SHA1 540dd1c98c36b36338936555953c222b6f216a6c lib/MooseX/Configuration.pm SHA1 e13fa2d84655bc349809c614e129336a638f126c lib/MooseX/Configuration/Trait/Attribute.pm SHA1 1ce1757d8e818a36d61585fa8a2eaa82d29bacfd lib/MooseX/Configuration/Trait/Attribute/ConfigKey.pm SHA1 33b9608886fb8cf658faad1d62e4502cc16d866f lib/MooseX/Configuration/Trait/Object.pm SHA1 43f94d53801849ae78eac8543a83514ede0b1338 t/basic.t SHA1 a032c41ef6887fab1b900669c2d304fab46680e2 t/release-eol.t SHA1 455d1dd1867212a665ad5ea4126b572411de300c t/release-no-tabs.t SHA1 ab75024ac101e262d0e9f9aaf232b1b4608bba2b t/release-pod-coverage.t SHA1 f4493aacf43ff1b3c61c34d117b3e71de054f028 t/release-pod-spell.t SHA1 b30cbdfaf935017c4568c0c91b242438cb87786e t/release-pod-syntax.t -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) iEYEARECAAYFAk0fs8IACgkQIgMCsV8qvRJI7ACfTl+72B5QBgt1pBAUezpu2FgQ g98An1iZrNoKwo+NKBLp+heXYAHaSs6h =t9YT -----END PGP SIGNATURE----- Makefile.PL000644001750001750 244411507731702 17754 0ustar00autarchautarch000000000000MooseX-Configuration-0.02 use strict; use warnings; use ExtUtils::MakeMaker 6.31; my %WriteMakefileArgs = ( 'ABSTRACT' => 'Define attributes which come from configuration files', 'AUTHOR' => 'Dave Rolsky ', 'BUILD_REQUIRES' => { 'File::Temp' => '0', 'Test::More' => '0.88' }, 'CONFIGURE_REQUIRES' => { 'ExtUtils::MakeMaker' => '6.31' }, 'DISTNAME' => 'MooseX-Configuration', 'EXE_FILES' => [], 'LICENSE' => 'artistic_2', 'NAME' => 'MooseX::Configuration', 'PREREQ_PM' => { 'Config::INI' => '0', 'List::AllUtils' => '0', 'Moose' => '0', 'MooseX::Types' => '0', 'MooseX::Types::Path::Class' => '0', 'Path::Class' => '0', 'Text::Autoformat' => '0', 'autodie' => '0', 'namespace::autoclean' => '0' }, 'VERSION' => '0.02', 'test' => { 'TESTS' => 't/*.t' } ); unless ( eval { ExtUtils::MakeMaker->VERSION(6.56) } ) { my $br = delete $WriteMakefileArgs{BUILD_REQUIRES}; my $pp = $WriteMakefileArgs{PREREQ_PM}; for my $mod ( keys %$br ) { if ( exists $pp->{$mod} ) { $pp->{$mod} = $br->{$mod} if $br->{$mod} > $pp->{$mod}; } else { $pp->{$mod} = $br->{$mod}; } } } delete $WriteMakefileArgs{CONFIGURE_REQUIRES} unless eval { ExtUtils::MakeMaker->VERSION(6.52) }; WriteMakefile(%WriteMakefileArgs); release-eol.t000644001750001750 47611507731702 20612 0ustar00autarchautarch000000000000MooseX-Configuration-0.02/t BEGIN { unless ($ENV{RELEASE_TESTING}) { require Test::More; Test::More::plan(skip_all => 'these tests are for release candidate testing'); } } use strict; use warnings; use Test::More; eval 'use Test::EOL'; plan skip_all => 'Test::EOL required' if $@; all_perl_files_ok({ trailing_whitespace => 1 }); release-no-tabs.t000644001750001750 45011507731702 21366 0ustar00autarchautarch000000000000MooseX-Configuration-0.02/t BEGIN { unless ($ENV{RELEASE_TESTING}) { require Test::More; Test::More::plan(skip_all => 'these tests are for release candidate testing'); } } use strict; use warnings; use Test::More; eval 'use Test::NoTabs'; plan skip_all => 'Test::NoTabs required' if $@; all_perl_files_ok(); release-pod-spell.t000644001750001750 120211507731702 21736 0ustar00autarchautarch000000000000MooseX-Configuration-0.02/t BEGIN { unless ($ENV{RELEASE_TESTING}) { require Test::More; Test::More::plan(skip_all => 'these tests are for release candidate testing'); } } use strict; use warnings; use Test::Spelling; my @stopwords; for () { chomp; push @stopwords, $_ unless /\A (?: \# | \s* \z)/msx; # skip comments, whitespace } add_stopwords(@stopwords); set_spell_cmd('aspell list -l en'); # This prevents a weird segfault from the aspell command - see # https://bugs.launchpad.net/ubuntu/+source/aspell/+bug/71322 local $ENV{LC_ALL} = 'C'; all_pod_files_spelling_ok; __DATA__ API INI PayPal Rolsky attribute's metaclass release-pod-syntax.t000644001750001750 45011507731702 22131 0ustar00autarchautarch000000000000MooseX-Configuration-0.02/t#!perl BEGIN { unless ($ENV{RELEASE_TESTING}) { require Test::More; Test::More::plan(skip_all => 'these tests are for release candidate testing'); } } use Test::More; eval "use Test::Pod 1.41"; plan skip_all => "Test::Pod 1.41 required for testing POD" if $@; all_pod_files_ok(); release-pod-coverage.t000644001750001750 120511507731702 22415 0ustar00autarchautarch000000000000MooseX-Configuration-0.02/t#!/usr/bin/perl BEGIN { unless ($ENV{RELEASE_TESTING}) { require Test::More; Test::More::plan(skip_all => 'these tests are for release candidate testing'); } } use strict; use warnings; use Test::More; eval "use Test::Pod::Coverage 1.04"; plan skip_all => "Test::Pod::Coverage 1.04 required for testing POD coverage" if $@; eval "use Pod::Coverage::Moose 0.02"; plan skip_all => "Pod::Coverage::Moose 0.02 required for testing POD coverage" if $@; pod_coverage_ok( 'MooseX::Configuration', { coverage_class => 'Pod::Coverage::Moose', }, 'Pod coverage for MooseX::Configuration' ); done_testing(); MooseX000755001750001750 011507731702 17617 5ustar00autarchautarch000000000000MooseX-Configuration-0.02/libConfiguration.pm000644001750001750 1403211507731702 23143 0ustar00autarchautarch000000000000MooseX-Configuration-0.02/lib/MooseXpackage MooseX::Configuration; BEGIN { $MooseX::Configuration::VERSION = '0.02'; } use strict; use warnings; use Moose::Exporter; Moose::Exporter->setup_import_methods( class_metaroles => { attribute => ['MooseX::Configuration::Trait::Attribute'], }, base_class_roles => ['MooseX::Configuration::Trait::Object'], ); 1; # ABSTRACT: Define attributes which come from configuration files =pod =head1 NAME MooseX::Configuration - Define attributes which come from configuration files =head1 VERSION version 0.02 =head1 SYNOPSIS package MyApp::Config; use Moose; use MooseX::Configuration; has database_name => ( is => 'ro', isa => 'Str', default => 'MyApp', section => 'database', key => 'name', documentation => 'The name of the database.', ); has database_username => ( is => 'ro', isa => Str, default => q{}, section => 'database', key => 'username', documentation => 'The username to use when connecting to the database. By default, this is empty.', ); my $config = MyApp::Config->new( config_file => '/path/to/config/myapp.ini' ); $config->write_file( ... ); =head1 DESCRIPTION This module lets you define attributes which can come from a configuration file. It also adds a role to your class which allows you to write a configuration file. It is based on using a simple INI-style configuration file, which contains sections and keys: key1 = value key2 = 42 [section] key3 = 2 =head1 ATTRIBUTE API Simply using this module in your class changes your class's attribute metaclass to add support for defining attributes as configuration items. There are two new parameters you can pass when defining an attribute, C
and C. These tell the module how to find the attribute's value in the configuration file. The C
parameter is optional. If you don't set it, but I provide a key, then the section defaults to C<_>, which is the main section of the config file. If you pass a C
you must also pass a C. Defining an attribute as a configuration item has several effects. First, it changes the default value for the attribute. Before looking at a C or C you define, the attribute will first look in the config file for a corresponding value. If one exists, it will use that, otherwise it will fall back to using a default you supply. If you do supply a default, it must be a string (or number), not a reference or undefined value. All configuration attributes are lazy. This is necessary because the configuration file needs to be loaded and parsed before looking up values. The C string is used when generating a configuration file. See below for details. =head1 CLASS API Your config class will do the L role. This adds several attributes and methods to your class. =head2 config_file attribute The C attribute defines the location of the configuration file. The role supplies a builder method that you can replace, C<_build_config_file>. It should return a string or L object pointing to the configuration file. It can also return C. If you I provide your own builder, then the C will default to C. =head2 $config->_raw_config() This returns the raw hash reference as read by L. If no config file was defined, then this simply returns an empty hash reference. =head2 $config->write_config_file( ... ) This method can be used to write a configuration file. It accepts several parameters: =over 4 =item * file This can be either a path or an open filehandle. The configuration text will be written to this file. This defaults to the value of C<< $self->config_file() >>. If no file is provided or already set in the object, this method will die. =item * generated_by If this parameter is passed, it will be included as a comment at the top of the generated file. =item * values This should be a hash reference of attribute names and values to write to the config file. It is optional. =back When writing the configuration file, any configuration item that was set in the configuration file originally will be set in the new file, as will any value passed in the C key. An attribute value set in the constructor or by a default will I be included in the generated file. Keys without a value will still be included in the file as a comment. If an attribute includes a documentation string, that string will appear as a comment above the key. If the attribute defines a simple scalar default, that will also be included in the comment, unless the default is the empty string. Finally, if the attribute is required, that is also mentioned in the comment. =head1 DONATIONS If you'd like to thank me for the work I've done on this module, please consider making a "donation" to me via PayPal. I spend a lot of free time creating free software, and would appreciate any support you'd care to offer. Please note that B in order for me to continue working on this particular software. I will continue to do so, inasmuch as I have in the past, for as long as it interests me. Similarly, a donation made in this way will probably not make me work on this software much more, unless I get so many donations that I can consider working on free software full time, which seems unlikely at best. To donate, log into PayPal and send money to autarch@urth.org or use the button on this page: L =head1 BUGS Please report any bugs or feature requests to C, or through the web interface at L. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes. =head1 AUTHOR Dave Rolsky =head1 COPYRIGHT AND LICENSE This software is Copyright (c) 2010 by Dave Rolsky. This is free software, licensed under: The Artistic License 2.0 =cut __END__ Trait000755001750001750 011507731702 23511 5ustar00autarchautarch000000000000MooseX-Configuration-0.02/lib/MooseX/ConfigurationObject.pm000644001750001750 754211507731702 25424 0ustar00autarchautarch000000000000MooseX-Configuration-0.02/lib/MooseX/Configuration/Traitpackage MooseX::Configuration::Trait::Object; BEGIN { $MooseX::Configuration::Trait::Object::VERSION = '0.02'; } use Moose::Role; use autodie; use namespace::autoclean; use B; use Config::INI::Reader; use List::AllUtils qw( uniq ); use MooseX::Types -declare => ['MaybeFile']; use MooseX::Types::Moose qw( HashRef Maybe Str ); use MooseX::Types::Path::Class qw( File ); use Path::Class::File; use Scalar::Util qw( looks_like_number ); use Text::Autoformat qw( autoformat ); subtype MaybeFile, as Maybe[File]; coerce MaybeFile, from Str, via { Path::Class::File->new($_) }; has config_file => ( is => 'ro', isa => MaybeFile, coerce => 1, lazy => 1, builder => '_build_config_file', clearer => '_clear_config_file', ); has _raw_config => ( is => 'ro', isa => HashRef [ HashRef [Str] ], lazy => 1, builder => '_build_raw_config', ); sub _build_config_file { } sub _build_raw_config { my $self = shift; my $file = $self->config_file() or return {}; return Config::INI::Reader->read_file($file) || {}; } sub _from_config { my $self = shift; my $section = shift; my $key = shift; my $hash = $self->_raw_config(); for my $key ( $section, $key ) { $hash = $hash->{$key}; return unless defined $hash && length $hash; } if ( ref $hash ) { die "Config for $section - $key did not resolve to a non-reference value"; } return $hash; } sub write_config_file { my $self = shift; my %p = @_; my $file = exists $p{file} ? $p{file} : $self->config_file(); die 'Cannot write a configuration file without a config file' unless defined $file; my @sections; my %attrs_by_section; for my $attr ( sort { $a->insertion_order() <=> $b->insertion_order() } grep { $_->can('config_section') } $self->meta()->get_all_attributes() ) { push @sections, $attr->config_section(); push @{ $attrs_by_section{ $attr->config_section() } }, $attr; } my $content = q{}; if ( $p{generated_by} ) { $content .= '; ' . $p{generated_by} . "\n\n"; } for my $section ( uniq @sections ) { unless ( $section eq q{_} ) { $content .= '[' . $section . ']'; $content .= "\n"; } for my $attr ( @{ $attrs_by_section{$section} } ) { my $doc; if ( $attr->has_documentation() ) { $doc = autoformat( $attr->documentation() ); $doc =~ s/\n\n+$/\n/; $doc =~ s/^/; /gm; } if ( $attr->is_required() ) { $doc .= "; This configuration key is required.\n"; } if ( $attr->has_original_default() ) { my $def = $attr->original_default(); if ( length $def ) { $def = looks_like_number($def) ? $def : B::perlstring($def); $doc .= "; Defaults to $def\n"; } } $content .= $doc if defined $doc; my $value = exists $p{values}{ $attr->name() } ? $p{values}{ $attr->name() } : $self->_from_config( $attr->config_section(), $attr->config_key(), ); my $key = $attr->config_key(); if ( defined $value && length $value ) { $content .= "$key = $value\n"; } else { $content .= "; $key =\n"; } $content .= "\n"; } } my $fh; if ( ref $file eq 'GLOB' || ref(\$file) eq 'GLOB' ) { $fh = $file; } else { open $fh, '>', $file; } print {$fh} $content; close $fh; } 1; Attribute.pm000644001750001750 76611507731702 26142 0ustar00autarchautarch000000000000MooseX-Configuration-0.02/lib/MooseX/Configuration/Traitpackage MooseX::Configuration::Trait::Attribute; BEGIN { $MooseX::Configuration::Trait::Attribute::VERSION = '0.02'; } use Moose::Role; use namespace::autoclean; around interpolate_class => sub { my $orig = shift; my ( $class, $options ) = @_; if ( exists $options->{section} || exists $options->{key} ) { $options->{traits} ||= []; push @{ $options->{traits} }, 'MooseX::Configuration::Trait::Attribute::ConfigKey'; } return $class->$orig($options); }; 1; Attribute000755001750001750 011507731702 25454 5ustar00autarchautarch000000000000MooseX-Configuration-0.02/lib/MooseX/Configuration/TraitConfigKey.pm000644001750001750 441511507731702 30033 0ustar00autarchautarch000000000000MooseX-Configuration-0.02/lib/MooseX/Configuration/Trait/Attributepackage MooseX::Configuration::Trait::Attribute::ConfigKey; BEGIN { $MooseX::Configuration::Trait::Attribute::ConfigKey::VERSION = '0.02'; } use Moose::Role; use namespace::autoclean; use MooseX::Types::Moose qw( Str ); has config_section => ( is => 'ro', isa => Str, default => q{_}, ); has config_key => ( is => 'ro', isa => Str, required => 1, ); has original_default => ( is => 'ro', isa => Str, predicate => 'has_original_default', ); around _process_options => sub { my $orig = shift; my ( $class, $name, $options ) = @_; $class->throw_error( 'Cannot define a configuration attribute unless you specify a config key name', data => $options ) unless defined $options->{key} && length $options->{key}; $class->$orig( $name, $options ); $class->_process_default_or_builder_option($options); $options->{config_section} = delete $options->{section} if exists $options->{section}; $options->{config_key} = delete $options->{key}; }; sub _process_default_or_builder_option { my $class = shift; my $options = shift; $options->{lazy} = 1; my $section = defined $options->{section} ? $options->{section} : q{_}; my $key = $options->{key}; if ( exists $options->{default} ) { my $def = $options->{default}; if ( ref $options->{default} ) { $options->{default} = sub { my $val = $_[0]->_from_config( $section, $key ); return $val if defined $val; return $def->( $_[0] ); }; } else { $options->{default} = sub { my $val = $_[0]->_from_config( $section, $key ); return $val if defined $val; return $def; }; $options->{original_default} = $def; } } elsif ( $options->{builder} ) { my $builder = delete $options->{builder}; $options->{default} = sub { my $val = $_[0]->_from_config( $section, $key ); return $val if defined $val; return $_[0]->$builder(); }; } else { $options->{default} = sub { return $_[0]->_from_config( $section, $key ); }; } } 1;