231 lines
8.4 KiB
Python
Executable File
231 lines
8.4 KiB
Python
Executable File
from P4 import P4, P4Exception
|
|
import re
|
|
|
|
class PerforceController():
|
|
p4Instance = None
|
|
|
|
def __init__(self):
|
|
try:
|
|
self.p4Instance = P4()
|
|
self.p4Instance.connect()
|
|
except P4Exception:
|
|
for e in self.p4Instance.errors:
|
|
print e
|
|
self.p4Instance = None
|
|
|
|
########################################################################
|
|
# Function to sync a specified file
|
|
########################################################################
|
|
def SyncFile(self, filename):
|
|
if self.p4Instance is not None:
|
|
try:
|
|
self.p4Instance.run_sync(filename, tagged=False)
|
|
return True
|
|
except P4Exception:
|
|
for e in self.p4Instance.errors:
|
|
print e
|
|
return False
|
|
else:
|
|
return False
|
|
|
|
########################################################################
|
|
# Function to retrieve the contents of a file from perforce
|
|
########################################################################
|
|
def GetFileContents(self, filename, revision=-1):
|
|
if self.p4Instance is not None and revision != 0:
|
|
try:
|
|
if revision == -1:
|
|
return self.p4Instance.run("print", "-q", filename, tagged=False)
|
|
else:
|
|
return self.p4Instance.run("print", "-q", "{0}#{1}".format(filename,str(revision)), tagged=False)
|
|
except P4Exception:
|
|
for e in self.p4Instance.errors:
|
|
print e
|
|
return []
|
|
else:
|
|
return []
|
|
|
|
########################################################################
|
|
# Function to return the fstat information of a file
|
|
########################################################################
|
|
def GetFStat(self, filename):
|
|
if self.p4Instance is not None:
|
|
try:
|
|
return self.p4Instance.run_fstat(filename, tagged=False)[0]
|
|
except P4Exception:
|
|
for e in self.p4Instance.errors:
|
|
print e
|
|
return None
|
|
else:
|
|
return None
|
|
########################################################################
|
|
# Function to return the filelog information of a file
|
|
########################################################################
|
|
def GetFileLog(self, filename):
|
|
if self.p4Instance is not None:
|
|
try:
|
|
return self.p4Instance.run_filelog(filename, tagged=False)
|
|
except P4Exception:
|
|
for e in self.p4Instance.errors:
|
|
print e
|
|
return None
|
|
else:
|
|
return None
|
|
########################################################################
|
|
# Function to check whether a file exists in the depot
|
|
########################################################################
|
|
def DoesFileExist(self, location):
|
|
try:
|
|
results = self.p4Instance.run("files", location)
|
|
return True
|
|
except P4Exception as e:
|
|
nosuchfile = False
|
|
for warning in e.warnings:
|
|
if "no such file" in warning.lower():
|
|
nosuchfile = True
|
|
break
|
|
if(nosuchfile):
|
|
return False
|
|
else:
|
|
raise e
|
|
########################################################################
|
|
# Function to check whether a folder exists in the depot
|
|
########################################################################
|
|
def DoesFolderExist(self, location):
|
|
if(not location.endswith("...") and not location.endswith("/")):
|
|
location = location + "/"
|
|
if(location.endswith("/")):
|
|
location = location + "..."
|
|
try:
|
|
results = self.p4Instance.run("files", location)
|
|
return True
|
|
except P4Exception as e:
|
|
nosuchfile = False
|
|
for warning in e.warnings:
|
|
if "no such file" in warning.lower():
|
|
nosuchfile = True
|
|
break
|
|
if(nosuchfile):
|
|
return False
|
|
else:
|
|
raise e
|
|
|
|
########################################################################
|
|
# Function to create an empty changelist and return its number
|
|
########################################################################
|
|
def CreateEmptyChangelist(self, description):
|
|
changeList = self.p4Instance.fetch_change()
|
|
changeList['Files'] = []
|
|
changeList['Description'] = description
|
|
outputForm = self.p4Instance.save_change(changeList)
|
|
return outputForm[0].split()[1]
|
|
########################################################################
|
|
# Function to create a changelist with files and return its number
|
|
########################################################################
|
|
def CreateChangelist(self, description, files):
|
|
filesToAdd = []
|
|
for file in files:
|
|
self.p4Instance.run_edit(file)
|
|
fstat = self.GetFStat(file)
|
|
filesToAdd.append(fstat['depotFile'])
|
|
if len(filesToAdd) == 0:
|
|
print("No files supplied to create changelist with")
|
|
changeList = self.p4Instance.fetch_change()
|
|
changeList['Files'] = filesToAdd
|
|
changeList['Description'] = description
|
|
outputForm = self.p4Instance.save_change(changeList)
|
|
return outputForm[0].split()[1]
|
|
|
|
########################################################################
|
|
# Function to submit a changelist
|
|
########################################################################
|
|
def SubmitChangelist(self, changelist):
|
|
changelistForm = self.p4Instance.fetch_change(changelist)
|
|
self.p4Instance.run_submit(changelistForm)
|
|
|
|
########################################################################
|
|
# Function to return list of files in a location
|
|
########################################################################
|
|
def GetFilesInLocation(self, Location, allSubFolders=False, ignoreDeletes=False):
|
|
if allSubFolders != False:
|
|
if not Location.endswith("..."):
|
|
if not Location.endswith("/"):
|
|
Location = Location + "/"
|
|
Location = Location + "..."
|
|
else:
|
|
if not Location.endswith("*"):
|
|
if not Location.endswith("/"):
|
|
Location = Location + "/"
|
|
if Location.endswith("/"):
|
|
Location = Location + "*"
|
|
files = self.p4Instance.run("files", Location)
|
|
ReturnFiles = []
|
|
for file in files:
|
|
if(ignoreDeletes):
|
|
if('delete' in file['action'].lower()):
|
|
continue
|
|
ReturnFiles.append(file['depotFile'])
|
|
return ReturnFiles
|
|
|
|
########################################################################
|
|
# Function to return list of folders in a location
|
|
########################################################################
|
|
def GetFoldersInLocation(self, Location):
|
|
if not Location.endswith("*"):
|
|
Location = Location + "/"
|
|
if Location.endswith("/"):
|
|
Location = Location + "*"
|
|
dirs = self.p4Instance.run("dirs", Location)
|
|
ReturnDirs = []
|
|
for dir in dirs:
|
|
ReturnDirs.append(dir['dir'])
|
|
return ReturnDirs
|
|
|
|
########################################################################
|
|
# Function to convert a local location to a p4 location
|
|
########################################################################
|
|
def GetP4LocationOfFile(self, fileName):
|
|
fstatOfFile = self.GetFStat(fileName)
|
|
if fstatOfFile == None:
|
|
return None
|
|
return fstatOfFile['depotFile']
|
|
|
|
########################################################################
|
|
# Run same logic as server to determine for a given changelist if any files are under its restriction limit
|
|
########################################################################
|
|
|
|
def GetUnderRestrictedFiles(self, changelist):
|
|
description = self.p4Instance.run("describe", changelist)[0]
|
|
files = description['depotFile']
|
|
fileTypes = description['type']
|
|
for curIdx in range(0, len(files)):
|
|
fileType = fileTypes[curIdx]
|
|
ALLOWEDSERVERLIMIT = 4
|
|
parts = fileType.split('+')
|
|
if(len(parts) > 1):
|
|
if('S' in parts[1]):
|
|
captures = re.match(".*S([0-9]*)", parts[1], 0).group(1)
|
|
if(captures is None or captures == "" or int(captures) < ALLOWEDSERVERLIMIT):
|
|
print("File under server limit {0}".format(files[curIdx]))
|
|
|
|
def GetChangelistsBetweenClAndHead(self, location, changelist):
|
|
output = []
|
|
additionalFormat = ""
|
|
if(changelist is not None):
|
|
additionalFormat = "@{0},#head".format(changelist)
|
|
changelists = self.p4Instance.run("changes", "{0}{1}".format(location, additionalFormat))
|
|
for cl in changelists:
|
|
files = self.p4Instance.run("describe", cl['change'])[0]['depotFile']
|
|
output.append((cl['change'], files))
|
|
return output
|
|
|
|
def GetFilesBetweenClAndHeadAndReportHeadCL(self, location, changelist):
|
|
changelists = self.GetChangelistsBetweenClAndHead(location, changelist)
|
|
headCL = changelists[0][0]
|
|
output = []
|
|
for cl in changelists:
|
|
if(str(cl[0]) != str(changelist)):
|
|
for file in cl[1]:
|
|
if(file not in output):
|
|
output.append(file)
|
|
return headCL,output |