Eigentlich sollten Systeme wie WordPress oder Drupal regelmäßig aktualisiert werden, schon um neu gefundene Sicherheitslücken zeitnah zu schließen. Manchmal bekommt man es als Web-Entwickler aber auch mit Websites zu tun, die besser mit “legacy” als mit “aktuell” zu beschreiben sind. Dann muss man die Installation schon mal über mehrere major versions (Hauptversionen) auf den neuesten Stand hieven - oder zumindest herausfinden, wie viel auf diesem Weg möglich ist im Vergleich zu einem kompletten Neuaufbau.
Im Fall von Drupal bedeutet das eine Migration. Man installiert ein aktuelles Drupal neben dem Legacy-System und überträgt die Daten. Ein Teil dieser Aufgabe ist, mit Drush die einzelnen Migrationsschritte zu ermitteln. drush migrate:upgrade
ermittelt mehrere bis viele Teil-Migrationen, die man mit drush migrate:status
auflisten kann. Tatsächlich durchführen kann man eine Teil-Migration mit drush migrate:import id_des_teilschritts
.
Will man alle Teil-Migrationen auf einmal durchführen, kann man das mit drush migrate:import --all
. Das ist aber nicht immer der beste Weg, beispielsweise wenn der Abstand zwischen der Legacy-Version und dem aktuellen Drupal sehr groß ist, oder die Legacy-Installation stark modifiziert wurde. Dann kann es besser sein, die Teil-Migrationen nach und nach durchzuführen, um auftretende Probleme leichter angehen zu können.
Die Anzahl der Teil-Migrationen kann allerdings schon mal dreistellig werden. Sie einzeln durchzuführen ist auch nicht immer ideal. Glücklicherweise sind die Migrationen mit Hilfe von Tags und Gruppen organisiert. Laut der Dokumentation von drush migrate:status
kann man mit drush migrate:status --tag name_des_tags
nach einem Tag filtern, oder mit drush migrate:status --tag
die Liste nach Tags gruppieren lassen. Letzteres funktioniert jedoch nicht im aktuellen Drush 12.5.2.0.
Wie kommt man also an die Information, welche Tags zu den Teil-Migrationen es gibt, und idealerweise auch gleich welche Gruppen? Praktischerweise kann man die Konfiguration inklusive der erstellten Teil-Migrationen exportieren, mittels drush config:export und der Option --destination
. Damit erzeugt man eine Reihe von YAML
-Dateien im angegebenen Verzeichnis. In diesen Dateien (jedenfalls in denen, die zu einem Migrationsschritt gehören und einen Tag und/oder eine Gruppe zugewiesen haben) stehen die gesuchten Informationen unter den Schlüsseln migration_tags
beziehungsweise migration_group
.
Für die Auswertung der YAML
-Dateien kann man ein kurzes Skript verwenden, geschrieben beispielsweise in Python:
#/bin/env python3
# MIT License (https://opensource.org/license/MIT)
#
# Copyright 2024 Henning Kockerbeck, henning.kockerbeck@isatis-online.de
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the “Software”),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
# IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
from os import listdir
from os.path import isfile, join
import yaml
# fetch paths to migration configs
CONFIG_PATH = '/directory/with/config/files/'
configs = [join(CONFIG_PATH, f) for f in listdir(CONFIG_PATH) if isfile(join(CONFIG_PATH, f)) and f.startswith('migrate_plus')]
# sets to store our findings in
groups = set()
tags = set()
# walk through config files
for config in configs:
with open(config) as file:
migration = yaml.safe_load(file)
# if there's a group, note it down
if 'migration_group' in migration:
groups.add(migration['migration_group'])
# if there are tags, note them down
if 'migration_tags' in migration:
tags.update(migration['migration_tags'])
# print the findings
print('Groups: ' + ', '.join(groups))
print()
print('Tags: ' + ', '.join(tags))
Die Konstante CONFIG_PATH
muss das Verzeichnis enthalten, in das die Konfigurationsdateien exportiert wurden, und generell muss das Skript eventuell an die jeweiligen lokalen Verhältnisse angepasst werden. Die grundsätzliche Idee sollte jedoch klar werden.