Created
October 30, 2012 23:16
-
-
Save uncreative/3983721 to your computer and use it in GitHub Desktop.
generate a .p4 file with P4CLIENT='correct-p4-client' and for every client for given user if that line does not already exist
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# encoding: utf-8 | |
""" | |
generate a .p4 file with P4CLIENT='correct-p4-client' for every client for given user if that line does not already exist | |
""" | |
__author__ = "Ayelet Goldin ([email protected])" | |
__version__ = "0.1" | |
__copyright__ = "Copyright (c) 2011-2011 Ayelet Goldin" | |
__license__ = "This script is in the public domain, free from copyrights or restrictions" | |
import logging | |
import time | |
from optparse import OptionParser | |
import subprocess | |
import re | |
import os | |
import sys | |
# regular expression to match client name to root path from the output of p4 clients | |
reClientNameToRootPath = re.compile("Client\s+(\S*)\s+\d{4}/\d{2}/\d{2}\s+root\s+([^']*)\s+'.*'") | |
class ClientSkipException(Exception): pass | |
def ConstructCommand(command): | |
path = RunCommand('launchctl getenv PATH') | |
return 'export PATH=%s:$PATH && %s' % (path, command) | |
def RunCommand(command): | |
p = subprocess.Popen(command, stdin=subprocess.PIPE,stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) | |
result, err = p.communicate() | |
if len(err) > 0: | |
raise Exception("error when running %s: %s " % (command, err)) | |
return result, err | |
def getP4ClientsForUser(p4user): | |
command = ConstructCommand('p4 clients -u %s' % p4user) | |
clientsForUserResult, err = RunCommand(command) | |
clientsForUserResult = clientsForUserResult.strip() | |
return clientsForUserResult.splitlines(True) | |
def getHostForClient(p4client): | |
command = ConstructCommand('p4 client -o %s|grep "^Host"' % p4client) | |
clientHostResult, err = RunCommand(command) | |
clientHostResult = clientHostResult.strip() | |
if len(clientHostResult) == 0: | |
return '' | |
clientHostResultWithoutHost = re.search(r'^Host:\s+(.*)', clientHostResult) | |
if clientHostResultWithoutHost and len(clientHostResultWithoutHost.groups()) > 0: | |
return clientHostResultWithoutHost.groups()[0].lower() | |
else: | |
raise ClientSkipException("Failed to parse host for client %s found host string: %s" % (p4client, clientHostResultWithoutHost)) | |
def clientPossiblyBelongsToThisHost(p4clientHost, p4host): | |
return p4clientHost.lower().strip() == p4host.lower().strip() or p4clientHost == "" | |
def p4LineNeeded(dotp4path, varToSet, valToSet): | |
if os.path.isfile(dotp4path): | |
with open(dotp4path) as dotp4in: | |
for line in dotp4in: | |
match = re.compile('\s*%s\s*=\s*(.*)\s*$' % varToSet).search(line) | |
if match: | |
if len(match.groups()) == 1 and match.groups()[0] == valToSet: | |
logging.info("correct file for %s already exists" % valToSet) | |
return False | |
else: | |
raise ClientSkipException("incorrect line %s exists on %s %s should be set to %s" % (line, dotp4path, varToSet, valToSet)) | |
return True | |
def generateP4ConfigFiles(p4user, p4host, varsToSet): | |
loglevel=logging.DEBUG | |
p4files = [] | |
skipped = [] | |
skippedForPotentialHost = [] | |
clientsToProcess = getP4ClientsForUser(p4user) | |
logging.info("%d clients to process" % len(clientsToProcess)) | |
for p4clientParts in clientsToProcess: | |
try: | |
logging.info("process %s" % p4clientParts) | |
match = reClientNameToRootPath.match(p4clientParts) | |
p4client, clientRootPath = match.groups() | |
# convert all paths to "os.sep" slashes | |
convertedClientRootPath = clientRootPath.replace('\\', os.sep).replace('/', os.sep) | |
p4clientHost = getHostForClient(p4client) | |
logging.info("checking if '%s' matches '%s'" % (p4clientHost, p4host)) | |
if clientPossiblyBelongsToThisHost(p4clientHost, p4host): | |
varsToSet['P4CLIENT'] = p4client | |
if not os.path.isdir(convertedClientRootPath): | |
raise ClientSkipException("found potential client %s with host '%s' for path %s, but no matching path. Not writing this p4 file" % (p4client, p4host, convertedClientRootPath)) | |
else: | |
for varToSet, valToSet in varsToSet.items(): | |
p4Line = "%s=%s" % (varToSet, valToSet) | |
dotp4path = os.path.join(convertedClientRootPath, ".p4") | |
if p4LineNeeded(dotp4path, varToSet, valToSet): | |
p4files.append(p4client) | |
logging.debug("print '%s' to %s for client %s" % (p4Line, dotp4path, p4client)) | |
with open(dotp4path, 'a+') as dotp4out: | |
dotp4out.write(os.linesep + p4Line) | |
else: | |
skipped.append(p4client) | |
logging.info("client %s host '%s' does not match" % (p4client, p4clientHost)) | |
except ClientSkipException, e: | |
logging.warn("skipping %s because of ERROR: %s" % (p4clientParts, e.message)) | |
skippedForPotentialHost.append(p4client) | |
return p4files, skipped, skippedForPotentialHost | |
def readOptions(argv): | |
""" | |
parse command line options | |
""" | |
parser = OptionParser(usage=globals()['__doc__'], version = __version__,) | |
parser.add_option("--debug", action="store_true", dest="debug", default=False, help="make even more noise") | |
parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=False, help="make lots of noise") | |
parser.add_option("-q", "--quiet", action="store_false", dest="verbose", help="be vewwy quiet (I'm hunting wabbits) [default]") | |
try: | |
options, args = parser.parse_args(argv) | |
if len(args) < 2: # must provide integer values and command | |
raise Exception("You must supply a p4user and p4host") | |
if len(args) > 2: # must provide two arguments | |
raise Exception("Too many arguments (%d) %s. Provide a two arguments: p4user and p4host." % (len(args), ','.join("'%s'" % arg for arg in argv))) | |
p4user = args[0] | |
p4host = args[1] | |
if options.verbose: | |
loglevel = logging.INFO | |
else: | |
loglevel = logging.WARNING | |
if options.debug: | |
loglevel = logging.DEBUG | |
logging.basicConfig(level=loglevel) | |
except Exception, e: | |
parser.error(e) | |
return p4user, p4host | |
def main(argv=None): | |
loglevel=logging.WARNING | |
if argv is None: | |
argv = sys.argv[1:] | |
p4user, p4host = readOptions(argv) # setup any options (verbose / warn or quit on bad input) | |
starttime = time.time() | |
logging.info("generating %s files for user %s on host %s" % ('.p4', p4user, p4host)) | |
varsToSet = {'P4USER':p4user, 'P4HOST':p4host} | |
p4files, skipped, skippedForPotentialHost = generateP4ConfigFiles(p4user, p4host, varsToSet) | |
logging.info("generated %s" % ', '.join(p4files)) | |
logging.warn("skipped %s" % ', '.join(skipped)) | |
logging.warn("skippedForPotentialHost %s", ', '.join(skippedForPotentialHost)) | |
logging.info("generated in %f seconds" % (time.time() - starttime)) | |
sys.exit(0) | |
if __name__ == "__main__": | |
sys.exit(main()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment