MooX-ConfigFromFile-0.009/000755 000765 000024 00000000000 13272110214 015166 5ustar00snostaff000000 000000 MooX-ConfigFromFile-0.009/ARTISTIC-1.0000644 000765 000024 00000014260 12440331053 016634 0ustar00snostaff000000 000000 The "Artistic License" Preamble The intent of this document is to state the conditions under which a Package may be copied, such that the Copyright Holder maintains some semblance of artistic control over the development of the package, while giving the users of the package the right to use and distribute the Package in a more-or-less customary fashion, plus the right to make reasonable modifications. Definitions: "Package" refers to the collection of files distributed by the Copyright Holder, and derivatives of that collection of files created through textual modification. "Standard Version" refers to such a Package if it has not been modified, or has been modified in accordance with the wishes of the Copyright Holder as specified below. "Copyright Holder" is whoever is named in the copyright or copyrights for the package. "You" is you, if you're thinking about copying or distributing this Package. "Reasonable copying fee" is whatever you can justify on the basis of media cost, duplication charges, time of people involved, and so on. (You will not be required to justify it to the Copyright Holder, but only to the computing community at large as a market that must bear the fee.) "Freely Available" means that no fee is charged for the item itself, though there may be fees involved in handling the item. It also means that recipients of the item may redistribute it under the same conditions they received it. 1. You may make and give away verbatim copies of the source form of the Standard Version of this Package without restriction, provided that you duplicate all of the original copyright notices and associated disclaimers. 2. You may apply bug fixes, portability fixes and other modifications derived from the Public Domain or from the Copyright Holder. A Package modified in such a way shall still be considered the Standard Version. 3. You may otherwise modify your copy of this Package in any way, provided that you insert a prominent notice in each changed file stating how and when you changed that file, and provided that you do at least ONE of the following: a) place your modifications in the Public Domain or otherwise make them Freely Available, such as by posting said modifications to Usenet or an equivalent medium, or placing the modifications on a major archive site such as uunet.uu.net, or by allowing the Copyright Holder to include your modifications in the Standard Version of the Package. b) use the modified Package only within your corporation or organization. c) rename any non-standard executables so the names do not conflict with standard executables, which must also be provided, and provide a separate manual page for each non-standard executable that clearly documents how it differs from the Standard Version. d) make other distribution arrangements with the Copyright Holder. 4. You may distribute the programs of this Package in object code or executable form, provided that you do at least ONE of the following: a) distribute a Standard Version of the executables and library files, together with instructions (in the manual page or equivalent) on where to get the Standard Version. b) accompany the distribution with the machine-readable source of the Package with your modifications. c) give non-standard executables non-standard names, and clearly document the differences in manual pages (or equivalent), together with instructions on where to get the Standard Version. d) make other distribution arrangements with the Copyright Holder. 5. You may charge a reasonable copying fee for any distribution of this Package. You may charge any fee you choose for support of this Package. You may not charge a fee for this Package itself. However, you may distribute this Package in aggregate with other (possibly commercial) programs as part of a larger (possibly commercial) software distribution provided that you do not advertise this Package as a product of your own. You may embed this Package's interpreter within an executable of yours (by linking); this shall be construed as a mere form of aggregation, provided that the complete Standard Version of the interpreter is so embedded. 6. The scripts and library files supplied as input to or produced as output from the programs of this Package do not automatically fall under the copyright of this Package, but belong to whoever generated them, and may be sold commercially, and may be aggregated with this Package. If such scripts or library files are aggregated with this Package via the so-called "undump" or "unexec" methods of producing a binary executable image, then distribution of such an image shall neither be construed as a distribution of this Package nor shall it fall under the restrictions of Paragraphs 3 and 4, provided that you do not represent such an executable image as a Standard Version of this Package. 7. C subroutines (or comparably compiled subroutines in other languages) supplied by you and linked into this Package in order to emulate subroutines and variables of the language defined by this Package shall not be considered part of this Package, but are the equivalent of input as in Paragraph 6, provided these subroutines do not change the language in any way that would cause it to fail the regression tests for the language. 8. Aggregation of this Package with a commercial distribution is always permitted provided that the use of this Package is embedded; that is, when no overt attempt is made to make this Package's interfaces visible to the end user of the commercial distribution. Such use shall not be construed as a distribution of this Package. 9. The name of the Copyright Holder may not be used to endorse or promote products derived from this software without specific prior written permission. 10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. The End MooX-ConfigFromFile-0.009/LICENSE000644 000765 000024 00000001233 12444022576 016207 0ustar00snostaff000000 000000 This software is licensed under the same terms as Perl5 itself. At the time of writing this means, you can redistribute it and/or modify it under the terms of either: a) the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version, or b) the "Artistic License" which both comes with this Kit. This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the Artistic License for more details. MooX-ConfigFromFile-0.009/Changes000644 000765 000024 00000004171 13272105463 016476 0ustar00snostaff000000 000000 Revision history for MooX-ConfigFromFile 0.009 2018-05-01 - ensure maximal test coverage - improve test diagnostics - fix distribution META data - add license files - introduce sorted_loaded_config to allow implementation of different sort strategies - allow tune merge behavior - improve documentation 0.008 2017-05-23 - ensure all tests run and report instead of swallowing issues - make tests passing with perl 5.26 - add import shortcuts config_prefixes and config_hashmergeloaded - ensure reasonable code quality by adding author tests against Perl::Critic and Perl::Tidy 0.007 2015-04-27 - separate loading and merging of configfile content - ensure order of multiple loaded config files - add support for merging deep structures in config files - eval all test-libraries to be aware of mistakes 0.006 2015-03-04 - add rough support for multiple prefixes - fix incorrect meta-data and incomplete handling of newer eumm features - improve test coverage - simplify some code to avoid useless conditions - add new tests for MooX::Cmd and MooX::Options integration - introduce import setting for config_identifier (consumed attribute from MooX::File::ConfigDir) - bump copyright year to 2015 0.005 2014-12-01 - Update Makefile.PL for up-to-date resources and requirements spec - consolidate Synopsis in main pod - move from README to README.md - improve author tests before releasing 0.004 2014-10-28 - add ability for options to importer of MooX::ConfigFromFile - add option to have a singleton config (loaded once). - improve documentation - harmonize tests 0.003 2014-08-02 - fix links in documentation to fix RT#97429 (thanks abraxxa for reporting) - switch to ExtUtils::MakeMaker - it better maintained these days 0.002 2013-09-27 - improve documentation - add test to verify we're working on Moose, too - ensure we're only $with->() for classes, not roles - add a Build.PL auto_feature for author test requires 0.001 2013-09-26 - First version, released on an unsuspecting world. MooX-ConfigFromFile-0.009/MANIFEST000644 000765 000024 00000002177 13272110214 016326 0ustar00snostaff000000 000000 ARTISTIC-1.0 calc/etc/large-operands.json calc/etc/operands.json calc/etc/small-operands.json Changes etc/calc-operands.json etc/calc.json etc/MooXCmdTest-test-this-hashmerged.json etc/MooXCmdTest-test-this.json etc/MooXCmdTest-test.json etc/MooXCmdTest.json etc/MooXCmdTest.test.this.json etc/MooXCmdTest.tested.json etc/MooXCmdTest/test-shortcut-hashmerged.json etc/MooXCmdTest/test-shortcut.json GPL-1 lib/MooX/ConfigFromFile.pm lib/MooX/ConfigFromFile/Role.pm lib/MooX/ConfigFromFile/Role/HashMergeLoaded.pm lib/MooX/ConfigFromFile/Role/SortedByFilename.pm LICENSE Makefile.PL MANIFEST MANIFEST.SKIP README.md t/00-load.t t/01-moo.t t/02-moose.t t/lib/MooXCmdTest.pm t/lib/MooXCmdTest/Cmd/Test.pm t/lib/MooXCmdTest/Cmd/Test/Cmd/Shortcut.pm t/lib/MooXCmdTest/Cmd/Test/Cmd/Shortcut/Cmd/HashMerged.pm t/lib/MooXCmdTest/Cmd/Test/Cmd/This.pm t/lib/MooXCmdTest/Cmd/Test/Cmd/This/Cmd/HashMerged.pm t/lib/MooXCmdTest/Cmd/Tested.pm t/testerr.pm t/testlib.pm t/testmxcmd.pm t/testmxopt.pm META.yml Module YAML meta-data (added by MakeMaker) META.json Module JSON meta-data (added by MakeMaker) MooX-ConfigFromFile-0.009/etc/000755 000765 000024 00000000000 13272110214 015741 5ustar00snostaff000000 000000 MooX-ConfigFromFile-0.009/GPL-1000644 000765 000024 00000030531 12442567673 015722 0ustar00snostaff000000 000000 GNU GENERAL PUBLIC LICENSE Version 1, February 1989 Copyright (C) 1989 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The license agreements of most software companies try to keep users at the mercy of those companies. By contrast, our General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. The General Public License applies to the Free Software Foundation's software and to any other program whose authors commit to using it. You can use it for your programs, too. When we speak of free software, we are referring to freedom, not price. Specifically, the General Public License is designed to make sure that you have the freedom to give away or sell copies of free software, that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of a such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must tell them their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any work containing the Program or a portion of it, either verbatim or with modifications. Each licensee is addressed as "you". 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this General Public License and to the absence of any warranty; and give any other recipients of the Program a copy of this General Public License along with the Program. You may charge a fee for the physical act of transferring a copy. 2. You may modify your copy or copies of the Program or any portion of it, and copy and distribute such modifications under the terms of Paragraph 1 above, provided that you also do the following: a) cause the modified files to carry prominent notices stating that you changed the files and the date of any change; and b) cause the whole of any work that you distribute or publish, that in whole or in part contains the Program or any part thereof, either with or without modifications, to be licensed at no charge to all third parties under the terms of this General Public License (except that you may choose to grant warranty protection to some or all third parties, at your option). c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the simplest and most usual way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this General Public License. d) You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. Mere aggregation of another independent work with the Program (or its derivative) on a volume of a storage or distribution medium does not bring the other work under the scope of these terms. 3. You may copy and distribute the Program (or a portion or derivative of it, under Paragraph 2) in object code or executable form under the terms of Paragraphs 1 and 2 above provided that you also do one of the following: a) accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Paragraphs 1 and 2 above; or, b) accompany it with a written offer, valid for at least three years, to give any third party free (except for a nominal charge for the cost of distribution) a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Paragraphs 1 and 2 above; or, c) accompany it with the information you received as to where the corresponding source code may be obtained. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form alone.) Source code for a work means the preferred form of the work for making modifications to it. For an executable file, complete source code means all the source code for all modules it contains; but, as a special exception, it need not include source code for modules which are standard libraries that accompany the operating system on which the executable file runs, or for standard header files or definitions files that accompany that operating system. 4. You may not copy, modify, sublicense, distribute or transfer the Program except as expressly provided under this General Public License. Any attempt otherwise to copy, modify, sublicense, distribute or transfer the Program is void, and will automatically terminate your rights to use the Program under this License. However, parties who have received copies, or rights to use copies, from you under this General Public License will not have their licenses terminated so long as such parties remain in full compliance. 5. By copying, distributing or modifying the Program (or any work based on the Program) you indicate your acceptance of this license to do so, and all its terms and conditions. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. 7. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of the license which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the license, you may choose any version ever published by the Free Software Foundation. 8. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to humanity, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19xx name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (a program to direct compilers to make passes at assemblers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice That's all there is to it! MooX-ConfigFromFile-0.009/t/000755 000765 000024 00000000000 13272110214 015431 5ustar00snostaff000000 000000 MooX-ConfigFromFile-0.009/README.md000644 000765 000024 00000014207 13272105463 016463 0ustar00snostaff000000 000000 # NAME MooX::ConfigFromFile - Moo eXtension for initializing objects from config file
Travis CI Coverage Status
# SYNOPSIS package Role::Action; use Moo::Role; has operator => ( is => "ro" ); package Action; use Moo; use MooX::ConfigFromFile; # imports the MooX::ConfigFromFile::Role with "Role::Action"; sub operate { return say shift->operator; } package OtherAction; use Moo; with "Role::Action", "MooX::ConfigFromFile::Role"; sub operate { return warn shift->operator; } package QuiteOtherOne; use Moo; # consumes the MooX::ConfigFromFile::Role but load config only once use MooX::ConfigFromFile config_singleton => 1; with "Role::Action"; sub _build_config_prefix { "die" } sub operate { return die shift->operator; } package main; my $action = Action->new(); # tries to find a config file in config_dirs and loads it my $other = OtherAction->new( config_prefix => "warn" ); # use another config file my $quite_o = QuiteOtherOne->new(); # quite another way to have an individual config file # DESCRIPTION This module is intended to easy load initialization values for attributes on object construction from an appropriate config file. The building is done in [MooX::ConfigFromFile::Role](https://metacpan.org/pod/MooX::ConfigFromFile::Role) - using MooX::ConfigFromFile ensures the role is applied. For easier usage, with 0.004, several options can be passed via _use_ resulting in default initializers for appropriate role attributes: - `config_prefix` Default for ["config\_prefix" in MooX::ConfigFromFile::Role](https://metacpan.org/pod/MooX::ConfigFromFile::Role#config_prefix). - `config_prefixes` Default for ["config\_prefixes" in MooX::ConfigFromFile::Role](https://metacpan.org/pod/MooX::ConfigFromFile::Role#config_prefixes). Ensure when use this flag together with [MooX::Cmd](https://metacpan.org/pod/MooX::Cmd) to load `MooX::ConfigFromFile` before `MooX::Cmd`. - `config_prefix_map_separator` Default for ["config\_prefix\_map\_separator" in MooX::ConfigFromFile::Role](https://metacpan.org/pod/MooX::ConfigFromFile::Role#config_prefix_map_separator). package Foo; # apply role MooX::ConfigFromFile::Role and override default for # attribute config_prefix_map_separator use MooX::ConfigFromFile config_prefix_map_separator => "~"; ... - `config_extensions` Default for ["config\_extensions" in MooX::ConfigFromFile::Role](https://metacpan.org/pod/MooX::ConfigFromFile::Role#config_extensions). - `config_dirs` Default for ["config\_dirs" in MooX::ConfigFromFile::Role](https://metacpan.org/pod/MooX::ConfigFromFile::Role#config_dirs). Same warning regarding modifying this attribute applies here: Possible, but use with caution! package Foo; use MooX::ConfigFromFile config_dirs => [qw(/opt/foo/etc /home/alfred/area/foo/etc)]; ... - `config_files` Default for ["config\_files" in MooX::ConfigFromFile::Role](https://metacpan.org/pod/MooX::ConfigFromFile::Role#config_files). Reasonable when you want exactly one config file in development mode. For production code it is highly recommended to override the builder. - `config_singleton` Flag adding a wrapper [around](https://metacpan.org/pod/Class::Method::Modifiers#around-method-s-sub) the _builder_ of ["loaded\_config" in MooX::ConfigFromFile::Role](https://metacpan.org/pod/MooX::ConfigFromFile::Role#loaded_config) to ensure a config is loaded only once per class. The _per class_ restriction results from applicable modifiers per class (and singletons are per class). - `config_identifier` Default for ["config\_identifier" in MooX::File::ConfigDir](https://metacpan.org/pod/MooX::File::ConfigDir#config_identifier). package Foo; # apply role MooX::ConfigFromFile::Role and override default for # attribute config_identifier - means to look e.g. in /etc/foo/ use MooX::ConfigFromFile config_identifier => "foo"; ... - `config_hashmergeloaded` Consumes role [MooX::ConfigFromFile::Role::HashMergeLoaded](https://metacpan.org/pod/MooX::ConfigFromFile::Role::HashMergeLoaded) directly after [MooX::ConfigFromFile::Role](https://metacpan.org/pod/MooX::ConfigFromFile::Role) has been consumed. # AUTHOR Jens Rehsack, `` # BUGS Please report any bugs or feature requests to `bug-moox-configfromfile at rt.cpan.org`, or through the web interface at [http://rt.cpan.org/NoAuth/ReportBug.html?Queue=MooX-ConfigFromFile](http://rt.cpan.org/NoAuth/ReportBug.html?Queue=MooX-ConfigFromFile). I will be notified, and then you'll automatically be notified of progress on your bug as I make changes. # SUPPORT You can find documentation for this module with the perldoc command. perldoc MooX::ConfigFromFile You can also look for information at: - RT: CPAN's request tracker (report bugs here) [http://rt.cpan.org/NoAuth/Bugs.html?Dist=MooX-ConfigFromFile](http://rt.cpan.org/NoAuth/Bugs.html?Dist=MooX-ConfigFromFile) - AnnoCPAN: Annotated CPAN documentation [http://annocpan.org/dist/MooX-ConfigFromFile](http://annocpan.org/dist/MooX-ConfigFromFile) - CPAN Ratings [http://cpanratings.perl.org/d/MooX-ConfigFromFile](http://cpanratings.perl.org/d/MooX-ConfigFromFile) - Search CPAN [http://search.cpan.org/dist/MooX-ConfigFromFile/](http://search.cpan.org/dist/MooX-ConfigFromFile/) # ACKNOWLEDGEMENTS # LICENSE AND COPYRIGHT Copyright 2013-2018 Jens Rehsack. This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License. See [http://dev.perl.org/licenses/](http://dev.perl.org/licenses/) for more information. MooX-ConfigFromFile-0.009/calc/000755 000765 000024 00000000000 13272110214 016070 5ustar00snostaff000000 000000 MooX-ConfigFromFile-0.009/MANIFEST.SKIP000644 000765 000024 00000000534 13271556710 017104 0ustar00snostaff000000 000000 \B\.svn\b \B\.git\b \.gitignore$ \.[Bb][Aa][Kk]$ \.orig$ \.old$ \.tdy$ \.tmp$ \..*swp ^Makefile$ ^Build$ ^Build\.bat$ \.Inline/.* _Inline/.* \.bak$ \.tar$ \.tgz$ \.tar\.gz$ ^mess/ ^tmp/ ^testdata/ ^blib/ ^sandbox/ ^pm_to_blib$ ^cover_db/ nytprof*/ nytprof.out ^_build/.* ~$ .*\.planner ^\..* MooX-ConfigFromFile-.* \bxt ^MYMETA\.json$ ^MYMETA\..*$ MooX-ConfigFromFile-0.009/META.yml000644 000765 000024 00000002010 13272110214 016430 0ustar00snostaff000000 000000 --- abstract: 'Moo eXtension for initializing objects from config file' author: - 'Jens Rehsack ' build_requires: Cwd: '0' File::Basename: '0' File::Spec: '0' Hash::Merge: '0' JSON: '0' Test::More: '0.9' configure_requires: ExtUtils::MakeMaker: '0' dynamic_config: 1 generated_by: 'ExtUtils::MakeMaker version 7.24, CPAN::Meta::Converter version 2.150010' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: MooX-ConfigFromFile no_index: directory: - t - inc requires: Config::Any: '0' File::Find::Rule: '0.30' FindBin: '0' Moo: '1.003' MooX::File::ConfigDir: '0.002' perl: v5.8.1 resources: bugtracker: http://rt.cpan.org/Public/Dist/Display.html?Name=MooX-ConfigFromFile homepage: https://metacpan.org/release/MooX-ConfigFromFile license: http://dev.perl.org/licenses/ repository: https://github.com/rehsack/MooX-ConfigFromFile.git version: '0.009' x_serialization_backend: 'CPAN::Meta::YAML version 0.018' MooX-ConfigFromFile-0.009/lib/000755 000765 000024 00000000000 13272110214 015734 5ustar00snostaff000000 000000 MooX-ConfigFromFile-0.009/Makefile.PL000644 000765 000024 00000012023 13267373325 017160 0ustar00snostaff000000 000000 use strict; use warnings; use 5.008001; use ExtUtils::MakeMaker; my %RUN_DEPS = ( "Config::Any" => 0, "File::Find::Rule" => "0.30", "FindBin" => 0, "Moo" => "1.003", "MooX::File::ConfigDir" => "0.002", ); my %CONFIGURE_DEPS = ( 'ExtUtils::MakeMaker' => 0, ); my %BUILD_DEPS = (); my %TEST_DEPS = ( 'Cwd' => 0, 'File::Basename' => 0, 'File::Spec' => 0, 'Hash::Merge' => 0, 'JSON' => 0, 'Test::More' => 0.90, ); WriteMakefile1( MIN_PERL_VERSION => '5.008001', META_ADD => { 'meta-spec' => {version => 2}, resources => { homepage => 'https://metacpan.org/release/MooX-ConfigFromFile', repository => { url => 'https://github.com/rehsack/MooX-ConfigFromFile.git', web => 'https://github.com/rehsack/MooX-ConfigFromFile', type => 'git', }, bugtracker => { web => 'http://rt.cpan.org/Public/Dist/Display.html?Name=MooX-ConfigFromFile', mailto => 'bug-MooX-ConfigFromFile@rt.cpan.org', }, license => 'http://dev.perl.org/licenses/', }, prereqs => { develop => { requires => { 'Test::CPAN::Changes' => 0, 'Test::CheckManifest' => 0, 'Module::CPANTS::Analyse' => '0.96', 'Test::Kwalitee' => 0, 'Test::Pod' => 0, 'Test::Pod::Coverage' => 0, 'Test::Pod::Spelling::CommonMistakes' => 0, 'Test::Spelling' => 0, 'Test::Perl::Critic' => 0, 'Test::PerlTidy' => 0, }, }, configure => { requires => {%CONFIGURE_DEPS}, }, build => {requires => {%BUILD_DEPS}}, test => { requires => {%TEST_DEPS}, suggests => { 'MooX::Cmd' => '0.012', 'MooX::Options' => '4.001' } }, runtime => { requires => { %RUN_DEPS, perl => '5.8.1', }, suggests => { "Hash::Merge" => 0, } }, }, }, NAME => 'MooX::ConfigFromFile', VERSION_FROM => 'lib/MooX/ConfigFromFile.pm', ABSTRACT_FROM => 'lib/MooX/ConfigFromFile.pm', LICENSE => 'perl', AUTHOR => q{Jens Rehsack }, PREREQ_PM => \%RUN_DEPS, CONFIGURE_REQUIRES => \%CONFIGURE_DEPS, BUILD_REQUIRES => \%BUILD_DEPS, TEST_REQUIRES => \%TEST_DEPS, test => {TESTS => 't/*.t xt/*.t'}, ); sub WriteMakefile1 { # originally written by Alexandr Ciornii, version 0.21. Added by eumm-upgrade. my %params = @_; my $eumm_version = $ExtUtils::MakeMaker::VERSION; $eumm_version = eval $eumm_version; die "EXTRA_META is deprecated" if (exists($params{EXTRA_META})); die "License not specified" if (!exists($params{LICENSE})); $params{TEST_REQUIRES} and $eumm_version < 6.6303 and $params{BUILD_REQUIRES} = {%{$params{BUILD_REQUIRES} || {}}, %{delete $params{TEST_REQUIRES}}}; #EUMM 6.5502 has problems with BUILD_REQUIRES $params{BUILD_REQUIRES} and $eumm_version < 6.5503 and $params{PREREQ_PM} = {%{$params{PREREQ_PM} || {}}, %{delete $params{BUILD_REQUIRES}}}; ref $params{AUTHOR} and "ARRAY" eq ref $params{AUTHOR} and $eumm_version < 6.5702 and $params{AUTHOR} = join(", ", @{$params{AUTHOR}}); delete $params{CONFIGURE_REQUIRES} if ($eumm_version < 6.52); delete $params{MIN_PERL_VERSION} if ($eumm_version < 6.48); delete $params{META_MERGE} if ($eumm_version < 6.46); delete $params{META_ADD}{prereqs} if ($eumm_version < 6.58); delete $params{META_ADD}{'meta-spec'} if ($eumm_version < 6.58); delete $params{META_ADD} if ($eumm_version < 6.46); delete $params{LICENSE} if ($eumm_version < 6.31); delete $params{AUTHOR} if ($] < 5.005); delete $params{ABSTRACT_FROM} if ($] < 5.005); delete $params{BINARY_LOCATION} if ($] < 5.005); # more or less taken from Moose' Makefile.PL if ($params{CONFLICTS}) { my $ok = CheckConflicts(%params); exit(0) if ($params{PREREQ_FATAL} and not $ok); my $cpan_smoker = grep { $_ =~ m/(?:CR_SMOKER|CPAN_REPORTER|AUTOMATED_TESTING)/ } keys %ENV; unless ($cpan_smoker || $ENV{PERL_MM_USE_DEFAULT}) { sleep 4 unless ($ok); } delete $params{CONFLICTS}; } WriteMakefile(%params); } MooX-ConfigFromFile-0.009/META.json000644 000765 000024 00000004743 13272110214 016617 0ustar00snostaff000000 000000 { "abstract" : "Moo eXtension for initializing objects from config file", "author" : [ "Jens Rehsack " ], "dynamic_config" : 1, "generated_by" : "ExtUtils::MakeMaker version 7.24, CPAN::Meta::Converter version 2.150010", "license" : [ "perl_5" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : "2" }, "name" : "MooX-ConfigFromFile", "no_index" : { "directory" : [ "t", "inc" ] }, "prereqs" : { "build" : { "requires" : {} }, "configure" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "develop" : { "requires" : { "Module::CPANTS::Analyse" : "0.96", "Test::CPAN::Changes" : "0", "Test::CheckManifest" : "0", "Test::Kwalitee" : "0", "Test::Perl::Critic" : "0", "Test::PerlTidy" : "0", "Test::Pod" : "0", "Test::Pod::Coverage" : "0", "Test::Pod::Spelling::CommonMistakes" : "0", "Test::Spelling" : "0" } }, "runtime" : { "requires" : { "Config::Any" : "0", "File::Find::Rule" : "0.30", "FindBin" : "0", "Moo" : "1.003", "MooX::File::ConfigDir" : "0.002", "perl" : "v5.8.1" }, "suggests" : { "Hash::Merge" : "0" } }, "test" : { "requires" : { "Cwd" : "0", "File::Basename" : "0", "File::Spec" : "0", "Hash::Merge" : "0", "JSON" : "0", "Test::More" : "0.9" }, "suggests" : { "MooX::Cmd" : "0.012", "MooX::Options" : "4.001" } } }, "release_status" : "stable", "resources" : { "bugtracker" : { "mailto" : "bug-MooX-ConfigFromFile@rt.cpan.org", "web" : "http://rt.cpan.org/Public/Dist/Display.html?Name=MooX-ConfigFromFile" }, "homepage" : "https://metacpan.org/release/MooX-ConfigFromFile", "license" : [ "http://dev.perl.org/licenses/" ], "repository" : { "type" : "git", "url" : "https://github.com/rehsack/MooX-ConfigFromFile.git", "web" : "https://github.com/rehsack/MooX-ConfigFromFile" } }, "version" : "0.009", "x_serialization_backend" : "JSON::PP version 2.27400_02" } MooX-ConfigFromFile-0.009/lib/MooX/000755 000765 000024 00000000000 13272110214 016616 5ustar00snostaff000000 000000 MooX-ConfigFromFile-0.009/lib/MooX/ConfigFromFile/000755 000765 000024 00000000000 13272110214 021447 5ustar00snostaff000000 000000 MooX-ConfigFromFile-0.009/lib/MooX/ConfigFromFile.pm000644 000765 000024 00000016117 13272105463 022025 0ustar00snostaff000000 000000 package MooX::ConfigFromFile; use strict; use warnings FATAL => 'all'; our $VERSION = '0.009'; my %loaded_configs; sub import { my (undef, %import_options) = @_; my $target = caller; my @target_isa; { no strict 'refs'; @target_isa = @{"${target}::ISA"} }; #don't add this to a role #ISA of a role is always empty ! ## no critic qw/ProhibitStringyEval/ @target_isa or return; my $apply_modifiers = sub { return if $target->can('_initialize_from_config'); my $with = $target->can('with'); $with->('MooX::ConfigFromFile::Role'); $import_options{config_sortedbyfilename} and $with->('MooX::ConfigFromFile::Role::SortedByFilename'); $import_options{config_hashmergeloaded} and $with->('MooX::ConfigFromFile::Role::HashMergeLoaded'); }; $apply_modifiers->(); my $around; defined $import_options{config_singleton} and $import_options{config_singleton} and do { $around = $target->can('around'); $around->( _build_loaded_config => sub { my $orig = shift; my $class = shift; defined $loaded_configs{$class} or $loaded_configs{$class} = $class->$orig(@_); return $loaded_configs{$class}; } ); }; my %default_modifiers = ( config_prefix => '_build_config_prefix', config_prefixes => '_build_config_prefixes', config_identifier => '_build_config_identifier', config_prefix_map_separator => '_build_config_prefix_map_separator', config_extensions => '_build_config_extensions', config_dirs => '_build_config_dirs', config_files => '_build_config_files', ); foreach my $opt_key (keys %default_modifiers) { exists $import_options{$opt_key} or next; $around or $around = $target->can('around'); $around->($default_modifiers{$opt_key} => sub { $import_options{$opt_key} }); } return; } =head1 NAME MooX::ConfigFromFile - Moo eXtension for initializing objects from config file =begin html Travis CI Coverage Status =end html =head1 SYNOPSIS package Role::Action; use Moo::Role; has operator => ( is => "ro" ); package Action; use Moo; use MooX::ConfigFromFile; # imports the MooX::ConfigFromFile::Role with "Role::Action"; sub operate { return say shift->operator; } package OtherAction; use Moo; with "Role::Action", "MooX::ConfigFromFile::Role"; sub operate { return warn shift->operator; } package QuiteOtherOne; use Moo; # consumes the MooX::ConfigFromFile::Role but load config only once use MooX::ConfigFromFile config_singleton => 1; with "Role::Action"; sub _build_config_prefix { "die" } sub operate { return die shift->operator; } package main; my $action = Action->new(); # tries to find a config file in config_dirs and loads it my $other = OtherAction->new( config_prefix => "warn" ); # use another config file my $quite_o = QuiteOtherOne->new(); # quite another way to have an individual config file =head1 DESCRIPTION This module is intended to easy load initialization values for attributes on object construction from an appropriate config file. The building is done in L - using MooX::ConfigFromFile ensures the role is applied. For easier usage, with 0.004, several options can be passed via I resulting in default initializers for appropriate role attributes: =over 4 =item C Default for L. =item C Default for L. Ensure when use this flag together with L to load C before C. =item C Default for L. package Foo; # apply role MooX::ConfigFromFile::Role and override default for # attribute config_prefix_map_separator use MooX::ConfigFromFile config_prefix_map_separator => "~"; ... =item C Default for L. =item C Default for L. Same warning regarding modifying this attribute applies here: Possible, but use with caution! package Foo; use MooX::ConfigFromFile config_dirs => [qw(/opt/foo/etc /home/alfred/area/foo/etc)]; ... =item C Default for L. Reasonable when you want exactly one config file in development mode. For production code it is highly recommended to override the builder. =item C Flag adding a wrapper L<< around|Class::Method::Modifiers/around method(s) => sub { ... }; >> the I of L to ensure a config is loaded only once per class. The I restriction results from applicable modifiers per class (and singletons are per class). =item C Default for L. package Foo; # apply role MooX::ConfigFromFile::Role and override default for # attribute config_identifier - means to look e.g. in /etc/foo/ use MooX::ConfigFromFile config_identifier => "foo"; ... =item C Consumes role L directly after L has been consumed. =back =head1 AUTHOR Jens Rehsack, C<< >> =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 SUPPORT You can find documentation for this module with the perldoc command. perldoc MooX::ConfigFromFile You can also look for information at: =over 4 =item * RT: CPAN's request tracker (report bugs here) L =item * AnnoCPAN: Annotated CPAN documentation L =item * CPAN Ratings L =item * Search CPAN L =back =head1 ACKNOWLEDGEMENTS =head1 LICENSE AND COPYRIGHT Copyright 2013-2018 Jens Rehsack. This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License. See L for more information. =cut 1; # End of MooX::ConfigFromFile MooX-ConfigFromFile-0.009/lib/MooX/ConfigFromFile/Role/000755 000765 000024 00000000000 13272110214 022350 5ustar00snostaff000000 000000 MooX-ConfigFromFile-0.009/lib/MooX/ConfigFromFile/Role.pm000644 000765 000024 00000017710 13272105463 022726 0ustar00snostaff000000 000000 package MooX::ConfigFromFile::Role; use strict; use warnings; our $VERSION = '0.009'; use FindBin qw/$Script/; use Config::Any; use File::Find::Rule; use Moo::Role; with "MooX::File::ConfigDir"; around BUILDARGS => sub { my $next = shift; my $class = shift; my $params = $class->$next(@_); $class->_initialize_from_config($params); return $params; }; sub _initialize_from_config { my ($class, $params) = @_; defined $params->{loaded_config} or $params->{loaded_config} = $class->_build_loaded_config($params); # This copies stuff from loaded_config into the object's parameters foreach my $cfg_key (keys %{$params->{loaded_config}}) { exists $params->{$cfg_key} and next; $params->{$cfg_key} = $params->{loaded_config}->{$cfg_key}; } return $params; } has 'config_prefix' => (is => 'lazy'); sub _build_config_prefix { $Script; } has 'config_prefixes' => (is => 'lazy'); sub _build_config_prefixes { my ($class, $params) = @_; defined $params->{config_prefix} or $params->{config_prefix} = $class->_build_config_prefix($params); [$params->{config_prefix}]; } has 'config_prefix_map_separator' => (is => 'lazy'); sub _build_config_prefix_map_separator { "-" } has 'config_prefix_map' => (is => 'lazy'); sub _build_config_prefix_map { my ($class, $params) = @_; defined $params->{config_prefix_map_separator} or $params->{config_prefix_map_separator} = $class->_build_config_prefix_map_separator($params); defined $params->{config_prefixes} or $params->{config_prefixes} = $class->_build_config_prefixes($params); my ($sep, $i, @prefix_map) = ($params->{config_prefix_map_separator}); for ($i = 0; $i < scalar @{$params->{config_prefixes}}; ++$i) { push @prefix_map, join($sep, @{$params->{config_prefixes}}[0 .. $i]); } \@prefix_map; } has 'config_extensions' => (is => 'lazy'); sub _build_config_extensions { [Config::Any->extensions()] } has 'config_files_pattern' => (is => 'lazy'); sub _build_config_files_pattern { my ($class, $params) = @_; defined $params->{config_prefix_map} or $params->{config_prefix_map} = $class->_build_config_prefix_map($params); defined $params->{config_extensions} or $params->{config_extensions} = $class->_build_config_extensions($params); ## no critic (BuiltinFunctions::ProhibitComplexMappings) my @cfg_pattern = map { my $ext = $_; map { $_ . "." . $ext } @{$params->{config_prefix_map}} } @{$params->{config_extensions}}; \@cfg_pattern; } has 'config_files' => (is => 'lazy'); sub _build_config_files { my ($class, $params) = @_; defined $params->{config_files_pattern} or $params->{config_files_pattern} = $class->_build_config_files_pattern($params); defined $params->{config_dirs} or $params->{config_dirs} = $class->_build_config_dirs($params); ref $params->{config_dirs} eq "ARRAY" or $params->{config_dirs} = ["."]; my @cfg_files = File::Find::Rule->file()->name(@{$params->{config_files_pattern}})->maxdepth(1)->in(@{$params->{config_dirs}}); return \@cfg_files; } has raw_loaded_config => ( is => 'lazy', clearer => 1 ); sub _build_raw_loaded_config { my ($class, $params) = @_; defined $params->{config_files} or $params->{config_files} = $class->_build_config_files($params); return [] if !@{$params->{config_files}}; Config::Any->load_files( { files => $params->{config_files}, use_ext => 1 } ); } has sorted_loaded_config => ( is => 'lazy', clearer => 1 ); sub _build_sorted_loaded_config { my ($class, $params) = @_; defined $params->{raw_loaded_config} or $params->{raw_loaded_config} = $class->_build_raw_loaded_config($params); return [] if !@{$params->{raw_loaded_config}}; [ ## no critic (BuiltinFunctions::RequireSimpleSortBlock) sort { my @a = %{$a}; my @b = %{$b}; $a[0] cmp $b[0]; } @{$params->{raw_loaded_config}} ]; } has 'loaded_config' => ( is => 'lazy', clearer => 1 ); sub _build_loaded_config { my ($class, $params) = @_; defined $params->{sorted_loaded_config} or $params->{sorted_loaded_config} = $class->_build_sorted_loaded_config($params); my $config_merged = {}; for my $c (map { values %$_ } @{$params->{sorted_loaded_config}}) { %$config_merged = (%$config_merged, %$c); } $config_merged; } =head1 NAME MooX::ConfigFromFile::Role - Moo eXtension for initializing objects from config file =head1 DESCRIPTION This role adds a initializing sub around L and puts all what could read from config files into the hash which will be used to construct the final object. While it does that, it internally calls it's own _build_* methods (I<_build_config_prefix>, I<_build_config_files> and I<_build_loaded_config>) unless the appropriate attributes are already in C<$params>. =head1 ATTRIBUTES This role uses following attributes which might be suitable customized by overloading the appropriate builder or pass defaults in construction arguments. Be sure to read L, especially L to understand how the L are build. When you miss a directory - see L and L. =head2 config_prefix This attribute is a string and defaults to L's C<$Script>. It's interpreted as the basename of the config file name to use. =head2 config_prefixes This attribute is an array of strings and defaults to C<<[ config_prefix ]>>. =head2 config_prefix_map_separator This attribute is a string and contains the character which is used building I from I. =head2 config_prefix_map This attribute is an array of strings containing all config-prefixes joint together C<($0, $0.$1, $0.$1.$2, ...)> using I. =head2 config_files_pattern This attribute contains a cross-product of I and I. Both are concatenated using the shell wildcard '*'. =head2 config_dirs This attribute is consumed from L. It might not be smart to override - but possible. Use with caution. =head2 config_extensions This attribute defaults to list of extensions from L. =head2 config_files This attribute contains the list of existing files in I matching I . I. Search is operated by L. =head2 raw_loaded_config This attribute contains the config as loaded from file system in an array of C<< filename => \%content >>. =head2 sorted_loaded_config This attribute contains the loaded files from filesystem sorted by string in the same format as L (array of C<< filename => \%content >>). The default algorithm is sorted by filename (B: C<< '-' < '.' >>). =head2 loaded_config This attribute contains the config loaded and transformed while constructing the instance. Construction is done from I, ignoring the filename part. For classes set up using use MooX::ConfigFromFile config_singleton = 1; this attribute is cached from the very first construction and fed by overwritten I. The content of this attribute is passed to lower I. =head1 AUTHOR Jens Rehsack, C<< >> =head1 ACKNOWLEDGEMENTS Toby Inkster suggested to rely on BUILDARGS instead of intercepting object creation with nasty hacks. He also taught me a bit more how Moo(se) works. =head1 LICENSE AND COPYRIGHT Copyright 2013-2018 Jens Rehsack. This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License. See L for more information. =cut 1; MooX-ConfigFromFile-0.009/lib/MooX/ConfigFromFile/Role/SortedByFilename.pm000644 000765 000024 00000015005 13272105463 026115 0ustar00snostaff000000 000000 package MooX::ConfigFromFile::Role::SortedByFilename; use strict; use warnings; our $VERSION = '0.009'; use File::Basename (); use Moo::Role; requires "raw_loaded_config"; sub _build_filename_sorted_loaded_config { my ($next, $class, $params) = @_; defined $params->{raw_loaded_config} or $params->{raw_loaded_config} = $class->_build_raw_loaded_config($params); return [] if !@{$params->{raw_loaded_config}}; defined $params->{config_dirs} or $params->{config_dirs} = $class->_build_config_dirs($params); defined $params->{config_extensions} or $params->{config_extensions} = $class->_build_config_extensions($params); my %config_dir_order = map { $params->{config_dirs}->[$_] . "/" => $_ } 0 .. $#{$params->{config_dirs}}; [ ## no critic (BuiltinFunctions::RequireSimpleSortBlock) sort { my @a = %{$a}; my @b = %{$b}; my ($fa, $pa, $sa) = File::Basename::fileparse($a[0], map { "." . $_ } @{$params->{config_extensions}}); my ($fb, $pb, $sb) = File::Basename::fileparse($b[0], map { "." . $_ } @{$params->{config_extensions}}); # uncoverable branch true $fa cmp $fb || $sa cmp $sb || $config_dir_order{$pa} <=> $config_dir_order{$pb}; } @{$params->{raw_loaded_config}} ]; } around _build_sorted_loaded_config => \&_build_filename_sorted_loaded_config; 1; =head1 NAME MooX::ConfigFromFile::Role::SortedByFilename - allows filename based sort algorithm for multiple config files =head1 SYNOPSIS package MyApp::Cmd::TPau; use DBI; use Moo; use MooX::Cmd with_configfromfile => 1; with "MooX::ConfigFromFile::Role::SortedByFilename"; with "MooX::ConfigFromFile::Role::HashMergeLoaded"; # ensure hashes are merged by top-most scalar wins around _build_config_merge_behavior => sub { 'RIGHT_PRECEDENT' }; has csv => (is => "ro", required => 1); sub execute { my $self = shift; DBI->connect("DBI::csv:", undef, undef, $self->csv); } __END__ $ cat etc/myapp.json { "csv": { "f_ext": ".csv/r", "f_dir": "data" "csv_sep_char": ";", "csv_class": "Text::CSV_XS" } } $cat etc/myapp-tpau.json { "csv": { "f_dir": "data/tpau" } } =head1 DESCRIPTION This is an additional role for MooX::ConfigFromFile to allow merging loaded configurations in a more predictable order: filename > extension > path. (Read: When the filename is identical, the extensions are compared, when they are identical, the locations are compared). While filename and file extension are compared on character basis, the sort order of the file locations (path) is based on precedence in L or L, respectively. This order is defined internally in C<@File::ConfigDir::extensible_bases>. =head1 ATTRIBUTES =head2 sorted_loaded_config This role modifies the builder for I by sorting the loaded files from I by filename, extension and location in the filesystem, respectively. Let's assume the affected setup has a I interface named C with I like C provides them, too. And the company using the application does it well by defining staging environments like C (Development), C (Testing), C (Integration) and C (Production). For the example, the I shall be C and C. This will give you possible Cs of # main command ['oper'] ['oper', 'dev'] ['oper', 'test'] ['oper', 'int'] ['oper', 'prod'] # deploy sub-command ['oper', 'deploy'] ['oper', 'deploy', 'dev'] ['oper', 'deploy', 'test'] ['oper', 'deploy', 'int'] ['oper', 'deploy', 'prod'] # report sub-command ['oper', 'report'] ['oper', 'report', 'dev'] ['oper', 'report', 'test'] ['oper', 'report', 'int'] ['oper', 'report', 'prod'] This will result in (let's further assume, developers prefer C, operators prefer C) following possible config filenames: [ # main command 'oper.json', 'oper.yaml', 'oper-dev.json', 'oper-dev.yaml', 'oper-test.json', 'oper-test.yaml', 'oper-int.json', 'oper-int.yaml', 'oper-prod.json', 'oper-prod.yaml', # deploy sub-command 'oper-deploy.json', 'oper-deploy.yaml', 'oper-deploy-dev.json', 'oper-deploy-dev.yaml', 'oper-deploy-test.json', 'oper-deploy-test.yaml', 'oper-deploy-int.json', 'oper-deploy-int.yaml', 'oper-deploy-prod.json', 'oper-deploy-prod.yaml', # report sub-command 'oper-report.json', 'oper-report.yaml', 'oper-report-dev.json', 'oper-report-dev.yaml', 'oper-report-test.json', 'oper-report-test.yaml', 'oper-report-int.json', 'oper-report-int.yaml', 'oper-report-prod.json', 'oper-report-prod.yaml', ] For a particular invoking (C in C stage) following files exists: [ '/etc/oper.json', # global configuration by developers '/etc/oper.yaml', # global configuration by operating policy '/opt/ctrl/etc/oper.json', # vendor configuration by developers '/opt/ctrl/etc/oper.yaml', # vendor configuration by operating policy '/opt/ctrl/etc/oper-int.yaml', # vendor configuration by stage operating policy '/opt/ctrl/etc/oper-report.yaml', # vendor configuration by report operating team '/home/usr4711/oper-report.yaml', # usr4711 individual configuration (e.g. for template adoption) ] The default sort algorithm will deliver [ "/etc/oper.json", "/etc/oper.yaml", "/home/usr4711/oper-report.yaml", "/opt/ctrl/etc/oper-int.yaml", "/opt/ctrl/etc/oper-report.yaml", "/opt/ctrl/etc/oper.json", "/opt/ctrl/etc/oper.yaml" ] This role will change the sort algorithm to deliver [ "/etc/oper.json", "/opt/ctrl/etc/oper.json", "/etc/oper.yaml", "/opt/ctrl/etc/oper.yaml", "/opt/ctrl/etc/oper-int.yaml", "/opt/ctrl/etc/oper-report.yaml", "/home/usr4711/oper-report.yaml" ] Which will cause that all policy configuration will override the developer defaults and user configuration override policy settings. =head1 AUTHOR Jens Rehsack, C<< >> =head1 ACKNOWLEDGEMENTS =head1 LICENSE AND COPYRIGHT Copyright 2018 Jens Rehsack. This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License. See L for more information. =cut MooX-ConfigFromFile-0.009/lib/MooX/ConfigFromFile/Role/HashMergeLoaded.pm000644 000765 000024 00000005622 13272105463 025701 0ustar00snostaff000000 000000 package MooX::ConfigFromFile::Role::HashMergeLoaded; use strict; use warnings; our $VERSION = '0.009'; use Hash::Merge; use Moo::Role; requires "loaded_config"; requires "sorted_loaded_config"; has "config_merge_behavior" => (is => "lazy"); sub _build_config_merge_behavior { 'LEFT_PRECEDENT' } has "config_merger" => (is => "lazy"); sub _build_config_merger { my ($class, $params) = @_; defined $params->{config_merge_behavior} or $params->{config_merge_behavior} = $class->_build_config_merge_behavior($params); Hash::Merge->new($params->{config_merge_behavior}); } sub _build_merged_loaded_config { my ($next, $class, $params) = @_; defined $params->{sorted_loaded_config} or $params->{sorted_loaded_config} = $class->_build_sorted_loaded_config($params); defined $params->{config_merger} or $params->{config_merger} = $class->_build_config_merger($params); my $config_merged = {}; for my $c (map { values %$_ } @{$params->{sorted_loaded_config}}) { %$config_merged = %{$params->{config_merger}->merge($config_merged, $c)}; } $config_merged; } around _build_loaded_config => \&_build_merged_loaded_config; 1; =head1 NAME MooX::ConfigFromFile::Role::HashMergeLoaded - allows better merge strategies for multiple config files =head1 SYNOPSIS package MyApp::Cmd::TPau; use DBI; use Moo; use MooX::Cmd with_configfromfile => 1; with "MooX::ConfigFromFile::Role::HashMergeLoaded"; has csv => (is => "ro", required => 1); sub execute { my $self = shift; DBI->connect("DBI::csv:", undef, undef, $self->csv); } __END__ $ cat etc/myapp.json { "csv": { "f_ext": ".csv/r", "csv_sep_char": ";", "csv_class": "Text::CSV_XS" } } $cat etc/myapp-tpau.json { "csv": { "f_dir": "data/tpau" } } =head1 DESCRIPTION This is an additional role for MooX::ConfigFromFile to allow better merging of deep structures. =head1 ATTRIBUTES =head2 config_merge_behavior This attribute contains the behavior which will L use to merge particular loaded configurations. =head2 config_merger This attribute contains the instance of L used to merge the I into I. =head2 loaded_config This role modifies the builder for I by merging the items from I in order of appearance. It is assumed that more relevant config files are in front and are filled up with defaults in following ones. =head1 AUTHOR Jens Rehsack, C<< >> =head1 ACKNOWLEDGEMENTS =head1 LICENSE AND COPYRIGHT Copyright 2015-2018 Jens Rehsack. This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License. See L for more information. =cut MooX-ConfigFromFile-0.009/calc/etc/000755 000765 000024 00000000000 13272110214 016643 5ustar00snostaff000000 000000 MooX-ConfigFromFile-0.009/calc/etc/small-operands.json000644 000765 000024 00000000036 12475550466 022503 0ustar00snostaff000000 000000 { "a" : 30, "b" : 6 } MooX-ConfigFromFile-0.009/calc/etc/operands.json000644 000765 000024 00000000036 12475551574 021376 0ustar00snostaff000000 000000 { "a" : 21, "b" : 4 } MooX-ConfigFromFile-0.009/calc/etc/large-operands.json000644 000765 000024 00000000041 12475550503 022451 0ustar00snostaff000000 000000 { "a" : 666, "b" : 222 } MooX-ConfigFromFile-0.009/t/02-moose.t000644 000765 000024 00000001226 13272100616 017165 0ustar00snostaff000000 000000 #!perl use 5.008001; use strict; use warnings FATAL => 'all'; use Test::More; BEGIN { eval "use Moose;"; $@ and plan skip_all => "Moose test requires Moose being installed"; } our $OO = "Moose"; $ENV{WHICH_MOODEL} = "Moose"; unshift @INC, "." unless grep { "." eq $_ } @INC; ok(do 't/testerr.pm', "do 't/testerr.pm'"); ok(do 't/testlib.pm', "do 't/testlib.pm'"); $@ and diag($@); eval "use MooX::Cmd 0.012; 1" and ok(do 't/testmxcmd.pm', "do 't/testmxcmd.pm'"); eval "{package MooX::ConfigFromFile::Test::Availability::Of::MooX::Options; use Moo; use MooX::Options 4.001; }; 1" and ok(do 't/testmxopt.pm', "do 't/testmxopt.pm'"); done_testing; MooX-ConfigFromFile-0.009/t/01-moo.t000644 000765 000024 00000001013 13272100616 016626 0ustar00snostaff000000 000000 #!perl use 5.008001; use strict; use warnings FATAL => 'all'; use Test::More; our $OO = "Moo"; unshift @INC, "." unless grep { "." eq $_ } @INC; ok(do 't/testerr.pm', "do 't/testerr.pm'"); ok(do 't/testlib.pm', "do 't/testlib.pm'"); $@ and diag($@); eval "use MooX::Cmd 0.012; 1" and ok(do 't/testmxcmd.pm', "do 't/testmxcmd.pm'"); eval "{package MooX::ConfigFromFile::Test::Availability::Of::MooX::Options; use Moo; use MooX::Options 4.001; }; 1" and ok(do 't/testmxopt.pm', "do 't/testmxopt.pm'"); done_testing; MooX-ConfigFromFile-0.009/t/testlib.pm000644 000765 000024 00000017616 13272101016 017450 0ustar00snostaff000000 000000 use strict; use warnings FATAL => "all"; use FindBin; eval sprintf( <<'EOCDECL', ($main::OO) x 9); { package # Calc::Role::BinaryOperation; use %s::Role; has a => ( is => "ro", required => 1, ); has b => ( is => "ro", required => 1, ); } { package # Calc::add; use %s; use MooX::ConfigFromFile; with "Calc::Role::BinaryOperation"; sub execute { my $self = shift; return $self->a + $self->b; } } { package # Calc::add_with_merge; use %s; use MooX::ConfigFromFile config_hashmergeloaded => 1; with "Calc::Role::BinaryOperation"; sub execute { my $self = shift; return $self->a + $self->b; } } { package # Calc::extended_add; use %s; extends "Calc::add"; with "MooX::ConfigFromFile::Role::HashMergeLoaded"; with "MooX::ConfigFromFile::Role::SortedByFilename"; } { package # Calc::sub; use %s; use MooX::ConfigFromFile config_prefix => "calc-operands"; with "Calc::Role::BinaryOperation"; sub execute { my $self = shift; return $self->a - $self->b; } } { package # Calc::mul; use %s; use MooX::ConfigFromFile config_prefix => "calc-operands", config_sortedbyfilename => 1, config_singleton => 1; with "Calc::Role::BinaryOperation"; sub execute { my $self = shift; return $self->a * $self->b; } } { package # Calc::div; use %s; use MooX::ConfigFromFile config_singleton => 0; with "Calc::Role::BinaryOperation"; around BUILDARGS => sub { my $next = shift; my $class = shift; my $a = shift; my $b = shift; my $loaded_config = { a => $a, b => $b }; $class->$next( loaded_config => $loaded_config, ); }; sub execute { my $self = shift; return $self->a / $self->b; } } { package # Dumb::Cfg; use %s; use MooX::ConfigFromFile config_sortedbyfilename => 0, config_hashmergeloaded => 0; sub execute { return; } } { package # Mock::Cfg; use %s; use MooX::ConfigFromFile config_sortedbyfilename => 1, config_hashmergeloaded => 1; sub execute { return; } } EOCDECL # This is for warn once note $main::OO; my $adder = Calc::add->new(config_prefix => "calc-operands"); ok(defined($adder->a), "read \"a\" from add config"); ok(defined($adder->b), "read \"b\" from add config"); cmp_ok($adder->execute, "==", 5, "read right adder config"); ok(Moo::Role::does_role($adder, "MooX::ConfigFromFile::Role"), "Applying MooX::ConfigFromFile::Role"); my $secadd = Calc::add->new(config_prefixes => [qw(calc operands)]); ok(defined($secadd->a), "read \"a\" from add configs"); ok(defined($secadd->b), "read \"b\" from add configs"); cmp_ok($secadd->execute, "==", 7, "use topmost adder config"); ok(Moo::Role::does_role($secadd, "MooX::ConfigFromFile::Role"), "Applying MooX::ConfigFromFile::Role"); my $thiadd = Calc::add_with_merge->new(config_prefixes => [qw(calc operands)]); ok(defined($thiadd->a), "read \"a\" from add configs"); ok(defined($thiadd->b), "read \"b\" from add configs"); cmp_ok($thiadd->execute, "==", 5, "read proper adder config"); ok(Moo::Role::does_role($thiadd, "MooX::ConfigFromFile::Role"), "Applying MooX::ConfigFromFile::Role"); my $fouadd = Calc::extended_add->new(config_prefixes => [qw(calc operands)]); ok(defined($fouadd->a), "read \"a\" from add configs"); ok(defined($fouadd->b), "read \"b\" from add configs"); cmp_ok($fouadd->execute, "==", 7, "use topmost adder config"); ok(Moo::Role::does_role($fouadd, "MooX::ConfigFromFile::Role"), "Applying MooX::ConfigFromFile::Role"); my @copy_attrs = qw(dirs extensions merger merge_behavior); foreach my $copy_attr ('raw_loaded_config', 'sorted_loaded_config', map { "config_$_" } @copy_attrs) { my $fivadd = Calc::extended_add->new( $copy_attr => $fouadd->$copy_attr, config_prefixes => [qw(calc operands)] ); ok(defined($fivadd->a), "read \"a\" from add config using $copy_attr"); ok(defined($fivadd->b), "read \"b\" from add config using $copy_attr"); cmp_ok($fivadd->execute, "==", 7, "read topmost adder config using $copy_attr"); } @copy_attrs = qw(extensions dirs prefix prefixes prefix_map prefix_map_separator files_pattern files); foreach my $copy_attr ('sorted_loaded_config', map { "config_$_" } @copy_attrs) { my $subber = Calc::sub->new($copy_attr => $adder->$copy_attr); ok(defined($subber->a), "read \"a\" from sub config using $copy_attr"); ok(defined($subber->b), "read \"b\" from sub config using $copy_attr"); cmp_ok($subber->execute, "==", -1, "read right subber config using $copy_attr"); } my $secsub = Calc::sub->new( raw_loaded_config => [ { t => { b => 2, a => 4 } } ] ); ok(defined($secsub->a), "read \"a\" from sub config"); ok(defined($secsub->b), "read \"b\" from sub config"); cmp_ok($secsub->execute, "==", 2, "use right secsub config"); ok(Moo::Role::does_role($secsub, "MooX::ConfigFromFile::Role"), "Applying MooX::ConfigFromFile::Role"); my $mul1 = Calc::mul->new(b => 4); ok(defined($mul1->a), "read \"a\" from mul1 config"); ok(defined($mul1->b), "read \"b\" from mul1 config"); cmp_ok($mul1->execute, "==", 8, "read right mul config"); my $mul2 = Calc::mul->new(config_prefix => "no-calc-operands"); ok(defined($mul2->a), "copy \"a\" from mul1 config"); ok(defined($mul2->b), "copy \"b\" from mul1 config"); cmp_ok($mul2->execute, "==", 6, "right mul2 config duplicated"); my $mul3 = $mul2->new; cmp_ok($mul3->execute, "==", 6, "right mul3 config duplicated"); my $div1 = Calc::div->new(12, 3); ok(defined($div1->a), "read \"a\" from div1 config"); ok(defined($div1->b), "read \"b\" from div1 config"); cmp_ok($div1->execute, "==", 4, "read right div1 config"); my $div2 = Calc::div->new(12, 6); ok(defined($div2->a), "read \"a\" from div2 config"); ok(defined($div2->b), "read \"b\" from div2 config"); cmp_ok($div2->execute, "==", 2, "read right div2 config"); my $dumb = Dumb::Cfg->new(config_dirs => 1); isa_ok($dumb, "Dumb::Cfg"); is($dumb->config_prefix, $FindBin::Script, "fallback config prefix"); is_deeply($dumb->config_dirs, [qw(.)], "fallback config dirs"); is_deeply($dumb->config_prefixes, [$FindBin::Script], "fallback config prefix"); my $mock = Mock::Cfg->new( config_dirs => [qw(/etc /opt/ctrl/etc /home/usr4711)], config_extensions => [qw(json yaml)], raw_loaded_config => [ # global configuration by developers {'/etc/oper.json' => {}}, # global configuration by operating policy {'/etc/oper.yaml' => {}}, # vendor configuration by developers {'/opt/ctrl/etc/oper.json' => {}}, # vendor configuration by operating policy {'/opt/ctrl/etc/oper.yaml' => {}}, # vendor configuration by stage operating policy {'/opt/ctrl/etc/oper-int.yaml' => {}}, # vendor configuration by report operating team {'/opt/ctrl/etc/oper-report.yaml' => {}}, # usr4711 individual configuration (e.g. for template adoption) {'/home/usr4711/oper-report.yaml' => {}}, ] ); isa_ok($mock, "Mock::Cfg"); is_deeply( $mock->sorted_loaded_config, [ {'/etc/oper.json' => {}}, {'/opt/ctrl/etc/oper.json' => {}}, {'/etc/oper.yaml' => {}}, {'/opt/ctrl/etc/oper.yaml' => {}}, {'/opt/ctrl/etc/oper-int.yaml' => {}}, {'/opt/ctrl/etc/oper-report.yaml' => {}}, {'/home/usr4711/oper-report.yaml' => {}} ], "Filename based sort order" ); my $mock2 = Mock::Cfg->new(raw_loaded_config => []); is_deeply($mock2->sorted_loaded_config, []); MooX-ConfigFromFile-0.009/t/testmxcmd.pm000644 000765 000024 00000004623 13272100616 020011 0ustar00snostaff000000 000000 use MooX::Cmd::Tester; use FindBin qw($Bin); use lib "$Bin/lib"; use MooXCmdTest; my @tests = ( [[], "MooXCmdTest", "MooXCmdTest", {complicated_setting => {say => "Hello!"}}], [ [qw(test)], "MooXCmdTest", "MooXCmdTest::Cmd::Test", { unintialized_attribute => sub { time - $_[0] < 1 } } ], [ [qw(tested)], "MooXCmdTest", "MooXCmdTest::Cmd::Tested", {confidential_setting => 42} ], [ [qw(test this)], "MooXCmdTest", "MooXCmdTest::Cmd::Test::Cmd::This", {dedicated_setting => 4711} ], [ [qw(test this hashmerged)], "MooXCmdTest", "MooXCmdTest::Cmd::Test::Cmd::This::Cmd::HashMerged", { dedicated_setting => 4711, merged_frame => { kept_value => "sane", "overwritten_value" => "dammed" } } ], [ [qw(test shortcut)], "MooXCmdTest", "MooXCmdTest::Cmd::Test::Cmd::Shortcut", {complex_attribute => [4711]} ], [ [qw(test shortcut hashmerged)], "MooXCmdTest", "MooXCmdTest::Cmd::Test::Cmd::Shortcut::Cmd::HashMerged", {complex_attribute => [501, 4711]} ], ); for (@tests) { SKIP: { my ($args, $class, $cmd_class, $attrs) = @{$_}; ref $args or $args = [split(' ', $args)]; my $rv = test_cmd($class => $args); #diag(explain($rv)); my $test_ident = "$class => " . join(" ", "[", @$args, "]"); ok($rv->cmd, "got cmd for $test_ident") or diag(explain($rv)); isa_ok($rv->cmd, $class) or skip("Cannot do attribute testing without command", 2); isa_ok($rv->cmd->command_chain_end, $cmd_class) or skip("Cannot do attribute testing without specific command", 1) if scalar @$args; my $cmd = scalar @$args ? $rv->cmd->command_chain_end : $rv->cmd; foreach my $k (keys %$attrs) { my $cmd_attr = $cmd->$k; ref $attrs->{$k} or is($attrs->{$k}, $cmd_attr, "Attribute $k for $test_ident"); "CODE" eq ref $attrs->{$k} and ok($attrs->{$k}->($cmd_attr), "Attribute $k ok for $test_ident"); ref $attrs->{$k} and "CODE" ne ref $attrs->{$k} and is_deeply($attrs->{$k}, $cmd_attr, "Attribute $k for $test_ident"); } } } 1; MooX-ConfigFromFile-0.009/t/00-load.t000644 000765 000024 00000001266 13272100616 016764 0ustar00snostaff000000 000000 #!perl use 5.008001; use strict; use warnings FATAL => 'all'; use Test::More; use Moo; BEGIN { use_ok('MooX::ConfigFromFile') || BAIL_OUT "Couldn't load MooX::ConfigFromFile"; use_ok('MooX::ConfigFromFile::Role') || BAIL_OUT "Couldn't load MooX::ConfigFromFile::Role"; use_ok('MooX::ConfigFromFile::Role::HashMergeLoaded') || BAIL_OUT "Couldn't load MooX::ConfigFromFile::Role::HashMergeLoaded"; use_ok('MooX::ConfigFromFile::Role::SortedByFilename') || BAIL_OUT "Couldn't load MooX::ConfigFromFile::Role::SortedByFilename"; } diag("Testing MooX::ConfigFromFile $MooX::ConfigFromFile::VERSION, Perl $], $^X"); done_testing(); MooX-ConfigFromFile-0.009/t/testerr.pm000644 000765 000024 00000001142 13111054374 017463 0ustar00snostaff000000 000000 use strict; use warnings FATAL => "all"; require Role::Tiny; eval sprintf( <<'EOCDECL', ($main::OO) x 1); { package # Must::Fail; use MooX::ConfigFromFile; sub new { bless {}, shift } } { package # Already::There; use %s; sub _initialize_from_config {} use MooX::ConfigFromFile; } EOCDECL note $main::OO; my $mf = Must::Fail->new; ok(!$mf->can("_initialize_from_config"), "Failed to apply MooX::ConfigFromFile::Role"); my $ar = Already::There->new; ok(!Role::Tiny::does_role($ar, "MooX::ConfigFromFile::Role"), "Skipped applying MooX::ConfigFromFile::Role"); MooX-ConfigFromFile-0.009/t/lib/000755 000765 000024 00000000000 13272110214 016177 5ustar00snostaff000000 000000 MooX-ConfigFromFile-0.009/t/testmxopt.pm000644 000765 000024 00000007040 13111054374 020045 0ustar00snostaff000000 000000 use strict; use warnings FATAL => "all"; use FindBin; use Cwd qw'abs_path getcwd'; use File::Spec; eval sprintf( <<'EOCDECL', ($main::OO) x 5); { package # oCalc::Role::BinaryOperation; use %s::Role; has a => ( is => "ro", required => 1, ); has b => ( is => "ro", required => 1, ); } { package # oCalc::add; use %s; use MooX::Options with_config_from_file => 1; with "oCalc::Role::BinaryOperation"; sub execute { my $self = shift; return $self->a + $self->b; } } { package # oCalc::sub; use %s; use MooX::Options with_config_from_file => 1; use MooX::ConfigFromFile config_identifier => "calc"; with "oCalc::Role::BinaryOperation"; sub execute { my $self = shift; return $self->a - $self->b; } } { package # oCalc::mul; use %s; use MooX::ConfigFromFile config_singleton => 1; use MooX::Options with_config_from_file => 1; with "oCalc::Role::BinaryOperation"; sub execute { my $self = shift; return $self->a * $self->b; } } { package # oCalc::div; use %s; use MooX::ConfigFromFile config_singleton => 0; use MooX::Options with_config_from_file => 1; with "oCalc::Role::BinaryOperation"; sub execute { my $self = shift; return $self->a / $self->b; } } EOCDECL # This is for warn once note $main::OO; my $cwd = abs_path(getcwd); my @cfg_files = map { ("--config-files", File::Spec->catfile($cwd, qw(calc etc), $_)) } qw(operands.json small-operands.json large-operands.json); SCOPE: { local @ARGV = qw(--config-prefix calc-operands); my $adder = oCalc::add->new_with_options; ok(defined($adder->a), "read \"a\" from add config"); ok(defined($adder->b), "read \"b\" from add config"); cmp_ok($adder->execute, "==", 5, "read right adder config"); ok(Moo::Role::does_role($adder, "MooX::ConfigFromFile::Role"), "Applying MooX::ConfigFromFile::Role to oCalc::add"); } SCOPE: { local @ARGV = qw(--config-prefix operands); my $subber = oCalc::sub->new_with_options; ok(defined($subber->a), "read \"a\" from sub config"); ok(defined($subber->b), "read \"b\" from sub config"); cmp_ok($subber->execute, "==", 17, "read right subber config"); ok(Moo::Role::does_role($subber, "MooX::ConfigFromFile::Role"), "Applying MooX::ConfigFromFile::Role to oCalc::sub"); } SCOPE: { local @ARGV = @cfg_files[0 .. 1]; my $mul = oCalc::mul->new_with_options; is($mul->a, 21,, "read \"a\" from mul config"); is($mul->b, 4, "read \"b\" from mul config"); cmp_ok($mul->execute, "==", 84, "read right mul config"); } SCOPE: { local @ARGV = @cfg_files[2 .. 3]; my $mul = oCalc::mul->new_with_options; is($mul->a, 21,, "keep \"a\" from first mul config"); is($mul->b, 4, "keep \"b\" from first mul config"); cmp_ok($mul->execute, "==", 84, "read right mul config"); } SCOPE: { local @ARGV = @cfg_files[2 .. 3]; my $div = oCalc::div->new_with_options; is($div->a, 30,, "read \"a\" from small div config"); is($div->b, 6, "read \"b\" from small div config"); cmp_ok($div->execute, "==", 5, "read right div config"); } SCOPE: { local @ARGV = @cfg_files[4 .. 5]; my $div = oCalc::div->new_with_options; is($div->a, 666,, "read \"a\" from large div config"); is($div->b, 222, "read \"b\" from large div config"); cmp_ok($div->execute, "==", 3, "read right div config"); } MooX-ConfigFromFile-0.009/t/lib/MooXCmdTest/000755 000765 000024 00000000000 13272110214 020345 5ustar00snostaff000000 000000 MooX-ConfigFromFile-0.009/t/lib/MooXCmdTest.pm000644 000765 000024 00000000561 13111054374 020713 0ustar00snostaff000000 000000 package MooXCmdTest; use strict; use warnings; BEGIN { my $moodel = $ENV{WHICH_MOODEL} || "Moo"; eval "use $moodel;"; $@ and die $@; $moodel->import; } use MooX::ConfigFromFile config_prefix => "MooXCmdTest"; use MooX::Cmd with_config_from_file => 1; has complicated_setting => ( is => "ro", required => 1 ); sub execute { @_ } 1; MooX-ConfigFromFile-0.009/t/lib/MooXCmdTest/Cmd/000755 000765 000024 00000000000 13272110214 021050 5ustar00snostaff000000 000000 MooX-ConfigFromFile-0.009/t/lib/MooXCmdTest/Cmd/Test/000755 000765 000024 00000000000 13272110214 021767 5ustar00snostaff000000 000000 MooX-ConfigFromFile-0.009/t/lib/MooXCmdTest/Cmd/Tested.pm000644 000765 000024 00000001015 13111054374 022641 0ustar00snostaff000000 000000 package MooXCmdTest::Cmd::Tested; use strict; use warnings; BEGIN { my $moodel = $ENV{WHICH_MOODEL} || "Moo"; eval "use $moodel;"; $@ and die $@; $moodel->import; } use MooX::ConfigFromFile config_prefix => "MooXCmdTest", config_prefix_map_separator => "."; use MooX::Cmd with_config_from_file => 1; has confidential_setting => ( is => "ro", builder => "_build_confidential_attribute", lazy => 1, ); sub _build_confidential_attribute { time } sub execute { @_ } 1; MooX-ConfigFromFile-0.009/t/lib/MooXCmdTest/Cmd/Test.pm000644 000765 000024 00000000603 13111054374 022332 0ustar00snostaff000000 000000 package MooXCmdTest::Cmd::Test; use strict; use warnings; BEGIN { my $moodel = $ENV{WHICH_MOODEL} || "Moo"; eval "use $moodel;"; $@ and die $@; $moodel->import; } use MooX::Cmd; has unintialized_attribute => ( is => "ro", builder => "_build_unintialized_attribute", lazy => 1 ); sub _build_unintialized_attribute { time } sub execute { @_ } 1; MooX-ConfigFromFile-0.009/t/lib/MooXCmdTest/Cmd/Test/Cmd/000755 000765 000024 00000000000 13272110214 022472 5ustar00snostaff000000 000000 MooX-ConfigFromFile-0.009/t/lib/MooXCmdTest/Cmd/Test/Cmd/Shortcut/000755 000765 000024 00000000000 13272110214 024305 5ustar00snostaff000000 000000 MooX-ConfigFromFile-0.009/t/lib/MooXCmdTest/Cmd/Test/Cmd/This.pm000644 000765 000024 00000000670 13111054374 023750 0ustar00snostaff000000 000000 package MooXCmdTest::Cmd::Test::Cmd::This; use strict; use warnings; BEGIN { my $moodel = $ENV{WHICH_MOODEL} || "Moo"; eval "use $moodel;"; $@ and die $@; $moodel->import; } use MooX::ConfigFromFile config_prefix => "MooXCmdTest", config_prefix_map_separator => "."; use MooX::Cmd with_config_from_file => 1; has dedicated_setting => ( is => "ro", required => 1 ); sub execute { @_ } 1; MooX-ConfigFromFile-0.009/t/lib/MooXCmdTest/Cmd/Test/Cmd/This/000755 000765 000024 00000000000 13272110214 023401 5ustar00snostaff000000 000000 MooX-ConfigFromFile-0.009/t/lib/MooXCmdTest/Cmd/Test/Cmd/Shortcut.pm000644 000765 000024 00000000647 13111054374 024660 0ustar00snostaff000000 000000 package MooXCmdTest::Cmd::Test::Cmd::Shortcut; use strict; use warnings; BEGIN { my $moodel = $ENV{WHICH_MOODEL} || "Moo"; eval "use $moodel;"; $@ and die $@; $moodel->import; } use MooX::ConfigFromFile config_identifier => "MooXCmdTest", config_prefixes => []; use MooX::Cmd with_config_from_file => 1; has complex_attribute => ( is => "ro", required => 1 ); sub execute { @_ } 1; MooX-ConfigFromFile-0.009/t/lib/MooXCmdTest/Cmd/Test/Cmd/This/Cmd/000755 000765 000024 00000000000 13272110214 024104 5ustar00snostaff000000 000000 MooX-ConfigFromFile-0.009/t/lib/MooXCmdTest/Cmd/Test/Cmd/This/Cmd/HashMerged.pm000644 000765 000024 00000001013 13111054374 026452 0ustar00snostaff000000 000000 package MooXCmdTest::Cmd::Test::Cmd::This::Cmd::HashMerged; use strict; use warnings; BEGIN { my $moodel = $ENV{WHICH_MOODEL} || "Moo"; eval "use $moodel;"; $@ and die $@; $moodel->import; } use MooX::ConfigFromFile config_prefix => "MooXCmdTest"; use MooX::Cmd with_config_from_file => 1; with "MooX::ConfigFromFile::Role::HashMergeLoaded"; has dedicated_setting => ( is => "ro", required => 1 ); has merged_frame => ( is => "ro", required => 1 ); sub execute { @_ } 1; MooX-ConfigFromFile-0.009/t/lib/MooXCmdTest/Cmd/Test/Cmd/Shortcut/Cmd/000755 000765 000024 00000000000 13272110214 025010 5ustar00snostaff000000 000000 MooX-ConfigFromFile-0.009/t/lib/MooXCmdTest/Cmd/Test/Cmd/Shortcut/Cmd/HashMerged.pm000644 000765 000024 00000000741 13111054374 027365 0ustar00snostaff000000 000000 package MooXCmdTest::Cmd::Test::Cmd::Shortcut::Cmd::HashMerged; use strict; use warnings; BEGIN { my $moodel = $ENV{WHICH_MOODEL} || "Moo"; eval "use $moodel;"; $@ and die $@; $moodel->import; } use MooX::ConfigFromFile config_identifier => "MooXCmdTest", config_prefixes => [], config_hashmergeloaded => 1; use MooX::Cmd with_config_from_file => 1; has complex_attribute => ( is => "ro", required => 1 ); sub execute { @_ } 1; MooX-ConfigFromFile-0.009/etc/MooXCmdTest/000755 000765 000024 00000000000 13272110214 020107 5ustar00snostaff000000 000000 MooX-ConfigFromFile-0.009/etc/MooXCmdTest-test-this-hashmerged.json000644 000765 000024 00000000077 12517401415 025044 0ustar00snostaff000000 000000 { "merged_frame": { "overwritten_value": "dammed" } } MooX-ConfigFromFile-0.009/etc/MooXCmdTest-test.json000644 000765 000024 00000000044 12475543102 021767 0ustar00snostaff000000 000000 { "unintialized_attribute": 1 } MooX-ConfigFromFile-0.009/etc/MooXCmdTest.test.this.json000644 000765 000024 00000000042 12517403542 022734 0ustar00snostaff000000 000000 { "dedicated_setting": 4711 } MooX-ConfigFromFile-0.009/etc/calc.json000644 000765 000024 00000000020 13272043172 017536 0ustar00snostaff000000 000000 { "a" : 4 } MooX-ConfigFromFile-0.009/etc/MooXCmdTest-test-this.json000644 000765 000024 00000000203 12517403515 022731 0ustar00snostaff000000 000000 { "dedicated_setting": 4711, "merged_frame": { "kept_value": "sane", "overwritten_value": "insane" } } MooX-ConfigFromFile-0.009/etc/MooXCmdTest.json000644 000765 000024 00000000070 12475540400 021007 0ustar00snostaff000000 000000 { "complicated_setting": { "say": "Hello!" } } MooX-ConfigFromFile-0.009/etc/MooXCmdTest.tested.json000644 000765 000024 00000000043 12475543064 022307 0ustar00snostaff000000 000000 { "confidential_setting": 42 } MooX-ConfigFromFile-0.009/etc/calc-operands.json000644 000765 000024 00000000035 12221023560 021345 0ustar00snostaff000000 000000 { "a" : 2, "b" : 3 } MooX-ConfigFromFile-0.009/etc/MooXCmdTest/test-shortcut-hashmerged.json000644 000765 000024 00000000045 13111022535 025736 0ustar00snostaff000000 000000 { "complex_attribute": [ 501 ] } MooX-ConfigFromFile-0.009/etc/MooXCmdTest/test-shortcut.json000644 000765 000024 00000000046 13111022535 023632 0ustar00snostaff000000 000000 { "complex_attribute": [ 4711 ] }