#! /usr/bin/env python ''' /* * Copyright (c) 2016, Charles McLouth * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * 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 STEWART LORD 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. p4ismapped.py Test whether a file path is mapped within Perforce client specs. $Id: //guest/cmclouth/python-utils/p4ismapped/src/p4ismapped.py#1 $ */ ''' import logging import P4 import sys import argparse logger = logging.getLogger(__name__) # logger.setLevel(logging.DEBUG) # debugHandler = logging.StreamHandler() # debugHandler.setFormatter(logging.Formatter('%(levelname)s:%(filename)s:%(lineno)d:%(funcName)s:%(message)s')) # logger.addHandler(debugHandler) def processInputParams(pargs=sys.argv): ''' process commandline arguments and run function ''' gParser = argparse.ArgumentParser() gParser.description="p4ismapped tool" gParser.epilog="p4ismapped tool" gParser.add_argument('-V', '--version', action='version', version='%(prog)s ') optsGroup = gParser.add_argument_group('g-opts - Global Options') optsGroup.add_argument('-c', dest='p4client', metavar='client', \ help='Overrides any P4CLIENT setting with the specified client name.') optsGroup.add_argument('-d', dest='p4dir', metavar='dir', \ help='Overrides any PWD setting (i.e. current working directory) and replaces'+\ ' it with the specified directory.') optsGroup.add_argument('-H', dest='p4host', metavar='host', \ help='Overrides any P4HOST setting with the specified hostname.') optsGroup.add_argument('-p', dest='p4port', metavar='port', \ help='Overrides any P4PORT setting with the specified port number.') optsGroup.add_argument('-P', dest='p4passwd', metavar='password', \ help='Overrides any P4PASSWD setting with the specified password.') optsGroup.add_argument('-u', dest='p4user', metavar='user', \ help='Overrides any P4USER, USER, or USERNAME setting with the specified user name.') optsGroup.add_argument('-C', dest='p4charset', metavar='charset', \ help='Overrides any P4CHARSET setting with the specified character set.') subParsers = gParser.add_subparsers(title='Commands', help='-h, --help additional help') sParser = subParsers.add_parser('clients') sParser.set_defaults(func=isMappedClients) sParser.description="clients -- reports clients that have mapped the supplied file(s)." sParser.add_argument('-u', dest='clientsUser', metavar='user', \ help='The -u user flag lists client workspaces that are owned by the specified user.') sParser.add_argument('-e', dest='clientsNameFilter', metavar='nameFilter', \ help='The -e nameFilter flag lists workspaces with a name that matches the nameFilter pattern, for example: -e \'svr-dev-rel*\'. The -e flag uses the server\'s normal case-sensitivity rules.') sParser.add_argument('-S', dest='clientsStream', metavar='stream', \ help='The -S stream flag limits output to the client workspaces dedicated to the stream.') sParser.add_argument('-U', dest='clientsUnload', metavar='unload', \ help='The -U flag lists unloaded clients (see \'p4 help unload\').') sParser.add_argument('-a', dest='clientsAll', action='store_true', \ help='The -a flag specifies that all clients should be displayed, not just those that are bound to this server.') sParser.add_argument('-s', dest='clientsServerID', metavar='serverID', \ help='The -s serverID flag specifies that only those clients bound to the specified serverID should be displayed. On an Edge Server, the -s flag defaults to the Edge Server\'s serverID.') sParser.add_argument('-m', dest='clientsMatch', action='store_true', \ help='The -m flag specifies that all files be found within the client view map. If not specified then any matching file will be reported.') sParser.add_argument('clientsFile', metavar='file', nargs='+', \ help='See filespec.') args = gParser.parse_args(pargs) if not hasattr(args, 'func'): gParser.print_help() return args def getP4Connection(args): p4api = P4.P4() if args.p4charset is not None: p4api.charset = args.p4charset if args.p4client is not None: p4api.client = args.p4client if args.p4dir is not None: p4api.cwd = args.p4dir if args.p4host is not None: p4api.host = args.p4host if args.p4passwd is not None: p4api.password = args.p4passwd if args.p4port is not None: p4api.port = args.p4port if args.p4user is not None: p4api.user = args.p4user p4api.prog = 'p4ismapped' p4api.connect() return p4api def getP4Clients(p4api, args): p4args = [] if args.clientsAll: p4args.append('-a') if args.clientsUser is not None: p4args.append('-u') p4args.append(args.clientsUser) if args.clientsNameFilter is not None: p4args.append('-e') p4args.append(args.nameFilter) if args.clientsStream is not None: p4args.append('-S') p4args.append(args.clientsStream) if args.clientsUnload is not None: p4args.append('-U') p4args.append(args.clientsUnload) if args.clientsServerID is not None: p4args.append('-s') p4args.append(args.clientsServerID) return p4api.run_clients(p4args) def getMap(viewList): # viewList is a list of two strings p4map = P4.Map() for view in viewList: p4map.insert(view) return p4map def reportFoundClient(client, clientFiles, testcase=None): if testcase is not None: testcase.foundTestResults.append((client, clientFiles)) logger.debug((client, clientFiles)) print(str(client)) def isMappedClients(args, testcase=None): logger.debug(args) # connect p4api = getP4Connection(args) for short_client in getP4Clients(p4api, args): logger.debug(short_client['client']) full_client = p4api.fetch_client(short_client['client']) testMap = getMap(full_client['View']) foundList = [] for fileName in args.clientsFile: logger.debug(fileName) logger.debug(testMap) logger.debug(testMap.translate(fileName)) if testMap.includes(fileName): foundList.append(fileName) # we could do an early exit if args.clientsMatch == False # but for now find all matches elif args.clientsMatch: break if (args.clientsMatch and len(foundList) == len(args.clientsFile)) or (not args.clientsMatch and len(foundList) > 0): reportFoundClient(full_client, foundList, testcase) p4api.disconnect() del(p4api) if __name__ == '__main__': args = processInputParams(sys.argv[1:]) if hasattr(args, 'func'): args.func(args)