© riedjal/Shutterstock.com
Erfolgreich Softwareprojekte modernisieren – Teil 4

Dependency-Management im Legacy-Code


Der vorangegangene Artikel der Serie „Erfolgreich Softwareprojekte modernisieren“ befasste sich mit der Einführung eines einheitlichen Coding-Standards. Nun ist es an der Zeit, sich mit den Abhängigkeiten eines Legacy-Projekts zu befassen.

Softwareprojekte verfolgen zumeist das Ziel, ein konkretes Problem zu lösen. Der Erfolg dieses Vorhabens hängt dabei von vielen Aspekten ab. Einer davon ist, wie gut es den Softwareentwickler:innen gelingt, den Gesamtaufwand für die Lösung des Problems zu reduzieren. Wie speziell geartet ein Problem auch zu sein scheint, bei genauerer Betrachtung lässt es sich immer in Teilprobleme zerlegen. Für die meisten Teilprobleme gibt es bereits eine oder mehrere Lösungen, die von gewollt oder ungewollt großzügigen Softwareentwickler:innen in der Form von Open-Source-Projekten, aber auch kommerziell erhältlich der Allgemeinheit zur Verfügung gestellt werden. Wirtschaftlich weniger erfolgreiche Umsetzungen eines Softwareprojekts versuchen hierbei, für jedes bereits gelöste Teilproblem eigene Lösungen zu entwickeln. Erfolgversprechender ist jedoch, den Großteil der Arbeit darauf zu verwenden, ein Kernproblem zu lösen, und für Randprobleme auf vorhandene Lösungen zurückzugreifen.

Software als Remix

Die meisten Softwareprojekte können daher als Remix von vorhandenen Lösungen zu bekannten Problemen angesehen werden, zu denen im weiteren Verlauf Lösungen für andere bekannte Probleme entwickelt werden. Neben Plattformen, auf denen Code ausgeführt wird, und Services, die über Schnittstellen angebunden werden können, können auf der Codeebene bereits vorhandene Lösungen auf verschiedene Arten eingebunden werden. Zum einen gibt es PHP-Erweiterungen, die – wie PHP – zumeist in der Programmiersprache C geschrieben sind und zusätzlich zu den standardmäßig mit PHP ausgelieferten Erweiterungen installiert und verwendet werden können. Auf dieser Plattform ausgeführter PHP-Code kann dann diese Funktionalitäten verwenden.

Zum anderen können PHP-Pakete von anderen Projekten oder Anbietern eingebunden und verwendet werden. Das kann zum Beispiel dadurch geschehen, dass Entwickler:innen PHP-Code aus persönlichen Codesammlungen oder aus Fragen und Antworten von stackoverflow.com kopieren, einzelne oder mehrere PHP-Klassen von phpclasses.org herunterladen, Quellcode aus anderen Projekten über Git Submodules einbinden, Applikationen und Tools mit Phive installieren, und ihre PHP-Pakete und Plattformanforderungen mit Composer verwalten und dokumentieren.

Welche Kombination dieser Varianten in einem Softwareprojekt verwendet wird, hängt zumeist von seinem Alter, den konkreten Umständen, und dem bereits betriebenen Modernisierungsaufwand ab. Welche Variante passend ist, hängt insbesondere davon ab, wohin die Reise gehen soll.

Dependency-Management mit Composer

Moderne PHP-Projekte verwenden Composer [1], um Anforderungen an die Plattform und Abhängigkeiten zu PHP-Paketen, sogenannten Dependencies, zu dokumentieren und zu verwalten. Aber, und das wird wenig überraschen, nicht alle Projekte, die Composer verwenden, sind modern.

Grundlagen composer.json

