diff --git a/LabelHandler.py b/LabelHandler.py index 6088295..e649f28 100644 --- a/LabelHandler.py +++ b/LabelHandler.py @@ -1,45 +1,50 @@ -from sqlalchemy import Table, Column, Integer, String,MetaData,select,insert,NVARCHAR +from sqlalchemy import Table, Column, Integer, String,MetaData,select,insert,NVARCHAR,TIMESTAMP,and_ from sqlalchemy.orm import sessionmaker from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import Session +import datetime Base = declarative_base() class LabelHandler: - def __init__(self,engine) -> None: + def __init__(self,engine,engineSource) -> None: self.engine=engine + self.engineSource=engineSource def getNewReleases(self): - class PropertyNamesChecked(Base): - __tablename__ = 'PropertyNamesChecked' + class LabelsChecked(Base): + __tablename__ = 'LabelsChecked' id = Column(Integer, primary_key=True) - Project = Column(NVARCHAR(length=100)) - CurrentVersion = Column(NVARCHAR(length=145)) + DW_ID_Label = Column(Integer) + DW_ID_Project = Column(Integer) + timestamp = Column(TIMESTAMP) - Base.metadata.create_all(self.engine) + + + #LabelsChecked. (self.engine) - #Session = sessionmaker(bind=self.engine) session = Session(self.engine, future=True) + sessionSource = Session(self.engineSource, future=True) meta = MetaData() - meta.reflect(bind=self.engine) - listDeployedLabels=meta.tables['ListDeployedLabels'] - class ListDeployedLabels(Base): - __table__=listDeployedLabels + meta.reflect(bind=self.engineSource,schema='dpl') + t_label=meta.tables['dpl.Label'] + class Label(Base): #biadmin.dpl.[Label] + __table__= t_label __mapper_args__ = { - 'primary_key':[listDeployedLabels.c.Project] + 'primary_key':[t_label.c.DW_ID_Label] } - statement=select(ListDeployedLabels).join(PropertyNamesChecked,PropertyNamesChecked.Project==ListDeployedLabels.Project) +# statement=select(ListDeployedLabels).join(PropertyNamesChecked,PropertyNamesChecked.Project==ListDeployedLabels.Project) - listOfUncheckedPropertyNames=session.execute(statement).scalars().all() + listOfUncheckedPropertyNames=sessionSource.scalars(select(Label).where(Label.isCurrent==True).where(Label.DateDeployed>=datetime.datetime.today()-datetime.timedelta(days=1))).all() return listOfUncheckedPropertyNames def markAsChecked(self): pass - def getLabel(self,listDeployedLabels:Base): + def getLabel(self,listDeployedLabels:Base) -> str: strLabel="" - strLabel=listDeployedLabels.CurrentVersion.split(':')[2].strip() + strLabel=listDeployedLabels.Label.split(':')[2].strip() return strLabel \ No newline at end of file diff --git a/RepositoryAutoCheck.py b/RepositoryAutoCheck.py index 1119856..0745eac 100644 --- a/RepositoryAutoCheck.py +++ b/RepositoryAutoCheck.py @@ -1,26 +1,52 @@ +from ast import Continue from sqlalchemy import create_engine import urllib from LabelHandler import LabelHandler from TfsHandler import TfsHandler +from jproperties import Properties +import datetime server = 'bi-dsa-udv\dsa' # to specify an alternate port database = 'udv_denker' -username = 'admindenker' -password = 'biadmin#kode4meO9' tfsBasePath=r'F:\Users\admindenker\TFS Workspace' -tfPath=r'c:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE' +tfPath=r'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer' +sqlpackage=r'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\Extensions\Microsoft\SQLDB\DAC\130' connection_string = "DRIVER={SQL Server};Database="+database+";SERVER="+server connection_string = urllib.parse.quote_plus(connection_string) connection_string = "mssql+pyodbc:///?odbc_connect=%s" % connection_string engine = create_engine(connection_string, echo = True) -labelHandler = LabelHandler(engine) +serverSource = 'bi-dsa-test\dsa' # to specify an alternate port +databaseSource = 'biadmin' +connection_string_source = "DRIVER={SQL Server};Database="+databaseSource+";SERVER="+serverSource +connection_string_source = urllib.parse.quote_plus(connection_string_source) +connection_string_source = "mssql+pyodbc:///?odbc_connect=%s" % connection_string_source +engineSource = create_engine(connection_string_source, echo = True) + + +labelHandler = LabelHandler(engine,engineSource) tfsHandler = TfsHandler(tfPath,tfsBasePath) newReleases=labelHandler.getNewReleases() + for a in newReleases: - print(labelHandler.getLabel(a)) - path=tfsHandler.getProjectPath(labelHandler.getLabel(a)) + print(a.Label) + failedPackages=tfsHandler.checkLabel(a.Label) + if(failedPackages is not None and len(failedPackages)>0): + logfile=open(r'f:\packageCheck\\'+str(datetime.datetime.today().year)+str(datetime.datetime.today().month)+str(datetime.datetime.today().day)+'_failedPackeges.txt','a') + logfile.write('---------------------------------------------------------------------------------------------------------------\n') + logfile.write(str(a.Label)+'\n') + logfile.write('Deployed af : ' + str(a.DeployedBy) + '\n') + logfile.write('---------------------------------------------------------------------------------------------------------------\n') + for packages in failedPackages: + logfile.write('File: '+ str(packages[0]) + '\n') + logfile.write('PropertyName: ' + str(packages[1]) + '\n') + + logfile.write('---------------------------------------------------------------------------------------------------------------\n') + logfile.write('\n') + logfile.close() + + print("done") diff --git a/TfsHandler.py b/TfsHandler.py index 767a717..84b5906 100644 --- a/TfsHandler.py +++ b/TfsHandler.py @@ -1,5 +1,9 @@ +from ast import List from pathlib import Path +from os import chdir import subprocess + +from LabelHandler import LabelHandler class TfsHandler(): def __init__(self,tfPath,tfsBasePath): self.tfPath=Path(tfPath) @@ -8,10 +12,12 @@ class TfsHandler(): pass def updateRepository(self): pass - def checkFile(self, file): + def checkFile(self, file:Path) -> List: + fileResult=[] f=open(file,"r", encoding='utf-8') for x in f: if(x.find("DTS:ObjectName")>-1): + fileResult=[file] propertyNameTokens=x.split('=') count=0 propertyNameToken=None @@ -22,28 +28,66 @@ class TfsHandler(): count+=2 if(propertyNameToken==None): print(f"propertyNameToken findes ikke i {file.name}") + fileResult+=['',False] continue - if(file.stem!=propertyNameToken): - ssisproject=[a for a in file.parts if a.find("SSIS_")>-1] - if(len(ssisproject)>0): - #insertOrUpdateTable(ssisproject[0],str(file.parent),str(file.stem),propertyNameToken) - # insertIntoTable(ssisproject[0],str(file.parent),str(file.stem),propertyNameToken) - print(ssisproject[0] + ' ' + str(file.parent) + ' ' + file.stem + ' ' + propertyNameToken) - print(x) + fileResult+=[propertyNameToken] + if( str.lower(file.stem)!=str.lower(propertyNameToken)): + fileResult+=[False] + else: + fileResult+=[True] break else: continue f.close() - def updateRepo(self,path): - project='' + return fileResult + def updateRepo(self,label,path): + chdir(path) + updateStatus=subprocess.run([str(self.tfPath.joinpath('tf.exe')),"vc","get","/all","/version:L"+label,str(path)],stdout=subprocess.PIPE,stderr=subprocess.PIPE,shell=True,text=True) + if(len(updateStatus.stdout)>0): + print("STDOUT:\n" + updateStatus.stdout) + return True + else: + print("STDERR:\n" + updateStatus.stdout) + return False + def getProjectPath(self,label): labelInfo=subprocess.run([str(self.tfPath.joinpath('tf.exe')),"vc","labels","/owner:*","/format:detailed",label],stdout=subprocess.PIPE,stderr=subprocess.PIPE,shell=True,text=True) if(len(labelInfo.stdout)>0): - relativePath=labelInfo.stdout.split('\n')[9].split('$')[1] - return self.tfsBasePath.joinpath(relativePath.removeprefix('/')) - def traverseDirectory(x): - if (x.name=='obj' or x.name.strip()=='DataPresentationArea' or x.name=='FastTrack' or x.name=='Undervisning' or x.name=='Udvikling'): - print(x.name) - return - [checkFile(z) for z in x.iterdir() if z.is_file and z.name.endswith('.dtsx')] - [traverseDirectory(y) for y in x.iterdir() if y.is_dir()] \ No newline at end of file + print("STDOUT:\n" + labelInfo.stdout) + for a in labelInfo.stdout.split('\n'): + if(a.find('$/Datavarehus')!=-1 and a.find('Scope')==-1): + relativePath=a.split('$')[1] + break + else: + print("STDERR:\n" + labelInfo.stdout) + return None + resPath=self.tfsBasePath.joinpath(relativePath.removeprefix('/')) + if(resPath.is_dir() == False): + return None + else: + return resPath + def traverseDirectory(self, x:Path,propertyNameDiffs:List): + [print(z) for z in x.iterdir() if z.is_file and z.name] + [propertyNameDiffs.append(self.checkFile(z)) for z in x.iterdir() if z.is_file and z.name.endswith('.dtsx')] + [self.traverseDirectory(y,propertyNameDiffs) for y in x.iterdir() if y.is_dir() and y.name!='obj'] + print(propertyNameDiffs) + + def checkLabel(self,label): + labelResult=[] + if(label[0:4]=='SSIS'): + projectPath=self.getProjectPath(label) + if projectPath == None: + return + updated=self.updateRepo(label,projectPath) + if(updated==False): + return + labelResult=self.checkSSISProject(projectPath) + return labelResult + def checkSSISProject(self, projectPath): + labelResult=[] + self.traverseDirectory(Path(projectPath),labelResult) + failed=[a for a in labelResult if a[-1]==False] + return failed + + +