PERL 프로젝트를 배포하기 전에 CPAN 종속성을 결정하려면 어떻게해야합니까?

StackOverflow https://stackoverflow.com/questions/240704

문제

맞춤형 개발 프로젝트에서 발생했을 수있는 모든 CPAN 의존성을 찾는 데 좋은 접근 방식에 대한 제안이 있습니까? 현지 개발 환경은 라이브 환경과 거의 일치하지 않으며 점점 더 많은 프로젝트를 구축함에 따라 지역 설치 모듈 라이브러리를 구축하는 경향이 있습니다. 그런 다음 최신 프로젝트가 비 핵심 모듈에 대한 요구 사항이 있음을 반드시 알지는 안됩니다. 일반적으로 다른 그룹에 배치를 위해 전체 프로젝트를 포장 해야하는 요구 사항이 있으므로 (당사의 경우 운영 팀) 패키지에 어떤 모듈이 포함되어야하는지 아는 것이 중요합니다.

누구든지 문제에 대한 통찰력이 있습니까?

감사

베드로

도움이 되었습니까?

해결책

나는이 문제를 직접했다. 개발 :: 모드리스트 (제안대로 이 답변)는 역동적 인 접근 방식을 취합니다. 스크립트의 특정 실행 중에 실제로로드 된 모듈을보고합니다. 이렇게하면 어떤 방법 으로든로드 된 모듈을 포착하지만 조건부 요구 사항을 포착하지 못할 수 있습니다. 즉, 다음과 같은 코드가있는 경우 :

if ($some_condition) { require Some::Module }

그리고 $some_condition 거짓이되고 Devel::Modlist 나열되지 않습니다 Some::Module 요구 사항으로.

나는 사용하기로 결정했다 모듈 :: 추출물 대신에. 정적 분석을 수행하므로 항상 잡을 수 있습니다. Some::Module 위의 예에서. 반면에 코드에 대해서는 아무것도 할 수 없습니다.

my $module = "Other::Module";
eval "use $module;";

물론 두 가지 접근 방식을 모두 사용한 다음 두 목록을 결합 할 수 있습니다.

어쨌든, 여기에 내가 생각해 낸 해결책이 있습니다.

#! /usr/bin/perl
#---------------------------------------------------------------------
# Copyright 2008 Christopher J. Madsen <perl at cjmweb.net>
#
# This program is free software; you can redistribute it and/or modify
# it under the same terms as Perl itself.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See either the
# GNU General Public License or the Artistic License for more details.
#
# Recursively collect dependencies of Perl scripts
#---------------------------------------------------------------------

use strict;
use warnings;
use File::Spec ();
use Module::CoreList ();
use Module::ExtractUse ();

my %need;
my $core = $Module::CoreList::version{'5.008'};

# These modules have lots of dependencies.  I don't need to see them now.
my %noRecurse = map { $_ => 1 } qw(
  Log::Log4perl
  XML::Twig
);

foreach my $file (@ARGV) {
  findDeps($file);
}

foreach my $module (sort keys %need) {
  print "  $module\n";
}

#---------------------------------------------------------------------
sub findDeps
{
  my ($file) = @_;

  my $p = Module::ExtractUse->new;

  $p->extract_use($file);

  foreach my $module ($p->array) {
    next if exists $core->{$module};
    next if $module =~ /^5[._\d]+/; # Ignore "use MIN-PERL-VERSION"
    next if $module =~ /\$/;        # Run-time specified module

    if (++$need{$module} == 1 and not $noRecurse{$module}) {
      my $path = findModule($module);
      if ($path) { findDeps($path) }
      else       { warn "WARNING: Can't find $module\n" }
    } # end if first use of $module
  } # end foreach $module used
} # end findDeps

#---------------------------------------------------------------------
sub findModule
{
  my ($module) = @_;

  $module =~ s!::|\'!/!g;
  $module .= '.pm';

  foreach my $dir (@INC) {
    my $path = File::Spec->catfile($dir, $module);
    return $path if -f $path;
  }

  return;
} # end findModule

당신은 다음과 같이 실행합니다.

perl finddeps.pl scriptToCheck.pl otherScriptToCheck.pl

나열된 스크립트를 실행하는 데 필요한 모든 비 코어 모듈 목록을 인쇄합니다. (모듈을 방지하는 모듈로드로 멋진 트릭을하지 않는 한 :: 추출물을 보지 못하게하십시오.)

다른 팁

온라인 웹 서비스를 사용할 수 있습니다 deps.cpantesters.org 그것은 당신에게 많은 유용한 종속성 데이터를 제공 할 것입니다. CPAN의 모든 모듈에는 이미 의존성 사이트 (모듈 페이지의 오른쪽)에 대한 링크가 있습니다.

과거에 나는 사용했습니다 개발 :: 모드리스트 당신이 갈 수있게하는 것은 합리적으로 좋은 것입니다

