Dies ist Folgeartikel 4 aus meiner Serie zu GitHub-Webhooks.
Die Perl-Skripte, die ich in den folgenden Artikeln genauer erläutere,
benutzen ein paar übergreifende Funktionen, die ich auf billigste
Weise in eine Library ausgelagert habe:
Ich habe einfach die Datei WebHookLib.pm
ins gleiche Verzeichnis wie
die Skripte geworfen und binde sie dann dort über
- #!/usr/bin/perl -I.
- use WebHookLib;
ein. Man beachte das -I.
um das aktuelle Verzeichnis in den
Suchpfad einzufügen. Äußerst schäbig, funktioniert aber.
Ich habe alle Funktionen in der Library mit POD-Dokumentation versehen
(was sich auch schon gelohnt hat, weil ich nach sechs Tagen
Programmierpause nicht mehr wusste, was ich vorher gebaut habe), aber
die lasse ich jetzt der Einfachheit weg. Stattdessen schreibe ich
einfach nach jeder Methode ein paar Zeilen. Dafür ist das dann auch –
anders als im Produktivcode – deutsche Doku :-)
Falls ihr die Library so direkt verwenden wollt, müsst ihr sie euch
hier aus den Code-Bröckchen zusammenkopieren. Ich sollte das echt mal
alles in ein git-Repository kippen…
WebHookLib.pm
- sub is_debug()
- {
- return $ENV{DEBUG} eq '1';
- }
Liefert den Debug-Status. Ich habe alle Skripte so gebaut, dass sie
keine „Außenwirkung“ entfalten, wenn ich beim Aufruf die
Umgebungsvariable DEBUG
auf 1
setze. So kann ich in Ruhe Fehler
suchen und Testläufe machen und bekomme z.B. Emails nur auf STDOUT
angezeigt statt die Mailingliste damit zu fluten.
- sub crlf
- {
- my ($text) = @_;
- $text =~ s/\r\n/\n/g;
- return $text;
- }
Diese Funktion wandelt in einem String CRLF nach LF um und ist
schrecklich benamst. GitHub liefert mehrzeilige Texte mit CRLF aus
und das macht sich später in den Emails nicht so gut.
- sub get_branch
- {
- my ($ref) = @_;
- $ref =~ s:^.*/:/:;
- return $ref;
- }
Ermittelt den Branch aus einer git-Ref: aus refs/heads/master
wird
/master
.
- sub get_short_branch
- {
- my ($ref) = @_;
- $branch = get_branch($ref);
- $branch =~ s:^/master$::;
- return $branch;
- }
Gibt den Branch einer git-Ref zurück, wenn es nicht der Master-Branch
ist. Funktioniert wie get_branch()
, aber aus refs/heads/master
wird ein Leerstring.
- use JSON::MaybeXS;
-
- sub read_payload
- {
- my $json_file = $ARGV[0];
- die "no input file given" unless defined $json_file and $json_file;
- die "input file `$json_file' does not exist" unless -e $json_file;
- die "input file `$json_file' not readable" unless -r $json_file;
-
- open my $file, '<', $json_file or die "can't open `$json_file': $!";
- local $/;
- my $json = decode_json(<$file>);
- close $file or die "can't close `$jsonfile': $!";
- return $json->{payload};
- }
Hierüber wird das JSON eingelesen: Der erste Kommandozeilenparameter
($ARGV[0]
) wird als der Datei genommen, welche dann gelesen und als
JSON geparst wird. Gibt nur den payload
-Teil der Daten zurück, also
genau das, was GitHub geschickt hat.
Das use JSON::MaybeXS;
steht eigentlich ganz oben in der Perl-Datei,
aber wenn ich den Code hier stückchenweise präsentiere, zeige ich es
da, wo es benötigt wird. Und eigentlich ist ja auch recht egal, wo
man sein use
hinschreibt.
- sub shorten
- {
- my ($text, $max) = @_;
-
- if (length $text <= $max) {
- return $text;
- }
- return substr($text, 0, $max-1) . "…";
- }
Verkürzt $text
, wenn er länger als $max
Zeichen ist.
shorten("Hallo", 3)
liefert "Ha…"
zurück. Ganz wichtig, wenn man
twittern will :-)
- sub send_mail
- {
- my ($to, $subject, $body) = @_;
-
- my $fh;
- if (is_debug) {
- $fh = *STDOUT;
- print $fh "--MAIL START\n";
- }
- else {
- open $fh, '|-', "/usr/sbin/exim -i $to" or die "can't open pipe to exim: $!";
- }
-
- print $fh "From: GitHub Webhooks <absender\@example.org>\n";
- print $fh "Content-Type: text/plain; charset=utf-8\n";
- print $fh "Content-Disposition: inline\n";
- print $fh "Content-Transfer-Encoding: 8bit\n";
- print $fh "To: $to\n";
- print $fh "Subject: $subject";
- print $fh "\n";
- print $fh "$body";
-
- if (is_debug) {
- print $fh "--MAIL END\n";
- }
- else {
- close $fh or die "can't close pipe to exim: $!";
- }
- }
Verschickt eine Email. Ich war zu faul, mich in eines der zahlreich
vorhandenen Perl-Module einzulesen (z.B. Email::Simple plus
Email::Sender) und habe schnell selber was geklimpert.
Funktioniert, fällt aber bestimmt schnell auseinander. Bitte nicht
nachmachen!
- sub tweet_it
- {
- my ($tweet) = @_;
- $tweet = shorten($tweet, 277);
- if (is_debug) {
- print "--TWEET START\n$tweet\n--TWEET END\n";
- }
- else {
- system('git/mtweet/mtweet', "$tweet") == 0 or die "mtweet call failed: $?";
- }
- }
Twittert einen Text. Er wird großzügig auf 277 Zeichen gekürzt und
danach meinem selbstgebauten Kommandozeilen-Twitterclient mtweet
übergeben. mtweet hatte ich fünf Jahre lang nicht angefasst, aber
es funktioniert immer noch :-)
Ganz klar: Jede gute Perl-Datei, die per use
eingebunden wird, hört
so auf, sonst gibt es einen Fehler beim Laden.
Netz - Rettung - Recht am : Wellenreiten 02/2019