Um Composer in einem PHP-Projekt zu verwenden, muss zunächst eine Datei mit dem Namen composer.json vorhanden sein. Diese Datei wird auch als Manifest bezeichnet, und kann neben allgemeinen Informationen zum Projekt, die für öffentlich verfügbare Projekte erforderlich sein können, konkrete Anforderungen des Projekts enthalten. Im Idealfall sollte sich diese Datei in der Wurzel eines Projekts befinden. Je nach Bedarf könnte man auch mehrere composer.json in verschiedenen Verzeichnissen eines Projekts anlegen. Das könnte der Fall sein, wenn man mit einem monolithischen Repository arbeitet, das mehrere Applikationen beherbergt, oder wenn man für Laufzeit und Entwicklung separate composer.json verwenden möchte. Letzteres könnte notwendig sein, wenn man für die Entwicklung eines Softwareprojekts Tools verwenden möchte, die auf Grund von Inkompatibilitäten untereinander nicht über eine einzelne composer.json verwaltet werden können.

Einige Entwickler:innen sprechen sich konkret dagegen aus, Tools, die zur Entwicklung eines Softwareprojekts, nicht aber für seine Ausführung benötigt werden, über Composer zu installieren. Diese Tools könnten alternativ als PHAR (PHP Archive [2]) eingebunden werden, durch direkten Download oder die Verwendung von phive, einem Tool zur Installation von Tools und Applikationen im PHAR-Format.

Sofern composer.json noch nicht existiert, kann diese Datei durch Ausführen von $ composer init angelegt werden. Nach der Ausführung dieses Befehls und der interaktiven Beantwortung einiger Fragen kann eine composer.json zum Beispiel so aussehen, wie in Listing 1 gezeigt.

Listing 1: Eine frisch erstellte composer.json

{ "name": "foo/bar", "type": "project", "license": "proprietary", "require": {} }

Man beachte im Besonderen die aktuell noch leere Sektion require, in der Plattformanforderungen und PHP-Pakete angegeben werden können, die für eine Verwendung in einer Produktivumgebung benötigt werden. Zusätzlich kann auch eine Sektion require-dev verwendet werden, in der weitere PHP-Pakete angegeben werden können, die nur für die Entwicklung des Projekts nötig sind. Die composer.json muss in die Versionskontrolle aufgenommen werden.

composer.lock

Ist eine composer.json vorhanden, wird durch Ausführen von $ composer install zunächst überprüft, ob eine Datei mit dem Namen composer.lock existiert. Ist das nicht der Fall, werden Informationen aus den Sektionen require und require-dev gesammelt, und überprüft, ob einerseits die aktuelle Plattform den dort hinterlegten Anforderungen genügt und andererseits alle dort angegebenen PHP-Pakete erkannt, aufgelöst und installiert werden können. Jedes dieser PHP-Pakete verwendet selbst eine composer.json, in der es in den Sektionen require und require-dev seine Plattformanforderungen und benötigten PHP-Pakete angeben kann. Das heißt, dass durch die direkte Einbindung eines einzelnen PHP-Pakets weitere PHP-Pakete indirekt in ein Projekt eingebunden werden können. Zu beachten ist hierbei, dass bei der Einbindung eines PHP-Pakets nur die Anforderungen in der jeweiligen require-Sektion herangezogen werden. Ist eine Auflösung und Installation nicht möglich, wird eine entsprechende Fehlermeldung ausgegeben.

Im Erfolgsfall werden die archivierten PHP-Pakete heruntergeladen, im Verzeichnis vendor/ ausgepackt und unter anderem eine Datei mit dem Namen composer.lock angelegt. Diese Datei, die auch als Lock-File bezeichnet wird, enthält alle Informationen, die zu einer erneuten Installation der soeben heruntergeladenen PHP-Pakete benötigt werden. Schaut man sich eine composer.lock genauer an, so stellt man fest, dass man dort die Inhalte der composer.json der jeweils installierten PHP-Pakete gruppiert wiederfindet, angereichert um weitere Informationen, wie URLs, unter denen die PHP-Pakete heruntergeladen werden können. Diese Informationen können von Packagist, dem zentralen PHP-Paket-Repository, aber auch aus anderen Quellen bezogen werden. Das ist besonders dann der Fall, wenn private...

Neugierig geworden? Wir haben diese Angebote für dich:

Angebote für Gewinner-Teams

Wir bieten Lizenz-Lösungen für Teams jeder Größe: Finden Sie heraus, welche Lösung am besten zu Ihnen passt.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang