openstreetmap-website/script/locale/diff
2009-06-22 16:32:58 +00:00

144 lines
3 KiB
Perl
Executable file

#!/usr/bin/env perl
use strict;
use warnings;
use YAML::Syck qw(LoadFile);
use Test::Differences;
use Pod::Usage ();
use Getopt::Long ();
=head1 NAME
locale-diff - Compare two YAML files and print how their datastructures differ
=head1 SYNOPSIS
diff en.yml is.yml
# --keys is the default
diff --keys en.yml is.yml
# --untranslated-values compares prints keys whose values don't differ
diff --untranslated-values en.yml is.yml
=head1 DESCRIPTION
This utility prints the differences between two YAML files using
L<Test::Differences>. The purpose of it is to diff the files is
F<config/locales> to find out what keys need to be added to the
translated files when F<en.yml> changes.
=head1 OPTIONS
=over
=item -h, --help
Print this help message.
=item --keys
Show the hash keys that differ between the two files, useful merging
new entries from F<en.yml> to a local file.
=item --untranslated-values
Show keys whose values are either exactly the same between the two
files, or don't exist in the target file (the latter file specified).
This helps to find untranslated values.
=back
=head1 AUTHOR
E<AElig>var ArnfjE<ouml>rE<eth> Bjarmason <avar@f-prot.com>
=cut
# Get the command-line options
Getopt::Long::Parser->new(
config => [ qw< bundling no_ignore_case no_require_order pass_through > ],
)->getoptions(
'h|help' => \my $help,
'keys' => \my $keys,
'untranslated-values' => \my $untranslated_values,
) or help();
# On --help
help() if $help;
# If we're not given two .yml files
help() if @ARGV != 2 or (!-f $ARGV[0] or !-f $ARGV[1]);
my ($from, $to) = @ARGV;
my $from_data = LoadFile($from);
my $to_data = LoadFile($to);
my $from_parsed = { iterate($from_data->{basename($from)}) };
my $to_parsed = { iterate($to_data->{basename($to)}) };
# Since this used to be the default, support that...
if ((not $untranslated_values and not $keys) or $keys)
{
print_key_differences();
}
elsif ($untranslated_values)
{
my @untranslated = untranslated_keys($from_parsed, $to_parsed);
print $_, "\n" for @untranslated;
}
exit 0;
sub print_key_differences
{
# Hack around Test::Differences wanting a Test::* module loaded
$INC{"Test.pm"} = 1;
sub Test::ok { print shift }
# Diff the tree
eq_or_diff([ sort keys %$from_parsed ], [ sort keys %$to_parsed ]);
}
sub untranslated_keys
{
my ($from_parsed, $to_parsed) = @_;
sort grep { not exists $to_parsed->{$_} or $from_parsed->{$_} eq $to_parsed->{$_} } keys %$from_parsed;
}
sub iterate
{
my ($hash, @path) = @_;
my @ret;
while (my ($k, $v) = each %$hash)
{
if (ref $v eq 'HASH')
{
push @ret => iterate($v, @path, $k);
}
else
{
push @ret => join(".",@path, $k), $v;
}
}
return @ret;
}
sub basename
{
my $name = shift;
$name =~ s[\..*?$][];
$name;
}
sub help
{
my %arg = @_;
Pod::Usage::pod2usage(
-verbose => $arg{ verbose },
-exitval => $arg{ exitval } || 0,
);
}