Blog

cpanfile – Teil 1

29.06.2022 // Renée Bäcker

Ein cpanfile ist eine Datei, die Abhängigkeiten von Anwendungen und Modulen beschreibt. Diese Dateien sind in der Perl-Welt nichts neues (sie gibt es seit über 8 Jahren) und sie sind eine sehr gute Möglichkeit, die Installation von Abhängigkeiten zu vereinfachen.

Die Nutzung einer solchen Datei eignet sich für folgende Szenarien:

  1. Ein Projekt soll direkt aus einem Repository heraus installiert werden.
  2. Neue Entwickler für das Projekt sollen schnell eine eigene Entwicklungsumgebung aufbauen können.
  3. Es soll immer eine reproduzierbare Umgebung aufgebaut werden können (es sollen immer die gleichen Versionen der Abhängigkeiten genutzt werden).
  4. und vermutlich noch viele weitere ...

Integration in Modulinstaller

cpanm kann die Abhängigkeiten aus einem cpanfile auslesen und diese installieren.

cpanm --installdeps .

liest die Datei namens cpanfile im aktuellen Verzeichnis aus.

Die nachfolgenden Abschnitten beschreiben die grundsätzlichen Möglichkeiten innerhalb des cpanfiles. Der nächste Artikel über cpanfiles wird noch weitergehen.

Standardabhängigkeiten werden einfach mit requires angegeben:

requires 'Mojolicious';

In diesem Fall wird einfach nur erwartet, dass irgendeine Version von Mojolicious installiert ist. Viele Module ändern ihr API, so dass man eine Mindestversion angeben sollte. Bei Mojolicious wurde z.B. mit Version 8.0 die Methode chmod in Mojo::File eingeführt. Benötigt die Anwendung diese Methode, muss sich das im cpanfile widerspiegeln:

requires 'Mojolicious' => 8;

Sollte eine Methode in 9.0 wieder abgeschafft werden und sie wird weiter verwendet, dann kann man auch einen Bereich angeben:

requires 'Mojolicious' => '>=8,<9';

Enthält eine Version der Abhängigkeit einen Bug, kann man diese Version explizit ausschließen:

requires 'Mojolicious' => '>8, != 8.12';

Diese Bedingungen sind mit und verknüpft.

In vielen Fällen werden für die Entwicklung der Anwendung oder des Moduls extra Abhängigkeiten benötigt. Wird die Anwendung ausgerollt oder das Modul installiert, sollen diese Abhängigkeiten nicht installiert werden.

Deshalb können sogenannte Phasen genutzt werden. Die oben gezeigten Beispiele gelten für die Phase runtime. Das ist die Standardphase und muss nicht extra angegeben werden. Gelten Abhängigkeiten nur für die Entwicklung, ist die Phase develop zu wählen. Abhängigkeiten, die für die Tests nötig sind, müssen für die Phase test installiert werden.

on 'develop' => sub {
    requires 'Dist::Zilla' => 0.1;
};

on 'test' => sub {
    requires 'Test::BDD::Cucumber' => 2;
};

Hier wird mit on bestimmt, dass die Phase sich ändert und in einer Subroutinen-Referenz werden dann die requires aufgelistet. Module::CPANfile kennt als Phasen runtime, develop, test und configure.

Die Installation mit cpanm über cpanm --installdeps . installiert nur die Module für die runtime und test. Sollen die Abhängigkeiten anderer Phasen installiert werden, muss das mit --with-<phase>, also z.B.

cpanm --with-develop --installdeps .

Soweit die Basisinformationen zu cpanfiles. Sie sind ein empfehlenswertes Werkzeug und mit den hier gezeigten Möglichkeiten kommt man in den allermeisten Fällen aus.


Permalink:

CPAN-Updates November/Dezember 2020

29.12.2020 // Renée Bäcker

Auch in den letzten beiden Monaten dieses Jahres waren wir nicht ganz untätig – teilweise mit Hilfe anderer Perl-Programmierer*innen.

In den folgenden Abschnitten stelle ich unsere neuen bzw. aktualisierten CPAN-Pakete vor:

CPANfile::Parse::PPI

Ein neues Modul, das ein statisches Parsen von *cpanfile*s ermöglicht. Ich habe schon in einem Blogpost erwähnt, warum wir nicht Module::CPANfile nutzen. Da ich noch mehre dieser Anwendungsfälle habe, habe ich ein Modul daraus gebaut: CPANfile::Parse::PPI.

use v5.24;
use CPANfile::Parse::PPI;
 
my $path     = '/path/to/cpanfile';
my $cpanfile = CPANfile::Parse::PPI->new( $path );
 
# or
# my $cpanfile = CPANfile::Parse::PPI->new( \$content );
 
for my $module ( $cpanfile->modules->@* ) {
    my $stage = "";
    $stage    = "on $module->{stage}" if $module->{stage};
    say sprintf "%s is %s", $module->{name}, $module->{type};
}

Perl::Critic::RENEEB

In dieser Distribution habe ich zwei neue Regeln hinzugefügt:

Zum einen eine Regel, mit der die Nutzung von *List::Util*s first gefordert wird, wenn im Code ein grep genutzt aber nur das erste Element weiterverwendet wird, wie in diesem Beispiel:

my ($first_even) = grep{
    $_ % 2 == 0
} @array;

Die zweite Regel fordert die Nutzung des postderef-Features. Das heißt, dass dieser Code

my @array = @{ $arrayref };

umgeschrieben werden soll als

my @array = $arrayref->@*;

Außerdem gab es kleine Änderungen an den Metadaten. Danke an Gabor Szabo für den Pull Request.

Mojolicious::Command::Author::generate::localplugin

Hier haben wir keine Arbeit aufwenden müssen, sondern durften auf die Fähigkeiten in der Perl-Community zurückgreifen. Andrew Fresh hat einen Pull Request eingereicht, der die Tests die dieses Modul für das generierte Plugin erstellt, lauffähig macht. Vielen Dank dafür!

Mojolicious::Plugin::FormFieldsFromJSON

Auch hier haben wir Pull Requests aus der Perl-Community erhalten:

  • Interne POD-Links wurden korrigiert (Danke an Håkon Hægland)
  • Ein paar Perl::Critic-Warnungen wurden korrigiert (Danke an Lubos Kolouch)
  • Der Grund von FAIL-Reports der CPANTester wurde gefixt (Danke an Mohammad S Anwar)

OTRS::OPM::Maker::Command::sopm

Vor kurzem kam die erste Anforderung, eines unserer Module für OTOBO zu portieren. Da wir die Spezifikationsdateien unserer Erweiterungen generieren lassen, musste das Kommando entsprechend angepasst werden.

In der Metadaten-Datei (z.B. die für DashboardMyTickets) muss nur noch als Produkt OTOBO angegeben werden, dann wird die .sopm-Datei richtig generiert.

OTRS::OPM::Parser

Das ist das zweite Modul, das für die Nutzung mit OTOBO ertüchtigt wurde. Mit der neuesten Version können Addons für OTOBO geparst werden. Das wurde notwendig, um einen OPAR-Klon für OTOBO aufsetzen zu können.

Zusätzlich wurde die Synopsis durch Håkon Hægland verbessert. Danke für den entsprechenden Pull Request.


Permalink: