Veille techno - PlantUML

Raymond Gauthier

2020/01/23

Histoire derrière PlantUML

Histoire derrière PlantUML

PlantUML Logo

Arnaud Roques

  • Développeur: Arnaud Roques

  • Premier release: 17 April 2009.

  • L’auteur désirait une façon de créer et mettre à jour ses diagrammes à même Microsoft word.

  • Inspiration de l’auteur: L’outil en ligne: WebSequenceDiagrams.

  • Était trop limité pour ses besoin (seulement diagramme de séquence) et puisqu’en ligne demandait tout de même des opérations de “copier / coller”.

Pourquoi PlantUML

Pourquoi PlantUML - Simplicité

So simple

  • Représentation textuelle

    Un simple DSL1 / notation bien spécifiée pour déclarer des diagrammes.

  • Gratuit

  • Édité avec les mêmes outils que le code source

  • Plus besoin de se poser des questions ennuyantes telles que:

    • Quel est l’outil ayant servit à générer cette image?
    • As t-on une license de disponible?
    • Roule-t-il sur mon système?
    • Ou est passé le bouton x pour faire y?
    • Pourquoi ça ne charge plus?
  • On édite simplement le diagramme avec notre éditeur préféré

Pourquoi PlantUML - Documentation vivante

Beating heart

  • Plus de diagrammes “pas à jour”

  • Vit au même endroit que votre code source

  • Versionnée

  • Un refactor du code impliquera un refactor des diagrammes

  • Un reviewer du code source verra également les changements au diagrammes

  • Bref, on a les choses bien en main!

Pourquoi PlantUML - Automatisable

Automation

  • Plus besoin d’opérations manuelles désagréables puisqu’on a une application en ligne de commande

  • L’outil devient le compilateur pour votre documentation

  • À ce titre, on peut même l’enrober dans un Makefile ou tout autre build system au choix

  • Nous en parlerons plus en détails dans quelques “slides”

Installation

Installation - Requis

java

  • Java Runtime Environment

  • Graphviz

  • plantuml.jar

  • Puisqu’en java, fonctionne donc sur toutes les plateformes supportant Java et Graphviz.

  • Pour les plateformes unix-like: nix/nixpkgs offre un packet qui s’occupe de tout installer pour vous tout en exposant un petit executable plantuml:

    $ nix-env -i plantuml
    $ plantuml -help
    # ..
  • Voir installer nix pour l’installation de nix.

Installation - Requis (suite)

  • Il est possible que votre distribution linux ou package manager osx offre également un packet du même genre.

    Je vous laisse cependant l’exercice de le découvrir vous même.

  • Pour tout autres plateformes, il s’agit d’installation les dépendances, télécharger plantuml.jar et de le rouler via la JVM.

    $ export GRAPHVIZ_DOT=/path/to/graphviz/dot
    $ java -jar /path/to/my/downloaded/plantuml.jar -help
    # ..

    À noter GRAPHVIZ_DOT permettant de spécifier l’emplacement d’installation de l’exécutable dot.

  • Il pourrait être également utile (dépendamment des outils utilisés) d’exposer l’emplacement d’installation de plantuml.jar via PLANTUML_JAR_PATH.

Utilisation

Utilisation - Ligne de commande

  • Assumant le fichier: my.puml suivant:

    @startuml
    A -> B: My message
    @enduml
  • Rouler:

    $ plantuml my.puml
    # ..
  • Produira l’image my.png suivante:

    my.png

  • Comme le montre l’aide en ligne de commande, png n’est pas le seul format de sortie:

    $ plantuml -help
    # ...
    -tpng               To generate images using PNG format (default)
    -tsvg               To generate images using SVG format
    -teps               To generate images using EPS format
    -tpdf               To generate images using PDF format
    -tvdx               To generate images using VDX format
    -txmi               To generate XMI file for class diagram
    -tscxml             To generate SCXML file for state diagram
    -thtml              To generate HTML file for class diagram
    -ttxt               To generate images with ASCII art
    -tutxt              To generate images with ASCII art using Unicode characters
    -tlatex             To generate images using LaTeX/Tikz format
    -tlatex:nopreamble  To generate images using LaTeX/Tikz format without preamble
    # ..

