2014-09-02 3 views
10

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

Однако системный администратор недавно обновил 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. 

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

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

ответ

5

Update: в течение некоторого времени, 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 в своем домашнем каталоге.

+1

+1 для упоминания резервной копии :-) и ['perlbrew'] (http://www.perlbrew.pl). –

+2

+1 для упоминания: 'используется установкой :: lib sucks' :) – jm666

+1

+1 @ jm666 для юмора –

1

Если вы используете 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 

(NB: это не ошибка проверки - записей в 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, вы можете easily copy and reinstall все ваши модули от одной версии perl до другой.

HTH!

+0

@ikegami спасибо за изменения :-) –

+1

Я сделал то же самое с моим, но я вернул его. Нам нужен «archname» изначально установленного Perl ('x86_64-linux'), а не установленный в данный момент (который может быть другим). Я оставлю все, что вы хотите, чтобы ваш код был. – ikegami

+0

uh oh это означает, что я должен помнить разницу между '/ usr/local/lib/perl5/site_perl/5.16/mach /' и '$ HOME/perl5/lib/perl5/amd64-freebsd-thread-multi'. .. :-) Так или иначе, я вижу проблему с курицей/яйцом в отношении обновлений, которые могут произойти. Мне очень нравится ваш простой подход к резервному копированию/переустановке с помощью 'mv perl5 {, 16}' и 'find' –

Смежные вопросы