Обновите все модули, установленные локальным:: lib

Я использую local:: lib для обработки установки модулей Perl на сервере, поэтому я могу получить правильные версии для некоторой разработки, не загрязняя установку системы.

Однако системный администратор недавно обновил Perl с 5.16 до 5.18, и теперь я получаю ошибки, связанные с двоичными модулями, например.

perl -e 'use Scalar::Util'
Perl API version v5.16.0 of List::Util does not match v5.18.0 at /usr/lib64/perl5/5.18.2/XSLoader.pm line 92.
Compilation failed in require at /home/paul/perl5/lib/perl5/x86_64-linux/Scalar/Util.pm line 11.
Compilation failed in require at -e line 1.
BEGIN failed--compilation aborted at -e line 1.

Я понимаю, что могу исправить эту проблему, вынудив local:: lib перестраивать все свои модули, но я не могу найти что-либо в документации, которая подсказывает мне, как это сделать, или даже как получить список из всех модулей, которые были установлены с использованием local:: lib (если бы у меня было это в текстовом файле "один модуль в строке", я мог бы легко написать Bash script для его обработки).

Возможно ли это, или мне нужно удалить каталог ~/perl5 и переустановить все модули с нуля (возможно, некоторые из них, поскольку я не могу их запомнить)?

Ответ 1

Обновить. В течение некоторого времени INSTALL_BASE создала лучшую структуру каталогов, которая позволяет избежать этой проблемы для новых установок.

И вот почему соглашение perl Makefile.PL INSTALL_BASE=... (и соответствующее для Build.PL), используемое установкой:: lib sucks.

Удаление (или переименование каталога с резервным копированием) является самым простым решением. Вы можете узнать, что вы установили, ища файлы .pm.

cd ~
mv perl5{,16}
cd perl516/lib/perl5
find -name '*.pm' | xargs perl -MConfig -E'
   for (@ARGV) {
      s!^\./!!;
      s!^5\.\d+\.\d+/!!;
      s!^x86_64-linux/!!;
      s!^auto/!!;
      s!\.pm\z!!;
      s!/!::!g;
      say;
   }
' | xargs cpan

(Сделайте сухой пробег, первый - без задней | xargs cpan.)

Обратите внимание, что если вы не хотите быть на милости своих обновлений для администратора, вы можете использовать perlbrew, чтобы легко установить целую сборку Perl в вашем домашнем каталоге.

Ответ 2

Если вы используете cpanm, вы можете заставить его перестраивать модули в вашем local::lib месте с помощью переключателей -L и --reinstall:

list_modules | cpanm -L ~/perl5 --reinstall

где list_modules - это script, который передает имена модулей в cpanm (также опция -f на cpanm). Этот script может быть как @ikegami выше или что-то вроде cpan-outdated (в котором перечислены только устаревшие модули). Вот хакерская попытка, которая в основном работала для меня в последнее время (примечание: ikegami, вероятно, лучше) - когда он терпит неудачу или script дает cpanm имя модуля, которое оно не распознает, cpanm продолжает двигаться и, похоже, не разбивается ничего (но делать резервные копии):

cd $PERL_LOCAL_LIB_ROOT  
perl -MFile::Find -MConfig -E'
      find { 
        wanted => sub { 
                       $mod = $_ if /\.pm\z/; 
                       $mod =~ s/lib\/perl5\/auto\/.*//g;
                       $mod =~ s/lib\/perl5\/\Q$Config{archname}\E\/.*//g;
                       $mod =~ s/lib\/perl5\///g;
                       push @mods, $mod unless $mod =~ /^$/;
                      },no_chdir=>1 
           },"lib/perl5"; @modhash{@mods}=(); say for sort keys %modhash '

Изменяя, где и что File::Find находит с помощью wanted(), вы можете подать другой список модулей на cpanm. Было бы неплохо, если бы cpan или cpanm имели внутренний _method или -switch, который позволял вам принудительно восстановить local::lib установленные модули, которые используют XS. Есть ли такая вещь?

Это было cpanm, carton (и видя инструмент node.js npm в действии), что побудило меня сделать гораздо больше local::lib. Теперь CORE в комплекте "клиент CPAN", который поставляется с perl (cpan), кажется, становится более автоматическим и более простым в использовании. Мне очень нравится local::lib, поскольку он позволяет использовать систему perl, но управлять собственным стеком модулей без привилегий системного уровня. Однако проще управлять изменениями и обновлениями, если вы используете perlbrew для запуска "несистема" ( "local" ) perl. Конечно, вы можете сделать это , а все еще есть local::lib, carton и т.д. Управлять каталогом или конкретным стеком модулей.

1). Другой способ сделать обновление - использовать perllocal для создания списка ваших установленных модулей ( NB. Я не совсем уверен, что perllocal.pod хранится в надежном/полезном состоянии). [Изменить: Фактически perllocal хранит историю ваших установленных модулей, а не список установленных в настоящее время. Вы захотите отфильтровать это, иначе вы сможете переустановить всю серию версий модулей один за другим!). Этот perlmonks node показывает, как очистить ваш perllocal.pod: http://www.perlmonks.org/?node_id=483020. Я предпочитаю сохранить историю. ]

Чтобы выполнить синтаксический анализ perllocal.pod для ввода в cpanm, выполните поиск по файлу и сохраните совпадения в массиве, а затем разделите их на два, чтобы создать хэш из элементов массива (key,value,key,value). Более поздние установки и номера версий в файле ниже, поэтому вы можете создать хэш с именами модулей в качестве ключей и обновить значения более поздними записями:

 perl -ne 'push @arr, grep {defined}
 (/\A=head2.*:\s+C<Module>\s+L<(.*)\||.*C<VERSION:\s(.*)>\Z/msx); }{
 %h = map{ split/,/,$_,2 } @arr; print "$_\@$h{$_}\n" for keys %h' perllocal.pod

(NB: это не проверка ошибок - записи в perllocal.pod иногда отсутствуют VERSION данные и другие странности, поэтому будьте осторожны.)

2). Но этот метод бледнеет по сравнению с оболочкой script, указанной ilmari в # perl-help на IRC. Оно использует jq - утилита командной строки, которая вам действительно нужна (после этого вы захотите ее больше). Если вы использовали cpanm для установки своих модулей, он создал файлы install.json. Вы можете использовать это, чтобы сделать список для подачи на cpanm для переустановки текущего набора модулей:

 find ~/perl5/ -name install.json -exec jq '.name + "@" + .version' {} +

Очень быстро, очень просто, и вы можете объединить его с методом cpanm использования curl для самостоятельной установки, чтобы перестроить ваши модули.

3). Если вы используете perlbrew для управления установками perl, вы можете легко скопировать и переустановить все ваши модули из одной версии perl в другую.

НТН!