Frage

Hat jemand irgendwelche Vorschläge für einen guten Ansatz, all CPAN Abhängigkeiten zu finden, die in einem maßgeschneiderten Entwicklungsprojekt entstanden sein könnten. Wie neigt der Fall Ihre lokale Entwicklungsumgebung selten entspricht Ihrer Live zu sein und wie Sie mehr und mehr Projekte bauen Sie neigen dazu, eine lokale Bibliothek der installierten Module aufzubauen. Diese werden dann zu Ihnen führen nicht unbedingt zu bemerken, dass Ihr jüngstes Projekt eine Anforderung auf einem Nicht-Kern-Modul hat. Da es in der Regel eine Voraussetzung ist, das gesamte Projekt bis zur Bereitstellung einer anderen Gruppe (in unserem Fall unseres Operations-Team) zu verpacken, ist es wichtig zu wissen, welche Module sollte im Paket enthalten sein.

Hat jemand irgendwelche Einblicke in das Problem.

Danke

Peter

War es hilfreich?

Lösung

Ich habe dieses Problem selbst hatte. Devel :: Modlist (wie von this Antwort ) hat einen dynamischen Ansatz. Es berichtet über die Module, die tatsächlich während eines bestimmten Laufes des Skripts geladen wurde. Dies fängt Module, die mit irgendwelchen Mitteln geladen werden, aber es kann nicht bedingte Anforderungen zu fangen. Das heißt, wenn Sie Code wie folgt aussehen:

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

und $some_condition passiert sein, falsch, Devel::Modlist nicht Some::Module als Anforderungsliste.

Ich entschied sich für Module :: ExtractUse statt. Es hat eine statische Analyse, was bedeutet, dass es immer Some::Module im obigen Beispiel fangen. Auf der anderen Seite kann es nichts Code tun:

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

Natürlich könnte man beiden Ansätze verwendet und dann kombiniert die beiden Listen.

Wie auch immer, hier ist die Lösung, die ich kam mit:

#! /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

Sie würden laufen diese wie:

perl finddeps.pl scriptToCheck.pl otherScriptToCheck.pl

Es gibt eine Liste aller nicht-Core-Module erforderlich, die Skripte auszuführen aufgeführt. (Es sei denn, sie tun ausgefallene Tricks mit Modul-Lade, die aus sehen, wie sie Module :: ExtractUse verhindern.)

Andere Tipps

Sie können mit Online-Web-Service unter deps.cpantesters.org , dass Sie viele nützliche Abhängigkeit liefert Daten. Alle Module auf CPAN haben bereits den Link zum Abhängigkeits Website (auf der rechten Seite des Moduls Seite).

In der Vergangenheit habe ich verwendet Devel :: Modlist , die recht gut ist erlaubt Sie gehen

perl -d:Modlist script.pl

Um eine Liste der benötigten Module zu erhalten.

Ich habe ein Make-basierte Build-System für all meine C / C ++ Anwendungen (sowohl auf PC-Basis und für verschiedene eingebettete Projekte), und während ich liebe es, ein Top-Level-Build auf einem frisches Maschine zu tun, und überprüfen Sie alle Abhängigkeiten vorhanden sind (ich meine Werkzeugketten überprüfen, um Revisionskontrolle: D)., ich habe bei nicht tun das gleiche für interpretierten Sprachen vereitelt worden, die derzeit keine Make-Datei in meinem Build-System haben

Ich bin versucht, ein Skript zu schreiben, dass:

  • sucht meine Revisionskontrolle Repository für Dateien mit der .pl oder .pm Erweiterung
  • läuft perl -d:Modlist auf sie (dank Vagnerr!)
  • es in der Liste der benötigten Module verketten
  • und vergleichen sie schließlich in die Liste der installierten Module.

Ich würde dann das Skript als Teil meines Top-Level-Build ausführen, so dass jemand etwas bauen wissen, ob sie alles, was sie jeden Perl-Skript ausführen müssen hat sie Revision Kontrolle. Wenn es einige Perl-Script laufen sie nie und wollen nicht CPAN installieren, was es ist erforderlich zu laufen, würden sie das unerwünschte Skript aus ihrer Festplatte entfernen müssen, so dass die Abhängigkeitsprüfer sie nicht finden können. Ich weiß, wie eine notgedrungen Client zu modifizieren bestimmte Unterverzeichnisse auszulassen, wenn Sie eine ‚sync‘ zu tun, werde ich aus für Subversion Abbildung müssen ...

Ich würde vorschlagen, dass die Abhängigkeitsprüfer ein einziges Skript zu machen, die für pl Dateien durchsucht, wie zu einer individuellen Make-Datei im Gegensatz Abhängigkeiten für jedes Skript zu überprüfen, oder basierend auf einer hartcodierte Liste der Skriptnamen. Wenn Sie eine Methode wählen, die Benutzeraktion erfordert einen Skript für Abhängigkeiten überprüft haben, werden die Menschen vergessen, diese Aktion durchzuführen, da sie in der Lage sein werden, das Skript selbst laufen, wenn sie die Abhängigkeitsprüfung nicht tun.

Wie ich schon sagte, ich habe die oben noch nicht implementiert, aber diese Frage hat mich dazu veranlasst, um zu versuchen, dies zu tun. Ich werde mit meiner Erfahrung nach zurück, nachdem ich fertig bin.

Die ‚offensichtliche‘ Art und Weise - schmerzhaft, aber mäßig wirksam - ist in einige aus dem Weg Lage eine völlig neue Build von Basis Perl zu installieren (Sie gehen zu verwenden, das nicht in der Produktion), und versuchen Sie dann zu installieren Modul diese ‚virgin‘ Version von Perl. Sie werden alle fehlenden Abhängigkeiten finden. Das erste Mal, könnte dies schmerzhaft sein. Nach dem ersten Mal werden, haben Sie bereits die Mehrheit der Abhängigkeiten bedeckt, und es wird wesentlich weniger schmerzhaft sein.

Betrachten Sie Ihre eigene lokale Repository von CPAN Module laufen - so dass Sie nicht immer den Code herunterladen. Sehen Sie sich auch, wie Sie die veralten Module aufzuräumen.

use Acme::Magic::Pony;

Im Ernst. Es wird automatisch installiert Perl-Module, wenn sie fehlt auftauchen. Sehen Sie sich die Gipfel :: Magic: :. Pony Seite in CPAN

Es ist ein „Pferd, das verschraubt ist“ Antwort, aber ich habe angewöhnt eine Bundle-Datei mit allen meinen Abhängigkeiten zu schaffen. So, wenn ich in eine neue Umgebung gehe ich kopieren Sie sie einfach über und installieren.

Für zB. Ich habe eine 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

Setzen Sie diese in ~ / .cpan / Bundle / (oder wo auch immer Ihr .cpan Leben) und dann installieren 'Bundle :: Baz' wie ein normales CPAN-Modul. Dies installiert dann alle Module, die unter „= head1 INHALT“.

Hier ist eine schnelle Nummer bash-Funktion (die ausgezeichnete 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
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top