Ich habe neulich darüber geschrieben, dass ich mit in meinem Homelab von Gitlab verabschieden möchte und nach Alternativen gesucht habe. Bei meiner Suche stieß ich auf verteilte Issue Tracker, die die vertraute Integration von PlantUML nicht bieten. Daher suchte ich nach einem Weg, auch dieses Feature in solchen Lösungen zu integrieren.
PlantUML ist ein vielseitiges Werkzeug, das in vielen Lösungen integriert wird. Das ist besonders einfach: Das Diagramm liegt als Text vor
@startuml
skinparam ParticipantPadding 20
skinparam BoxPadding 10
title RMI actors and interactions
autonumber "<b>[0]"
box "server process"
participant "server\napplication" as serv
participant "remote\nobject" as obj
end box
participant "registry" as reg
box "client process"
participant "stub\nobject" as stub
participant "client\napplication" as client
end box
participant "class\nserver" as cls
== Initialization ==
create obj
serv --> obj : instantiate
serv -[#red]> reg : bind remote object
client -[#red]> reg : look up
autonumber 4 "(0)"
client -[#blue]> cls : request classes
activate cls
cls -[#blue]> client : provide classes
deactivate cls
create stub
autonumber 6 "<b>[0]"
client --> stub : instantiate
== Usage ==
client --> stub : use
stub -[#green]> obj : remote call
activate obj
obj -[#green]> stub :return result
deactivate obj
@enduml
und kann mittels entsprechender Programme in die verschiedensten Ausgabeformate überführt werden. Dabei reichen die Möglichkeiten von Scalable Vector Graphics (SVG)
PlantUML-Diagramm als SVG-Graphik
über Bitmap-Graphikformate bis hin zu ASCII-Art:
RMI actors and interactions
┌───────────┐ ┌───────────┐ ┌──────┐
│server │ ┌────────┐ │client │ │class │
│application│ │registry│ │application│ │server│
└─────┬─────┘ └───┬────┘ └─────┬─────┘ └──┬───┘
│ │ │ │
│ │ ╔════════════════╗ │ │
═══════════╪══════════════════════════════════════╪═╣ Initialization ╠═════════════════════╪═════════════════════╪═════════
│ │ ╚════════════════╝ │ │
│ │ │ │ │
│ [1] in┌──────┐e │ │ │
│ ─ ─ ─ ─ ─ ─ ─ ─│remote│ ─ ─ ─ ─ ─ > │ │ │
│ │object│ │ │ │
│ └──┬───┘ │ │ │
│ [2] bind remote object │ │ │
│──────────────────────────────────────> │ │
│ │ │ │ │
│ │ │ [3] look up │ │
│ │ │ <──────────────────────────────────────│ │
│ │ │ │ │
│ │ │ │(4) request classes ┌┴┐
│ │ │ │───────────────────>│ │
│ │ │ │ └┬┘
│ │ │ │(5) provide classes │
│ │ │ │<────────────────────│
│ │ │ │ │ │
│ │ │ [┌──────┐ntiate │ │
│ │ │ <─ ─ ─ ─ ─ │stub │─ ─ ─ ─ ─ ─ ─ ─ ─│ │
│ │ │ │object│ │ │
│ │ │ └──┬───┘ │ │
│ │ │ │ │ │
│ │ │ ╔═══════╗ │ │ │
═══════════╪═══════════════════╪══════════════════╪══════╣ Usage ╠═══╪═════════════════════╪═════════════════════╪═════════
│ │ │ ╚═══════╝ │ │ │
│ │ │ │ │ │
│ │ │ │ [7] use │ │
│ │ │ │ <─ ─ ─ ─ ─ ─ ─ ─ ─ ─│ │
│ │ │ │ │ │
│ ┌┴┐ [8] remote call │ │ │
│ │ │ <────────────────────────────────── │ │
│ └┬┘ │ │ │ │
│ │ [9] return result │ │ │
│ │ ────────────────────────────────────> │ │
┌─────┴─────┐ ┌──┴───┐ ┌───┴────┐ ┌──┴───┐ ┌─────┴─────┐ ┌──┴───┐
│server │ │remote│ │registry│ │stub │ │client │ │class │
│application│ │object│ └────────┘ │object│ │application│ │server│
└───────────┘ └──────┘ └──────┘ └───────────┘ └──────┘
Wie man sehen kann, hat das Rendering als ASCII-Art jedoch auch seine Grenzen...
Die verteilten Issue-Tracker - jedenfalls die, die ich mir im Zuge meiner Recherchen angesehen habe - verfügen lediglich über ein Terminal-Frontend oder - wenn sie wie git-bug über ein Web-Frontend verfügen - sie haben nicht die Möglichkeit, PlantUML-Diagramme on-the-fly zu konvertieren.
Ich suchte also nach einer Möglichkeit, diese Brücke - zwischen der Textbeschreibung der Inhalte in den Issues und der graphischen Repräsentation der Inhalte - zu schlagen. Eine Möglichkeit wäre, den Online-Editor zur Erstellung der Diagramme zu nutzen und die jeweilige charakteristische URL in die Tickets einzupflegen. Dann wäre es eine einfache Sache, diese URL aus dem Issue-Text zu nehmen, sie in die Adresszeile eines Browsers einzugeben und - voila - die Graphik taucht zusammen mit der Definition in Textform im Browser auf.
Das würde aber bedeuten, man müsste das tun - die URL verrät nichts über den Inhalt der Definition. Man könnte natürlich die Definition und die URL im Issue vermerken - dann hätte man aber zusätzlichen Aufwand: Bei jeder Änderung an der Beschreibung müsste man beides in das Issue kopieren. Neben dem zusätzlichen Aufwand wäre das eine Einladung für Fehler.
Daher mein Gedanke: Könnte man nicht nur die Definition in das Issue packen und auf einfache Weise wann immer gewünscht die Darstellung rendern? Dazu müsste man lediglich auf Zuruf die URL generieren können, die man dann in den Browser eingeben würde, um die Darstellung anzuzeigen.
Es existieren für diverse Sprachen entsprechende Bibliotheken für die Erzeugun solcher URLs - allerdings war mein Ehrgeiz geweckt: Es musste doch möglich sein, diese URL aus den Beschreibungen mit Linux-Bordmitteln zu erstellen?
Nach längerer Suche war ich tatsächlich erfolgreich: Es ist möglich, einen Datenstrom mittels gzip ohne jegliche Header und Metainformationen als reinen komprimierten Output zu erzeugen:
cat te1.puml | gzip --no-name | tail --bytes=+11 | head --bytes=-8 > gzip-without-anything
Dieser Datenstrom wird anschließend Base64 kodiert.
base64 gzip-without-anything -w 0 >te1.b64
Da aber PlantUML ein anderes Alphabet benutzt, kommt anschließend noch tr zum Einsatz:
cat te1.b64 |tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\-_'
Und damit wird aus dem Beispiel oben:
TLB1Qjmm4BthAmRtqXu2sr9w2Dqbz9P38HHwokv1bWUZHfPSpMX9-_MTiRnTEI47WpNptjDxpxuZjfdB50mz-JZRR2Tua8btVhQH7-mm-3Z2frsp_vQUB_EFEyEU0yAFx_TW7QTCOEC0FZ9cEViKoTZ2APQfnmpTr_xmk3jrfa_Fq17cimpdd1mITMQ-NdnP7gETv-2TLQaEB87EjyYCKs8ynjJ_GiSBI5uDYW-vvYLszCJvpuAIGpNYWiV8RndXqc_4TR25LFvhhtNUEcavbkWOQymLJMQ_X_lesTlW_ouwiDyRbz4oBg4K3ZSt1pt0hVHCB6fUr-lkyLt6uNJGS0BelTnT2u8QmQnXNm13IazGvlPZVORk_Uv3rn3wK50OObGO6NyN98Ob29BHptrM8vf3dfPG5MwruRCVy3zdm2sh1jM2MoDVhl_DggGDA6fRWRRta-o8MjfhP24q-gh6nemOJskDbuAS3U4QG-kMfqLNeOnSSXGIbS1j16NSOHpA5Fu1
Beziehungsweise als One-Liner
xdg-open "https://plantuml.com/plantuml/uml/$(cat te1.puml | \
gzip --no-name | tail --bytes=+11 | head --bytes=-8 | base64 -w 0 - | \
tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\-_')"
Das ergibt dann folgenden Link...
Man kann sich die Graphik als ASCII.-Art auch direkt ins Terminal rendern lassen:
wget -O - "https://plantuml.com/plantuml/txt/$(cat te1.puml | \
gzip --no-name | tail --bytes=+11 | head --bytes=-8 | base64 -w 0 - | \
tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\-_')"
Oder - wenn man den ganzen Weg konsequent zu Ende geht und als Terminal xterm mit aktiviertem Sixel-Modus benutzt (natürlich ohne GNU screen, denn das macht ja sixel kaputt!)- kann man sich die Graphik einfach direkt im Terminal ansehen:
wget -O - "https://plantuml.com/plantuml/img/$(cat te1.puml | \
gzip --no-name | tail --bytes=+11 | head --bytes=-8 | base64 -w 0 - | \
tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\-_')" \
|convert - sixel:-
Der Vollständigkeit halber sei noch erwähnt, dass ich ja oben als Ziel ausgegeben hatte, in Issues enthaltene PlantUML-Definitionen darzustellen - bisher jedoch ging es lediglich darum, PlantUML-Dateien zu verarbeiten. Dieser letzte Schritt ist allerdings einfach: Man definiert lediglich einen Start-und einen End-Marker für PlantUML-Definitionen im Text eines Issues. Dann kann man mittels awk gezielt diese Sektion herausschneiden und mit dem Ergebnis dann so verfahren, wie bereits beschrieben. Ich demonstriere das hier mal, indem ich eine Idee von stackoverflow ein wenig erweitere - zunächst definieren wir die Testdaten:
#END
This is a simple test file.
#BEGIN
These lines should be extracted by our script.
Everything here will be copied.
#END
That should be all.
#BEGIN
Nothing from here.
#END
Mit folgendem Skript für awk kann man bestimmen, dass man den section Block zwischen marker_start und marker_end herausschneiden möchte:
#!/usr/bin/awk -f
BEGIN {
a=section
}
$1 ~ marker_start { # If we match the BEGIN line
a-- # Set a flag to one
next # skip to the next line
}
$1 ~ marker_end && a == 0 { # if we match the END line and we found the BEGIN we searched for
#$1 ~ close { # if we match the END line
exit # exit the process
}
a == 0 { # if the flag is not zero
print $0 # print the current line
}
Aufgerufen wird das dann mittels awk -v section=2 -v marker_start=#BEGIN -v marker_end=#END te.txt
Damit ist mein Ziel erreicht: ich kann die Beschreibung als Text in Issues packen und habe eine schnelle und unkomplizierte (wenn man den One-Liner in ein Shell-Skript verpackt) Methode, mit Bordmitteln schnell auf die Darstellung zuzugreifen!
BeanShell REPL Plugin für sQLshell
17.08.2021
Es gibt wieder einmal ein neues Plugin für die sQLshell
WeiterlesenAI und ML Android Basteln C und C++ Chaos Datenbanken Docker dWb+ ESP Wifi Garten Geo Go GUI Hardware Java Jupyter JupyterBinder Komponenten Links Linux Markdown Markup Music Numerik OpenSource PKI-X.509-CA Präsentationen Python QBrowser Rants Raspi Revisited Security Software-Test sQLshell TeleGrafana Verschiedenes Video Virtualisierung Windows Upcoming...
Hier meine Highlights der DefCon 34 in Las Vegas
WeiterlesenNach der letzten losen Zusammenstellung (für mich) interessanter Links aus den Tiefen des Internet von 2026 folgt hier gleich die nächste:
Weiterlesen
DOT-Export aus dWb+Bereits seit längerem war ein Feature in dWb+ in der Beta-Phase, das es unkompliziert erlaubt, Workspaces in beliebige andere Formate zu exportieren. Während dieser Tests wurden verschiedene Formate als Testsubjekt herangezogen - unter anderem DOT.
WeiterlesenManche nennen es Blog, manche Web-Seite - ich schreibe hier hin und wieder über meine Erlebnisse, Rückschläge und Erleuchtungen bei meinen Hobbies.
Wer daran teilhaben und eventuell sogar davon profitieren möchte, muss damit leben, daß ich hin und wieder kleine Ausflüge in Bereiche mache, die nichts mit IT, Administration oder Softwareentwicklung zu tun haben.
Ich wünsche allen Lesern viel Spaß und hin und wieder einen kleinen AHA!-Effekt...
PS: Meine öffentlichen Codeberg-Repositories findet man hier.