'''
Created on Nov 28, 2017
@author: Charlie McLouth
'''
from P4 import P4 as _P4, DepotFile, FilelogOutputHandler, Integration, Map, \
OutputHandler, P4Exception, processFilelog, Progress, ReportHandler, \
Resolver, Revision, Spec, TextProgress
class P4(_P4):
'''
classdocs
'''
# static set of commands supporting the -m limit
withlimits = set(["branches", "changes", "clients", "groups", "jobs",
"labels", "property", "remotes", "repos", "streams",
"users", "counters", "describe", "diff", "filelog",
"files", "fixes", "fstat", "journals", "keys",
"logparse", "opened", "print", "sizes"])
# commands to ignore limits
withoutlimits = set(["sync"])
extendedattributes = {}
def __init__(self, *args, **kargs):
# add a global result limit
self.extendedattributes.setdefault("resultLimit", 0)
resultlimit = kargs.pop("limit", 0)
if resultlimit is not None:
if not isinstance(resultlimit, int):
try:
resultlimit = int(resultlimit)
if resultlimit < 0:
resultlimit = 0
except:
resultlimit = 0
self.extendedattributes["resultLimit"] = resultlimit
self.specfields.update({"ldaps": ("ldap","Name"),
"remotes": ("remote","RemoteID"),
"repos": ("repo","Repo"),
"servers": ("server","ServerID")})
return _P4.__init__(self, *args, **kargs)
def run(self, *args, **kargs):
command = args[0]
offset = kargs.pop("offset", None)
if offset is not None and not isinstance(offset, int):
try:
offset = int(offset)
if offset < 0:
offset = 0
except:
offset = None
limit = kargs.pop("limit", self.extendedattributes["resultLimit"])
if limit is not None and not isinstance(limit, int):
try:
limit = int(limit)
if limit < 1:
limit = 0
except:
limit = 0
# ignore limits
if command in self.withoutlimits:
offset = None
limit = 0
# if the command supports -m limit add them
if limit > 0 and command in self.withlimits:
args = (args[0], "-m", str(limit + 1 + (offset or 0))) + args[1:]
result = _P4.run(self, *args, **kargs)
if isinstance(result, list) \
and (limit > 0 or offset is not None):
if offset is not None and offset > 0:
if offset < len(result):
result = result[offset:]
elif offset >= len(result):
message = "Positioning offset({}) greater than result "\
"count({}).".format(offset, len(result))
self.warnings.append(message)
self.warnings.append({"offset": offset, "count": len(result)})
if self.exception_level >= _P4.RAISE_ALL:
raise P4Exception(message)
result = []
if limit > 0:
if limit < len(result):
message = "More results available at positioning offset"\
"({}).".format(limit + (offset or 0))
self.warnings.append(message)
self.warnings.append({"next_offset": limit + (offset or 0)})
result = result[:limit]
if self.exception_level >= _P4.RAISE_ALL:
raise P4Exception(message)
return result
def __specgenerator(self, cmd, specs):
'''generator that accumulates warnings
warnings are preserved in the order they occur
'''
spec = self.specfields[cmd][0]
field = self.specfields[cmd][1]
for x in specs:
# copy any previous warnings
previouswarnings = list(self.warnings)
# run the command
result = self.run(spec, '-o', x[field])
# insert previous warnings
self.warnings[0:0] = previouswarnings
yield result[0]
def __iterate(self, cmd, *args, **kargs):
if cmd in self.specfields:
specs = self.run(cmd, *args, **kargs)
return self.__specgenerator(cmd, specs)
else:
raise Exception('Unknown spec list command: %s', cmd)