При использовании интернационализации в своем проекте на spring через MessageSource вы можете столкнуться с неприятной ситуацией: в коде используется какое-то сообщение, но в property файле его нет. К примеру, удалили, забыли закоммитить или допустили опечатку (как намеренно сделал я в примере далее). В этом случае сборка не завалится и только после запуска вы получите блокирующий баг из-за исключения вида:
org.springframework.context.NoSuchMessageException: No message found under code ‘сard.Dialog.windowTtle‘ for locale ‘ru’. — опечатка в слове Title.
Я решил написать скрипт на perl, который сделал частью процесса сборки — сразу после скачивания (check out) из репозитория. Таким образом я уменьшаю цену нахождения и исправления ошибки — чем раньше, тем лучше. Скрипт возвращает 1 в случае найденных ошибок или 0, когда в исходниках все правильно. В случае ошибок вы получите такой отчет:
field.lengthExceeded not found in messages_ru.properties
field.lengthExceeded not found in messages_en.properties
card.fullFileName not found in messages_en.properties
Вот его код:
#!/usr/bin/perl use strict; use warnings; use File::Find; my @usages = (); my @ru_messages = (); my @en_messages = (); sub process_java_file { return unless -f ; my $filename = $File::Find::name; open my $info, $filename or die "Could not open $filename: $!"; while( my $line = <$info>) { while($line =~ /messageSource\.\s*getMessage\s*\(\s*"([^"]*)/g) { unless ($1 ~~ @usages) { push @usages, $1; } } } } sub process_message_file { my $filename = $_[0]; my @list = (); open my $message_file, $filename or die "Could not open $filename: $!"; while( my $line = <$message_file>) { while($line =~ /([^=\s]*)\s*=/g) { push @list, $1; } } @list } my $source_base="/some/path"; my $messages_en="$source_base/path/to/messages_en.properties"; my $messages_ru="$source_base/path/to/messages_ru.properties"; my @DIRLIST = ("$source_base/path/to/java/sources"); find(\&process_java_file, @DIRLIST); @en_messages = &process_message_file($messages_en); @ru_messages = &process_message_file($messages_ru); my $res = 0; foreach my $used_message (@usages){ unless ($used_message ~~ @ru_messages){ print "$used_message not found in messages_ru.properties\n"; $res = 1; } unless ($used_message ~~ @en_messages){ print "$used_message not found in messages_en.properties\n"; $res = 1; } } exit $res; |
Пара замечаний. Ожидается, что использование сообщений будет в вызовах вида messageSource.getMessage(«key»), допустимы пробелы. В цикле, который создает отчет, можно сделать подсчет в переменной $res числа ошибок или менять ее значение на 1 только если там еще 0.