From b3fa49c38792421b72d2ebb348ca6d48a5fd670a Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Thu, 18 Feb 2010 12:06:32 -0600 Subject: initial implementation --- dist.ini | 4 ++ lib/Locale/POFileManager.pm | 108 +++++++++++++++++++++++++++++++++++++++ lib/Locale/POFileManager/File.pm | 67 ++++++++++++++++++++++++ t/000-load.t | 11 ++-- 4 files changed, 186 insertions(+), 4 deletions(-) create mode 100644 lib/Locale/POFileManager/File.pm diff --git a/dist.ini b/dist.ini index b680b24..6465afd 100644 --- a/dist.ini +++ b/dist.ini @@ -8,3 +8,7 @@ abstract = [@Classic] [Prereq] +List::MoreUtils = 0 +Locale::PO = 0 +Moose = 0.90 +MooseX::Types::Path::Class = 0 diff --git a/lib/Locale/POFileManager.pm b/lib/Locale/POFileManager.pm index b774807..5924754 100644 --- a/lib/Locale/POFileManager.pm +++ b/lib/Locale/POFileManager.pm @@ -1,5 +1,6 @@ package Locale::POFileManager; use Moose; +use MooseX::Types::Path::Class qw(Dir); =head1 NAME @@ -13,6 +14,113 @@ Locale::POFileManager - =cut +has base_dir => ( + is => 'ro', + isa => Dir, + required => 1, + coerce => 1, +); + +has files => ( + traits => [qw(Array)], + isa => 'ArrayRef[Locale::POFileManager::File]', + lazy => 1, + builder => '_build_files', + init_arg => undef, + handles => { + files => 'elements', + first_file => 'first', + _add_file => 'push', + }, +); + +sub _build_files { + my $self = shift; + my $dir = $self->base_dir; + + require Locale::POFileManager::File; + + my @files; + for my $file ($dir->children) { + next unless $file->is_file; + next unless $file->stringify =~ /\.po$/; + push @files, Locale::POFileManager::File->new(file => $file); + } + + return \@files; +} + +has canonical_language => ( + is => 'ro', + isa => 'Str', + required => 1, # TODO: make this not required at some point? +); + +sub BUILD { + my $self = shift; + + confess("Canonical language file must exist") + unless $self->has_language($self->canonical_language); +} + +sub has_language { + my $self = shift; + my ($lang) = @_; + + for my $file ($self->files) { + $file->stringify =~ m{.*/(.*)\.po}; + return 1 if $1 eq $lang; + } + + return; +} + +sub add_language { + my $self = shift; + my ($lang) = @_; + + return if $self->has_language($lang); + + my $file = $self->base_dir->file("$lang.po"); + confess("Can't overwrite existing language file for $lang") + if -e $file->stringify; + + my $pofile = Locale::POFileManager::File->new(file => $file); + $pofile->save; + + $self->_add_file($pofile); +} + +sub canonical_language_file { + my $self = shift; + my $lang = $self->canonical_language; + + return $self->first_file(sub { + $_->file->stringify =~ /\Q$lang\E\.po$/; + }); +} + +sub find_missing { + my $self = shift; + my $canon_file = $self->canonical_language_file; + + my %ret; + for my $file ($self->files) { + $ret{$file->file->stringify} = $file->find_missing_from($canon_file); + } + + return %ret; +} + +sub add_stubs { + my $self = shift; + my $canon_file = $self->canonical_language_file; + + for my $file ($self->files) { + $file->add_stubs_from($canon_file); + } +} + __PACKAGE__->meta->make_immutable; no Moose; diff --git a/lib/Locale/POFileManager/File.pm b/lib/Locale/POFileManager/File.pm new file mode 100644 index 0000000..b3aa78b --- /dev/null +++ b/lib/Locale/POFileManager/File.pm @@ -0,0 +1,67 @@ +package Locale::POFileManager::File; +use Moose; + +use MooseX::Types::Path::Class qw(File); +use List::MoreUtils qw(any); +use Locale::PO; + +has file => ( + is => 'ro', + isa => File, + coerce => 1, + required => 1, +); + +has entries => ( + traits => [qw(Array)], + isa => 'ArrayRef[Locale::PO]', + lazy => 1, + builder => '_build_entries', + init_arg => undef, + handles => { + entries => 'elements', + add_entry => 'push', + msgids => [ map => sub { $_->msgid } ], + }, +); + +sub _build_entries { + my $self = shift; + my $filename = $self->file->stringify; + + return (-r $filename) ? Locale::PO->load_file_asarray($filename) : []; +} + +sub save { + my $self = shift; + + Locale::PO->save_file_fromarray($self->file->stringify, [$self->entries]); +} + +sub find_missing_from { + my $self = shift; + my ($other) = @_; + $other = blessed($self)->new(file => $other) unless blessed($other); + + my @ret; + my @msgids = $self->msgids; + for my $msgid ($other->msgids) { + push @ret, $msgid unless any { $msgid eq $_ } @msgids; + } + + return @ret; +} + +sub add_stubs_from { + my $self = shift; + my ($other) = @_; + + $self->add_entry($_) for map { Locale::PO->new(-msgid => $_) } + $self->find_missing_from($other); + $self->save; +} + +__PACKAGE__->meta->make_immutable; +no Moose; + +1; diff --git a/t/000-load.t b/t/000-load.t index 881e304..c530ad0 100644 --- a/t/000-load.t +++ b/t/000-load.t @@ -1,8 +1,11 @@ #!/usr/bin/env perl use strict; use warnings; -use Test::More tests => 1; +use Test::More; -package Foo; -::use_ok('Locale::POFileManager') - or ::BAIL_OUT("couldn't load Locale::POFileManager"); +use_ok('Locale::POFileManager') + or BAIL_OUT("couldn't load Locale::POFileManager"); +use_ok('Locale::POFileManager::File') + or BAIL_OUT("couldn't load Locale::POFileManager::File"); + +done_testing; -- cgit v1.2.3