Utilisation - Ligne de commande (suite)

  • Ma recommandation en générale est de générer une image svg:

    $ plantuml -tsvg my.puml
    # ..
    $ ls
    my.puml my.svg # ..

    Voici pouquoi:

    • Format vectoriel sans perte / non discrétisé. Vous ne serez pas limité à un affichage à un dpi spécifique.

    • Textuel, donc mieux supporté par git et autres système de gestions de code source.

    • S’ouvre à l’aide de n’importe que navigateur moderne (e.g: firefox ./my.svg).

  • Voici le résultat:

    my.svg

  • Bien remarquer également la transparent du fond de l’image contrairement au png.

Utilisation - Makefile

  • On peut en quelques lignes se faire un petit makefile (gnu dans ce cas-ci) permettant de produire des images (*.svg dans ce cas) pour l’ensemble des fichier de code *.puml dans une arborescence de répertoires:

    MKF_CWD := $(shell pwd)
    OUTPUT_REL_DIR := .
    SRC_PUML := $(shell \
        find . -mindepth 1 -type f -name '*.puml' -printf '%P\n')
    OUT_SVG_FROM_PUML := $(patsubst \
        %.puml,$(OUTPUT_REL_DIR)/%.svg,$(SRC_PUML))
    
    
    .PHONY: all clean svg-from-puml clean-svg-from-puml
    all: svg-from-puml
    clean: clean-svg-from-puml
    svg-from-puml: $(OUT_SVG_FROM_PUML)
    clean-svg-from-puml:
        rm -f $(OUT_SVG_FROM_PUML)
    
    .SECONDEXPANSION:
    $(OUTPUT_REL_DIR)/%.svg : %.puml | $$(@D)/.
        plantuml -tsvg -o "$(MKF_CWD)/$(@D)/" "$<"
    $ make
    plantuml -tsvg -o "/my/cwd/./" "AtRoot.puml"
    plantuml -tsvg -o "/my/cwd/SubDir/" "SubDir/InSubDir.puml"
    $ tree
    .
    ├── AtRoot.puml
    ├── AtRoot.svg
    ├── Makefile
    └── SubDir
        ├── InSubDir.puml
        └── InSubDir.svg
    
    1 directory, 5 files
    • Un avantage vis-à-vis plantuml -r (mode récursif de PlantUML) c’est qu’on a un bien meilleur contrôle sur les images en sortie (où on les envoi, etc).
    • Également, le makefile ne relancera pas la commande si le fichier de source est inchangé.

Utilisation - Extension vscode

Vscode - PlantUML extension - Screenshot

  • Vscode - PlantUML extension

    Une extension permettant d’obtenir un preview pane du code plantuml.

    Amène également un support de syntax highlighting pour le code source plantuml.

    • Ouvrir le fichier *.puml, *.iuml ou *.wsd.
    • Mettre votre pointeur à l’intérieur de la zone @start / @end.
    • Alt + D.
    • Un panneau s’ouvrira à droite avec la version rendue de votre diagramme.
  • Une excellent façon d’itérer sur un diagramme.

  • À noter: le panneau se rafraîchit automatiquement lorsque vous éditez le code.

Utilisation - Cloud

Pour tous nos amis qui ont la tête dans les nuages, plusieurs solutions s’offrent à vous:

PlantText UML Editor - Screenshot

Utilisation - Microsoft Word / Open office

  • On voit ici à gauche la démonstration d’une macro pour l’intégration PlanUML dans Microsoft Word.

    Rappelez vous, c’était l’une des motivation principales de l’auteur.

    PlantUML - Word Add-in

  • Je ne suis pas certain que tout fonctionne encore bien avec Office 365 (puisqu’en ligne), du moins sans avoir à payer une souscription! À essayer avec la version installé.

