171 lines
4.6 KiB
Python
171 lines
4.6 KiB
Python
|
import win32con, string, traceback
|
||
|
import win32com.client, win32com.client.gencache
|
||
|
import pythoncom
|
||
|
import time
|
||
|
import os
|
||
|
|
||
|
constants = win32com.client.constants
|
||
|
|
||
|
win32com.client.gencache.EnsureModule('{783CD4E0-9D54-11CF-B8EE-00608CC9A71F}', 0, 5, 0)
|
||
|
|
||
|
error = "vssutil error"
|
||
|
|
||
|
def GetSS():
|
||
|
ss=win32com.client.Dispatch("SourceSafe")
|
||
|
# SS seems a bit weird. It defaults the arguments as empty strings, but
|
||
|
# then complains when they are used - so we pass "Missing"
|
||
|
ss.Open(pythoncom.Missing, pythoncom.Missing, pythoncom.Missing)
|
||
|
return ss
|
||
|
|
||
|
def test(projectName):
|
||
|
ss=GetSS()
|
||
|
project = ss.VSSItem(projectName)
|
||
|
|
||
|
for item in project.GetVersions(constants.VSSFLAG_RECURSYES):
|
||
|
print(item.VSSItem.Name, item.VersionNumber, item.Action)
|
||
|
|
||
|
|
||
|
# item=i.Versions[0].VSSItem
|
||
|
# for h in i.Versions:
|
||
|
# print `h.Comment`, h.Action, h.VSSItem.Name
|
||
|
|
||
|
|
||
|
def SubstituteInString(inString, evalEnv):
|
||
|
substChar = "$"
|
||
|
fields = string.split(inString, substChar)
|
||
|
newFields = []
|
||
|
for i in range(len(fields)):
|
||
|
didSubst = 0
|
||
|
strVal = fields[i]
|
||
|
if i%2!=0:
|
||
|
try:
|
||
|
strVal = eval(strVal,evalEnv[0], evalEnv[1])
|
||
|
newFields.append(strVal)
|
||
|
didSubst = 1
|
||
|
except:
|
||
|
traceback.print_exc()
|
||
|
print("Could not substitute", strVal)
|
||
|
if not didSubst:
|
||
|
newFields.append(strVal)
|
||
|
return string.join(map(str, newFields), "")
|
||
|
|
||
|
def SubstituteInFile(inName, outName, evalEnv):
|
||
|
inFile = open(inName, "r")
|
||
|
try:
|
||
|
outFile = open(outName, "w")
|
||
|
try:
|
||
|
while 1:
|
||
|
line = inFile.read()
|
||
|
if not line: break
|
||
|
outFile.write(SubstituteInString(line, evalEnv))
|
||
|
finally:
|
||
|
outFile.close()
|
||
|
finally:
|
||
|
inFile.close()
|
||
|
|
||
|
def VssLog(project, linePrefix = "", noLabels = 5, maxItems=150):
|
||
|
lines = []
|
||
|
num = 0
|
||
|
labelNum = 0
|
||
|
for i in project.GetVersions(constants.VSSFLAG_RECURSYES):
|
||
|
num = num + 1
|
||
|
if num > maxItems : break
|
||
|
commentDesc = itemDesc = ""
|
||
|
if i.Action[:5]=="Added":
|
||
|
continue
|
||
|
if len(i.Label):
|
||
|
labelNum = labelNum + 1
|
||
|
itemDesc = i.Action
|
||
|
else:
|
||
|
itemDesc = i.VSSItem.Name
|
||
|
if str(itemDesc[-4:])==".dsp":
|
||
|
continue
|
||
|
if i.Comment:
|
||
|
commentDesc ="\n%s\t%s" % (linePrefix, i.Comment)
|
||
|
lines.append("%s%s\t%s%s" % (linePrefix, time.asctime(time.localtime(int(i.Date))), itemDesc, commentDesc))
|
||
|
if labelNum > noLabels:
|
||
|
break
|
||
|
return string.join(lines,"\n")
|
||
|
|
||
|
def SubstituteVSSInFile(projectName, inName, outName):
|
||
|
import win32api
|
||
|
if win32api.GetFullPathName(inName)==win32api.GetFullPathName(outName):
|
||
|
raise RuntimeError("The input and output filenames can not be the same")
|
||
|
sourceSafe=GetSS()
|
||
|
project = sourceSafe.VSSItem(projectName)
|
||
|
# Find the last label
|
||
|
label = None
|
||
|
for version in project.Versions:
|
||
|
if version.Label:
|
||
|
break
|
||
|
else:
|
||
|
print("Couldnt find a label in the sourcesafe project!")
|
||
|
return
|
||
|
# Setup some local helpers for the conversion strings.
|
||
|
vss_label = version.Label
|
||
|
vss_date = time.asctime(time.localtime(int(version.Date)))
|
||
|
now = time.asctime(time.localtime(time.time()))
|
||
|
SubstituteInFile(inName, outName, (locals(),globals()))
|
||
|
|
||
|
|
||
|
def CountCheckouts(item):
|
||
|
num = 0
|
||
|
if item.Type==constants.VSSITEM_PROJECT:
|
||
|
for sub in item.Items:
|
||
|
num = num + CountCheckouts(sub)
|
||
|
else:
|
||
|
if item.IsCheckedOut:
|
||
|
num = num + 1
|
||
|
return num
|
||
|
|
||
|
def GetLastBuildNo(project):
|
||
|
i = GetSS().VSSItem(project)
|
||
|
# Find the last label
|
||
|
lab = None
|
||
|
for version in i.Versions:
|
||
|
lab = str(version.Label)
|
||
|
if lab: return lab
|
||
|
return None
|
||
|
|
||
|
def MakeNewBuildNo(project, buildDesc = None, auto=0, bRebrand = 0):
|
||
|
if buildDesc is None: buildDesc = "Created by Python"
|
||
|
ss = GetSS()
|
||
|
i = ss.VSSItem(project)
|
||
|
num = CountCheckouts(i)
|
||
|
if num > 0:
|
||
|
msg = "This project has %d items checked out\r\n\r\nDo you still want to continue?" % num
|
||
|
import win32ui
|
||
|
if win32ui.MessageBox(msg, project, win32con.MB_YESNO) != win32con.IDYES:
|
||
|
return
|
||
|
|
||
|
|
||
|
oldBuild = buildNo = GetLastBuildNo(project)
|
||
|
if buildNo is None:
|
||
|
buildNo = "1"
|
||
|
oldBuild = "<None>"
|
||
|
else:
|
||
|
try:
|
||
|
buildNo = string.atoi(buildNo)
|
||
|
if not bRebrand: buildNo = buildNo + 1
|
||
|
buildNo = str(buildNo)
|
||
|
except ValueError:
|
||
|
raise error("The previous label could not be incremented: %s" % (oldBuild))
|
||
|
|
||
|
if not auto:
|
||
|
from pywin.mfc import dialog
|
||
|
buildNo = dialog.GetSimpleInput("Enter new build number", buildNo, "%s - Prev: %s" % (project, oldBuild))
|
||
|
if buildNo is None: return
|
||
|
i.Label(buildNo, "Build %s: %s" % (buildNo,buildDesc))
|
||
|
if auto:
|
||
|
print("Branded project %s with label %s" % (project, buildNo))
|
||
|
return buildNo
|
||
|
|
||
|
if __name__=='__main__':
|
||
|
# UpdateWiseExeName("PyWiseTest.wse", "PyWiseTest-10.exe")
|
||
|
|
||
|
# MakeVersion()
|
||
|
# test(tp)
|
||
|
# MakeNewBuildNo(tp)
|
||
|
tp = "\\Python\\Python Win32 Extensions"
|
||
|
SubstituteVSSInFile(tp, "d:\\src\\pythonex\\win32\\win32.txt", "d:\\temp\\win32.txt")
|