import os, re """ pyPvcs contains functions that can be useful for work with the PVCS (now Merant) source control system. Several capabilities that are not easy to do in the GUI have been scripted for aiding in getting projects together to do builds. """ # location of merant database, as seen in GUI client pvcsdb = r"J:\Merant\Projects" # local director with client binary files pvcsbindir = r"C:\Program Files\Merant\vm\win32\bin" # root directory for Merant archive pvcsLanDir = r"J:\Merant\Projects\archives" # location of work files on client workfilelocation = r"." # root where projects from merant are stored on client localroot = r"C:\PVCSProjects" def dbgprint(toPrint): if True: print toPrint def spawnPcliCmd(cmd, *args): """ Kicks off the given command line task (cmd) with the given parameters (*args) in a separate process """ print cmd, args argList = list(args) argList.insert(0, cmd) argList.insert(0, "pcli") os.spawnv(os.P_WAIT, os.path.join(pvcsbindir,"pcli"), tuple(argList)) def runPcliCmd(cmdLine): """ uses popen2 to pipe the given command line to the shell and then returns the results in an array of strings """ p = os.popen2("cmd /k") p[0].write(cmdLine + "\r\n") p[0].flush() p[0].write("exit \r\n") p[0].flush() return p[1].readlines() def labelByDate(labelName, projectDir, endMonth, endDay, endYear, recursive=True): """ Gets the files in the given project (projectDir) and recursively sets the label (labelName) to the revision that comes closes to the end date without going over. NOTE: recursive is currently not used """ archiveLines = runPcliCmd("pcli vlog -de" + str(endMonth) + "/" + str(endDay) +"/" + str(endYear) + \ " -pr" + pvcsdb + " -z \"" + projectDir + "\"") revBreak = "-----------------------------------" currRev = "" newArc = False prevLine = "" pvcsFileName = "" for arcLine in archiveLines: lineStart, arcName = arcLine[:8], arcLine[18:-5] if lineStart == "Archive:": print "*" + arcName + "*" pvcsFileName = arcName.replace(pvcsLanDir, "").replace("\\","/") #print "(" + arcLine + ")", "-" + prevLine + "-" currRev = "" newArc = True if newArc and prevLine.strip() == revBreak: currRev = arcLine.split(" ")[-1].strip() spawnPcliCmd("Label", "-pr" + pvcsdb, "-r" + currRev, "\"-v" + labelName + "\"", "\"" + pvcsFileName + "\"") newArc = False prevLine = arcLine def mappvcsdir(projectdir): """ maps the given directory (projectdir) to the local directory specified in the module variable workfilelocation """ dbgprint( "finding projects for " + projectdir) projectlist = runPcliCmd("pcli List -pr" + pvcsdb + " -l -z -tProject \"" + projectdir + "\"") dbgprint("projects found") projectsWritten = open("c:\\pvcsprojectsmapped" + re.sub("\W","_",projectdir) + ".txt","w") projectsWritten.writelines(projectlist) projectsWritten.close() dbgprint( "processing project ") for currProject in projectlist: if currProject[0] == "/": workfilelocation = os.path.join(localroot, currProject.strip().replace("/","\\").lstrip("\\")) dbgprint( 'running ' + currProject.strip()) dbgprint( 'workfile location ' + workfilelocation + "\n\n") os.spawnl(os.P_WAIT, os.path.join(pvcsbindir,"pcli"), "pcli", "SetWorkLocation", "\"-pr" + pvcsdb + "\"", "\"-w" + workfilelocation + "\"", "\"" + currProject.strip() + "\"") def getFilesForVersion(labelName, outputPath, projectdir): os.spawnl(os.P_W, os.path.join(pvcsbindir, "pcli"), "pcli", "Get" , "\"-pr" + pvcsdb + "\"", "\"-v" + labelName + "\"", "-z", "-o", "\"-a" + outputPath + "\"", "\"" + projectdir + "\"") def compareDefaultAndLabelVersions(labelName, projectdir): """ recursively checks the given project (projectdir) to make sure that the label of the latest revision matches labelName. Each project gets an HTML file generated that has all the files in it and a status of either 'good' (the label is applied to the latest revision) or 'BAD' (label is NOT applied to the latest revision). HTML files that contain one or more BAD files will automatically be shown to the user in their default browser. """ dbgprint( "comparing version and default labels for project") projectlist = runPcliCmd("pcli List -pr" + pvcsdb + " -l -z -tProject \"" + projectdir + "\"") dbgprint( "projects found") projectsWritten = open("c:\\pvcsLabelCheckProjects" + re.sub("\W","_",projectdir) + ".txt","w") projectsWritten.writelines(projectlist) projectsWritten.close() DefaultVersionFiles = dict() NamedVersionFiles = dict() filesToShow = dict() for currProject in projectlist: if currProject[0] == "/": DefaultVersionlist = runPcliCmd("pcli ListRevision -pr" + pvcsdb + " \"" + currProject + "\"") for versionFile in DefaultVersionlist: #print "vf",versionFile.strip() if versionFile[0] == "/": currMatch = re.match("(.*?)\s+DefaultVersion", versionFile) if currMatch != None: DefaultVersionFiles[currMatch.group(1)] = versionFile.strip()[versionFile.find(":=") + 2:] dbgprint (versionFile.strip() + " is *" + DefaultVersionFiles[currMatch.group(1)] + "*") print "\n\n****************************\n\n" NamedVersionlist = runPcliCmd("pcli ListRevision \"-v" + labelName + "\" -pr" + pvcsdb + " \"" + currProject + "\"") for versionFile in NamedVersionlist: #print "vf",versionFile.strip() if versionFile[0] == "/": currMatch = re.match("(.*?)\s+" + labelName, versionFile) if currMatch != None: NamedVersionFiles[currMatch.group(1)] = versionFile.strip()[versionFile.find(":=") + 2:] dbgprint( versionFile.strip() + " is *" + NamedVersionFiles[currMatch.group(1)] + "*") newFileName = "c:\\" + re.sub("\W", "_", projectdir) + " Label " + \ re.sub("\W", "_", labelName) + ".html" outputFile = open(newFileName,"w") outputFile.write("
| File | Default Version | " + \ labelName + " | Status |
| " + vFile + " | " + \ DefaultVersionFiles[vFile] + " | " + \ NamedVersionFiles[vFile] + " | good |
| " + vFile + " | " + \ DefaultVersionFiles[vFile] + " | " + \ NamedVersionFiles[vFile] + " | BAD |