Utilisation - À même un doc markdown

  • Une extension vscode et atom supportant le rendu de blocs de code PlantUML se trouvant directement dans un fichier markdown (*.md).

    • Support l’import de fichier *.puml externe via la directive @import.
    • Support plusieurs autres types de diagrammes / visualisations.
    • L’intérêt ici c’est de se servir des diagramme pour expliquer quelque chose: le diagramme vient en support au texte.
  • Il est également assez simple d’automatiser workflow en combinant pandoc, PlantUML et un build system au choix (e.g.: gnumake).

    Voir pandoc-md-wiki pour un example d’intégration. Cette présentation en est d’ailleur un example.

Utilisation - Autres

Types de diagrammes UML

Types de diagrammes - Sequence

@startuml
hide footbox
actor user
participant webfrontend
participant webserver
participant hwdevice
participant os

user -> hwdevice ++ : power on
hwdevice -> hwdevice ++: boot process
hwdevice -> os ++: boot loader
os -> webserver **: launch
activate webserver
return success
os -> webfrontend **: launch
activate webfrontend
webfrontend -> webserver ++: request html ui
return html ui
webfrontend --> os : success
deactivate webfrontend
@enduml

puml

Types de diagrammes - Sequence (suite)

@startuml
hide footbox
actor user
participant webfrontend
participant webserver
participant hwdevice
participant os

user ->> webfrontend ++: click on process button
webfrontend -> webserver ++: request processing result
webserver -> hwdevice ++: request sensor state\nsample (camera, etc)
return sensors states
webserver -> webserver ++: process sensor states
return result
webfrontend -> webfrontend ++: render into images
return images
webfrontend ->> user: images as light
@enduml

puml

Types de diagrammes - Class

@startuml
interface Animal {
    +get_name(): str
    +get_legs(): Leg[]
}

class Leg
class Fin
class Dog {
    +barks()
}
class Master {
    +run()
}

Animal <|-- Dog: inherits
Animal <|-- Dolphin: inherits
Lion -|> Animal: inherits

Lion o--> "0-1" Dog: hold in its mouth
Lion o--> "0-1" Master: hold in its mouth
Dog *--> "4" Leg: has
Dolphin *--> "0" Leg
Dolphin *--> "1" Fin

Dog ..> Master: depends on its
@enduml

puml

Types de diagrammes - Activity

