40-validation/validate-semantic-quality-gate.py

#!/usr/bin/env python3
import argparse,json
from pathlib import Path
def validate(config_path):
 config=json.loads(config_path.read_text(encoding='utf-8')); errors=[]; reviews=[]; covered=[]
 for item in config.get('checks',[]):
  ident=item.get('id','UNKNOWN'); path=(config_path.parent/item.get('report','')).resolve()
  if not path.is_file(): errors.append({'code':'NOT_YET_COVERED','check':ident,'report':item.get('report'),'message':'Pflichtreport fehlt.'});continue
  try: report=json.loads(path.read_text(encoding='utf-8')); status=report.get('status')
  except Exception as exc: errors.append({'code':'INVALID_REPORT','check':ident,'message':str(exc)});continue
  covered.append({'id':ident,'report':item.get('report'),'status':status})
  if status=='FAILED': errors.append({'code':'FAILED_CHECK','check':ident,'report':item.get('report')})
  elif status=='REVIEW_REQUIRED': reviews.append({'id':ident,'report':item.get('report'),'reason':'Einzelreport verlangt fachliches Review.'})
  elif status=='NOT_YET_COVERED' and not item.get('optional',False): errors.append({'code':'NOT_YET_COVERED','check':ident,'report':item.get('report')})
  elif status!='PASSED' and status!='NOT_YET_COVERED': errors.append({'code':'INVALID_CHECK_STATUS','check':ident,'status':status})
 return {'schemaVersion':'1.0','workItem':'SE-0034','status':'FAILED' if errors else 'PASSED','phase3Passed':not errors,'checks':covered,'reviewRequired':reviews,'failed':errors,'contentTruthAssessed':False}
def main():
 p=argparse.ArgumentParser();p.add_argument('config',type=Path);p.add_argument('--output',type=Path);a=p.parse_args()
 try:r=validate(a.config)
 except Exception as e:r={'schemaVersion':'1.0','workItem':'SE-0034','status':'FAILED','phase3Passed':False,'checks':[],'reviewRequired':[],'failed':[{'code':'INVALID_INPUT','message':str(e)}],'contentTruthAssessed':False}
 text=json.dumps(r,ensure_ascii=False,indent=2)+'\n'
 if a.output:a.output.parent.mkdir(parents=True,exist_ok=True);a.output.write_text(text,encoding='utf-8')
 else:print(text,end='')
 raise SystemExit(0 if r['status']=='PASSED' else 1)
if __name__=='__main__':main()