##
## Copyright (c) 2006 Jason Dillon
##
## Licensed under the Apache License, Version 2.0 (the "License");
## you may not use this file except in compliance with the License.
## You may obtain a copy of the License at
##
## http://www.apache.org/licenses/LICENSE-2.0
##
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
## See the License for the specific language governing permissions and
## limitations under the License.
##
##
## $Id: //guest/jason_dillon/p4spam/main/pylib/perforce/commands/__init__.py#2 $ $Date: 2006/04/12 $
##
from perforce import logging
import popen2, marshal
log = logging.Logger("perforce.commands")
def create(name, p4):
assert name != None
try:
mod_name = "perforce.commands.%s" % name
log.debug("Loading: %s" % mod_name)
mod = __import__(mod_name, globals(), locals(), [ "create" ])
assert mod != None
log.debug("Loaded: %s" % mod)
except ImportError:
raise Exception("Unconfigured command: %s" % name)
factory = getattr(mod, "create")
log.debug("Factory: %s" % factory)
return factory(p4);
##
## ResultSupport
##
class ResultSupport:
def toString(this):
raise "Abstract method"
def __str__(this):
return this.toString()
def __repr__(this):
return this.toString()
##
## CommandSupport
##
class CommandSupport:
def __init__(this, name, p4):
this.log = logging.Logger(this)
this.name = name
this.p4 = p4
this.p4flags = "-G"
def convertArguments(this, args):
_args = []
for arg in args:
_args.append(str(arg))
return _args
def createCommandLine(this, args):
cmdline = []
cmdline.append("p4")
if this.p4flags != None and len(this.p4flags.strip()) != 0:
cmdline.append(this.p4flags)
cmdline.append(this.name)
for arg in args:
cmdline.append(str(arg))
this.log.debug("Using command-line: %s" % (cmdline))
return cmdline
def processOutput(this, stream):
raise "Abstract method"
def execute(this, args):
# HACK: Convert all args to strings
args = this.convertArguments(args)
# HACK: Flatten the list into a string
cmdline = this.createCommandLine(args)
this.log.debug("Executing: %s" % (cmdline))
proc = popen2.Popen3(cmdline)
stream = proc.fromchild
#
# TODO: Try to detect a failure here before we get too far
#
result = this.processOutput(stream)
this.log.debug("Result: %s" % result)
return result
##
## SingleResultCommand
##
class SingleResultCommand(CommandSupport):
def createResult(this, entry):
raise "Abstract method"
def processOutput(this, stream):
entry = marshal.load(stream)
assert entry != None
this.log.debug("Entry: %s" % entry)
return this.createResult(entry)
##
## RawResultCommand
##
class RawResultCommand(SingleResultCommand):
def __init__(this, name, p4):
SingleResultCommand.__init__(this, name, p4)
this.p4flags = "" # Clear the -G flag
def isValid(this, lines):
return True
def validate(this, lines):
if not this.isValid(lines):
raise Exception("Raw content does not look like output from `p4 %s`: %s" % (this.name, lines))
def processOutput(this, stream):
trace = this.log.isTraceEnabled()
lines = stream.readlines()
if trace:
for line in lines:
this.log.trace(line.rstrip())
this.validate(lines)
return lines
##
## StreamedResultCommand
##
class StreamedResultCommand(CommandSupport):
def createResult(this, entry):
raise "Abstract method"
def processOutput(this, stream):
return StreamedResultIterator(stream, this)
##
## StreamedResultIterator
##
class StreamedResultIterator:
def __init__(this, stream, resultFactory):
this.log = logging.Logger(this)
this.stream = stream
this.resultFactory = resultFactory
def __iter__(this):
return this
def next(this):
try:
entry = marshal.load(this.stream)
assert entry != None
this.log.debug("Entry: %s" % entry)
return this.resultFactory.createResult(entry)
except EOFError:
raise StopIteration