perl -d:Modlist script.pl

필요한 모듈 목록을 얻으려면

모든 C/C ++ 응용 프로그램 (PC 기반 및 다양한 임베디드 프로젝트 모두)을위한 제조 기반 빌드 시스템이 있으며, 신선한 기계에서 최상위 빌드를 수행하고 모든 종속성이 장소 (수정 제어에 대한 도구 체인을 확인하십시오 : D), 현재 빌드 시스템에 MakeFile이없는 해석 된 언어에 대해서도 동일하게 수행하지 않는 것에 좌절했습니다.

나는 다음과 같은 대본을 쓰고 싶은 유혹이있다.

  • .pl 또는 .pm Extension이있는 파일의 개정 제어 저장소를 검색합니다.
  • 실행 perl -d:Modlist 그들에게 (감사합니다!)
  • 필요한 모듈 목록에 연결합니다
  • 마지막으로 설치된 모듈 목록과 비교합니다.

그런 다음 해당 스크립트를 최상위 구역 빌드의 일부로 실행하여 모든 것을 구축하는 사람은 개정 제어에서 얻은 모든 Perl 스크립트를 실행하는 데 필요한 모든 것을 가지고 있는지 알 수 있습니다. PERL 스크립트가있는 경우 실행되지 않고 CPAN을 실행하는 데 필요한 것을 설치하고 싶지 않은 경우 하드 드라이브에서 원치 않는 스크립트를 제거해야하므로 종속성 검사기가 찾을 수 없습니다. 나는 당신이 '동기화'를 할 때 특정 하위 디렉토리를 남기기 위해 Perforce 클라이언트를 수정하는 방법을 알고 있습니다.

각 스크립트의 종속성을 확인하거나 하드 코딩 된 스크립트 이름 목록을 기반으로 한 개별 MakeFile과는 대조적으로 종속성 검사기를 PL 파일을 검색하는 단일 스크립트로 만드는 것이 좋습니다. 종속성에 대해 스크립트를 확인하기 위해 사용자 조치가 필요한 메소드를 선택하는 경우, 사람들은 종속성 검사를 수행하지 않더라도 스크립트를 실행할 수 있기 때문에 해당 작업을 수행하는 것을 잊어 버립니다.

내가 말했듯이, 나는 아직 위의 것을 구현하지 않았지만이 질문으로 인해 그렇게하려고 노력했다. 내가 끝난 후에 내 경험으로 다시 게시하겠습니다.

'명백한'방법 - 고통 스럽지만 적당히 효과적인 방법은 일부 위치에 새로운 기본 Perl 빌드를 설치하는 것입니다 (생산에서 이것을 사용하지 않을 것입니다). Perl의 'Virgin'버전. 누락 된 종속성을 모두 찾을 수 있습니다. 처음으로 이것은 고통 스러울 수 있습니다. 처음 후에, 당신은 이미 대부분의 종속성을 다루고 있으며, 그것은 크게 덜 고통 스러울 것입니다.

CPAN 모듈의 로컬 저장소를 실행하는 것을 고려하여 코드를 항상 다운로드 할 필요는 없습니다. 또한 날짜가 아닌 모듈을 어떻게 정리하는지 고려하십시오.

use Acme::Magic::Pony;

진지하게. Perl 모듈이 누락되면 자동 설치됩니다. 참조 acme :: 마술 :: 조랑말 CPAN의 페이지.

"볼트로 고정 된 말"답변이지만 모든 종속성이있는 번들 파일을 만드는 습관을 들었습니다. 따라서 새로운 환경으로 가면 복사하여 설치합니다.

예를 들어. 나는 baz.pm을 가지고 있습니다

package Bundle::Baz;
$VERSION = '0.1';
1;
__END__
=head1 NAME
Bundle::Baz
=head1 SYNOPSIS
perl -MCPAN -e 'install Bundle::Baz'
=head1 CONTENTS
# Baz's modules
XML::Twig
XML::Writer
Perl6::Say
Moose

이것을 ~/.cpan/bundle/(또는 .CPAN 생활에 따라)에 넣은 다음 일반 CPAN 모듈처럼 '번들 :: baz'를 설치하십시오. 그런 다음 "= head1 내용"아래에 나열된 모든 모듈을 설치합니다.

다음은 Quickie Bash 기능입니다 (우수 사용 사용 ACK):

# find-perl-module-use <directory> (lib/ by default)
function find-perl-module-use() {
    dir=${1:-lib}
    ack '^\s*use\s+.*;\s*$' $dir | awk '{ print $2 }' | sed 's/();\?$\|;$//' | sort | uniq
    ack '^\s*use\s+base\s+.*;\s*$' $dir | awk '{ print $3 }' | sed 's/();\?$\|;$//' | sort | uniq
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top