contract_validator.py
- Pfad:
/var/www/mcp-servers/mcp-contracts/validators/contract_validator.py
- Namespace: -
- Zeilen: 120 | Größe: 4,402 Bytes
- Geändert: 2025-12-28 13:28:45 | Gescannt: 2025-12-31 10:22:15
Code Hygiene Score: 97
- Dependencies: 90 (25%)
- LOC: 100 (20%)
- Methods: 100 (20%)
- Secrets: 100 (15%)
- Classes: 100 (10%)
- Magic Numbers: 90 (10%)
Issues 1
| Zeile |
Typ |
Beschreibung |
| 109 |
magic_number |
Magic Number gefunden: 100 |
Dependencies 6
- use os
- use typing.Optional
- use typing.Any
- use domain.contracts.ContractValidationResult
- use validators.scope_resolver.ScopeResolver
- use validators.rule_evaluator.RuleEvaluator
Klassen 1
-
ContractValidator
class
Zeile 11
Funktionen 1
-
run_contract_validation()
Zeile 113
Code
"""Contract Validator - Orchestriert Contract-Validierung."""
import os
from typing import Optional, Any
from domain.contracts import ContractValidationResult
from validators.scope_resolver import ScopeResolver
from validators.rule_evaluator import RuleEvaluator
class ContractValidator:
"""Orchestriert Contract-Validierung mittels ScopeResolver und RuleEvaluator."""
BASE_PATH = "/var/www/dev.campus.systemische-tools.de"
SUPPORTED_EXTENSIONS = (".php", ".js", ".css", ".py")
def __init__(
self,
contract_data: dict[str, Any],
scope_resolver: Optional[ScopeResolver] = None,
rule_evaluator: Optional[RuleEvaluator] = None,
):
self.contract_data = contract_data
self.contract_name = contract_data.get("contract", {}).get("name", "unknown")
self.scope_resolver = scope_resolver or ScopeResolver(self.BASE_PATH)
self.rule_evaluator = rule_evaluator or RuleEvaluator()
def validate(self, target_path: Optional[str] = None) -> ContractValidationResult:
"""Fuehrt vollstaendige Validierung durch."""
result = ContractValidationResult(
contract=self.contract_name,
outcome="passed",
critical=0,
major=0,
minor=0,
findings=[],
)
contract = self.contract_data.get("contract", {})
scope = contract.get("scope", {})
legacy_applicability = self.contract_data.get("applicability")
check_paths = self.scope_resolver.resolve_paths(
scope, target_path, legacy_applicability
)
if not check_paths:
result.findings.append({"type": "info", "message": "No paths to validate"})
return result
for check_path in check_paths:
if not os.path.exists(check_path):
result.critical += 1
result.findings.append({
"type": "critical",
"factor": "path_existence",
"message": f"Path does not exist: {check_path}",
})
continue
if os.path.isdir(check_path):
self._validate_directory(check_path, result)
else:
self._validate_file(check_path, result)
result.outcome = self.rule_evaluator.determine_outcome(result)
return result
def _validate_directory(self, dir_path: str, result: ContractValidationResult) -> None:
"""Validiert alle Dateien in einem Verzeichnis."""
for root, _, files in os.walk(dir_path):
for f in files:
if f.endswith(self.SUPPORTED_EXTENSIONS):
self._validate_file(os.path.join(root, f), result)
def _validate_file(self, file_path: str, result: ContractValidationResult) -> None:
"""Validiert eine einzelne Datei gegen den Contract."""
try:
with open(file_path, "r", encoding="utf-8") as f:
content = f.read()
contract = self.contract_data.get("contract", {})
# Rules-basierte Validierung
for rule in contract.get("rules", []):
in_files = rule.get("in_files", "**/*")
if self.scope_resolver.file_matches_pattern(file_path, in_files):
self.rule_evaluator.evaluate_rule(file_path, content, rule, result)
# Legacy-Formate
forbidden = contract.get("forbidden", [])
if forbidden:
self.rule_evaluator.evaluate_legacy_forbidden(
file_path, content, forbidden, result
)
required = contract.get("required", [])
if required:
self.rule_evaluator.evaluate_legacy_required(
file_path, content, required, result
)
except Exception as e:
result.minor += 1
result.findings.append({
"type": "minor",
"factor": "file_read_error",
"file": file_path,
"message": str(e)[:100],
})
def run_contract_validation(
contract_data: dict[str, Any],
target_path: Optional[str] = None,
) -> ContractValidationResult:
"""Hilfsfunktion fuer Contract-Validierung."""
validator = ContractValidator(contract_data)
return validator.validate(target_path)