Works with TestTrack 2008 and 2009
Works with Surround SCM 2008 and 2009
A popular feature request is the ability to attach to a TestTrack defect when a file is promoted. While this is something we periodically review when we consider enhancements for future relases, this can be done using triggers in the meantime.
Similar examples have been posted on how to attach an SCC file from Perforce and Subversion to TestTrack. This example takes the same approach, only modified to retrieve the Surround SCM environment variables.
The Trigger
The trigger in Surround SCM must be setup to run after a promote action. The Precondition must be set to be the branch you will be promoting to (the parent branch). The action the trigger will fire is a script that uses the TestTrack SOAP based SDK and updates the specific defect.
Use Case
While some TestTrack information may be hard coded in the script, like the Project name, the user to login via SOAP, etc…, at least one piece of information must be passed when the promote takes place, the defect number.
In the example script below, a token is used to parse the defect number out of the comments. The format of the token is:
<:#:>
Where # is where the defect number would go. The parsing logic in the example script will only work if a single defect number is passed. It can accept multiple digits, but not multiple digits separated by a comma, semicolon, etc…
Some examples of what the token may look like:
<:23:> <:6:> <:45123:>
Some examples of what the token may not look like:
<:23,34,45:> <:234fdf:> <:23;74;78:>
NOTE: If you want to be able to pass multiple defect numbers, change the parse logic to account for this.
The Script
The following are examples of what the script may look like. Feel free to add your own version of the script to this article.
C# Example
This is the easiest of all three examples. This script can only handle one defect number being passed.
using System;
using System.Collections.Generic;
using System.Text;
namespace AttachOnPromote
{
class Program
{
static void Main(string[] args)
{
string s_DNum = "";
long i_DNum = 0;
string scmComments = System.Environment.GetEnvironmentVariable("SSCM_COMMENT");
string scmBranch = System.Environment.GetEnvironmentVariable("SSCM_BRANCH");
string scmVersion = System.Environment.GetEnvironmentVariable("SSCM_FILEVERSION");
string scmRepo = System.Environment.GetEnvironmentVariable("SSCM_REPOSITORY");
string scmFile = System.Environment.GetEnvironmentVariable("SSCM_FILE");
string scmDate = System.Environment.GetEnvironmentVariable("SSCM_DATE");
string e_Message = ""; ;
if ((scmComments != "") && (scmComments != null))
{
if ((scmComments.Contains("<:")) && (scmComments.Contains(":>")))
{
scmComments = scmComments.Remove(0, scmComments.IndexOf("<:") + 2);
s_DNum = scmComments.Substring(0, scmComments.IndexOf(":>"));
bool isInt = false;
try
{
i_DNum = Convert.ToInt64(s_DNum);
//if no exception, then we set the boolean to true
isInt = true;
}
catch (Exception d)
{
//if we get an exception, we set the boolean to false
isInt = false;
}
if (!((s_DNum == "") || (s_DNum == null) || (isInt == false)))
{
long m_Cookie = 0;
long m_DNum = i_DNum;
string m_SCCFilePath = scmBranch + "::" + scmRepo + "/" + scmFile;
string m_User = "Administrator";
string m_Password = "password";
string m_Url = "http://localhost/scripts/ttsoapcgi.exe";
string m_ProjectName = "Sample Project";
ttsoapcgi m_ttsoapcgi = new ttsoapcgi();
m_ttsoapcgi.Url = m_Url;
CProject m_Project = new CProject();
CProject[] m_Projects = m_ttsoapcgi.getProjectList(m_User, m_Password);
for (int i = 0; i < m_Projects.Length; i++)
{
if (m_Projects[i].database.name == m_ProjectName)
{
m_Project = m_Projects[i];
}
}
try
{
m_Cookie = m_ttsoapcgi.ProjectLogon(m_Project, m_User, m_Password);
}
catch (Exception fcc)
{
e_Message = fcc.Message;
}
if ( e_Message != "")
{
}
else
{
CDefect m_Defect = m_ttsoapcgi.editDefect(m_Cookie, m_DNum, "", false);
CSCCFileRecord m_SCCFile = new CSCCFileRecord();
m_SCCFile.mstrFileName = m_SCCFilePath;
m_SCCFile.mstrFixedRevision = scmVersion;
m_SCCFile.mdateFixedTimestamp = Convert.ToDateTime(scmDate);
if (m_Defect.pSCCFileList == null)
{
m_Defect.pSCCFileList = new CSCCFileRecord[1];
m_Defect.pSCCFileList.SetValue(m_SCCFile, m_Defect.pSCCFileList.Length -1);
}
else
{
m_Defect.pSCCFileList.SetValue(m_SCCFile, m_Defect.pSCCFileList.Length);
}
m_ttsoapcgi.saveDefect(m_Cookie, m_Defect);
m_ttsoapcgi.DatabaseLogoff(m_Cookie);
}
}
}
}
}
}
} Java Example
Almost as easy as C#, except you have to a little more work to build array of SCC files, since there isn’t a SetValue() method you can call.
The testtrack_Interface imported in this example was obtained from here.
import testtrack_Interface.*;
import java.util.*;
import java.text.*;
import java.io.*;
/**
*
* @author cremerf
*/
public class Main {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
//Let's define our vars
//Surround SCM env vars
String scmComments = System.getenv("SSCM_COMMENT");
if ((scmComments.contains("<:"))&&(scmComments.contains(":>")))
{
String scmBranch = System.getenv("SSCM_BRANCH");
String scmRepository = System.getenv("SSCM_Repository");
String scmFile = System.getenv("SSCM_FILE");
String scmVersion = System.getenv("SSCM_FILEVERSION");
String strDNum = parseComments(scmComments);
String strDate = System.getenv("SSCM_DATE");
Calendar cal=Calendar.getInstance();
try
{
DateFormat formatter ;
Date date ;
formatter = new SimpleDateFormat("dd-mm-yy");
date = (Date)formatter.parse(strDate);
cal.setTime(date);
}
catch (ParseException e)
{
try
{
FileWriter outFile = new FileWriter("c:\\errpromote.txt");
PrintWriter out = new PrintWriter(outFile);
out.println("The following error was encountered:");
out.println(e.getMessage());
out.close();
}
catch (IOException ef)
{
e.printStackTrace();
}
}
//build the file including the full path
String sccFile = scmBranch + "::" + scmRepository + "/" + scmFile;
//TestTrack vars
String ttUser = "Administrator";
String ttPassword = "password";
String ttURL = "http://localhost/scripts/ttsoapcgi.exe";
String ttProject = "Sample Project";
long ttCookie =0;
long DNum = Integer.parseInt(strDNum);
//Now we can try to log in
try
{ // This code block invokes the Ttsoapcgi:projectLogon operation on web service
Ttsoapcgi ttsoapcgi = new Ttsoapcgi_Impl();
//the _ttsoapcgi is what we'll use to make all the calls
TtsoapcgiPortType _ttsoapcgi = ttsoapcgi.getTtsoapcgi();
CProject ttProj = new CProject();
CProject[] ttProjs = _ttsoapcgi.getProjectList(ttUser,ttPassword);
for (int i = 0; i <ttProjs.length;i++)
{
if (ttProjs[i].getDatabase().getName().equals(ttProject))
{
ttProj = ttProjs[i];
}
}
ttCookie = _ttsoapcgi.projectLogon(ttProj, ttUser, ttPassword);
if (ttCookie > 0)
{
CDefect theDefect = _ttsoapcgi.editDefect(ttCookie, DNum , "", false);
CSCCFileRecord[] ttSCCFiles = theDefect.getPSCCFileList();
int fileCount = 0;
if (ttSCCFiles != null)
{
fileCount= ttSCCFiles.length;
//check to see if file exists
boolean sccFileExists = false;
for (int i = 0;i < fileCount; i++)
{
if (ttSCCFiles[i].getMstrFileName().equals(sccFile))
{
ttSCCFiles[i].setMstrFixedRevision(ttSCCFiles[i].getMstrFixedRevision() + "," + scmVersion);
sccFileExists = true;
}
}
if (sccFileExists == false)
{
CSCCFileRecord[] ttNSCCFiles = new CSCCFileRecord[fileCount + 1];
for (int i = 0; i < fileCount; i++)
{
ttNSCCFiles[i] = new CSCCFileRecord();
ttNSCCFiles[i].setMdateFixedTimestamp(ttSCCFiles[i].getMdateFixedTimestamp());
ttNSCCFiles[i].setMstrFileName(ttSCCFiles[i].getMstrFileName());
ttNSCCFiles[i].setMstrFixedRevision(ttSCCFiles[i].getMstrFixedRevision());
}
ttNSCCFiles[fileCount] = new CSCCFileRecord();
ttNSCCFiles[fileCount].setMstrFileName(sccFile);
ttNSCCFiles[fileCount].setMstrFixedRevision(scmVersion);
ttNSCCFiles[fileCount].setMdateFixedTimestamp(cal);
theDefect.setPSCCFileList(ttNSCCFiles);
}
}
else
{
CSCCFileRecord[] ttNSCCFiles = new CSCCFileRecord[fileCount + 1];
ttNSCCFiles[fileCount] = new CSCCFileRecord();
ttNSCCFiles[fileCount].setMstrFileName(sccFile);
ttNSCCFiles[fileCount].setMstrFixedRevision(scmVersion);
ttNSCCFiles[fileCount].setMdateFixedTimestamp(cal);
theDefect.setPSCCFileList(ttNSCCFiles);
}
_ttsoapcgi.saveDefect(ttCookie, theDefect);
_ttsoapcgi.databaseLogoff(ttCookie);
}
}
catch(Exception ex)
{
java.util.logging.Logger.getLogger(testtrack_Interface.Ttsoapcgi.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
try
{
FileWriter outFile = new FileWriter("c:\\errorpromote.txt");
PrintWriter out = new PrintWriter(outFile);
out.println("The following error was encountered:");
out.println(ex.getMessage());
out.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
} Python Example
By far the most difficult, since you have to build the XML envelope from scratch. This script, however, can handle more than one defect number being passed.
This script is based on this one.
import getopt
import httplib
import os
import StringIO
import sys
import time
import xml
from xml.dom import DOMImplementation, DocumentType
from xml.dom.ext import PrettyPrint
import xml.dom.minidom
class Usage(Exception):
def __init__(self, msg):
self.msg = msg
c_soapaddr = "127.0.0.1"
c_soapport = 80
c_soapcgi = "http://127.0.0.1/scripts/ttsoapcgi.exe"
c_project = "Sample Project"
m_comments = ""
def parseComments(p_comments):
#First, make sure we find the token
istart = p_comments.find("<:")
#if token found
if istart >= 0:
#find end of token
iend = p_comments.find(":>", istart)
#extract from the comments the token
ttpcomments = p_comments[istart+2:iend]
icomma1=istart
icomma2=0
defectnum = ""
defectList = []
defectCount = 0
while icomma2 >= 0 :
icomma2 = ttpcomments.find(",", icomma1)
#icomma2 will be -1 once it does not find a comma in the remmainning portion,
#so we know that is the last item in the token
if icomma2 == -1:
defectnum = ttpcomments[icomma1:len(ttpcomments)]
defectList[defectCount:0] = [defectnum]
else:
defectnum = ttpcomments[icomma1:icomma2]
defectList[defectCount:0] = [defectnum]
defectCount = defectCount + 1
#reset the starting position
icomma1 = icomma2+1
return defectList
def login(p_user, p_pwd):
dom = DOMImplementation.getDOMImplementation ()
typ = xml.dom.DocumentType.DocumentType ("Envelope", [], [], "", "")
# this is not the namespace required by soap 1.2
# but the service requires this namespace (from error message)
doc = dom.createDocument ("http://schemas.xmlsoap.org/soap/envelope/", "Envelope", typ)
env = doc.getElementsByTagName ("Envelope")[0]
bdy = doc.createElement ("Body")
env.appendChild (bdy)
msg = doc.createElementNS ("urn:testtrack-interface", "DatabaseLogon")
bdy.appendChild (msg)
eleProject = doc.createElement("dbname")
eleProject.setAttributeNode( doc.createAttribute("xsi:type"))
eleProject.setAttribute("xsi:type", "xsd:string")
msg.appendChild(eleProject)
eleProject.appendChild(doc.createTextNode(str(c_project)))
eleUser = doc.createElement("username")
eleUser.setAttributeNode( doc.createAttribute("xsi:type"))
eleUser.setAttribute("xsi:type", "xsd:string")
msg.appendChild(eleUser)
eleUser.appendChild(doc.createTextNode(str(p_user)))
elePwd = doc.createElement("password")
elePwd.setAttributeNode( doc.createAttribute("xsi:type"))
elePwd.setAttribute("xsi:type", "xsd:string")
msg.appendChild(elePwd)
elePwd.appendChild(doc.createTextNode(str(p_pwd)))
# Let's lock the defect for editing!
buffer = StringIO.StringIO()
PrettyPrint(doc, buffer)
request = buffer.getvalue()
#print request #DEBUG
httpsvr = httplib.HTTPConnection(c_soapaddr, c_soapport)
httpsvr.putrequest("POST", c_soapcgi)
httpsvr.putheader("Content-Type", "text/xml")
httpsvr.putheader("Content-Length", str(len(request)))
httpsvr.endheaders()
httpsvr.send(request)
response = httpsvr.getresponse()
session = response.read()
print "DatabaseLogon", response.status, response.reason
return session[session.find("<Cookie>")+8:session.find("</Cookie>")]
def logout(p_session):
dom = DOMImplementation.getDOMImplementation ()
typ = xml.dom.DocumentType.DocumentType ("Envelope", [], [], "", "")
# this is not the namespace required by soap 1.2
# but the service requires this namespace (from error message)
doc = dom.createDocument ("http://schemas.xmlsoap.org/soap/envelope/", "Envelope", typ)
env = doc.getElementsByTagName ("Envelope")[0]
bdy = doc.createElement ("Body")
env.appendChild (bdy)
msg = doc.createElementNS ("urn:testtrack-interface", "DatabaseLogoff")
bdy.appendChild (msg)
eleCookie = doc.createElement("cookie")
eleCookie.setAttributeNode( doc.createAttribute("xsi:type"))
eleCookie.setAttribute("xsi:type", "xsd:int")
msg.appendChild(eleCookie)
eleCookie.appendChild(doc.createTextNode(str(p_session)))
# Let's lock the defect for editing!
buffer = StringIO.StringIO()
PrettyPrint(doc, buffer)
request = buffer.getvalue()
httpsvr = httplib.HTTPConnection(c_soapaddr, c_soapport)
httpsvr.putrequest("POST", c_soapcgi)
httpsvr.putheader("Content-Type", "text/xml")
httpsvr.putheader("Content-Length", str(len(request)))
httpsvr.endheaders()
httpsvr.send(request)
response = httpsvr.getresponse()
print "DatabaseLogoff", response.status, response.reason
def updateDefect(p_session, p_defectnumber, p_revnum, p_file, p_fixdate):
dom = DOMImplementation.getDOMImplementation ()
typ = xml.dom.DocumentType.DocumentType ("Envelope", [], [], "", "")
# this is not the namespace required by soap 1.2
# but the service requires this namespace (from error message)
doc = dom.createDocument ("http://schemas.xmlsoap.org/soap/envelope/", "Envelope", typ)
env = doc.getElementsByTagName ("Envelope")[0]
bdy = doc.createElement ("Body")
env.appendChild (bdy)
msg = doc.createElementNS ("urn:testtrack-interface", "editDefect")
bdy.appendChild (msg)
eleCookie = doc.createElement("cookie")
eleCookie.setAttributeNode( doc.createAttribute("xsi:type"))
eleCookie.setAttribute("xsi:type", "xsd:int")
msg.appendChild(eleCookie)
eleCookie.appendChild(doc.createTextNode(str(p_session)))
eleNum = doc.createElement("defectNumber")
eleNum.setAttributeNode( doc.createAttribute("xsi:type"))
eleNum.setAttribute("xsi:type", "xsd:int")
msg.appendChild(eleNum)
eleNum.appendChild(doc.createTextNode(str(p_defectnumber)))
eleSummary = doc.createElement("summary")
eleSummary.setAttributeNode( doc.createAttribute("xsi:type"))
eleSummary.setAttribute("xsi:type", "xsd:string")
msg.appendChild(eleSummary)
eleSummary.appendChild(doc.createTextNode(""))
eleDnldAtt = doc.createElement("bDownloadAttachments")
eleDnldAtt.setAttributeNode( doc.createAttribute("xsi:type"))
eleDnldAtt.setAttribute("xsi:type", "xsd:boolean")
msg.appendChild(eleDnldAtt)
eleDnldAtt.appendChild(doc.createTextNode("false"))
# Let's lock the defect for editing!
buffer = StringIO.StringIO()
PrettyPrint(doc, buffer)
request = buffer.getvalue()
httpsvr = httplib.HTTPConnection(c_soapaddr, c_soapport)
httpsvr.putrequest("POST", c_soapcgi)
httpsvr.putheader("Content-Type", "text/xml")
httpsvr.putheader("Content-Length", str(len(request)))
httpsvr.endheaders()
httpsvr.send(request)
response = httpsvr.getresponse()
respDefect = response.read()
# Replace 'editDefectRequest' with 'saveDefect' and we're ready to use this block to save changes.
dom = xml.dom.minidom.parseString(respDefect.replace("editDefectResponse", "saveDefect"))
eleSaveDefect = dom.getElementsByTagName("ttns:saveDefect")
if (len(eleSaveDefect) == 0):
return # defect wasn't found!
eleCookie = dom.createElement("cookie")
eleCookie.setAttributeNode( dom.createAttribute("xsi:type"))
eleCookie.setAttribute("xsi:type", "xsd:int")
eleCookie.appendChild(dom.createTextNode(str(p_session)))
eleSaveDefect[0].appendChild(eleCookie)
eleDefect = dom.getElementsByTagName("pDefect")[0]
# first, go through and fix all of the item tags to have all of the required child elements for events.
# The response doesn't include 'value' child elements for date fields w/o a value set.
eleEvents = dom.getElementsByTagName("eventlist")
if (len(eleEvents) > 0):
eleEvents = eleEvents[0]
records = eleEvents.getElementsByTagName("fieldlist") # there are multiple item elements and we only care about custom fields.
iRecCount = len(records)
for item in records:
recItems = item.getElementsByTagName("item")
for itemField in recItems:
if (itemField.getAttribute("xsi:type") == "ttns:CDateField"): # only handle DateField types
eleValue = itemField.getElementsByTagName("value")
if (len(eleValue) == 0):
eleValue = dom.createElement("value")
itemField.appendChild( eleValue)
eleValue.appendChild( dom.createTextNode("0001-01-01")) # element has to have a closing bracket, or TTP can't handle it.
else:
eleTextNode = eleValue[0].childNodes
if (len(eleTextNode) == 0):
eleValue[0].appendChild( dom.createTextNode("0001-01-01")) # element has to have a closing bracket, or TTP can't handle it.
# second, go through and fix all of the item tags to have all of the required child elements for custom fields.
# The response doesn't include 'value' child elements for date fields w/o a value set.
eleCustom = dom.getElementsByTagName("customFieldList")
if (len(eleCustom) > 0):
eleCustom = eleCustom[0]
records = eleCustom.getElementsByTagName("item")
iRecCount = len(records)
for item in records:
if (item.getAttribute("xsi:type") == "ttns:CDateField"): # only handle DateField types
eleValue = item.getElementsByTagName("value")
if (len(eleValue) == 0):
eleValue = dom.createElement("value")
item.appendChild( eleValue)
eleValue.appendChild( dom.createTextNode("0001-01-01")) # element has to have a closing bracket, or TTP can't handle it.
else:
eleTextNode = eleValue[0].childNodes
if (len(eleTextNode) == 0):
eleValue[0].appendChild( dom.createTextNode("0001-01-01")) # element has to have a closing bracket, or TTP can't handle it.
eleSCCI = dom.getElementsByTagName("pSCCFileList")
# If the defect has no SCC files attached, then the response will not include the pSCCIFileList element so create it here.
if (len(eleSCCI) == 0):
eleSCCI = dom.createElement("pSCCFileList")
eleDefect.appendChild(eleSCCI)
eleSCCI.setAttributeNode( dom.createAttribute("xsi:type"))
eleSCCI.setAttribute("xsi:type", "SOAP-ENC:Array")
else:
eleSCCI = eleSCCI[0]
# Now, go through and fix all of item tags to have all of the required child elements. The
# response doesn't include child elements of item if the value is blank ie. m-strFixedRevision
# will not have an element for an item where it has no value. This won't work on the save, so fix it here.
records = eleSCCI.getElementsByTagName("item")
iRecCount = len(records)
for item in records:
eleFRev = item.getElementsByTagName("m-strFixedRevision")
if (len(eleFRev) == 0):
eleFRev = dom.createElement("m-strFixedRevision")
item.appendChild( eleFRev)
eleFRev.setAttributeNode( dom.createAttribute("xsi:type"))
eleFRev.setAttribute("xsi:type", "xsd:string")
eleFRev.appendChild( dom.createTextNode(""))
eleFDate = item.getElementsByTagName("m-dateFixedTimestamp")
if (len(eleFDate) == 0):
eleFDate = dom.createElement("m-dateFixedTimestamp")
item.appendChild( eleFDate)
eleFDate.setAttributeNode( dom.createAttribute("xsi:type"))
eleFDate.setAttribute("xsi:type", "xsd:dateTime")
eleFDate.appendChild( dom.createTextNode(""))
# Ok! The saveDefect request is now valid. All we have to do now is update it based on the current file.
records = eleSCCI.getElementsByTagName("item")
fFound = 0
if (len(records) > 0):
for item in records:
eleFName = item.getElementsByTagName("m-strFileName")
if (len(eleFName) > 0):
if (eleFName[0].firstChild.nodeValue == p_file):
# file is already attached, so just add to the rev and make sure all of the elements are present
fFound = 1
eleFRev = item.getElementsByTagName("m-strFixedRevision")
if (len(eleFRev) == 0):
eleFRev = dom.createElement("m-strFixedRevision")
item.appendChild( eleFRev)
eleFRev.setAttributeNode( dom.createAttribute("xsi:type"))
eleFRev.setAttribute("xsi:type", "xsd:string")
eleFRev.appendChild( dom.createTextNode(str(p_revnum)))
else:
if (len(eleFRev[0].firstChild.nodeValue) > 0):
eleFRev[0].firstChild.nodeValue = eleFRev[0].firstChild.nodeValue + ", " + str(p_revnum)
else:
eleFRev[0].firstChild.nodeValue = str(p_revnum)
if fFound == 0: # File not already attached to defect, so let's add it here.
iRecCount = iRecCount + 1
eleItem = dom.createElement("item")
eleSCCI.appendChild( eleItem)
eleItem.setAttributeNode( dom.createAttribute("xsi:type"))
eleItem.setAttribute("xsi:type", "ttns:CSCCFileRecord")
eleRecId = dom.createElement("recordid")
eleItem.appendChild( eleRecId)
eleRecId.setAttributeNode( dom.createAttribute("xsi:type"))
eleRecId.setAttribute("xsi:type", "xsd:int")
eleRecId.appendChild( dom.createTextNode("0"))
eleFName = dom.createElement("m-strFileName")
eleItem.appendChild( eleFName)
eleFName.setAttributeNode( dom.createAttribute("xsi:type"))
eleFName.setAttribute("xsi:type", "xsd:string")
eleFName.appendChild( dom.createTextNode(p_file))
eleFRev = dom.createElement("m-strFixedRevision")
eleItem.appendChild( eleFRev)
eleFRev.setAttributeNode( dom.createAttribute("xsi:type"))
eleFRev.setAttribute("xsi:type", "xsd:string")
eleFRev.appendChild( dom.createTextNode(str(p_revnum)))
eleFDate = dom.createElement("m-dateFixedTimestamp")
eleItem.appendChild( eleFDate)
eleFDate.setAttributeNode( dom.createAttribute("xsi:type"))
eleFDate.setAttribute("xsi:type", "xsd:dateTime")
eleFDate.appendChild( dom.createTextNode((p_fixdate)))
# Update the pSCCIFileList element's type attribute to correctly reflect how many files are attached.
eleSCCI.setAttributeNode( dom.createAttribute("SOAP-ENC:arrayType"))
eleSCCI.setAttribute( "SOAP-ENC:arrayType", "ttns:CSCCFileRecord[" + str(iRecCount) + "]")
# Let's save the defect!
buffer = StringIO.StringIO ()
PrettyPrint (dom, buffer)
request = buffer.getvalue ()
#print request #DEBUG
httpsvr = httplib.HTTPConnection(c_soapaddr, c_soapport)
httpsvr.putrequest("POST", c_soapcgi)
httpsvr.putheader("Content-Type", "text/xml")
httpsvr.putheader("Content-Length", str(len(request)))
httpsvr.endheaders()
httpsvr.send(request)
resp = httpsvr.getresponse()
print "saveDefect", resp.status, resp.reason
def main(argv=None):
if argv is None:
argv = sys.argv
try:
try:
log = file('C:\defectlist.log', 'w')
log.write("starting...")
m_branch = os.environ.get("SSCM_BRANCH")
m_repo = os.environ.get("SSCM_REPOSITORY")
m_file = os.environ.get("SSCM_FILE")
m_version = os.environ.get("SSCM_FILEVERSION")
m_date = os.environ.get("SSCM_DATE")
m_comments = os.environ.get("SSCM_COMMENT")
log.write(m_branch + "\n")
log.write(m_repo + "\n")
log.write(m_file + "\n")
log.write(m_version + "\n")
log.write(m_date + "\n")
log.write(m_comments + "\n")
sccFile = m_branch + "::" + m_repo + m_file
opts, args = getopt.getopt(argv[1:], "h", ["help"])
m_defects = parseComments(m_comments)
for defect in m_defects:
log.write(defect + "\n")
try:
session = login("Administrator", "password")
if session > 0:
updateDefect(session, defect, m_version, sccFile,m_date)
logout(session)
except getopt.error, msg:
raise Usage(msg)
except getopt.error, msg:
raise Usage(msg)
# more code, unchanged
except Usage, err:
print >>sys.stderr, err.msg
print >>sys.stderr, "for help use --help"
return 2
if __name__ == "__main__":
sys.exit(main())Related posts:









