Compare commits

1 Commits

Author SHA1 Message Date
9eb63b111d Dateien nach "/" hochladen 2026-04-01 08:00:29 +02:00
3 changed files with 256 additions and 331 deletions

2
.gitignore vendored
View File

@@ -1,2 +0,0 @@
# Testskripte werden nicht versioniert (enthalten ggf. sensible Produktionsskripte)
testskripte/

View File

@@ -1,74 +0,0 @@
# 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

View File

@@ -1,5 +1,3 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
""" """
repovizcheck.py repovizcheck.py
@@ -22,7 +20,6 @@ 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"| _ \ ___ _ __ ___ \ \ / (_)____ / ___| |__ ___ ___| | _____ _ __ ")
@@ -60,10 +57,9 @@ 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 = io.open(name, "r", encoding='utf-8') f = 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
@@ -71,7 +67,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 io.open(name, "r", encoding='ISO-8859-1') return 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!")
@@ -117,11 +113,11 @@ def erstelle_liste(datei, typ): # 2 Parameter
return tabellenliste return tabellenliste
def trennzeile(typ): # Funktion zum Ausgeben einer Trennzeile. def trennzeile(typ): # Funktion zum Ausgeben einer 80 Zeichen breiten Trennzeile.
''' '''
Erstellt eine 87 zeichenbreite Zeile mit dem übergebenen Zeichen Erstellt eine 80 zeichenbreite Zeile mit dem übergebenen Zeichen
''' '''
print(typ * 87) # Das Trennzeichen ist variabel und wird der Funktion als Parameter uebergeben. print(typ * 80) # 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
@@ -206,14 +202,15 @@ 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
@@ -223,8 +220,10 @@ 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("~")
@@ -242,8 +241,10 @@ 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("+")