#!/usr/bin/env python ################################################################################ # # Copyright (c) 2023, Perforce Software, Inc. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL PERFORCE SOFTWARE, INC. BE LIABLE FOR ANY # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # DATE # # $Date: 2023/04/24 $ # # SYNOPSIS # # check-move.py -p p4port -u p4user -c p4client -d client_working_dir source target # # DESCRIPTION # # Prevent move command to be performed accross depots or branches # # Intented to be used as part of a before command trigger: # # check-move command pre-user-move "python /triggers_path/check-move.py -p %serverport% -u %user% -c %client% -d %clientcwd% %args%" # # REQUIREMENT # # P4Python must be installed: https://www.perforce.com/manuals/p4python # ################################################################################ from __future__ import print_function from P4 import P4, P4Exception import argparse import os import sys python3 = sys.version_info[0] >= 3 def getPath(str, depth): path = "" if str.count('/') > depth + 2: # for special case: //depot/file path = str.split("/")[2 + depth] return(path) def main(): parser = argparse.ArgumentParser(prog='check-move', usage='%(prog)s -p p4port -u p4user -c p4client -d client_working_dir source target') if python3: parser.add_argument("files", nargs="*", help="source and target of the move", type=os.fsencode) else: parser.add_argument("files", nargs="*", help="source and target of the move") parser.add_argument("-p", "--port", dest="port", help="server:port value") parser.add_argument("-u", "--user", dest="user", help="user value") parser.add_argument("-c", "--client", dest="client", help="client value") parser.add_argument("-d", "--cwd", dest="cwd", help="client working directory value") args, unknown = parser.parse_known_args() if not len(args.files) == 2: exit(1) p4 = P4() p4.port = args.port p4.user = args.user p4.client = args.client p4.cwd = args.cwd p4.connect() try: source = p4.run_where(args.files[0])[0]['depotFile'] target = p4.run_where(args.files[1])[0]['depotFile'] if not getPath(source, 0) == getPath(target, 0): sys.exit("Unable to move files accross depots, use 'p4 integrate'/'p4 delete' for this") if not getPath(source, 1) == getPath(target, 1): sys.exit("Unable to move files accross branches, use 'p4 integrate'/'p4 delete' for this") exit(0) except P4Exception: for e in p4.errors: exit(e) if __name__ == '__main__': main()