]> git.openstreetmap.org Git - rails.git/blob - script/locale/diff
fdaf4a4fbea7bb1c1986915c7d6b5b9dada95264
[rails.git] / script / locale / diff
1 #!/usr/bin/env perl
2 use strict;
3 use warnings;
4 use YAML::Syck qw(LoadFile);
5 use Test::Differences;
6 use Pod::Usage ();
7 use Getopt::Long ();
8
9 =head1 NAME
10
11 locale-diff - Compare two YAML files and print how their datastructures differ
12
13 =head1 SYNOPSIS
14
15     locale-diff en.yml is.yml
16     locale-diff en.yml is.yml | grep '*'
17
18 =head1 DESCRIPTION
19
20 This utility prints the differences between two YAML files using
21 L<Test::Differences>. The purpose of it is to diff the files is
22 F<config/locales> to find out what keys need to be added to the
23 translated files when F<en.yml> changes.
24
25 =head1 OPTIONS
26
27 =over
28
29 =item -h, --help
30
31 Print this help message.
32
33 =item --diff-keys
34
35 Show the hash keys that differ between the two files, useful merging
36 new entries from F<en.yml> to a local file.
37
38 =item --untranslated-values
39
40 Show keys whose values are either exactly the same between the two
41 files, or don't exist in the target file (the latter file specified).
42
43 This helps to find untranslated values.
44
45 =back
46
47 =head1 AUTHOR
48
49 E<AElig>var ArnfjE<ouml>rE<eth> Bjarmason <avar@f-prot.com>
50
51 =cut
52
53 # Get the command-line options
54 Getopt::Long::Parser->new(
55     config => [ qw< bundling no_ignore_case no_require_order pass_through > ],
56 )->getoptions(
57     'h|help' => \my $help,
58     'diff-keys' => \my $diff_keys,
59     'undiff-values' => \my $undiff_values,
60 ) or help();
61
62 # On --help
63 help() if $help;
64
65 # If we're not given two .yml files
66 help() if @ARGV != 2 or (!-f $ARGV[0] or !-f $ARGV[1]);
67
68 my ($from, $to) = @ARGV;
69
70 my $from_data = LoadFile($from);
71 my $to_data   = LoadFile($to);
72
73 my $from_parsed = { iterate($from_data->{basename($from)}) };
74 my $to_parsed = { iterate($to_data->{basename($to)}) };
75
76 # Since this used to be the default, support that...
77 if ((not $undiff_values and not $diff_keys) or $diff_keys)
78 {
79     print_key_differences();
80 }
81 elsif ($undiff_values)
82 {
83     my @untranslated = untranslated_keys($from_parsed, $to_parsed);
84
85     print $_, "\n" for @untranslated;
86 }
87
88 exit 0;
89
90 sub print_key_differences
91 {
92     # Hack around Test::Differences wanting a Test::* module loaded
93     $INC{"Test.pm"} = 1;
94     sub Test::ok { print shift }
95
96     # Diff the tree
97     eq_or_diff([ sort keys %$from_parsed ], [ sort keys %$to_parsed ]);
98 }
99
100 sub untranslated_keys
101 {
102     my ($from_parsed, $to_parsed) = @_;
103     sort grep { not exists $to_parsed->{$_} or $from_parsed->{$_} eq $to_parsed->{$_} } keys %$from_parsed;
104 }
105
106 sub iterate
107 {
108     my ($hash, @path) = @_;
109     my @ret;
110         
111     while (my ($k, $v) = each %$hash)
112     {
113         if (ref $v eq 'HASH')
114         {
115              push @ret => iterate($v, @path, $k);
116         }
117         else
118         {
119             push @ret => join(".",@path, $k), $v;
120         }
121     }
122
123     return @ret;
124 }
125
126 sub basename
127 {
128     my $name = shift;
129     $name =~ s[\..*?$][];
130     $name;
131 }
132
133 sub help
134 {
135     my %arg = @_;
136
137     Pod::Usage::pod2usage(
138         -verbose => $arg{ verbose },
139         -exitval => $arg{ exitval } || 0,
140     );
141 }