@startuml
start
-> <u>**Systemd supports parallel boot!**</u>;
partition "System Boot" {
  fork
    partition "Update System" {
      if (requires updates?) then
        repeat :Download <u>*app*</u> update package;
        repeat while (not ok and retry count\nnot exhausted)
        if (download package?) then
          -[#green]->
          :Installing new <u>*app*</u> package;
        else
          -[#red]-> Cannot proceed, this is not safe!
          **shuting down** the system...;
          end
        endif
      endif
    }
  fork again
    :Launching postgres db;
    :Launching application backend;
  end fork
}
:Lauching application;
stop
@enduml

puml

Types de diagrammes - Timing

@startuml
scale 1 as 100 pixels
Title Power of a street light as a function of time
legend
february 18 2017
end legend
header: Test MY-MODEL

robust "Street light power 80000 (kWh) as P" as P
robust "Requested (%)" as R
P has 0.07,0.06,0.05,0.04,0.03,0.02,0.01,0.00
R has 100,90,80,70,60,50,40,30,20,10,0

@0
P is 0.00: 15:00
R is 0
@1
P is 0.00
R is 0
@2
P is 0.02 : 17:00
R is 30
@3
P is 0.08 : Sun set
R is 80
@4
P is 0.04
R is 80
@enduml

puml

Types de diagrammes - State

@startuml
state "Awaiting input" as State1
state "Looking for matches" as State2
state "Processing selection" as State4

[*] -> State1
State1 --> State2 : Input received
State1 --> [*] : Timeout
State2 --> State1 : No matches / To many matches
State2 --> State4 : Single match
State2 --> State3 : Multiple maches found
state State3 {
  [*] --> State3A
  state "CursorOnMatch1" as State3A
  state "CursorOnMatch2" as State3B
  State3A --> State3B: Arrow down
  State3A --> [*]: Enter / Esc / Ctrl+c
  State3B --> State3A: Arrow up
  State3B --> [*]: Enter / Esc / Ctrl+c
}

State3 --> [*] : Selection rejected / Aborted
State3 --> State4 : Single match selected
State4 --> [*]: Done
@enduml

puml

Types de diagrammes - Use Case

@startuml
left to right direction
skinparam packageStyle rectangle
actor customer
actor clerk
rectangle checkout {
  customer -- (checkout)
  (checkout) .> (payment) : include
  (help) .> (checkout) : extends
  (checkout) -- clerk
}
@enduml

puml

Types de diagrammes - Component

@startuml

package "Some Group" {
  HTTP - [First Component]
  [Another Component]
}
 
node "Other Groups" {
  FTP - [Second Component]
  [First Component] --> FTP
} 

cloud {
  [Example 1]
}


database "MySql" {
  folder "This is my folder" {
    [Folder 3]
  }
  frame "Foo" {
    [Frame 4]
  }
}


[Another Component] --> [Example 1]
[Example 1] --> [Folder 3]
[Folder 3] --> [Frame 4]

@enduml

puml

Types de diagrammes - Autres UML

Voici d’autres diagrammes que je n’ai pas encore eu l’occasion ou trouvé le besoin d’utiliser:

Types de diagrammes Non-UML

Types de diagrammes - Entity Relationship

Une extension des diagrammes de classes permettant de faire de la schématisation DB.

@startuml
skinparam linetype ortho

entity "Class" as e_class {
  *class_id : number <<generated>>
  --
  *name : text
}

entity "Student" as e_student {
  *student_id : number <<generated>>
  --
  class_id : number <<FK>>
  phone_number : text
}

entity "Teacher" as e_teacher {
  *teacher_id : number <<generated>>
  --
  *class_id : number <<FK>>
  other_details : text
}

e_class }|..o{ e_student: includes / goes to
e_class ||..o{ e_teacher: is taught / teaches
e_student }|..|{ e_teacher: has
@enduml

puml

Types de diagrammes - Mind Map

@startmindmap
+ OS
++ Ubuntu
+++ Linux Mint
+++ Kubuntu
+++ Lubuntu
+++ KDE Neon
++ LMDE
++ SolydXK
++ SteamOS
++ Raspbian
-- Windows 95
-- Windows 98
-- Windows NT
--- Windows 8
--- Windows 10
@endmindmap

puml

Types de diagrammes - Gantt

Pour Cédric et autre gestionnaires:

@startgantt
[Prototype design] lasts 13 days and is colored in Lavender/LightBlue
[Test prototype] lasts 9 days and is colored in Coral/Green and starts 3 days after [Prototype design]'s end
[Write tests] lasts 5 days and ends at [Prototype design]'s end
[Hire tests writers] lasts 6 days and ends at [Write tests]'s start
[Init and write tests report] is colored in Coral/Green
[Init and write tests report] starts 1 day before [Test prototype]'s start and ends at [Test prototype]'s end
@endgantt

puml

Types de diagrammes - WBS

@startwbs
+ New Job
++ Decide on Job Requirements
+++ Identity gaps
+++ Review JDs
++++ Sign-Up for courses
++++ Volunteer
++++ Reading
++- Checklist
+++- Responsibilities
+++- Location
++ CV Upload Done
+++ CV Updated
++++ Spelling & Grammar
++++ Check dates
---- Skills
+++ Recruitment sites chosen
@endwbs

puml

Types de diagrammes - GUI Mock

Via Salt, on peut même faire du design d’interfaces graphique!

@startsalt
{+
{* File | Edit | Source | Refactor 
 Refactor | New | Open File | - | Close | Close All }
{/ General | Fullscreen | Behavior | Saving }
{
    { Open image in: | ^Smart Mode^ }
    [X] Smooth images when zoomed
    [X] Confirm image deletion
    [ ] Show hidden images 
}
[Close]
}
@endsalt

puml

Types de diagrammes - GUI State machine

Un autre example vraiment très intéressant permettant d’inclure Salt à même un diagramme d’état. Je ne montrerai pas le code puisque trop long, mais voici tout de même le résultat:

puml

Types de diagrammes - Dot

Puisque PlantUML dépend déjà de Graphviz, un support du language dot est offert.

@startdot
digraph foo {
  node [style=rounded]
  node1 [shape=box]
  node2 [fillcolor=yellow, style="rounded,filled", shape=diamond]
  node3 [shape=record, label="{ a | b | c }"]

  node1 -> node2 -> node3
}
@enddot

puml

Types de diagrammes - Ditaa

Le diagram parfait pour les artistes ASCII. Via outil ditaa installable et utilisable séparément.

@startditaa
+--------+   +-------+    +-------+
|        +---+ ditaa +--> |       |
|  Text  |   +-------+    |diagram|
|Document|   |!magic!|    |       |
|     {d}|   |       |    |       |
+---+----+   +-------+    +-------+
    :                         ^
    |       Lots of work      |
    +-------------------------+
@endditaa

puml

Usage avancé

Usage avancé - Diagramme réutilisables

  • Inclusion par path relatif:

    ./my-shared.iuml:

    class MyClass1
    '..

    ./my-diagram.puml:

    !%include ./my-shared.iuml
  • Configuration par défaut: ./my-config.iuml:

    skinparam backgroundColor Silver
    '..
    $ plantuml -I"./my-config.iuml" # ..
    # ..

Usage avancé - Libraries globales

  • Include search path:

    $ java -Dplantuml.include.path="/path/to/my/includes/dir" -jar plantuml.jar # ..
    # ..
  • Permet d’inclure certaines libraries réutilisable à travers les projets.

    En particulier pratique pour les styles mais sans y être limité.

  • Par example:

    $ tree /path/to/my/includes/dir
    /path/to/my/includes/dir
    ├── my-cross-project.iuml
    └── my-other-cross-project.iuml
    
    0 directories, 1 file
    @startuml
    !%include my-cross-project.iuml
    ' Use my shared library.
    my_fn("my-arg1", 22, "blablabla")
    @enduml

Usage avancé - Réutilisation

  • PlantUML vient avec un préprocesseur simple.

  • Permet un certain niveau de réutilisation de diagrammes / parties de diagrammes et configuration.

  • On peut par example penser à un diagramme paramétrable.

    ./my-parameterizable.iuml:

    !function $var_exists_or_default($varname, $default_value)
    !if (%not(%variable_exists($varname)))
    %set_variable_value($varname, $default_value)
    !endif
    !endfunction
    
    $var_exists_or_default("$my_param_a", 5)
    $var_exists_or_default("$my_param_b", 10)
    
    robust "MyEntity" as myEntity
    
    @$my_param_a
    myEntity is StateA
    @$my_param_b
    myEntity is StateB
    !$my_computed_c = $my_param_a + $my_param_b
    @$my_computed_c
    myEntity is StateC
    • Lorsque paramétré par ./my-concrete-diagram.puml

      !$my_param_a = 20
      !include ./my-parameterizable.iuml

      resultat page suivante.

Usage avancé - Réutilisation (suite)

  • Donne:

    puml

  • On remarque StateC commence à 30 plutôt que 15 que l’on aurait obtenu par défaut.

Usage avancé - Éviter la répétition

  • Il arrive parfois que l’on se trouve à répéter un certain patron (timing diagram, etc).

  • Le préprocesseur à la rescousse!

  • Il est en effet possible de répéter un bout de diagramme plusieurs fois via une fonction récursive:

    @startuml
    !function $my_recursive_fn($rec_it, $n_times)
    !if ($rec_it < $n_times)
    
    ' **Pattern** to be repeated here.
    
    'Recurse
    $my_recursive_fn($rec_it + 1, $n_times)
    !endif
    !endfunction
    
    ' Will repeat **Pattern** trice.
    $my_recursive_fn(0, 3)
    @enduml
    @startuml
    ' **Pattern** to be repeated here.
    ' **Pattern** to be repeated here.
    ' **Pattern** to be repeated here.
    @enduml

Usage avancé - Éviter la répétition (suite)

Un example concret:

@startuml
interface MyInterface

!function $my_recursive_fn($rec_it, $n_times)
!if ($rec_it < $n_times)

'**Pattern**
MyInterface <|-- MyDescendant##$rec_it

'Recurse
$my_recursive_fn($rec_it + 1, $n_times)
!endif
!endfunction

' Will repeat **Pattern** trice.
$my_recursive_fn(0, 3)
@enduml

puml

Usage avancé - Aspect visuel

@startuml
skinparam backgroundColor LightYellow
skinparam state {
  StartColor MediumBlue
  EndColor Red
  BackgroundColor Peru
  BackgroundColor<<Warning>> Olive
  BorderColor Gray
  FontName Impact
}

[*] --> NotShooting

state "Not Shooting State" as NotShooting {
  state "Idle mode" as Idle <<Warning>>
  state "Configuring mode" as Configuring
  [*] --> Idle
  Idle --> Configuring : EvConfig
  Configuring --> Idle : EvConfig
}

NotShooting --> [*]
@enduml

puml

Usage avancé - Aspect visuel (suite)

@startuml

skinparam backgroundColor #AAFFFF
skinparam activity {
  StartColor red
  BarColor SaddleBrown
  EndColor Silver
  BackgroundColor Peru
  BackgroundColor<< Begin >> Olive
  BorderColor Peru
  FontName Impact
}

(*) --> "Climbs on Platform" << Begin >>
--> === S1 ===
--> Bows
--> === S2 ===
--> WavesArmes
--> (*)

@enduml

puml

Usage avancé - Library standard

Il existe des dépôts pour Amazon AWS, Kubernetes, la suite Office, etc. Petit example (AWS):

@startuml
!include <aws/common>
!include <aws/Storage/AmazonS3/AmazonS3>
!include <aws/Storage/AmazonS3/bucket/bucket>

AMAZONS3(s3_internal)
AMAZONS3(s3_partner,"Vendor's S3")
s3_internal <- s3_partner
@enduml

puml

Usage avancé - Génération de code à partir de diagramme et l’inverse

À-propos

À-propos - Outils similaires

  • WebSequenceDiagrams

    Celui qui aura inspiré l’auteur.

    Permet de faire des diagrammes de séquence.

  • flowchart.js

    Permet de faire des diagrammes d’activité / diagrammes blocs.

  • js-sequence-diagrams

    Permet de faire des diagrammes de séquence.

  • mermaid

    Permet de faire: activité, séquence, Gantt, class, state, etc.

    Celui qui se rapproche le plus de PlanUML au niveau de la largeur de couverture.

  • wavedrom

    Permet de faire des timing diagrams.

À-propos - Ressources

  • https://plantuml.com

    Le site officiel. Vous y trouverez un documentation généralement assez complète sur chacun des types de diagrammes (beaucoup d’examples).

  • PlantUML Q&A

    Lorsque vous avez des questions plus pointues, une petite recherche / poser une question sur le forum officiel est un des meilleur moyen d’obtenir une réponse avant d’aller fouiller le code source.

    Je vous conseille de vous abonner au flux RSS de ce forum pour les nouveautés.

  • Real World PlantUML

    Grosse librairie comportant des example des différents types de diagrammes.

  • All Skin Parameters

    Une excellente documentation de la grosse majorité des paramètres permettant de changer l’aspect visuel. À noter, tout n’est malheureusement pas là.

  • External and useful links

    Plusieurs références vers des outils utilisant ou liés à PlantUML.

À-propos - Cette présentation