32 Stimmen

Wie finde ich die Modulabhängigkeiten meines Perl-Skripts?

Ich möchte einen anderen Entwickler bitten, ein von mir geschriebenes Perl-Skript auszuführen. Das Skript verwendet viele CPAN-Module, die installiert werden müssen, bevor das Skript ausgeführt werden kann. Ist es möglich, das Skript (oder die perl-Binärdatei) dazu zu bringen, eine Liste aller fehlenden Module auszugeben? Perl gibt die Namen der fehlenden Module aus, wenn ich versuche, das Skript auszuführen, aber dies ist umständlich und listet nicht alle fehlenden Module auf einmal auf. Ich möchte gerne etwas ähnliches tun:

$ cpan -i `said-script --list-deps`

Oder sogar:

$ list-deps said-script > required-modules # auf meinem Rechner
$ cpan -i `cat required-modules` # auf seinem Rechner

Gibt es einen einfachen Weg, dies zu tun? Das ist kein Showstopper, aber ich möchte das Leben des anderen Entwicklers erleichtern. (Die benötigten Module sind über mehrere Dateien verstreut, daher ist es nicht einfach für mich, die Liste von Hand zu erstellen, ohne etwas zu übersehen. Ich kenne PAR, aber es scheint etwas zu kompliziert für das, was ich will.)


Update: Danke, Manni, das wird funktionieren. Ich kannte %INC nicht, ich kannte nur @INC. Ich habe mich für etwas wie das hier entschieden:

print join("\n", map { s|/|::|g; s|\.pm$||; $_ } keys %INC);

Das gibt aus:

Moose::Meta::TypeConstraint::Registry
Moose::Meta::Role::Application::ToClass
Class::C3
List::Util
Imager::Color
…

Sieht so aus, als ob das funktionieren wird.

28voto

tsee Punkte 4970

Überprüfen Sie Module::ScanDeps und das mitgelieferte Dienstprogramm "scandeps.pl". Es kann eine statische (und rekursive) Analyse Ihres Codes auf Abhängigkeiten sowie das %INC-Dump entweder nach dem Kompilieren oder Ausführen des Programms durchführen.

Bitte beachten Sie, dass die statische Quellenscanung immer dazu neigt, zu viele Abhängigkeiten einzuschließen. (Es ist der Abhängigkeitsscanner, der von PAR verwendet wird und darauf abzielt, es für den Endbenutzer am einfachsten zu machen.)

Sie könnten sich schließlich entscheiden, Ihr Skript als CPAN-Distribution zu verteilen. Das klingt viel komplizierter, als es tatsächlich ist. Sie können etwas wie Module::Starter verwenden, um ein Grundgerüst einer vorläufigen App::YourScript-Distribution einzurichten. Legen Sie Ihr Skript im bin/ Unterverzeichnis ab und bearbeiten Sie die Makefile.PL, um alle Ihre direkten Abhängigkeiten zu referenzieren. Dann führen Sie für die Verteilung folgendes aus:

  1. perl Makefile.PL
  2. make
  3. make dist

Der letzte Schritt generiert eine schöne App-YourScript-VERSION.tar.gz Wenn der Client nun alle Abhängigkeiten installieren möchte, führt er Folgendes aus:

  1. Richten Sie den CPAN-Client richtig ein. Führen Sie ihn einfach aus und beantworten Sie die Fragen. Aber das verlangen Sie sowieso bereits.
  2. "tar -xz App-YourScript-VERSION.tar.gz && cd App-YourScript-VERSION"
  3. Führen Sie "cpan ." aus

Der CPAN-Client installiert nun alle direkten Abhängigkeiten und die Abhängigkeiten dieser Distributionen automatisch. Je nachdem, wie Sie es einrichten, folgt er entweder automatisch den Voraussetzungen rekursiv oder fragt jedes Mal mit y/n.

Als Beispiel hierfür könnten Sie sich einige der App::*-Distributionen auf CPAN ansehen. App::Ack wäre ein gutes Beispiel. Vielleicht eine der App::*-Distributionen aus meinem CPAN-Verzeichnis (SMUELLER).

21voto

innaM Punkte 46916

Sie könnten %INC am Ende Ihres Skripts ausgeben. Es wird alle verwendeten und benötigten Module enthalten. Aber natürlich ist dies nur hilfreich, wenn Sie Module nicht bedingt benötigen (benötige Foo if $bar).

14voto

brian d foy Punkte 124323

Für schnelle und schmutzige, gelegentliche Verwendung ist das %INC der beste Weg. Wenn Sie dies jedoch mit kontinuierlicher Integrationstests oder etwas Robusterem durchführen müssen, gibt es einige andere Tools, die helfen können.

Steffen hat bereits das Modul::ScanDeps erwähnt.

Der Code in Test::Prereq tut dies, hat jedoch eine zusätzliche Ebene, die sicherstellt, dass Ihre Makefile.PL oder Build.PL sie als Abhängigkeit auflistet. Wenn Sie Ihre Skripte wie eine normale Perl-Distribution aussehen lassen, ist es ziemlich einfach, nach neuen Abhängigkeiten zu suchen; führen Sie einfach den Testlauf erneut durch.

Abgesehen davon könnten Sie ein Tool wie Module::Extract::Use verwenden, das den statischen Code analysiert und nach Verwendung von use- und require-Anweisungen sucht (obwohl es sie nicht in String-Evaluierungen finden wird). Das gibt Ihnen nur die Module, die Sie Ihrem Skript geladen haben. Außerdem, sobald Sie wissen, welche Module Sie geladen haben, können Sie das mit David Cantrells CPANdeps Tool kombinieren, das bereits den Abhängigkeitsbaum für die meisten CPAN-Module erstellt hat.

Beachten Sie auch, dass Sie über optionale Funktionen nachdenken müssen. Ihr Code hat in diesem Fall vielleicht keine, aber manchmal laden Sie ein Modul erst, wenn Sie es benötigen:

sub foo
    {
    require Bar; # nicht laden, bis wir es verwenden müssen
    ....
    }

Wenn Sie diese Funktion in Ihrem Testlauf oder Test nicht ausführen, werden Sie nicht sehen, dass Sie Bar für diese Funktion benötigen. Ein ähnliches Problem tritt auf, wenn ein Modul in einer anderen Umgebung (z.B. mod_perl oder Windows usw.) eine andere Reihe von abhängigen Modulen lädt.

Es gibt keinen guten, automatisierten Weg, um optionale Funktionen wie diese zu testen, damit Sie deren Abhängigkeiten erhalten. Allerdings denke ich, dass dies auf meiner To-Do-Liste stehen sollte, da es sich nach einem interessanten Problem anhört.

7voto

rjbs Punkte 1327

Ein weiteres Werkzeug in diesem Bereich, das von Dist::Zilla und seinem AutoPrereqs-Plugin verwendet wird, ist Perl::PrereqScanner. Es installiert ein scan-perl-prereqs-Programm, das PPI und einige Plugins verwendet, um nach den meisten Arten von Vorbedingungserklärungen zu suchen, unter Verwendung der von Ihnen definierten Mindestversionen. Im Allgemeinen empfehle ich dies über das Scannen von %INC, das falsche Anforderungen mit sich bringen kann und Versionen ignoriert.

2voto

zoul Punkte 99332

Heute entwickle ich meine Perl-Apps als CPAN-ähnliche Distributionen unter Verwendung von Dist::Zilla, das sich um die Abhängigkeiten durch das AutoPrereq-Plugin kümmern kann. Ein weiteres interessantes Stück Code in diesem Bereich ist carton.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X