Compare commits
5 Commits
albert-pat
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| f64aeaf31c | |||
| c444a3f6ac | |||
| 2ed4a107b9 | |||
| b2959bebdb | |||
| 6bccca2864 |
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# Testskripte werden nicht versioniert (enthalten ggf. sensible Produktionsskripte)
|
||||||
|
testskripte/
|
||||||
74
README.md
74
README.md
@@ -0,0 +1,74 @@
|
|||||||
|
# RepoVizChecker
|
||||||
|
|
||||||
|
Ein Python-Werkzeug zum Abgleich von **RepoViz-Annotationen** mit dem tatsächlich verwendeten SQL-Code in Kornshell-Skripten (`.ksh`).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Beschreibung
|
||||||
|
|
||||||
|
KSH-Skripte enthalten häufig RepoViz-Metadaten in Form von Kommentar-Annotationen:
|
||||||
|
|
||||||
|
```ksh
|
||||||
|
#@modul: mein_skript.ksh
|
||||||
|
#@quelle: TABELLE_A, TABELLE_B
|
||||||
|
#@ziel: TABELLE_Z
|
||||||
|
```
|
||||||
|
|
||||||
|
`repovizcheck.py` liest diese Annotationen aus und vergleicht sie mit den Tabellennamen, die im Code über `$SCHEMA.<TABELLE>` bzw. `${SCHEMA}.<TABELLE>` tatsächlich referenziert werden.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- ✅ Liest `#@modul:`, `#@quelle:` und `#@ziel:` Annotationen aus dem KSH-Skript
|
||||||
|
- ✅ Erkennt verwendete Tabellen per Regex (`$SCHEMA.*` / `${SCHEMA}.*`)
|
||||||
|
- ✅ Vergleich **Repo → SQL**: Sind alle dokumentierten Tabellen im Code vorhanden?
|
||||||
|
- ✅ Vergleich **SQL → Repo**: Sind alle Code-Tabellen in den Annotationen dokumentiert?
|
||||||
|
- ✅ Prüft, ob der Skriptname in `#@modul:` eingetragen ist
|
||||||
|
- ✅ Encoding-Fallback: UTF-8 → ISO-8859-1
|
||||||
|
- ✅ Temporäre Tabellen (`TMP_*`) werden automatisch ignoriert
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Voraussetzungen
|
||||||
|
|
||||||
|
- Python 3.x
|
||||||
|
- Keine zusätzlichen Pakete erforderlich (nur Standardbibliothek)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Aufruf
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
python repovizcheck.py <skript.ksh>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Beispiel
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
python repovizcheck.py C:\projekte\etl_job.ksh
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Ausgabe (Übersicht)
|
||||||
|
|
||||||
|
| Abschnitt | Beschreibung |
|
||||||
|
|---|---|
|
||||||
|
| **RepoViz-Informationen** | Sortierte Ausgabe von Modul, Quell- und Zieltabellen |
|
||||||
|
| **Modul-Check** | Ist der Skriptname in `#@modul:` eingetragen? |
|
||||||
|
| **Repo → SQL** | Welche dokumentierten Tabellen sind im Code vorhanden / fehlen? |
|
||||||
|
| **SQL → Repo** | Welche Code-Tabellen sind dokumentiert / nicht dokumentiert? |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Hinweise
|
||||||
|
|
||||||
|
- Es werden ausschließlich `.ksh`-Dateien akzeptiert (case-insensitive).
|
||||||
|
- Tabellennamen werden für alle Vergleiche in **Großbuchstaben** normalisiert.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Lizenz
|
||||||
|
|
||||||
|
Internes Werkzeug – Deutsche Telekom AG
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
repovizcheck.py
|
repovizcheck.py
|
||||||
|
|
||||||
@@ -20,6 +22,7 @@ import sys
|
|||||||
import re
|
import re
|
||||||
import os.path as p
|
import os.path as p
|
||||||
import argparse
|
import argparse
|
||||||
|
import io
|
||||||
|
|
||||||
print(r" ____ __ ___ ____ _ _ ")
|
print(r" ____ __ ___ ____ _ _ ")
|
||||||
print(r"| _ \ ___ _ __ ___ \ \ / (_)____ / ___| |__ ___ ___| | _____ _ __ ")
|
print(r"| _ \ ___ _ __ ___ \ \ / (_)____ / ___| |__ ___ ___| | _____ _ __ ")
|
||||||
@@ -57,9 +60,10 @@ if file_suffix not in perm_file_suffix:
|
|||||||
# Funktion zum Oeffnen einer Datei mit Pruefung
|
# Funktion zum Oeffnen einer Datei mit Pruefung
|
||||||
def get(name):
|
def get(name):
|
||||||
'''Funktion zum Oeffnen einer Datei mit Pruefung (prüft Encoding)'''
|
'''Funktion zum Oeffnen einer Datei mit Pruefung (prüft Encoding)'''
|
||||||
|
# io.open() wird verwendet, da es in Python 2 und 3 den encoding-Parameter unterstuetzt.
|
||||||
# Versuche zuerst UTF-8, lese die gesamte Datei zur Validierung.
|
# Versuche zuerst UTF-8, lese die gesamte Datei zur Validierung.
|
||||||
try:
|
try:
|
||||||
f = open(name, "r", encoding='utf-8')
|
f = io.open(name, "r", encoding='utf-8')
|
||||||
f.read() # komplette Datei lesen, um Decode-Fehler sicher zu erkennen
|
f.read() # komplette Datei lesen, um Decode-Fehler sicher zu erkennen
|
||||||
f.seek(0)
|
f.seek(0)
|
||||||
return f
|
return f
|
||||||
@@ -67,7 +71,7 @@ def get(name):
|
|||||||
# UTF-8 passt nicht — versuche ISO-8859-1
|
# UTF-8 passt nicht — versuche ISO-8859-1
|
||||||
try:
|
try:
|
||||||
f.close()
|
f.close()
|
||||||
return open(name, "r", encoding='ISO-8859-1')
|
return io.open(name, "r", encoding='ISO-8859-1')
|
||||||
except IOError:
|
except IOError:
|
||||||
print("")
|
print("")
|
||||||
print("The File", name, "can't be opened with fallback encoding!")
|
print("The File", name, "can't be opened with fallback encoding!")
|
||||||
@@ -113,11 +117,11 @@ def erstelle_liste(datei, typ): # 2 Parameter
|
|||||||
return tabellenliste
|
return tabellenliste
|
||||||
|
|
||||||
|
|
||||||
def trennzeile(typ): # Funktion zum Ausgeben einer 80 Zeichen breiten Trennzeile.
|
def trennzeile(typ): # Funktion zum Ausgeben einer Trennzeile.
|
||||||
'''
|
'''
|
||||||
Erstellt eine 80 zeichenbreite Zeile mit dem übergebenen Zeichen
|
Erstellt eine 87 zeichenbreite Zeile mit dem übergebenen Zeichen
|
||||||
'''
|
'''
|
||||||
print(typ * 80) # Das Trennzeichen ist variabel und wird der Funktion als Parameter uebergeben.
|
print(typ * 87) # Das Trennzeichen ist variabel und wird der Funktion als Parameter uebergeben.
|
||||||
|
|
||||||
|
|
||||||
modulliste = erstelle_liste(sourcefile, such_modul) # Erstelle Liste mit den Modulen
|
modulliste = erstelle_liste(sourcefile, such_modul) # Erstelle Liste mit den Modulen
|
||||||
@@ -202,15 +206,14 @@ trennzeile("~")
|
|||||||
# Quelle - quelleliste
|
# Quelle - quelleliste
|
||||||
# nehme Liste "quelleliste" und suche damit in Liste "neue_liste"
|
# nehme Liste "quelleliste" und suche damit in Liste "neue_liste"
|
||||||
# trennzeile("#")
|
# trennzeile("#")
|
||||||
|
ausgabe = "{:12}{:55}{:20}" # Ausgabeformat: Label(12), Tabellenname(55), Status(20)
|
||||||
print("Are the tables of the list", such_quelle, "included in the SQL?")
|
print("Are the tables of the list", such_quelle, "included in the SQL?")
|
||||||
trennzeile("~")
|
trennzeile("~")
|
||||||
for item in quelleliste:
|
for item in quelleliste:
|
||||||
# quelleliste wurde in erstelle_liste bereits normalisiert (upper)
|
# quelleliste wurde in erstelle_liste bereits normalisiert (upper)
|
||||||
if item.upper() in neue_liste:
|
if item.upper() in neue_liste:
|
||||||
ausgabe = "{:12}{:40}{:20}"
|
|
||||||
print(ausgabe.format("The Table", item, "is available"))
|
print(ausgabe.format("The Table", item, "is available"))
|
||||||
else:
|
else:
|
||||||
ausgabe = "{:12}{:40}{:20}"
|
|
||||||
print(ausgabe.format("The Table", item, "is not available"))
|
print(ausgabe.format("The Table", item, "is not available"))
|
||||||
|
|
||||||
# Quelle - zielliste
|
# Quelle - zielliste
|
||||||
@@ -220,10 +223,8 @@ print("Are the tables of the list", such_ziel, "included in the SQL?")
|
|||||||
trennzeile("~")
|
trennzeile("~")
|
||||||
for item in zielliste:
|
for item in zielliste:
|
||||||
if item.upper() in neue_liste:
|
if item.upper() in neue_liste:
|
||||||
ausgabe = "{:12}{:40}{:20}"
|
|
||||||
print(ausgabe.format("The Table", item, "is available"))
|
print(ausgabe.format("The Table", item, "is available"))
|
||||||
else:
|
else:
|
||||||
ausgabe = "{:12}{:40}{:20}"
|
|
||||||
print(ausgabe.format("The Table", item, "is not available"))
|
print(ausgabe.format("The Table", item, "is not available"))
|
||||||
|
|
||||||
trennzeile("~")
|
trennzeile("~")
|
||||||
@@ -241,10 +242,8 @@ print("Note: I've merged <#@quelle> and <#@ziel> into one list ")
|
|||||||
trennzeile("~")
|
trennzeile("~")
|
||||||
for item in neue_liste:
|
for item in neue_liste:
|
||||||
if item in q_z_liste:
|
if item in q_z_liste:
|
||||||
ausgabe = "{:12}{:40}{:20}"
|
|
||||||
print(ausgabe.format("The Table", item, "is available"))
|
print(ausgabe.format("The Table", item, "is available"))
|
||||||
else:
|
else:
|
||||||
ausgabe = "{:12}{:40}{:20}"
|
|
||||||
print(ausgabe.format("The Table", item, "is not available"))
|
print(ausgabe.format("The Table", item, "is not available"))
|
||||||
|
|
||||||
trennzeile("+")
|
trennzeile("+")
|
||||||
|
|||||||
Reference in New Issue
Block a user