Обновите все модули, установленные local::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 для его обработки).

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

2 ответа

Решение

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

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

Удаление (или переименование каталога, чтобы у вас была резервная копия) - самое простое решение. Вы можете узнать, что вы установили, ища .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 в вашей домашней директории.

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

list_modules | cpanm -L ~/perl5 --reinstall

где list_modules это скрипт, который кормит имена модулей в cpanm (есть также -f возможность cpanm). Этот скрипт может быть похож на @ikegami выше или что-то вроде cpan-outdated (который только перечисляет устаревшие модули однако). Вот хакерская попытка, которая в основном работала для меня в последнее время (примечание: ikegami, вероятно, лучше) - когда это не удается или скрипт дает 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 запустить "не системный" ("локальный") perl, Конечно, вы можете сделать это и до сих пор local::lib, carton и т. д. управлять каталогом или прикладным стеком модулей.

1). Другой способ сделать обновление - это использовать perllocal сгенерировать список ваших установленных на данный момент модулей (NB Я не совсем уверен, если perllocal.pod хранится в надежном / полезном состоянии). [Редактировать: На самом деле perllocal хранит историю ваших установленных модулей, а не список установленных в данный момент. Вы захотите отфильтровать это, или вы в конечном итоге переустановите всю серию версий модулей одна за другой!). Этот узел perlmonks показывает, как очистить ваш 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

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

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

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

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

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

НТН!

Другие вопросы по тегам