Dist-Zilla-LocaleTextDomain-0.87000755000767000024 012244302227 16171 5ustar00davidstaff000000000000Changes100644000767000024 475612244302227 17561 0ustar00davidstaff000000000000Dist-Zilla-LocaleTextDomain-0.87Revision history for Perl extension Dist-Zilla-LocaleTextDomain 0.87 2013-11-24T04:46:40Z - Updated file gathering to suport Dist::Zilla 5.0's improved character encoding support. - Fixed Pod link to actually link. 0.86 2013-04-09T00:32:43Z - Added diagnostic output to some tests to help figure out why they fail on some platforms. - Added code to the installer to throw an error if the version of GNU gettext appears to be less then v0.17.0. v0.17.0 is required for the `--package-name` and `--package-version` options. 0.85 2013-01-08T23:07:42Z - Changed `msg-compile` to take a list of file names, rather than language codes. This brings it in line with the interface of `msg-merge`. - Added a section for translators to the documentation. 0.84 2013-01-08T20:24:42Z - Changed some logging output to be prefixed with `[LocalTextDomain]` rather than `[DZ]`. - Added the `msg-compile` command, which allows one to arbitrarily compile one or more language catalogs. This should be useful for translators who want to test a catalog as they translate it. 0.83 2012-12-04T23:54:12Z - Added improved failure message when GNU gettext cannot be found, as well as slightly improved detection of the fact that it's not installed. Thanks to Jeff Lavallee for the box to test it on. 0.82 2012-12-03T19:06:03Z - Fixed broken call to `log_fatal` in the `msg-init` command that caused the actual error to be lost in favor of a bad method call error. Thanks Joenio Costa for the patch. - Added a note on how to get Locale::TextDomain to return character strings instead of byte strings. - Now refuse to build if `gettext --version` does not work at build time. 0.81 2012-10-02T16:25:43Z - Removed tests for the `add_lang` command, which was never shipped, but renamed `msg_init`. 0.80 2012-10-01T19:00:55Z - Switched from `system()` to IPC::Run3, so that STDOUT and STDERR messages can be passed to the Dist::Zilla logger. - Added new `dzil` commands: + `msg-scan` - Scan modules for messages to create translation template file + `msg-init` - Create a new language translation file + `msg-merge` - Merge message changes into translation files - Added short tutorial as main documentation, Dist::Zilla::LocaleTextDomain. 0.10 2012-09-06T22:12:48Z - Initial release with just the LocaleTextDomain plugin. t000755000767000024 012244302227 16355 5ustar00davidstaff000000000000Dist-Zilla-LocaleTextDomain-0.87pod.t100644000767000024 24112244302227 17441 0ustar00davidstaff000000000000Dist-Zilla-LocaleTextDomain-0.87/t#!/usr/bin/perl -w use strict; 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(); LICENSE100644000767000024 4366712244302227 17317 0ustar00davidstaff000000000000Dist-Zilla-LocaleTextDomain-0.87This software is copyright (c) 2012 by David E. Wheeler. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. Terms of the Perl programming language system itself 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" --- The GNU General Public License, Version 1, February 1989 --- This software is Copyright (c) 2012 by David E. Wheeler. This is free software, licensed under: The GNU General Public License, Version 1, February 1989 GNU GENERAL PUBLIC LICENSE Version 1, February 1989 Copyright (C) 1989 Free Software Foundation, Inc. 51 Franklin St, Suite 500, Boston, MA 02110-1335 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! --- The Artistic License 1.0 --- This software is Copyright (c) 2012 by David E. Wheeler. This is free software, licensed under: The Artistic License 1.0 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. - "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 ftp.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) accompany any non-standard executables with their corresponding Standard Version executables, giving the non-standard executables non-standard names, and clearly documenting 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. 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 whomever generated them, and may be sold commercially, and may be aggregated with this Package. 7. C or perl subroutines supplied by you and linked into this Package shall not be considered part of this Package. 8. The name of the Copyright Holder may not be used to endorse or promote products derived from this software without specific prior written permission. 9. 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 base.t100644000767000024 110612244302227 17612 0ustar00davidstaff000000000000Dist-Zilla-LocaleTextDomain-0.87/t#!/usr/bin/perl -w use strict; use warnings; use Test::More tests => 14; require_ok 'Dist::Zilla::Plugin::LocaleTextDomain'; is_deeply [Dist::Zilla::Plugin::LocaleTextDomain->mvp_multivalue_args], [qw(language)], 'Should have mvp_multivalue_args'; for my $cmd (qw(msg_init msg_scan msg_merge msg_compile)) { my $module = "Dist::Zilla::App::Command::$cmd"; require_ok $module; isa_ok $module => 'App::Cmd::Command'; can_ok $module => qw( command_names abstract usage_desc opt_spec validate_args execute ); } META.yml100644000767000024 225012244302227 17522 0ustar00davidstaff000000000000Dist-Zilla-LocaleTextDomain-0.87--- abstract: 'Tools for managing Locale::TextDomain language catalogs' author: - 'David E. Wheeler ' build_requires: App::Cmd::Tester::CaptureExternal: 0 Dist::Zilla::App::Tester: 0 Module::Build: 0.35 Test::DZil: 0 Test::File: 0 Test::File::Contents: 0 Test::More: 0.90 configure_requires: ExtUtils::MakeMaker: 6.30 Module::Build: 0.35 dynamic_config: 0 generated_by: 'Dist::Zilla version 5.006, CPAN::Meta::Converter version 2.132830' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 name: Dist-Zilla-LocaleTextDomain requires: Dist::Zilla::App: 0 Dist::Zilla::File::FromCode: 0 Dist::Zilla::Role::FileGatherer: 0 Email::Address: 0 Encode: 0 File::Basename: 0 File::Copy: 0 File::Find::Rule: 0 File::Path: 2.07 File::Temp: 0 IPC::Cmd: 0 IPC::Run3: 0 Locale::Country: 0 Locale::Language: 0 Moose: 0 Moose::Role: 0 Moose::Util::TypeConstraints: 0 MooseX::Types::Path::Class: 0 Path::Class: 0 namespace::autoclean: 0 perl: v5.8.5 strict: 0 warnings: 0 resources: repository: https://github.com/theory/dist-zilla-localetextdomain.git version: 0.87 MANIFEST100644000767000024 117312244302227 17405 0ustar00davidstaff000000000000Dist-Zilla-LocaleTextDomain-0.87Build.PL Changes LICENSE MANIFEST META.json META.yml Makefile.PL README.md inc/Dist/Zilla/LocaleTextDomainBuild.pm lib/Dist/Zilla/App/Command/msg_compile.pm lib/Dist/Zilla/App/Command/msg_init.pm lib/Dist/Zilla/App/Command/msg_merge.pm lib/Dist/Zilla/App/Command/msg_scan.pm lib/Dist/Zilla/LocaleTextDomain.pm lib/Dist/Zilla/Plugin/LocaleTextDomain.pm lib/Dist/Zilla/Role/PotFile.pm lib/Dist/Zilla/Role/PotWriter.pm t/base.t t/dist/dist.ini t/dist/lib/DZT/Sample.pm t/dist/po/de.po t/dist/po/fr.po t/dist/po/org.imperia.simplecal.pot t/msg_compile.t t/msg_init.t t/msg_merge.t t/msg_scan.t t/plugin.t t/pod.t xt/release/pod-spelling.t Build.PL100644000767000024 402012244302227 17542 0ustar00davidstaff000000000000Dist-Zilla-LocaleTextDomain-0.87 use strict; use warnings; use Module::Build 0.35; use lib qw{inc}; use Dist::Zilla::LocaleTextDomainBuild; my %module_build_args = ( "build_requires" => { "Module::Build" => "0.35" }, "configure_requires" => { "ExtUtils::MakeMaker" => "6.30", "Module::Build" => "0.35" }, "dist_abstract" => "Tools for managing Locale::TextDomain language catalogs", "dist_author" => [ "David E. Wheeler " ], "dist_name" => "Dist-Zilla-LocaleTextDomain", "dist_version" => "0.87", "license" => "perl", "module_name" => "Dist::Zilla::LocaleTextDomain", "recommends" => {}, "recursive_test_files" => 1, "requires" => { "Dist::Zilla::App" => 0, "Dist::Zilla::File::FromCode" => 0, "Dist::Zilla::Role::FileGatherer" => 0, "Email::Address" => 0, "Encode" => 0, "File::Basename" => 0, "File::Copy" => 0, "File::Find::Rule" => 0, "File::Path" => "2.07", "File::Temp" => 0, "IPC::Cmd" => 0, "IPC::Run3" => 0, "Locale::Country" => 0, "Locale::Language" => 0, "Moose" => 0, "Moose::Role" => 0, "Moose::Util::TypeConstraints" => 0, "MooseX::Types::Path::Class" => 0, "Path::Class" => 0, "namespace::autoclean" => 0, "perl" => "v5.8.5", "strict" => 0, "warnings" => 0 }, "script_files" => [], "test_requires" => { "App::Cmd::Tester::CaptureExternal" => 0, "Dist::Zilla::App::Tester" => 0, "Test::DZil" => 0, "Test::File" => 0, "Test::File::Contents" => 0, "Test::More" => "0.90" } ); my %fallback_build_requires = ( "App::Cmd::Tester::CaptureExternal" => 0, "Dist::Zilla::App::Tester" => 0, "Module::Build" => "0.35", "Test::DZil" => 0, "Test::File" => 0, "Test::File::Contents" => 0, "Test::More" => "0.90" ); unless ( eval { Module::Build->VERSION(0.4004) } ) { delete $module_build_args{test_requires}; $module_build_args{build_requires} = \%fallback_build_requires; } my $build = Dist::Zilla::LocaleTextDomainBuild->new(%module_build_args); $build->create_build_script; README.md100644000767000024 270312244302227 17533 0ustar00davidstaff000000000000Dist-Zilla-LocaleTextDomain-0.87Dist/Zilla/LocaleTextDomain version 0.87 ======================================== Dist::Zilla::LocaleTextDomain provides tools to scan your Perl libraries for [Local::TextDomain](http://metacpan.org/module/Locale::TextDomain)-style localizable strings, create a language template, and initialize translation files and keep them up-to-date. If you use [Local::TextDomain](http://metacpan.org/module/Locale::TextDomain) and [Dist::Zilla](http://dzil.org/), you need this module! Installation ------------ To install this module, type the following: perl Build.PL ./Build ./Build test ./Build install Or, if you don't have Module::Build installed, type the following: perl Makefile.PL make make test make install Dependencies ------------ This module requires the the [gettext](http://www.gnu.org/software/gettext/) utilities. It also requires the following non-core modules: * Dist::Zilla * Dist::Zilla::File::FromCode * Dist::Zilla::Role::FileGatherer * Email::Address * Encode * File::Find::Rule * IPC::Cmd * IPC::Run3 * Locale::Codes::Country * Locale::Codes::Language * Moose * Moose::Role: * Moose::Util::TypeConstraints * MooseX::Types::Path::Class * Path::Class * namespace::autoclean Copyright and License --------------------- This software is copyright (c) 2012-2013 by David E. Wheeler. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. META.json100644000767000024 424412244302227 17677 0ustar00davidstaff000000000000Dist-Zilla-LocaleTextDomain-0.87{ "abstract" : "Tools for managing Locale::TextDomain language catalogs", "author" : [ "David E. Wheeler " ], "dynamic_config" : 0, "generated_by" : "Dist::Zilla version 5.006, CPAN::Meta::Converter version 2.132830", "license" : [ "perl_5" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : "2" }, "name" : "Dist-Zilla-LocaleTextDomain", "prereqs" : { "build" : { "requires" : { "Module::Build" : "0.35" } }, "configure" : { "requires" : { "ExtUtils::MakeMaker" : "6.30", "Module::Build" : "0.35" } }, "runtime" : { "requires" : { "Dist::Zilla::App" : "0", "Dist::Zilla::File::FromCode" : "0", "Dist::Zilla::Role::FileGatherer" : "0", "Email::Address" : "0", "Encode" : "0", "File::Basename" : "0", "File::Copy" : "0", "File::Find::Rule" : "0", "File::Path" : "2.07", "File::Temp" : "0", "IPC::Cmd" : "0", "IPC::Run3" : "0", "Locale::Country" : "0", "Locale::Language" : "0", "Moose" : "0", "Moose::Role" : "0", "Moose::Util::TypeConstraints" : "0", "MooseX::Types::Path::Class" : "0", "Path::Class" : "0", "namespace::autoclean" : "0", "perl" : "v5.8.5", "strict" : "0", "warnings" : "0" } }, "test" : { "requires" : { "App::Cmd::Tester::CaptureExternal" : "0", "Dist::Zilla::App::Tester" : "0", "Test::DZil" : "0", "Test::File" : "0", "Test::File::Contents" : "0", "Test::More" : "0.90" } } }, "release_status" : "stable", "resources" : { "repository" : { "type" : "git", "url" : "https://github.com/theory/dist-zilla-localetextdomain.git", "web" : "https://github.com/theory/dist-zilla-localetextdomain" } }, "version" : "0.87" } plugin.t100644000767000024 452212244302227 20203 0ustar00davidstaff000000000000Dist-Zilla-LocaleTextDomain-0.87/t#!/usr/bin/perl -w use strict; use warnings; use Test::More 0.90; use Test::DZil; use IPC::Cmd 'can_run'; plan skip_all => 'msgfmt not found' unless can_run 'msgfmt'; sub tzil { Builder->from_config( { dist_root => 't/dist' }, { add_files => { 'source/dist.ini' => simple_ini( 'GatherDir', ['LocaleTextDomain', @_], ), }, }, ); } ok my $tzil = tzil(), 'Create tzil';; ok $tzil->build, 'Build it'; my @messages = grep { /^\Q[LocaleTextDomain]/ } @{ $tzil->log_messages }; is $messages[0], '[LocaleTextDomain] Compiling language files in po', 'Compiling message should have been emitted'; my $i = 0; my $slurp = $tzil->can('slurp_file_raw') || $tzil->can('slurp_file'); for my $lang (qw(de fr)) { like $messages[++$i], qr/(?:po.$lang[.]po: )?19/m, "$lang.po message should have been logged"; ok my $contents = $tzil->$slurp( "build/share/LocaleData/$lang/LC_MESSAGES/DZT-Sample.mo", ), "Read in $lang .mo file"; like $contents, qr/^Language: $lang$/m, "Compiled $lang .mo should have language content"; } # Specify the attributes. ok $tzil = tzil({ textdomain => 'org.imperia.simplecal', lang_dir => 'po', share_dir => 'lib', msgfmt => 'msgfmt', lang_file_suffix => 'po', bin_file_suffix => 'bo', language => ['fr'] }), 'Create another tzil'; ok $tzil->build, 'Build again'; @messages = grep { /^\Q[LocaleTextDomain]/ } @{ $tzil->log_messages }; is $messages[0], '[LocaleTextDomain] Compiling language files in po', 'Compiling message should have been emitted again'; ok -e $tzil->tempdir->file("build/lib/LocaleData/fr/LC_MESSAGES/org.imperia.simplecal.bo"), 'Should have fr .bo file'; ok !-e $tzil->tempdir->file("build/lib/LocaleData/de/LC_MESSAGES/org.imperia.simplecal.bo"), 'Should not have de .bo file'; $i = 0; for my $lang (qw(fr)) { like $messages[++$i], qr/(?:po.$lang[.]po: )?19/m, "$lang.po message should have been logged again"; ok my $contents = $tzil->$slurp( "build/lib/LocaleData/$lang/LC_MESSAGES/org.imperia.simplecal.bo", ), "Read in $lang .bo file"; like $contents, qr/^Language: $lang$/m, "Complied $lang .bo file should have language content"; } done_testing; Makefile.PL100644000767000024 503712244302227 20231 0ustar00davidstaff000000000000Dist-Zilla-LocaleTextDomain-0.87 use strict; use warnings; use 5.008005; use ExtUtils::MakeMaker 6.30; my %WriteMakefileArgs = ( "ABSTRACT" => "Tools for managing Locale::TextDomain language catalogs", "AUTHOR" => "David E. Wheeler ", "BUILD_REQUIRES" => { "Module::Build" => "0.35" }, "CONFIGURE_REQUIRES" => { "ExtUtils::MakeMaker" => "6.30", "Module::Build" => "0.35" }, "DISTNAME" => "Dist-Zilla-LocaleTextDomain", "EXE_FILES" => [], "LICENSE" => "perl", "NAME" => "Dist::Zilla::LocaleTextDomain", "PREREQ_PM" => { "Dist::Zilla::App" => 0, "Dist::Zilla::File::FromCode" => 0, "Dist::Zilla::Role::FileGatherer" => 0, "Email::Address" => 0, "Encode" => 0, "File::Basename" => 0, "File::Copy" => 0, "File::Find::Rule" => 0, "File::Path" => "2.07", "File::Temp" => 0, "IPC::Cmd" => 0, "IPC::Run3" => 0, "Locale::Country" => 0, "Locale::Language" => 0, "Moose" => 0, "Moose::Role" => 0, "Moose::Util::TypeConstraints" => 0, "MooseX::Types::Path::Class" => 0, "Path::Class" => 0, "namespace::autoclean" => 0, "strict" => 0, "warnings" => 0 }, "TEST_REQUIRES" => { "App::Cmd::Tester::CaptureExternal" => 0, "Dist::Zilla::App::Tester" => 0, "Test::DZil" => 0, "Test::File" => 0, "Test::File::Contents" => 0, "Test::More" => "0.90" }, "VERSION" => "0.87", "test" => { "TESTS" => "t/*.t" } ); my %FallbackPrereqs = ( "App::Cmd::Tester::CaptureExternal" => 0, "Dist::Zilla::App" => 0, "Dist::Zilla::App::Tester" => 0, "Dist::Zilla::File::FromCode" => 0, "Dist::Zilla::Role::FileGatherer" => 0, "Email::Address" => 0, "Encode" => 0, "File::Basename" => 0, "File::Copy" => 0, "File::Find::Rule" => 0, "File::Path" => "2.07", "File::Temp" => 0, "IPC::Cmd" => 0, "IPC::Run3" => 0, "Locale::Country" => 0, "Locale::Language" => 0, "Module::Build" => "0.35", "Moose" => 0, "Moose::Role" => 0, "Moose::Util::TypeConstraints" => 0, "MooseX::Types::Path::Class" => 0, "Path::Class" => 0, "Test::DZil" => 0, "Test::File" => 0, "Test::File::Contents" => 0, "Test::More" => "0.90", "namespace::autoclean" => 0, "strict" => 0, "warnings" => 0 ); unless ( eval { ExtUtils::MakeMaker->VERSION(6.63_03) } ) { delete $WriteMakefileArgs{TEST_REQUIRES}; delete $WriteMakefileArgs{BUILD_REQUIRES}; $WriteMakefileArgs{PREREQ_PM} = \%FallbackPrereqs; } delete $WriteMakefileArgs{CONFIGURE_REQUIRES} unless eval { ExtUtils::MakeMaker->VERSION(6.52) }; WriteMakefile(%WriteMakefileArgs); msg_init.t100644000767000024 1366112244302227 20542 0ustar00davidstaff000000000000Dist-Zilla-LocaleTextDomain-0.87/t#!/usr/bin/perl -w use strict; use warnings; use Test::More 0.90; use Test::DZil; use IPC::Cmd 'can_run'; use Path::Class; use Test::File; use Test::File::Contents; use Dist::Zilla::App::Tester; use App::Cmd::Tester::CaptureExternal; BEGIN { # Make Tester to inherit CaptureExternal to prevent "Bad file descriptor". package Dist::Zilla::App::Tester; for (@Dist::Zilla::App::Tester::ISA) { $_ = 'App::Cmd::Tester::CaptureExternal' if $_ eq 'App::Cmd::Tester'; } } $ENV{DZIL_GLOBAL_CONFIG_ROOT} = 't'; my $ext = $^O eq 'MSWin32' ? '.exe' : ''; plan skip_all => 'msginit not found' unless can_run 'msginit' . $ext; plan skip_all => 'xgettext not found' unless can_run 'xgettext' . $ext; require_ok 'Dist::Zilla::App::Command::msg_init'; is_deeply [Dist::Zilla::App::Command::msg_init->command_names], ['msg-init'], 'Should have correct message name'; is Dist::Zilla::App::Command::msg_init->abstract, 'add language translation files to a distribution', 'Should have correct abstract'; is Dist::Zilla::App::Command::msg_init->usage_desc, '%c %o [ ...]', 'Should have correct usage description'; is_deeply [Dist::Zilla::App::Command::msg_init->opt_spec], [ [ 'xgettext|x=s' => 'location of xgttext utility' ], [ 'msginit|i=s' => 'location of msginit utility' ], [ 'encoding|e=s' => 'character encoding to be used' ], [ 'pot-file|pot|p=s' => 'pot file location' ], [ 'copyright-holder|c=s' => 'name of the copyright holder' ], [ 'bugs-email|b=s' => 'email address for reporting bugs' ], ], 'Option spec should be correct'; # Start with no lang specified. ok my $result = test_dzil('t/dist', [qw(msg-init)]), 'Call msg-init with no arg'; isnt $result->exit_code, 0, 'Should not have exited 0'; like $result->error, qr/Error: dzil msg-init takes one or more arguments/, 'Should have reason for the failure in the error message'; # Create a new language. ok $result = test_dzil('t/dist', [qw(msg-init ja.UTF-8)]), 'Init ja.UTF-8'; is $result->exit_code, 0, 'Should have exited 0' or diag @{ $result->log_messages }; ok((grep { /extracting gettext strings/ } @{ $result->log_messages }), 'Should have logged the POT file creation'); ok((grep { /ja[.]po/} @{ $result->log_messages }), 'File name should have been emitted from msginit'); my $po = file $result->tempdir, qw(source po ja.po); file_exists_ok $po, 'po/ja.po should now exist'; file_contents_like $po, qr/Language: ja/, 'Language name "ja" should be present'; file_contents_like $po, qr/\QLast-Translator: Automatically generated/, 'Should not have set translator'; file_contents_like $po, qr/^\Qmsgid "Hi"\E$/m, 'po/ja.pot should exist should have "Hi" msgid'; file_contents_like $po, qr/^\Qmsgid "Bye"\E$/m, 'po/ja.pot should exist should have "Bye" msgid'; # Try creating an existing language. ok $result = test_dzil('t/dist', [qw(msg-init fr)]), 'Init existing lang'; isnt $result->exit_code, 0, 'Should not have exited 0' or diag @{ $result->log_messages }; like $result->error, qr/po.fr[.]po already exists/, 'Should get error trying to create existing language'; # Now specify a bunch of options. my $pot = file qw(po org.imperia.simplecal.pot); ok $result = test_dzil('t/dist', [ 'msg-init', '--encoding' => 'Latin-1', '--pot-file' => $pot, '--copyright-holder' => 'Homer Simpson', '--bugs-email' => 'foo@bar.com', 'pt_BR' ]), 'Init with options'; is $result->exit_code, 0, 'Should have exited 0' or diag @{ $result->log_messages }; ok(!(grep { /extracting gettext strings/ } @{ $result->log_messages }), 'Should not have logged the POT file creation'); ok((grep { /pt_BR[.]po/} @{ $result->log_messages }), 'pt_BR name should have been emitted from msginit'); $po = file $result->tempdir, qw(source po pt_BR.po); file_exists_ok $po, 'po/pt_BR.po should now exist'; file_contents_like $po, qr/Language: pt_BR/, 'Language name "pt_BR" should be present'; file_contents_like $po, qr/\QLast-Translator: Automatically generated/, 'Should not have set translator'; file_contents_like $po, qr/^\Qmsgid "January"\E$/m, 'po/pt_BR.po should have "January" msgid'; file_contents_like $po, qr/^\Qmsgid "February"\E$/m, 'po/pt_BR.po should have "February" msgid'; # Now point to an invalid POT file. ok $result = test_dzil('t/dist', [qw(msg-init ja --pot-file nonesuch.pot)]), 'Init with nonexistent pot file'; isnt $result->exit_code, 0, 'Should not have exited 0' or diag @{ $result->log_messages }; like $result->error, qr/\QTemplate file nonesuch.pot does not exist/, 'Should get error trying to use nonexistent POT file'; # Fail with various other invalid values. for my $spec ( [ 'ja', 'bad xgettext', 'Cannot find "./nonexistent": Are the GNU gettext utilities installed?', '--xgettext' => './nonexistent' ], [ 'ja', 'bad msginit', 'Cannot find "./nonexistent": Are the GNU gettext utilities installed?', '--msginit' => './nonexistent' ], [ 'ja', 'bad encoding', '"L0LZ" is not a valid encoding', '--encoding' => 'L0LZ', ], [ 'FOO', 'bad lang', '"FOO" is not a valid language code', ], [ 'en-L0LZ', 'bad-country', '"L0LZ" is not a valid country code', ], [ 'en_L0LZ', 'bad_country', '"L0LZ" is not a valid country code', ], [ 'en-US.L0LZ', 'bad lang encoding', '"L0LZ" is not a valid encoding', ], ) { my $lang = shift @{$spec}; my $desc = shift @{$spec}; my $msg = shift @{$spec}; ok my $result = test_dzil( 't/dist', [ 'msg-init', $lang, @{ $spec } ] ), "Execute with $desc"; isnt $result->exit_code, 0, "Should not have exited 0 with $desc"; like $result->error, qr/\Q$msg/, "Should get $desc error"; } done_testing; msg_scan.t100644000767000024 540712244302227 20502 0ustar00davidstaff000000000000Dist-Zilla-LocaleTextDomain-0.87/t#!/usr/bin/perl -w use strict; use warnings; use Test::More 0.90; use Test::DZil; use IPC::Cmd 'can_run'; use Path::Class; use Test::File; use Test::File::Contents; use Dist::Zilla::App::Tester; use App::Cmd::Tester::CaptureExternal; BEGIN { # Make Tester to inherit CaptureExternal to prevent "Bad file descriptor". package Dist::Zilla::App::Tester; for (@Dist::Zilla::App::Tester::ISA) { $_ = 'App::Cmd::Tester::CaptureExternal' if $_ eq 'App::Cmd::Tester'; } } $ENV{DZIL_GLOBAL_CONFIG_ROOT} = 't'; plan skip_all => 'xgettext not found' unless can_run 'xgettext'; require_ok 'Dist::Zilla::App::Command::msg_scan'; my $result = test_dzil('t/dist', [qw(msg-scan)]); is $result->exit_code, 0, "dzil would have exited 0" or diag @{ $result->log_messages }; ok((grep { /extracting gettext strings into po.DZT-Sample[.]pot/ } @{ $result->log_messages }), 'Should have logged the POT file creation'); my $pot = file $result->tempdir, qw(source po DZT-Sample.pot); file_exists_ok $pot, 'po/DZT-Sample.pot should exist'; file_contents_like $pot, qr/\QCopyright (C) YEAR David E. Wheeler/m, 'po/DZT-Sample.pot should have copyright holder'; file_contents_like $pot, qr/^\Q"Project-Id-Version: DZT-Sample 1.2\n"\E$/m, 'po/DZT-Sample.pot should exist should have project ID and version'; file_contents_like $pot, qr/^\Q"Report-Msgid-Bugs-To: david\E[@]\Qjustatheory.com\n"\E$/m, 'po/DZT-Sample.pot should exist should have bugs email'; file_contents_like $pot, qr/^\Qmsgid "Hi"\E$/m, 'po/DZT-Sample.pot should exist should have "Hi" msgid'; file_contents_like $pot, qr/^\Qmsgid "Bye"\E$/m, 'po/DZT-Sample.pot should exist should have "Bye" msgid'; # Try setting some stuff. $result = test_dzil('t/dist', [qw( msg-scan --pot-file my.pot --bugs-email homer@example.com --copyright-holder ), 'Homer Simpson']); is $result->exit_code, 0, "dzil would have exited 0 again" or diag @{ $result->log_messages }; ok((grep { /extracting gettext strings into my[.]pot/ } @{ $result->log_messages }), 'Should have logged the mo.pot creation'); $pot = file $result->tempdir, qw(source my.pot); file_exists_ok $pot, 'my.pot should exist'; file_contents_like $pot, qr/\QCopyright (C) YEAR Homer Simpson/m, 'my.pot should have copyright holder'; file_contents_like $pot, qr/^\Q"Project-Id-Version: DZT-Sample 1.2\n"\E$/m, 'my.pot should exist should have project ID and version'; file_contents_like $pot, qr/^\Q"Report-Msgid-Bugs-To: homer\E[@]\Qexample.com\n"\E$/m, 'my.pot should exist should have custom bugs email'; file_contents_like $pot, qr/^\Qmsgid "Hi"\E$/m, 'my.pot should exist should have "Hi" msgid'; file_contents_like $pot, qr/^\Qmsgid "Bye"\E$/m, 'my.pot should exist should have "Bye" msgid'; done_testing; msg_merge.t100644000767000024 1272112244302227 20672 0ustar00davidstaff000000000000Dist-Zilla-LocaleTextDomain-0.87/t#!/usr/bin/perl -w use strict; use warnings; use Test::More 0.90; use Test::DZil; use IPC::Cmd 'can_run'; use Path::Class; use Test::File; use Test::File::Contents; use Dist::Zilla::App::Tester; use App::Cmd::Tester::CaptureExternal; BEGIN { # Make Tester to inherit CaptureExternal to prevent "Bad file descriptor". package Dist::Zilla::App::Tester; for (@Dist::Zilla::App::Tester::ISA) { $_ = 'App::Cmd::Tester::CaptureExternal' if $_ eq 'App::Cmd::Tester'; } } $ENV{DZIL_GLOBAL_CONFIG_ROOT} = 't'; my $ext = $^O eq 'MSWin32' ? '.exe' : ''; plan skip_all => 'msgmerge not found' unless can_run 'msgmerge' . $ext; plan skip_all => 'xgettext not found' unless can_run 'xgettext' . $ext; require_ok 'Dist::Zilla::App::Command::msg_merge'; is_deeply [Dist::Zilla::App::Command::msg_merge->command_names], ['msg-merge'], 'Should have correct message name'; is Dist::Zilla::App::Command::msg_merge->abstract, 'merge localization strings into translation catalogs', 'Should have correct abstract'; is Dist::Zilla::App::Command::msg_merge->usage_desc, '%c %o [ ...]', 'Should have correct usage description'; is_deeply [Dist::Zilla::App::Command::msg_merge->opt_spec], [ [ 'xgettext|x=s' => 'location of xgttext utility' ], [ 'msgmerge|m=s' => 'location of msgmerge utility' ], [ 'encoding|e=s' => 'character encoding to be used' ], [ 'pot-file|pot|p=s' => 'pot file location' ], [ 'copyright-holder|c=s' => 'name of the copyright holder' ], [ 'bugs-email|b=s' => 'email address for reporting bugs' ], [ 'backup!' => 'back up files before merging' ], ], 'Option spec should be correct'; # Start with no file specified. ok my $result = test_dzil('t/dist', [qw(msg-merge)]), 'Call msg-merge with no arg'; is $result->exit_code, 0, 'Should have exited 0' or diag @{ $result->log_messages }; ok got_msg(qr/extracting gettext strings/), 'Should have logged the POT file creation'; for my $lang (qw(de fr)) { my $po = file 'po', "$lang.po"; ok got_msg(qr/Merging gettext strings into $po/), "Should have message for merging $lang.po"; my $path = file $result->tempdir, qw(source po), "$lang.po"; file_exists_ok $path, "$po should exist"; file_not_exists_ok "$path~", "$po~ should not exist"; file_contents_like $path, qr/^\Qmsgid "Hi"\E$/m, qq{$po should have "Hi" msgid}; file_contents_like $path, qr/^\Q#~ msgid "May"\E$/m, qq{$po should have "May" msgid commented out}; } # Try specifying a file. my $de = file qw(po de.po); my $fr = file qw(po fr.po); ok $result = test_dzil('t/dist', [qw(msg-merge), $de, '--backup']), 'Call msg-merge with de.po arg'; is $result->exit_code, 0, 'Should have exited 0' or diag @{ $result->log_messages }; ok got_msg(qr/extracting gettext strings/), 'Should have logged the POT file creation'; # Make sure the German was merged. my $path = file $result->tempdir, 'source', $de; ok got_msg(qr/Merging gettext strings into $de/), "Should have message for merging $de"; file_exists_ok $path, "$de should exist"; file_exists_ok "$path~", "$de~ backup should not exist"; file_contents_like $path, qr/^\Qmsgid "Hi"\E$/m, qq{$de should have "Hi" msgid}; file_contents_like $path, qr/^\Q#~ msgid "May"\E$/m, qq{$de should have "May" msgid commented out}; # The French should not have been merged. $path = file $result->tempdir, 'source', $fr; ok !got_msg(qr/Merging gettext strings into $fr/), "Should not have message for merging $fr"; file_exists_ok $path, "$fr should exist"; file_not_exists_ok "$path~", "$fr~ should not exist"; file_contents_unlike $path, qr/^\Qmsgid "Hi"\E$/m, qq{$fr should not have "Hi" msgid}; file_contents_like $path, qr/^\Qmsgid "May"\E$/m, qq{$fr should have uncommented "May" msgid}; # Now specify a bunch of options. my $pot = file qw(po org.imperia.simplecal.pot); ok $result = test_dzil('t/dist', [ 'msg-merge', '--encoding' => 'Latin-1', '--pot-file' => file(qw(po org.imperia.simplecal.pot)), '--copyright-holder' => 'Homer Simpson', '--bugs-email' => 'foo@bar.com', '--backup', ]), 'Init with options'; is $result->exit_code, 0, 'Should have exited 0' or diag @{ $result->log_messages }; ok !got_msg(qr/extracting gettext strings/), 'Should not have logged the POT file creation'; for my $lang (qw(de fr)) { my $po = file 'po', "$lang.po"; ok got_msg(qr/Merging gettext strings into $po/), "Should have message for merging $lang.po"; my $path = file $result->tempdir, qw(source po), "$lang.po"; file_exists_ok $path, "$po should exist"; file_not_exists_ok "$path~", "$po~ should not exist (no changes)"; file_contents_unlike $path, qr/^\Qmsgid "Hi"\E$/m, qq{$po should not have "Hi" msgid}; file_contents_like $path, qr/^\Qmsgid "May"\E$/m, qq{$po should have "May" msgid}; } my $nonpot = file(qw(po nonexistent.top)); # Now try a non-existent POT file. ok $result = test_dzil('t/dist', [ 'msg-merge', '--pot-file' => $nonpot, ]), 'Execute with nonexistent POT file'; isnt $result->exit_code, 1, 'Should not have exited 0'; like $result->error, qr/^[[][^]]+[]]\s+Template file $nonpot does not exist\b/, 'Should have got error about nonexistent POT'; sub got_msg { my $regex = shift; return 1 if grep { /$regex/ } @{ $result->log_messages }; return 0; } #use Data::Dump; ddx $result->log_messages; done_testing; msg_compile.t100644000767000024 603712244302227 21206 0ustar00davidstaff000000000000Dist-Zilla-LocaleTextDomain-0.87/t#!/usr/bin/perl -w use strict; use warnings; use Test::More 0.90; use Test::DZil; use IPC::Cmd 'can_run'; use Path::Class; use Test::File; use Test::File::Contents; use Dist::Zilla::App::Tester; use App::Cmd::Tester::CaptureExternal; my $ext = $^O eq 'MSWin32' ? '.exe' : ''; plan skip_all => 'msgfmt not found' unless can_run 'msgfmt' . $ext; require_ok 'Dist::Zilla::App::Command::msg_compile'; is_deeply [Dist::Zilla::App::Command::msg_compile->command_names], ['msg-compile'], 'Should have correct message name'; is Dist::Zilla::App::Command::msg_compile->abstract, 'compile language translation files', 'Should have correct abstract'; is Dist::Zilla::App::Command::msg_compile->usage_desc, '%c %o [ ...]', 'Should have correct usage description'; is_deeply [Dist::Zilla::App::Command::msg_compile->opt_spec], [ [ 'dest-dir|d=s' => 'location in which to save complied files' ], [ 'msgfmt|m=s' => 'location of msgfmt utility' ], ], 'Option spec should be correct'; # Start with no options or args. my $result = test_dzil('t/dist', [qw(msg-compile)]); is $result->exit_code, 0, "dzil would have exited 0"; my $i = 0; for my $lang (qw(de fr)) { like $result->log_messages->[$i++], qr/(?:po.$lang[.]po: )?19/m, "$lang.po message should have been logged"; my $mo = file $result->tempdir, qw(source LocaleData), $lang, qw(LC_MESSAGES DZT-Sample.mo); my $t = $result->tempdir; file_exists_ok $mo, "$lang .mo file should now exist"; file_contents_like $mo, qr/^Language: $lang$/m, "Compiled $lang .mo should have language content"; } # Try creating just one language. my $de = file qw(po de.po); my $fr = file qw(po fr.po); $result = test_dzil('t/dist', [qw(msg-compile), $fr]); is $result->exit_code, 0, '"msg-compile fr" should have exited 0'; is @{ $result->log_messages }, 1, 'Should have only one log message'; like $result->log_messages->[0], qr/(?:po.fr[.]po: )?19/m, '... And it should be for the french file'; my $mo = file $result->tempdir, qw(source LocaleData fr LC_MESSAGES DZT-Sample.mo); file_exists_ok $mo, "fr .mo file should exist"; file_contents_like $mo, qr/^Language: fr$/m, "f r.mo should have language content"; $mo = file $result->tempdir, qw(source LocaleData de LC_MESSAGES DZT-Sample.mo); file_not_exists_ok $mo, 'de .mo file should not exist'; # Make sure it works when we specify the optoins. $result = test_dzil('t/dist', [qw(msg-compile --dest-dir foo --msgfmt), 'msgfmt' . $ext]); is $result->exit_code, 0, '"msg-compile" with options sould have exited 0'; $i = 0; for my $lang (qw(de fr)) { like $result->log_messages->[$i++], qr/(?:po.$lang[.]po: )?19/m, "$lang.po message should have been logged"; my $mo = file $result->tempdir, qw(source foo LocaleData), $lang, qw(LC_MESSAGES DZT-Sample.mo); my $t = $result->tempdir; file_exists_ok $mo, "$lang .mo file should now exist"; file_contents_like $mo, qr/^Language: $lang$/m, "Compiled $lang .mo should have language content"; } done_testing; dist000755000767000024 012244302227 17320 5ustar00davidstaff000000000000Dist-Zilla-LocaleTextDomain-0.87/tdist.ini100644000767000024 24412244302227 21104 0ustar00davidstaff000000000000Dist-Zilla-LocaleTextDomain-0.87/t/distname = DZT-Sample version = 1.2 license = Perl_5 author = David E. Wheeler copyright_holder = David E. Wheeler [@Basic] [LocaleTextDomain] po000755000767000024 012244302227 17736 5ustar00davidstaff000000000000Dist-Zilla-LocaleTextDomain-0.87/t/distde.po100644000767000024 344212244302227 21031 0ustar00davidstaff000000000000Dist-Zilla-LocaleTextDomain-0.87/t/dist/po# German translations for SimpleCal. # Copyright (C) 2003 Imperia AG, Guido Flohr . # This file is distributed under the same license as libintl-perl. # msgid "" msgstr "" "Project-Id-Version: SimpleCal\n" "Report-Msgid-Bugs-To: Edit the file PACAKGE to change this.\n" "POT-Creation-Date: 2012-08-31 16:04-0700\n" "PO-Revision-Date: 2003-07-28 04:06+0200\n" "Last-Translator: Guido Flohr \n" "Language-Team: German \n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=iso-8859-1\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: ../lib/SimpleCal.pm:26 msgid "January" msgstr "Januar" #: ../lib/SimpleCal.pm:28 msgid "February" msgstr "Februar" #: ../lib/SimpleCal.pm:30 msgid "March" msgstr "März" #: ../lib/SimpleCal.pm:32 msgid "April" msgstr "April" #: ../lib/SimpleCal.pm:34 msgid "May" msgstr "Mai" #: ../lib/SimpleCal.pm:36 msgid "June" msgstr "Juni" #: ../lib/SimpleCal.pm:38 msgid "July" msgstr "Juli" #: ../lib/SimpleCal.pm:40 msgid "August" msgstr "August" #: ../lib/SimpleCal.pm:42 msgid "September" msgstr "September" #: ../lib/SimpleCal.pm:44 msgid "October" msgstr "Oktober" #: ../lib/SimpleCal.pm:46 msgid "November" msgstr "November" #: ../lib/SimpleCal.pm:48 msgid "December" msgstr "Dezember" #: ../lib/SimpleCal.pm:70 msgid "Sun" msgstr "So" #: ../lib/SimpleCal.pm:71 msgid "Mon" msgstr "Mo" #: ../lib/SimpleCal.pm:72 msgid "Tue" msgstr "Di" #: ../lib/SimpleCal.pm:73 msgid "Wed" msgstr "Mi" #: ../lib/SimpleCal.pm:74 msgid "Thu" msgstr "Do" #: ../lib/SimpleCal.pm:75 msgid "Fri" msgstr "Fr" #: ../lib/SimpleCal.pm:76 msgid "Sat" msgstr "Sa" #~ msgid "Welcome to {package}!\n" #~ msgstr "Willkommen bei {package}!\n" #~ msgid "Bye.\n" #~ msgstr "Tschüss!\n" fr.po100644000767000024 337312244302227 21053 0ustar00davidstaff000000000000Dist-Zilla-LocaleTextDomain-0.87/t/dist/po# French translations for SimpleCal. # Copyright (C) 2003 Imperia AG, Guido Flohr . # This file is distributed under the same license as libintl-perl. # msgid "" msgstr "" "Project-Id-Version: SimpleCal\n" "Report-Msgid-Bugs-To: Edit the file PACAKGE to change this.\n" "POT-Creation-Date: 2012-08-31 16:04-0700\n" "PO-Revision-Date: 2003-07-28 04:07+0200\n" "Last-Translator: Guido Flohr \n" "Language-Team: French \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=iso-8859-1\n" "Content-Transfer-Encoding: 8bit\n" #: ../lib/SimpleCal.pm:26 msgid "January" msgstr "janvier" #: ../lib/SimpleCal.pm:28 msgid "February" msgstr "février" #: ../lib/SimpleCal.pm:30 msgid "March" msgstr "mars" #: ../lib/SimpleCal.pm:32 msgid "April" msgstr "avril" #: ../lib/SimpleCal.pm:34 msgid "May" msgstr "mai" #: ../lib/SimpleCal.pm:36 msgid "June" msgstr "juin" #: ../lib/SimpleCal.pm:38 msgid "July" msgstr "juillet" #: ../lib/SimpleCal.pm:40 msgid "August" msgstr "août" #: ../lib/SimpleCal.pm:42 msgid "September" msgstr "septembre" #: ../lib/SimpleCal.pm:44 msgid "October" msgstr "octobre" #: ../lib/SimpleCal.pm:46 msgid "November" msgstr "novembre" #: ../lib/SimpleCal.pm:48 msgid "December" msgstr "décembre" #: ../lib/SimpleCal.pm:70 msgid "Sun" msgstr "di" #: ../lib/SimpleCal.pm:71 msgid "Mon" msgstr "lu" #: ../lib/SimpleCal.pm:72 msgid "Tue" msgstr "ma" #: ../lib/SimpleCal.pm:73 msgid "Wed" msgstr "me" #: ../lib/SimpleCal.pm:74 msgid "Thu" msgstr "je" #: ../lib/SimpleCal.pm:75 msgid "Fri" msgstr "ve" #: ../lib/SimpleCal.pm:76 msgid "Sat" msgstr "sa" #~ msgid "Welcome to {package}!\n" #~ msgstr "Bienvenu à {package}!\n" #~ msgid "Bye.\n" #~ msgstr "À toute à l'heure!\n" DZT000755000767000024 012244302227 20527 5ustar00davidstaff000000000000Dist-Zilla-LocaleTextDomain-0.87/t/dist/libSample.pm100644000767000024 60712244302227 22431 0ustar00davidstaff000000000000Dist-Zilla-LocaleTextDomain-0.87/t/dist/lib/DZT # ABSTRACT: DZT test distribution package DZT::Sample; use strict; use warnings; our $VERSION = 1.2; sub hi { __ 'Hi'; } sub bye { __ 'Bye'; } =head1 Copyright and License This software is copyright (c) 2012-2013 by David E. Wheeler. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut release000755000767000024 012244302227 20165 5ustar00davidstaff000000000000Dist-Zilla-LocaleTextDomain-0.87/xtpod-spelling.t100644000767000024 46712244302227 23076 0ustar00davidstaff000000000000Dist-Zilla-LocaleTextDomain-0.87/xt/release#!/usr/bin/perl -w use strict; use Test::More; eval "use Test::Spelling"; plan skip_all => "Test::Spelling required for testing POD spelling" if $@; add_stopwords(); all_pod_files_spelling_ok(); __DATA__ gettext textdomain ShareDir localizable parseable Perlers colour workover UTF subdirectory Poedit Role000755000767000024 012244302227 21537 5ustar00davidstaff000000000000Dist-Zilla-LocaleTextDomain-0.87/lib/Dist/ZillaPotFile.pm100644000767000024 710512244302227 23602 0ustar00davidstaff000000000000Dist-Zilla-LocaleTextDomain-0.87/lib/Dist/Zilla/Rolepackage Dist::Zilla::Role::PotFile; # ABSTRACT: Something finds or creates a gettext language translation template file use Moose::Role; use strict; use warnings; use Path::Class; use namespace::autoclean; with 'Dist::Zilla::Role::PotWriter'; requires 'zilla'; our $VERSION = '0.87'; sub pot_file { my ( $self, %p ) = @_; my $dzil = $self->zilla; my $pot = $p{pot_file}; if ($pot) { $dzil->log_fatal("Template file $pot does not exist") unless -e $pot; return $pot; } # Look for a template in the default location used by `msg-scan`. my $plugin = $self->zilla->plugin_named('LocaleTextDomain') or $dzil->log_fatal('LocaleTextDomain plugin not found in dist.ini!'); $pot = file $plugin->lang_dir, $dzil->name . '.pot'; return $pot if -e $pot; # Create a temporary template file. require File::Temp; my $tmp = $self->{tmp} = File::Temp->new(SUFFIX => '.pot', OPEN => 0); $pot = file $tmp->filename; $self->log('extracting gettext strings'); $self->write_pot( to => $pot, xgettext => $p{xgettext}, encoding => $p{encoding}, copyright_holder => $p{copyright_holder}, bugs_email => $p{bugs_email}, ); return $self->{potfile} = $pot; } 1; __END__ =head1 Name Dist::Zilla::Plugin::PotFile - Something finds or creates a gettext language translation template file =head1 Synopsis with 'Dist::Zilla::Role::PotFile'; # ... sub execute { my $self = shift; my $pot_file = $self->pot_file(%params); } =head1 Description This role provides a utility method for finding or creating a L-style language translation template. =head2 Instance Methods =head3 C $self->pot_file(%params); Finds or creates a temporary L-style language translation file. It works in this order: =over =item * If the C parameter is passed a value and the named file exists, it will be returned. =item * If the file stored in the language directory, as specified for the L plugin|Dist::Zilla::Plugin::LocaleTextDomain>, with the name of the distribution and ending in F<.pot>, it will be returned. This is the default location for a template file created by the L|Dist::Zilla::App::Command::msg_scan> command. =item * The sources will be scanned for localizable strings and a temporary template file created. This file will automatically be deleted at program exit. =back The supported parameters are: =over =item C A path to an existing translation template file. If this file does not exist, an exception will be thrown. =item C Path to the C application. Defaults to just C (C on Windows), which should work if it's in your path. =item C Encoding to assume when scanning for localizable strings. Defaults to C. =item C The name of the translation copyright holder. Defaults to the copyright holder configured for L. =item C Email address for reporting translation bugs. Defaults to the email address of the first author known to L, if available and parseable by L. =back =head1 Author David E. Wheeler =head1 Copyright and License This software is copyright (c) 2012-2013 by David E. Wheeler. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut PotWriter.pm100644000767000024 1043712244302227 24221 0ustar00davidstaff000000000000Dist-Zilla-LocaleTextDomain-0.87/lib/Dist/Zilla/Rolepackage Dist::Zilla::Role::PotWriter; # ABSTRACT: Something that writes gettext language translation template file use Moose::Role; use strict; use warnings; use File::Path qw(make_path); use IPC::Run3; use namespace::autoclean; our $VERSION = '0.87'; sub files_to_scan { my $self = shift; my $dzil = $self->zilla; $dzil->chrome->logger->mute; $_->gather_files for @{ $dzil->plugins_with(-FileGatherer) }; $dzil->chrome->logger->unmute; # XXX Consider replacing with a LocaleTextDomain-specific file finder? return grep { /[.]pm\z/ } map { $_->name } @{ $dzil->files }; } sub write_pot { my ($self, %p) = @_; my $dzil = $self->zilla; my $pot = $p{to} or $dzil->log_fatal('Missing required "to" parameter to write_pot()'); my $verb = -e $pot ? 'update' : 'create'; # Make sure the directory exists. make_path $pot->parent->stringify unless -d $pot->parent; # Need to do this before calling other methods, as they need the # files loaded to find various information. my @files = $self->files_to_scan; my $email = $p{bugs_email} || do { if (my $author = $dzil->authors->[0]) { require Email::Address; my ($addr) = Email::Address->parse($author); $addr->address if $addr; } } || ''; my $log = sub { $dzil->log(@_) }; run3 [ $p{xgettext} || 'xgettext' . ($^O eq 'MSWin32' ? '.exe' : ''), '--from-code=' . ($p{encoding} || 'UTF-8'), '--add-comments=TRANSLATORS:', '--package-name=' . ($p{package} || $dzil->name), '--package-version=' . ($p{version} || $dzil->version || 'VERSION'), '--copyright-holder=' . ($p{copyright_holder} || $dzil->copyright_holder), ($email ? '--msgid-bugs-address=' . $email : ()), '--keyword', '--keyword=\'$__\'}', '--keyword=__', '--keyword=__x', '--keyword=__n:1,2', '--keyword=__nx:1,2', '--keyword=__xn:1,2', '--keyword=__p:1c,2', '--keyword=__np:1c,2,3', '--keyword=__npx:1c,2,3', '--keyword=N__', '--keyword=N__n:1,2', '--keyword=N__p:1c,2', '--keyword=N__np:1c,2,3', '--keyword=%__', '--language=perl', '--output=' . $pot, @files, ], undef, $log, $log; $dzil->log_fatal("Cannot $verb $pot") if $?; } requires 'zilla'; 1; __END__ =head1 Name Dist::Zilla::Plugin::PotWriter - Something that writes gettext language translation template file =head1 Synopsis with 'Dist::Zilla::Role::PotWriter'; # ... sub execute { my $self = shift; $self->write_pot(%params); } =head1 Description This role provides a utility method for generating a L-style language translation template. =head2 Instance Methods =head3 C $self->write_pot(%params); Creates or updates a L-style language translation file. The supported parameters are: =over =item C L object representing the file to write to. Required. =item C Array reference listing the files to scan. Defaults to all F<*.pm> files gathered by L. =item C Path to the C application. Defaults to just C (C on Windows), which should work if it's in your path. =item C Encoding to assume when scanning for localizable strings. Defaults to C. =item C The name of the localization package. Defaults to the distribution name as configured for L. =item C The version of the package. Defaults to the version as configured for L. =item C The name of the translation copyright holder. Defaults to the copyright holder configured for L. =item C Email address for reporting translation bugs. Defaults to the email address of the first author known to L, if available and parseable by L. =back =head1 Author David E. Wheeler =head1 Copyright and License This software is copyright (c) 2012-2013 by David E. Wheeler. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Zilla000755000767000024 012244302227 20636 5ustar00davidstaff000000000000Dist-Zilla-LocaleTextDomain-0.87/lib/DistLocaleTextDomain.pm100644000767000024 3072312244302227 24555 0ustar00davidstaff000000000000Dist-Zilla-LocaleTextDomain-0.87/lib/Dist/Zilla# ABSTRACT: Tools for managing Locale::TextDomain language catalogs package Dist::Zilla::LocaleTextDomain; use v5.8.5; our $VERSION = '0.87'; 1; __END__ =head1 Name Dist::Zilla::LocaleTextDomain - Tools for managing Locale::TextDomain language catalogs =head1 Synopsis In F: [ShareDir] [LocaleTextDomain] textdomain = My-App share_dir = share Scan localizable messages from your Perl libraries into a language template file, F: dzil msg-scan Initialize language translation files: dzil msg-init fr de.UTF-8 Merge changes to localizable messages into existing translation files: dzil msg-merge Compile translation files into message catalogs for testing: dzil msg-compile --dest-dir . fr de.UTF-8 Binary message catalogs are automatically added to your distribution by the C and C commands: dzil build dzil release =head1 Description L provides a nice interface for localizing your Perl applications. The tools for managing translations, however, is a bit arcane. Fortunately, you can just use this plugin and get all the tools you need to scan your Perl libraries for localizable strings, create a language template, and initialize translation files and keep them up-to-date. All this is assuming that your system has the L utilities installed. =head1 The Details I put off learning how to use L for quite a while because, while the L tools are great for translators, the tools for the developer were a little more opaque, especially for Perlers used to L. But I put in the effort while hacking L. As I had hoped, using it in my code was easy. Using it for my distribution was harder, so I decided to write Dist::Zilla::LocaleTextDomain to make life simpler for developers who manage their distributions with L. What follows is a quick tutorial on using L and managing its translation files with Dist::Zilla::LocaleTextDomain. =head1 This is my domain First thing to do is to start using L in your code. Load it into each module with the name of your distribution, as set by the C attribute in your F file. For example, if your F looks something like this: name = My-GreatApp author = Homer Simpson license = Perl_5 Then, in you Perl libraries, load L like this: use Locale::TextDomain qw(My-GreatApp); use Locale::Messages qw(bind_textdomain_filter); use Encode; $ENV{OUTPUT_CHARSET} = 'UTF-8'; bind_textdomain_filter 'My-GreatApp' => \&Encode::decode_utf8; L uses the string we pass to it to find localization catalogs, so naturally Dist::Zilla::LocaleTextDomain will use it to put those catalogs in the right place. It's also a best practice to coerce Locale::TextDomain to return character strings, rather than bytes, by setting the C<$OUTPUT_CHARSET> environment variable to "UTF-8" and then binding a filter to decode the resulting strings into Perl character strings. This makes it easier to work with such strings in our application. Just be sure to encode them before outputting them! Okay, so it's loaded, how do you use it? The documentation of the L is quite comprehensive, and I think you'll find it pretty simple once you get used to it. For example, simple strings are denoted with C<__>: say __ 'Hello'; If you need to specify variables, use C<__x>: say __x( 'You selected the color {color}', color => $color ); Need to deal with plurals? Use C<__n> say __n( 'One file has been deleted', 'All files have been deleted', $num_files, ); And then you can mix variables with plurals with C<__nx>: say __nx( 'One file has been deleted.', '{count} files have been deleted.'", $num_files, count => $num_files, ); Pretty simple, right? Get to know these functions, and just make it a habit to use them in user-visible messages in your code. Even if you never expect to translate those messages, just by doing this you make it easier for someone else to come along and start translating for you. =head2 The setup Now you're localizing your code. Great! What's next? Officially, nothing. If you never do anything else, your code will always emit the messages as written. You can ship it and things will work just as if you had never done any localization. But what's the fun in that? Let's set things up so that translation catalogs will be built and distributed once they're written. Add these lines to your F: [ShareDir] [LocaleTextDomain] There are actually quite a few attributes you can set here to tell the plugin where to find language files and where to put them. For example, if you used a domain different from your distribution name, e.g., use Locale::TextDomain 'com.example.My-GreatApp'; Then you would need to set the C attribute so that the C does the right thing with the language files: [LocaleTextDomain] textdomain = com.example.My-GreatApp Consult the L configuration docs|Dist::Zilla::Plugin::LocaleTextDomain/Configuration> for details on all available attributes. B<(Special note until L is merged: set the C attribute to C instead of the default value, C. If you use L, you will also need a subclass to do the right thing with the catalog files; see L for details.)> What does including the plugin do? Mostly nothing. You might see this line from C, though: [LocaleTextDomain] Skipping language compilation: directory po does not exist Now at least you know it was looking for something to compile for distribution. Let's give it something to find. =head2 Initialize languages To add translation files, use the L|Dist::Zilla::App::Command::msg_init> command: > dzil msg-init de Created po/de.po. At this point, the L utilities will need to be installed and visible in your path, or else you'll get errors. This command scans all of the Perl modules gathered by Dist::Zilla and initializes a German translation file, named F. This file is now ready for your German-speaking public to start translating. Check it into your source code repository so they can find it. Create as many language files as you like: > dzil msg-init fr ja.JIS en_US.UTF-8 Created po/fr.po. Created po/ja.po. Created po/en_US.po. As you can see, each language results in the generation of the appropriate file in the F directory, sans encoding (i.e., no F<.UTF-8> in the C file name). Now let your translators go wild with all the languages they speak, as well as the regional dialects. (Don't forget to colour your code with C translations!) Once you have translations and they're committed to your repository, when you build your distribution, the language files will automatically be compiled into binary catalogs. You'll see this line output from C: [LocaleTextDomain] Compiling language files in po po/fr.po: 10 translated messages, 1 fuzzy translation, 0 untranslated messages. po/ja.po: 10 translated messages, 1 fuzzy translation, 0 untranslated messages. po/en_US.po: 10 translated messages, 1 fuzzy translation, 0 untranslated messages. You'll then find the catalogs in the shared directory of your distribution: > find My-GreatApp-0.01/share -type f My-GreatApp-0.01/share/LocaleData/de/LC_MESSAGES/App-Sqitch.mo My-GreatApp-0.01/share/LocaleData/en_US/LC_MESSAGES/App-Sqitch.mo My-GreatApp-0.01/share/LocaleData/ja/LC_MESSAGES/App-Sqitch.mo These binary catalogs will be installed as part of the distribution just where C can find them. Here's an optional tweak: add this line to your C: ^po/ This prevents the F directory and its contents from being included in the distribution. Sure, you can include them if you like, but they're not required for the running of your app; the generated binary catalog files are all you need. Might as well leave out the translation files. =head2 But I'm a Translator Not a developer, but want to translate a project? I've written this special section just for you. Translating your language is relatively straight-forward. First, make sure that the translation file is up-to-date. Say you're translating into French; use the L|Dist::Zilla::App::Command::msg_merge> command to update the translation file: > dzil msg-merge po/fr.po [LocaleTextDomain] Merging gettext strings into po/fr.po If you get an error about it not existing, use the L|Dist::Zilla::App::Command::msg_init> command to create it: > dzil msg-init fr [LocaleTextDomain] Created po/fr.po. Now edit F. You can use a tool such as L or L to make it easier. As you work, you can use the L|Dist::Zilla::App::Command::msg_compile> command to make sure that you're translation file is error-free: > dzil msg-compile po/fr.po [LocaleTextDomain] po/fr.po: 195 translated messages. This command compiles a catalog file into the F subdirectory of the current directory (or directory of your choice via the C<--dest-dir> option), so that you can even run the app with the compiled catalog to make sure things look the way you think they ought to. Just set the C<$LANGUAGE> environment variable and make sure that Perl includes the current directory in its path, something like: LANGUAGE=fr perl -I . bin/myapp.pl Consult the developer for help with this bit, as how apps run varies between projects. =head2 Mergers and acquisitions You've got translation files and helpful translators given them a workover. What happens when you change your code, add new messages, or modify existing ones? The translation files need to periodically be updated with those changes, so that your translators can deal with them. We got you covered with the L|Dist::Zilla::App::Command::msg_merge> command: > dzil msg-merge extracting gettext strings Merging gettext strings into po/de.po Merging gettext strings into po/en_US.po Merging gettext strings into po/ja.po This will scan your module files again and update all of the translation files with any changes. Old messages will be commented-out and new ones added. Just commit the changes to your repository and notify the translation army that they've got more work to do. If for some reason you need to update only a subset of language files, you can simply list them on the command-line: > dzil msg-merge po/de.po po/en_US.po Merging gettext strings into po/de.po Merging gettext strings into po/en_US.po =head2 What's the scan, man Both the C and C commands depend on a translation template file to create and merge language files. Thus far, this has been invisible: they will create a temporary template file to do their work, and then delete it when they're done. However, it's common to also store the template file in your repository and to manage it directly, rather than implicitly. If you'd like to do this, the L|Dist::Zilla::App::Command::msg_scan> command will scan the Perl module files gathered by Dist::Zilla and make it for you: > dzil msg-scan gettext strings into po/My-GreatApp.pot The resulting F<.pot> file will then be used by C and C rather than scanning your code all over again. This actually then makes C a two-step process: You need to update the template before merging. Updating the template is done by exactly the same command, C: > dzil msg-scan extracting gettext strings into po/My-GreatApp.pot > dzil msg-merge Merging gettext strings into po/de.po Merging gettext strings into po/en_US.po Merging gettext strings into po/ja.po =head2 Ship It! And that's all there is to it. Go forth and localize and internationalize your Perl apps! =head1 Author David E. Wheeler =head1 Copyright and License This software is copyright (c) 2012-2013 by David E. Wheeler. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut org.imperia.simplecal.pot100644000767000024 307312244302227 25011 0ustar00davidstaff000000000000Dist-Zilla-LocaleTextDomain-0.87/t/dist/po# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Edit the file PACKAGE to change this. # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: Edit the file PACAKGE to change this.\n" "POT-Creation-Date: 2012-08-31 16:04-0700\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" #: ../lib/SimpleCal.pm:26 msgid "January" msgstr "" #: ../lib/SimpleCal.pm:28 msgid "February" msgstr "" #: ../lib/SimpleCal.pm:30 msgid "March" msgstr "" #: ../lib/SimpleCal.pm:32 msgid "April" msgstr "" #: ../lib/SimpleCal.pm:34 msgid "May" msgstr "" #: ../lib/SimpleCal.pm:36 msgid "June" msgstr "" #: ../lib/SimpleCal.pm:38 msgid "July" msgstr "" #: ../lib/SimpleCal.pm:40 msgid "August" msgstr "" #: ../lib/SimpleCal.pm:42 msgid "September" msgstr "" #: ../lib/SimpleCal.pm:44 msgid "October" msgstr "" #: ../lib/SimpleCal.pm:46 msgid "November" msgstr "" #: ../lib/SimpleCal.pm:48 msgid "December" msgstr "" #: ../lib/SimpleCal.pm:70 msgid "Sun" msgstr "" #: ../lib/SimpleCal.pm:71 msgid "Mon" msgstr "" #: ../lib/SimpleCal.pm:72 msgid "Tue" msgstr "" #: ../lib/SimpleCal.pm:73 msgid "Wed" msgstr "" #: ../lib/SimpleCal.pm:74 msgid "Thu" msgstr "" #: ../lib/SimpleCal.pm:75 msgid "Fri" msgstr "" #: ../lib/SimpleCal.pm:76 msgid "Sat" msgstr "" Command000755000767000024 012244302227 22734 5ustar00davidstaff000000000000Dist-Zilla-LocaleTextDomain-0.87/lib/Dist/Zilla/Appmsg_init.pm100644000767000024 1340612244302227 25267 0ustar00davidstaff000000000000Dist-Zilla-LocaleTextDomain-0.87/lib/Dist/Zilla/App/Commandpackage Dist::Zilla::App::Command::msg_init; # ABSTRACT: Add language translation catalogs to a dist use Dist::Zilla::App -command; use strict; use warnings; use Path::Class; use Dist::Zilla::Plugin::LocaleTextDomain; use Moose; use IPC::Run3; use File::Find::Rule; use namespace::autoclean; our $VERSION = '0.87'; with 'Dist::Zilla::Role::PotFile'; sub command_names { qw(msg-init) } sub abstract { 'add language translation files to a distribution' } sub usage_desc { '%c %o [ ...]' } sub opt_spec { return ( [ 'xgettext|x=s' => 'location of xgttext utility' ], [ 'msginit|i=s' => 'location of msginit utility' ], [ 'encoding|e=s' => 'character encoding to be used' ], [ 'pot-file|pot|p=s' => 'pot file location' ], [ 'copyright-holder|c=s' => 'name of the copyright holder' ], [ 'bugs-email|b=s' => 'email address for reporting bugs' ], ); } sub validate_args { my ($self, $opt, $args) = @_; require IPC::Cmd; my $xget = $opt->{xgettext} ||= 'xgettext' . ($^O eq 'MSWin32' ? '.exe' : ''); $self->zilla->log_fatal( qq{Cannot find "$xget": Are the GNU gettext utilities installed?} ) unless IPC::Cmd::can_run($xget); my $init = $opt->{msginit} ||= 'msginit' . ($^O eq 'MSWin32' ? '.exe' : ''); $self->zilla->log_fatal( qq{Cannot find "$init": Are the GNU gettext utilities installed?} ) unless IPC::Cmd::can_run($init); if (my $enc = $opt->{encoding}) { require Encode; $self->zilla->log_fatal(qq{"$enc" is not a valid encoding}) unless Encode::find_encoding($enc); } else { $opt->{encoding} = 'UTF-8'; } $self->usage_error('dzil msg-init takes one or more arguments') if @{ $args } < 1; require Locale::Language; require Locale::Country; for my $lang ( @{ $args } ) { my ($name, $enc) = split /[.]/, $lang, 2; if ($enc) { require Encode; $self->zilla->log_fatal(qq{"$enc" is not a valid encoding}) unless Encode::find_encoding($enc); } my ($lang, $country) = split /[-_]/, $name; $self->zilla->log_fatal(qq{"$lang" is not a valid language code}) unless Locale::Language::code2language($lang); if ($country) { $self->zilla->log_fatal(qq{"$country" is not a valid country code}) unless Locale::Country::code2country($country); } } } sub execute { my ($self, $opt, $args) = @_; my $dzil = $self->zilla; my $plugin = $self->zilla->plugin_named('LocaleTextDomain') or $dzil->log_fatal('LocaleTextDomain plugin not found in dist.ini!'); my $lang_dir = $plugin->lang_dir; my $lang_ext = '.' . $plugin->lang_file_suffix; my $pot_file = $self->pot_file( %{ $opt } ); my @cmd = ( $opt->{msginit}, '--input=' . $pot_file, '--no-translator', ); my $log = sub { $plugin->log(@_) }; for my $lang (@{ $args }) { # Strip off encoding. (my $name = $lang) =~ s/[.].+$//; my $dest = $lang_dir->file( $name . $lang_ext ); $plugin->log_fatal("$dest already exists") if -e $dest; run3 ( [@cmd, "--locale=$lang", '--output-file=' . $dest], undef, $log, $log ); $plugin->log_fatal("Cannot generate $dest") if $?; } } 1; __END__ =head1 Name Dist::Zilla::App::Command::msg_init - Add language translation catalogs to a dist =head1 Synopsis In F: [LocaleTextDomain] textdomain = My-App lang_dir = po On the command line: dzil msg-init fr =head1 Description This command initializes and adds one or more L-style language catalogs to your distribution. It can either use an existing template file (such as can be created with the L|Dist::Zilla::App::Command::msg_init> command) or will scan your distribution's Perl modules directly to create the catalog. It relies on the settings from the L plugin|Dist::Zilla::Plugin::LocaleTextDomain> for its settings, and requires that the GNU gettext utilities be available. =head2 Options =head3 C<--xgettext> The location of the C program, which is distributed with L. Defaults to just C (or C on Windows), which should work if it's in your path. Not used if C<--pot-file> points to an existing template file. =head3 C<--msginit> The location of the C program, which is distributed with L. Defaults to just C (or C on Windows), which should work if it's in your path. =head3 C<--encoding> The encoding to assume the Perl modules are encoded in. Defaults to C. =head3 C<--pot-file> The name of the template file to use to generate the message catalogs. If not specified, C<$lang_dir/$textdomain.pot> will be used if it exists. Otherwise, a temporary template file will be created by scanning the Perl sources. =head3 C<--copyright-holder> Name of the application copyright holder. Defaults to the copyright holder defined in F. Used only to generate a temporary template file. =head3 C<--bugs-email> Email address to which translation bug reports should be sent. Defaults to the email address of the first distribution author, if available. Used only to generate a temporary template file. =head1 Author David E. Wheeler =head1 Copyright and License This software is copyright (c) 2012-2013 by David E. Wheeler. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut msg_scan.pm100644000767000024 716212244302227 25232 0ustar00davidstaff000000000000Dist-Zilla-LocaleTextDomain-0.87/lib/Dist/Zilla/App/Commandpackage Dist::Zilla::App::Command::msg_scan; # ABSTRACT: Collect localization strings into a translation template use Dist::Zilla::App -command; use strict; use warnings; use Moose; use namespace::autoclean; our $VERSION = '0.87'; with 'Dist::Zilla::Role::PotWriter'; sub command_names { qw(msg-scan) } sub abstract { 'scan localization strings into a translation template' } sub usage_desc { '%c %o' } sub opt_spec { return ( [ 'xgettext|x=s' => 'location of xgttext utility' ], [ 'encoding|e=s' => 'charcter encoding to be used' ], [ 'pot-file|pot|p=s' => 'pot file location' ], [ 'copyright-holder|c=s' => 'name of the copyright holder' ], [ 'bugs-email|b=s' => 'email address for reporting bugs' ], ); } sub validate_args { my ($self, $opt, $args) = @_; require IPC::Cmd; my $xget = $opt->{xgettext} ||= 'xgettext' . ($^O eq 'MSWin32' ? '.exe' : ''); $self->zilla->log_fatal( qq{Cannot find "$xget": Are the GNU gettext utilities installed?} ) unless IPC::Cmd::can_run($xget); if (my $enc = $opt->{encoding}) { require Encode; $self->zilla->log_fatal(qq{"$enc" is not a valid encoding}) unless Encode::find_encoding($enc); } else { $opt->{encoding} = 'UTF-8'; } } sub execute { my ( $self, $opt ) = @_; require Path::Class; my $dzil = $self->zilla; my $plugin = $self->zilla->plugin_named('LocaleTextDomain') or $dzil->log_fatal('LocaleTextDomain plugin not found in dist.ini!'); my $pot_file = Path::Class::file($opt->{pot_file} || ( $plugin->lang_dir, $self->zilla->name . '.pot' )); $plugin->log("extracting gettext strings into $pot_file"); $self->write_pot( to => $pot_file, xgettext => $opt->{xgettext}, encoding => $opt->{encoding}, copyright_holder => $opt->{copyright_holder}, bugs_email => $opt->{bugs_email}, ); } 1; __END__ =head1 Name Dist::Zilla::App::Command::msg_scan - Scan localization strings into a translation template =head1 Synopsis In F: [LocaleTextDomain] textdomain = My-App lang_dir = po On the command line: dzil msg-scan =head1 Description This command scans your distribution's Perl modules and creates or updates a L-style language translation template. It relies on the settings from the L plugin|Dist::Zilla::Plugin::LocaleTextDomain> for its settings, and requires that the GNU gettext utilities be available. =head2 Options =head3 C<--xgettext> The location of the C program, which is distributed with L. Defaults to just C, which should work if it's in your path. =head3 C<--encoding> The encoding to assume the Perl modules are encoded in. Defaults to C. =head3 C<--pot-file> The name of the template file to write to. Defaults to C<$lang_dir/$textdomain.pot>. =head3 C<--copyright-holder> Name of the application copyright holder. Defaults to the copyright holder defined in F. =head3 C<--bugs-email> Email address to which translation bug reports should be sent. Defaults to the email address of the first distribution author, if available. =head1 Author David E. Wheeler =head1 Copyright and License This software is copyright (c) 2012-2013 by David E. Wheeler. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Zilla000755000767000024 012244302227 20641 5ustar00davidstaff000000000000Dist-Zilla-LocaleTextDomain-0.87/inc/DistLocaleTextDomainBuild.pm100644000767000024 205412244302227 25514 0ustar00davidstaff000000000000Dist-Zilla-LocaleTextDomain-0.87/inc/Dist/Zillapackage Dist::Zilla::LocaleTextDomainBuild; use strict; use warnings; use Module::Build 0.35; use base 'Module::Build'; sub new { my $self = shift->SUPER::new(@_); my $gettext = 'gettext' . ($^O eq 'MSWin32' ? '.exe' : ''); my $version = $self->_backticks($gettext, '--version'); if (!$version || $version =~ /--version/) { print STDERR '#' x 64, "\n", "# Cannot find compatible GNU gettext in PATH. Download it from:\n", "# http://www.gnu.org/software/gettext/gettext.html\n", "# Aborting build.\n", '#' x 64, "\n\n"; exit 255; } my ($maj, $min, $patch) = $version =~ /(\d+)[.](\d+)(?:[.](\d+))?$/ms; if (!($maj || $min) || !($maj > 0 || $min >= 17)) { print STDERR '#' x 64, "\n", "# Need GNU gettext v0.17.0 or higher; found $maj.$min.$patch in PATH.\n", "# Download latest from:\n", "# http://www.gnu.org/software/gettext/gettext.html\n", "# Aborting build.\n", '#' x 64, "\n\n"; exit 255; } return $self; } 1; msg_merge.pm100644000767000024 1277212244302227 25430 0ustar00davidstaff000000000000Dist-Zilla-LocaleTextDomain-0.87/lib/Dist/Zilla/App/Commandpackage Dist::Zilla::App::Command::msg_merge; # ABSTRACT: Merge localization strings into translation catalogs use Dist::Zilla::App -command; use strict; use warnings; use Path::Class; use Dist::Zilla::Plugin::LocaleTextDomain; use File::Basename; use Moose; use IPC::Run3; use File::Copy; use File::Find::Rule; use namespace::autoclean; our $VERSION = '0.87'; with 'Dist::Zilla::Role::PotFile'; sub command_names { qw(msg-merge) } sub abstract { 'merge localization strings into translation catalogs' } sub usage_desc { '%c %o [ ...]' } sub opt_spec { return ( [ 'xgettext|x=s' => 'location of xgttext utility' ], [ 'msgmerge|m=s' => 'location of msgmerge utility' ], [ 'encoding|e=s' => 'character encoding to be used' ], [ 'pot-file|pot|p=s' => 'pot file location' ], [ 'copyright-holder|c=s' => 'name of the copyright holder' ], [ 'bugs-email|b=s' => 'email address for reporting bugs' ], [ 'backup!' => 'back up files before merging' ], ); } sub validate_args { my ($self, $opt, $args) = @_; require IPC::Cmd; my $xget = $opt->{xgettext} ||= 'xgettext' . ($^O eq 'MSWin32' ? '.exe' : ''); $self->zilla->log_fatal( qq{Cannot find "$xget": Are the GNU gettext utilities installed?} ) unless IPC::Cmd::can_run($xget); my $merge = $opt->{msgmerge} ||= 'msgmerge' . ($^O eq 'MSWin32' ? '.exe' : ''); $self->zilla->log_fatal( qq{Cannot find "$merge": Are the GNU gettext utilities installed?} ) unless IPC::Cmd::can_run($merge); if (my $enc = $opt->{encoding}) { require Encode; $self->zilla->log_fatal(qq{"$enc" is not a valid encoding}) unless Encode::find_encoding($enc); } else { $opt->{encoding} = 'UTF-8'; } } sub _po_files { my ( $self, $plugin ) = @_; require File::Find::Rule; my $lang_ext = $plugin->lang_file_suffix; return File::Find::Rule->file->name("*.$lang_ext")->in($plugin->lang_dir); } sub execute { my ($self, $opt, $args) = @_; my $dzil = $self->zilla; my $plugin = $self->zilla->plugin_named('LocaleTextDomain') or $dzil->log_fatal('LocaleTextDomain plugin not found in dist.ini!'); my $lang_dir = $plugin->lang_dir; my $lang_ext = '.' . $plugin->lang_file_suffix; my $pot_file = $self->pot_file( %{ $opt } ); my @pos = @{ $args } ? @{ $args } : $self->_po_files( $plugin ); $plugin->log_fatal("No language catalog files found") unless @pos; my @cmd = ( $opt->{msgmerge}, qw(--quiet --update), '--backup=' . ($opt->{backup} ? 'simple' : 'none'), ); my $log = sub { $plugin->log(@_) }; for my $file (@pos) { $plugin->log("Merging gettext strings into $file"); run3 [@cmd, $file, $pot_file], undef, $log, $log; $plugin->log_fatal("Cannot merge into $file") if $?; } } 1; __END__ =head1 Name Dist::Zilla::App::Command::msg_merge - Merge localization strings into translation catalogs =head1 Synopsis In F: [LocaleTextDomain] textdomain = My-App lang_dir = po On the command line: dzil msg-init fr de Later, after adding or modifying localizations strings: dzil msg-merge =head1 Description This command merges localization strings into translation catalog files. The strings are merged from a L-style language translation template, which can be created by the L command|Dist::Zilla::App::Command::msg_merge>. If no template file is found or can be found, the Perl sources will be scanned to create a temporary one. This command relies on the settings from the L plugin|Dist::Zilla::Plugin::LocaleTextDomain> for its settings, and requires that the GNU gettext utilities be available. =head2 Options =head3 C<--xgettext> The location of the C program, which is distributed with L. Defaults to just C (or C on Windows), which should work if it's in your path. Not used if C<--pot-file> is specified. =head3 C<--msgmerge> The location of the C program, which is distributed with L. Defaults to just C (or C on Windows), which should work if it's in your path. =head3 C<--encoding> The encoding to assume the Perl modules are encoded in. Defaults to C. =head3 C<--pot-file> The name of the template file to use to merge the message catalogs. If not specified, C<$lang_dir/$textdomain.pot> will be used if it exists. Otherwise, a temporary template file will be created by scanning the Perl sources. =head3 C<--copyright-holder> Name of the application copyright holder. Defaults to the copyright holder defined in F. Used only to generate a temporary template file. =head3 C<--bugs-email> Email address to which translation bug reports should be sent. Defaults to the email address of the first distribution author, if available. Used only to generate a temporary template file. =head3 C<--backup> Back up each language file before merging it. The backup files will have the suffix F<~>. =head1 Author David E. Wheeler =head1 Copyright and License This software is copyright (c) 2012-2013 by David E. Wheeler. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut msg_compile.pm100644000767000024 1011512244302227 25746 0ustar00davidstaff000000000000Dist-Zilla-LocaleTextDomain-0.87/lib/Dist/Zilla/App/Commandpackage Dist::Zilla::App::Command::msg_compile; # ABSTRACT: Compile language translation files use Dist::Zilla::App -command; use strict; use warnings; use Path::Class; use Dist::Zilla::Plugin::LocaleTextDomain; use IPC::Run3; use File::Path 2.07 qw(make_path); use namespace::autoclean; our $VERSION = '0.87'; sub command_names { qw(msg-compile) } sub abstract { 'compile language translation files' } sub usage_desc { '%c %o [ ...]' } sub opt_spec { return ( [ 'dest-dir|d=s' => 'location in which to save complied files' ], [ 'msgfmt|m=s' => 'location of msgfmt utility' ], ); } sub validate_args { my ($self, $opt, $args) = @_; if ( my $msgfmt = $opt->{msgfmt} ) { require IPC::Cmd; $self->zilla->log_fatal( qq{Cannot find "$msgfmt": Are the GNU gettext utilities installed?} ) unless IPC::Cmd::can_run($msgfmt); } if ( my $dir = $opt->{dest_dir} ) { $opt->{dest_dir} = dir $dir; } } sub _po_files { my ( $self, $plugin ) = @_; require File::Find::Rule; my $lang_ext = $plugin->lang_file_suffix; return File::Find::Rule->file->name("*.$lang_ext")->in($plugin->lang_dir); } sub execute { my ($self, $opt, $args) = @_; my $plugin = $self->zilla->plugin_named('LocaleTextDomain') or $self->zilla->log_fatal('LocaleTextDomain plugin not found in dist.ini!'); my $lang_dir = $plugin->lang_dir; my $dest_dir = $opt->{dest_dir} || dir; my $lang_ext = $plugin->lang_file_suffix; my $bin_ext = $plugin->bin_file_suffix; my $txt_dom = $plugin->textdomain; my $log = sub { $plugin->log(@_) }; my @cmd = ( $opt->{msgfmt} || $plugin->msgfmt, '--check', '--statistics', '--verbose', '--output-file', ); my @pos = @{ $args } ? @{ $args } : $self->_po_files( $plugin ); $plugin->log_fatal("No language catalog files found") unless @pos; make_path $dest_dir->stringify; for my $file (@pos) { $file = file $file; ( my $lang = $file->basename ) =~ s{[.][^.]*$}{}; my $dest = file $dest_dir, 'LocaleData', $lang, 'LC_MESSAGES', "$txt_dom.$bin_ext"; make_path $dest->dir->stringify; run3 [@cmd, $dest, $file], undef, $log, $log; $plugin->log_fatal("Cannot compile $file") if $?; } } __END__ =head1 Name Dist::Zilla::App::Command::msg_compile - Compile language translation files =head1 Synopsis In F: [LocaleTextDomain] textdomain = My-App lang_dir = po On the command line: dzil msg-compile po/fr.po =head1 Description This command compiles one or more L-style language catalogs into a directory in your distribution. The idea is to be able to easily compile a catalog while working on it, to see how it works, without having to compile the entire distribution. It can either compile the specified translation files, or will scan the language directory to compile all the translation files in the distribution. It relies on the settings from the L plugin|Dist::Zilla::Plugin::LocaleTextDomain> for its settings, and requires that the GNU gettext utilities be available. =head2 Options =head3 C<-d> =head3 C<--dest-dir> Destination directory for the compiled catalogs. The compiled language files will be stored in this directory as F. As long as the specified directory is in Perl's C<@INC>, Locale::TextDomain should be able to find them there. Defaults to the current directory. =head3 C<--msgfmt> The location of the C program, which is distributed with L. Defaults to just C (or C on Windows), which should work if it's in your path. =head1 Author David E. Wheeler =head1 Copyright and License This software is copyright (c) 2012-2013 by David E. Wheeler. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Plugin000755000767000024 012244302227 22074 5ustar00davidstaff000000000000Dist-Zilla-LocaleTextDomain-0.87/lib/Dist/ZillaLocaleTextDomain.pm100644000767000024 1670012244302227 26012 0ustar00davidstaff000000000000Dist-Zilla-LocaleTextDomain-0.87/lib/Dist/Zilla/Plugin# ABSTRACT: Compile Local::TextDomain language files package Dist::Zilla::Plugin::LocaleTextDomain; use strict; use warnings; use Moose; use Path::Class; use IPC::Cmd qw(can_run); use IPC::Run3; use MooseX::Types::Path::Class; use Moose::Util::TypeConstraints; use Dist::Zilla::File::FromCode; use File::Path 2.07 qw(make_path remove_tree); use namespace::autoclean; with 'Dist::Zilla::Role::FileGatherer'; our $VERSION = '0.87'; use IPC::Cmd qw(can_run); BEGIN { subtype 'App', as 'Str', where { !!can_run $_ }, message { qq{Cannot find "$_": Are the GNU gettext utilities installed?}; }; } has textdomain => ( is => 'ro', isa => 'Str', lazy => 1, default => sub { shift->zilla->name }, ); has lang_dir => ( is => 'ro', isa => 'Path::Class::Dir', coerce => 1, default => sub { dir 'po' }, ); has share_dir => ( is => 'ro', isa => 'Path::Class::Dir', coerce => 1, default => sub { dir 'share' }, ); has _tmp_dir => ( is => 'ro', isa => 'Path::Class::Dir', default => sub { require File::Temp; dir File::Temp::tempdir(CLEANUP => 1); }, ); has msgfmt => ( is => 'ro', isa => 'App', default => sub { 'msgfmt' } ); has lang_file_suffix => ( is => 'ro', isa => 'Str', default => 'po', ); has bin_file_suffix => ( is => 'ro', isa => 'Str', default => 'mo', ); has language => ( is => 'ro', isa => 'ArrayRef[Str]', lazy => 1, default => sub { my $self = shift; my $lang_dir = $self->lang_dir; my $lang_ext = $self->lang_file_suffix; my @langs; for my $file ( $lang_dir->children ) { next if $file->is_dir || $file !~ /[.]$lang_ext\z/; (my $lang = $file->basename) =~ s/[.]$lang_ext\z//; push @langs => $lang; } return \@langs; }, ); sub mvp_multivalue_args { return qw(language) } sub gather_files { my ($self, $arg) = @_; my $dzil = $self->zilla; my $lang_dir = $self->lang_dir; my $lang_ext = $self->lang_file_suffix; my $bin_ext = $self->bin_file_suffix; my $txt_dom = $self->textdomain; my $shr_dir = $self->share_dir; my $tmp_dir = $self->_tmp_dir; my @cmd = ( $self->msgfmt, '--check', '--statistics', '--verbose', '--output-file', ); unless (-d $lang_dir) { $self->log( "Skipping language compilation: directory $lang_dir does not exist" ); return; } $self->log("Compiling language files in $lang_dir"); make_path $tmp_dir->stringify; my @encoding_params = Dist::Zilla::File::FromCode->VERSION >= 5.0 ? ( encoding => 'bytes', code_return_type => 'bytes', ) : (); for my $lang (@{ $self->language }) { my $file = $lang_dir->file("$lang.$lang_ext"); my $dest = file $shr_dir, 'LocaleData', $lang, 'LC_MESSAGES', "$txt_dom.$bin_ext"; my $temp = $tmp_dir->file("$lang.$bin_ext"); my $log = sub { $self->log(@_) }; $self->add_file( Dist::Zilla::File::FromCode->new({ @encoding_params, name => $dest->stringify, code => sub { run3 [@cmd, $temp, $file], undef, $log, $log; $dzil->log_fatal("Cannot compile $file") if $?; scalar $temp->slurp(iomode => '<:raw'); }, }) ); } } __PACKAGE__->meta->make_immutable; 1; __END__ =head1 Name Dist::Zilla::Plugin::LocaleTextDomain - Compile Local::TextDomain language files =head1 Synopsis In F: [ShareDir] [LocaleTextDomain] textdomain = My-App lang_dir = po share_dir = share =head1 Description This plugin compiles GNU gettext language files and adds them into the distribution for use by L. This is useful if your distribution maintains gettext language files in a directory, with each file named for a language. The plugin uses C to compile each file and then adds it to the distribution's F directory. You can then use the L to make sure it gets installed in the right place. =head2 Installation Ideally, L would search for language files in the shared directory for your distribution, as defined by L. A L has been submitted to add this support, after which the example code from the L should just work. Until that time, however, L searches for files in Perl's C<@INC> directories, in which case the use of the L will not work. You will have to install the compiled language files into the F directory in your distribution. To do so, simply set the C attribute to "lib": [LocaleTextDomain] textdomain = My-App lang_dir = po share_dir = lib If your distribution uses L to do the installation, the files will now be installed in the proper location. If it relies on L, you will have to do a bit of additional work. First, subclass Module::Build by creating F with this code: package Module::Build::MyApp; use parent 'Module::Build'; sub new { my ( $class, %p ) = @_; my $self = $class->SUPER::new(%p); $self->add_build_element('mo'); return $self; } Then tell L to use the subclass via the C attribute in F: [ModuleBuild] mb_class = Module::Build::MyApp Now the F<.mo> files will be installed where L can find them. =head2 Configuration Configuration attributes settable in F to change the plugin behavior. =head3 C The textdomain to use for your language files, as defined by the L documentation. This should be the same value declared in each use of Locale::TextDomain in your module. For example, if such lines look like this: use LocaleText::Domain qw(com.example.myApp); Then set it to such in your F [LocaleTextDomain] textdomain = com.example.myApp Defaults to the name of your distribution, which is the value that L recommends you use. =head3 C The directory containing your language files. Defaults to F. =head3 C The name of the distribution directory into which compiled language files should be added. Defaults to C. =head3 C The location of the C program, which is distributed with L. Defaults to just C, which should work if it's in your path. =head3 C A language to be compiled. May be specified more than once. If not specified, the default will be the list of files in C ending in C. =head3 C Suffix used in the language file names. These are the files your translators maintain in your repository. Defaults to C. =head3 C Suffix to use for the compiled language file. Defaults to C. =head1 Author David E. Wheeler =head1 Copyright and License This software is copyright (c) 2012-2013 by David E. Wheeler. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut