from __future__ import print_function
import P4
from enum import Enum
import sys
import logging
import argparse
class StreamType(Enum):
MAIN = 'mainline'
VIRTUAL = 'virtual'
DEVELOP = 'development'
RELEASE = 'release'
TASK = 'task'
stream_cache = {}
class Stream:
def __init__(self, stream: dict):
self.name = stream["Name"]
self.stream = stream["Stream"]
if stream["Parent"] == "none":
self.parent = None
else:
if stream["Parent"] in stream_cache:
self.parent = stream_cache[stream["Parent"]]
else:
raise Exception("Cannot find {} in stream_cache".format(self.parent))
self.stream_type = StreamType(stream["Type"])
self.options = stream["Options"]
self.owner = stream["Owner"]
self.description = stream["desc"]
self.substreams = []
self.developmentStreams = []
self.releaseStreams = []
self.virtualStreams = []
self.taskStreams = []
self.stream_map = {StreamType.DEVELOP: self.developmentStreams,
StreamType.RELEASE: self.releaseStreams,
StreamType.VIRTUAL: self.virtualStreams,
StreamType.TASK: self.taskStreams}
if self.parent:
self.parent.add_sub_stream(self)
# add this stream to the cache for faster lookup
stream_cache[self.stream] = self
def add_sub_stream(self, stream):
self.substreams.append(stream)
self.stream_map[stream.stream_type].append(stream)
def __str__(self):
output = "Stream {}\n".format(self.stream)
for st in self.developmentStreams:
output += " Develop {}\n".format(st)
for st in self.releaseStreams:
output += " Release {}\n".format(st)
for st in self.virtualStreams:
output += " Virtual {}\n".format(st)
for st in self.taskStreams:
output += " Task {}\n".format(st)
return output
class StreamHierarchy:
def __init__(self, **kargs):
self.p4 = P4.P4()
if kargs["port"]:
self.p4.port = kargs["port"]
if kargs["user"]:
self.p4.user= kargs["user"]
self.target = P4.P4()
self.target.port = kargs["target"]
if kargs["target_user"]:
self.target.user = kargs["target_user"]
else:
self.target.user = self.p4.user
#self.p4.logger = logging.getLogger("P4")
#self.p4.logger.setLevel(logging.INFO)
#self.p4.logger.addHandler(logging.StreamHandler())
def retrieve_hierarchy(self, name: str):
with self.p4.connect():
self.mainline = self.get_stream_by_name(name)
self.get_stream_by_base_parent(self.mainline)
def get_stream_by_name(self, name: str) -> Stream:
stream_data = self.p4.run_streams("-F", "Stream={}".format(name))
if stream_data:
return Stream(stream_data[0])
else:
raise Exception("Stream {} not found".format(name))
def get_stream_by_base_parent(self, parent: Stream):
stream_data = self.p4.run_streams("-F", "baseParent={}".format(parent.stream))
for st in stream_data:
stream = Stream(st)
def create_stream(self, stream : Stream):
st = self.target.fetch_stream('-t', stream.stream_type.value, stream.stream)
st._options = stream.options
st._parent = stream.parent.stream if stream.parent else "none"
st._owner = stream.owner
st._description = stream.description
self.target.save_stream(st)
def transfer_streams(self):
with self.target.connect():
self.create_stream(self.mainline)
for st in self.mainline.substreams:
self.create_stream(st)
if __name__ == '__main__':
parser = argparse.ArgumentParser(
description="TransferStreams",
epilog="Copyright (C) 2017 Sven Erik Knop, Perforce Software Ltd"
)
parser.add_argument("-p", "--port", help="P4PORT")
parser.add_argument("-u", "--user", help="P4USER")
parser.add_argument("-t", "--target", help="Target P4PORT", required=True)
parser.add_argument("-U", "--target-user", help="Target P4USER")
parser.add_argument("mainstream")
args = parser.parse_args()
mainStreamName = args.mainstream
hierarchy = StreamHierarchy(**vars(args))
hierarchy.retrieve_hierarchy(mainStreamName)
hierarchy.transfer_streams()
| # | Change | User | Description | Committed | |
|---|---|---|---|---|---|
| #4 | 23700 | Sven Erik Knop |
Completed test cases for Stream Transfer, including rename. Good to go, no further changes required from my point of view. |
||
| #3 | 23699 | Sven Erik Knop |
Always create test cases. Found a couple of nasty bugs already. Direct and indirect transfers are tested and seem to work fine. I am going to add a few more tests, specifically but not exclusive to renames. |
||
| #2 | 23623 | Sven Erik Knop | Updated to enable renaming of target streams | ||
| #1 | 23587 | Sven Erik Knop | Renamed to Transfer | ||
| //guest/sven_erik_knop/P4Pythonlib/scripts/Transfer/ShowStreamHierarchy.py | |||||
| #1 | 23586 | Sven Erik Knop | Little tool to transfer stream hierarchies | ||